aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/musb/davinci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/davinci.c')
-rw-r--r--drivers/usb/musb/davinci.c171
1 files changed, 82 insertions, 89 deletions
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 7c569f51212..de8492b06e4 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -24,16 +24,18 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/init.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
+#include <linux/usb/usb_phy_generic.h>
#include <mach/cputype.h>
+#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -113,8 +115,7 @@ static void davinci_musb_enable(struct musb *musb)
dma_off = 0;
/* force a DRVVBUS irq so we can start polling for ID change */
- if (is_otg_enabled(musb))
- musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
+ musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
DAVINCI_INTR_DRVVBUS << DAVINCI_USB_USBINT_SHIFT);
}
@@ -213,7 +214,7 @@ static void otg_timer(unsigned long _musb)
*/
devctl = musb_readb(mregs, MUSB_DEVCTL);
dev_dbg(musb->controller, "poll devctl %02x (%s)\n", devctl,
- otg_state_string(musb->xceiv->state));
+ usb_otg_state_string(musb->xceiv->state));
spin_lock_irqsave(&musb->lock, flags);
switch (musb->xceiv->state) {
@@ -232,10 +233,8 @@ static void otg_timer(unsigned long _musb)
MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
break;
case OTG_STATE_B_IDLE:
- if (!is_peripheral_enabled(musb))
- break;
-
- /* There's no ID-changed IRQ, so we have no good way to tell
+ /*
+ * There's no ID-changed IRQ, so we have no good way to tell
* when to switch to the A-Default state machine (by setting
* the DEVCTL.SESSION flag).
*
@@ -265,6 +264,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
unsigned long flags;
irqreturn_t retval = IRQ_NONE;
struct musb *musb = __hci;
+ struct usb_otg *otg = musb->xceiv->otg;
void __iomem *tibase = musb->ctrl_base;
struct cppi *cppi;
u32 tmp;
@@ -312,8 +312,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
u8 devctl = musb_readb(mregs, MUSB_DEVCTL);
int err = musb->int_usb & MUSB_INTR_VBUSERROR;
- err = is_host_enabled(musb)
- && (musb->int_usb & MUSB_INTR_VBUSERROR);
+ err = musb->int_usb & MUSB_INTR_VBUSERROR;
if (err) {
/* The Mentor core doesn't debounce VBUS as needed
* to cope with device connect current spikes. This
@@ -329,16 +328,16 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
WARNING("VBUS error workaround (delay coming)\n");
- } else if (is_host_enabled(musb) && drvvbus) {
+ } else if (drvvbus) {
MUSB_HST_MODE(musb);
- musb->xceiv->default_a = 1;
+ otg->default_a = 1;
musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
portstate(musb->port1_status |= USB_PORT_STAT_POWER);
del_timer(&otg_workaround);
} else {
musb->is_active = 0;
MUSB_DEV_MODE(musb);
- musb->xceiv->default_a = 0;
+ otg->default_a = 0;
musb->xceiv->state = OTG_STATE_B_IDLE;
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
}
@@ -349,7 +348,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
davinci_musb_source_power(musb, drvvbus, 0);
dev_dbg(musb->controller, "VBUS %s (%s)%s, devctl %02x\n",
drvvbus ? "on" : "off",
- otg_state_string(musb->xceiv->state),
+ usb_otg_state_string(musb->xceiv->state),
err ? " ERROR" : "",
devctl);
retval = IRQ_HANDLED;
@@ -362,8 +361,7 @@ static irqreturn_t davinci_musb_interrupt(int irq, void *__hci)
musb_writel(tibase, DAVINCI_USB_EOI_REG, 0);
/* poll for ID change */
- if (is_otg_enabled(musb)
- && musb->xceiv->state == OTG_STATE_B_IDLE)
+ if (musb->xceiv->state == OTG_STATE_B_IDLE)
mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
spin_unlock_irqrestore(&musb->lock, flags);
@@ -381,11 +379,13 @@ static int davinci_musb_init(struct musb *musb)
{
void __iomem *tibase = musb->ctrl_base;
u32 revision;
+ int ret = -ENODEV;
- usb_nop_xceiv_register();
- musb->xceiv = otg_get_transceiver();
- if (!musb->xceiv)
- return -ENODEV;
+ musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);
+ if (IS_ERR_OR_NULL(musb->xceiv)) {
+ ret = -EPROBE_DEFER;
+ goto unregister;
+ }
musb->mregs += DAVINCI_BASE_OFFSET;
@@ -394,8 +394,7 @@ static int davinci_musb_init(struct musb *musb)
if (revision == 0)
goto fail;
- if (is_host_enabled(musb))
- setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
+ setup_timer(&otg_workaround, otg_timer, (unsigned long) musb);
davinci_musb_source_power(musb, 0, 1);
@@ -416,12 +415,7 @@ static int davinci_musb_init(struct musb *musb)
if (cpu_is_davinci_dm355()) {
u32 deepsleep = __raw_readl(DM355_DEEPSLEEP);
- if (is_host_enabled(musb)) {
- deepsleep &= ~DRVVBUS_OVERRIDE;
- } else {
- deepsleep &= ~DRVVBUS_FORCE;
- deepsleep |= DRVVBUS_OVERRIDE;
- }
+ deepsleep &= ~DRVVBUS_FORCE;
__raw_writel(deepsleep, DM355_DEEPSLEEP);
}
@@ -442,15 +436,15 @@ static int davinci_musb_init(struct musb *musb)
return 0;
fail:
- otg_put_transceiver(musb->xceiv);
- usb_nop_xceiv_unregister();
- return -ENODEV;
+ usb_put_phy(musb->xceiv);
+unregister:
+ usb_phy_generic_unregister();
+ return ret;
}
static int davinci_musb_exit(struct musb *musb)
{
- if (is_host_enabled(musb))
- del_timer_sync(&otg_workaround);
+ del_timer_sync(&otg_workaround);
/* force VBUS off */
if (cpu_is_davinci_dm355()) {
@@ -464,7 +458,7 @@ static int davinci_musb_exit(struct musb *musb)
davinci_musb_source_power(musb, 0 /*off*/, 1);
/* delay, to avoid problems with module reload */
- if (is_host_enabled(musb) && musb->xceiv->default_a) {
+ if (musb->xceiv->otg->default_a) {
int maxdelay = 30;
u8 devctl, warn = 0;
@@ -491,8 +485,7 @@ static int davinci_musb_exit(struct musb *musb)
phy_off();
- otg_put_transceiver(musb->xceiv);
- usb_nop_xceiv_unregister();
+ usb_put_phy(musb->xceiv);
return 0;
}
@@ -509,13 +502,19 @@ static const struct musb_platform_ops davinci_ops = {
.set_vbus = davinci_musb_set_vbus,
};
-static u64 davinci_dmamask = DMA_BIT_MASK(32);
+static const struct platform_device_info davinci_dev_info = {
+ .name = "musb-hdrc",
+ .id = PLATFORM_DEVID_AUTO,
+ .dma_mask = DMA_BIT_MASK(32),
+};
-static int __init davinci_probe(struct platform_device *pdev)
+static int davinci_probe(struct platform_device *pdev)
{
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
+ struct resource musb_resources[3];
+ struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct platform_device *musb;
struct davinci_glue *glue;
+ struct platform_device_info pinfo;
struct clk *clk;
int ret = -ENOMEM;
@@ -526,80 +525,84 @@ static int __init davinci_probe(struct platform_device *pdev)
goto err0;
}
- musb = platform_device_alloc("musb-hdrc", -1);
- if (!musb) {
- dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err1;
- }
-
clk = clk_get(&pdev->dev, "usb");
if (IS_ERR(clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
ret = PTR_ERR(clk);
- goto err2;
+ goto err3;
}
ret = clk_enable(clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
- goto err3;
+ goto err4;
}
- musb->dev.parent = &pdev->dev;
- musb->dev.dma_mask = &davinci_dmamask;
- musb->dev.coherent_dma_mask = davinci_dmamask;
-
glue->dev = &pdev->dev;
- glue->musb = musb;
glue->clk = clk;
pdata->platform_ops = &davinci_ops;
+ usb_phy_generic_register();
platform_set_drvdata(pdev, glue);
- ret = platform_device_add_resources(musb, pdev->resource,
- pdev->num_resources);
- if (ret) {
- dev_err(&pdev->dev, "failed to add resources\n");
- goto err4;
- }
+ memset(musb_resources, 0x00, sizeof(*musb_resources) *
+ ARRAY_SIZE(musb_resources));
- ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
- if (ret) {
- dev_err(&pdev->dev, "failed to add platform_data\n");
- goto err4;
- }
+ musb_resources[0].name = pdev->resource[0].name;
+ musb_resources[0].start = pdev->resource[0].start;
+ musb_resources[0].end = pdev->resource[0].end;
+ musb_resources[0].flags = pdev->resource[0].flags;
- ret = platform_device_add(musb);
- if (ret) {
- dev_err(&pdev->dev, "failed to register musb device\n");
- goto err4;
+ musb_resources[1].name = pdev->resource[1].name;
+ musb_resources[1].start = pdev->resource[1].start;
+ musb_resources[1].end = pdev->resource[1].end;
+ musb_resources[1].flags = pdev->resource[1].flags;
+
+ /*
+ * For DM6467 3 resources are passed. A placeholder for the 3rd
+ * resource is always there, so it's safe to always copy it...
+ */
+ musb_resources[2].name = pdev->resource[2].name;
+ musb_resources[2].start = pdev->resource[2].start;
+ musb_resources[2].end = pdev->resource[2].end;
+ musb_resources[2].flags = pdev->resource[2].flags;
+
+ pinfo = davinci_dev_info;
+ pinfo.parent = &pdev->dev;
+ pinfo.res = musb_resources;
+ pinfo.num_res = ARRAY_SIZE(musb_resources);
+ pinfo.data = pdata;
+ pinfo.size_data = sizeof(*pdata);
+
+ glue->musb = musb = platform_device_register_full(&pinfo);
+ if (IS_ERR(musb)) {
+ ret = PTR_ERR(musb);
+ dev_err(&pdev->dev, "failed to register musb device: %d\n", ret);
+ goto err5;
}
return 0;
-err4:
+err5:
clk_disable(clk);
-err3:
+err4:
clk_put(clk);
-err2:
- platform_device_put(musb);
-
-err1:
+err3:
kfree(glue);
err0:
return ret;
}
-static int __exit davinci_remove(struct platform_device *pdev)
+static int davinci_remove(struct platform_device *pdev)
{
struct davinci_glue *glue = platform_get_drvdata(pdev);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
+ platform_device_unregister(glue->musb);
+ usb_phy_generic_unregister();
clk_disable(glue->clk);
clk_put(glue->clk);
kfree(glue);
@@ -608,7 +611,8 @@ static int __exit davinci_remove(struct platform_device *pdev)
}
static struct platform_driver davinci_driver = {
- .remove = __exit_p(davinci_remove),
+ .probe = davinci_probe,
+ .remove = davinci_remove,
.driver = {
.name = "musb-davinci",
},
@@ -617,15 +621,4 @@ static struct platform_driver davinci_driver = {
MODULE_DESCRIPTION("DaVinci MUSB Glue Layer");
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
MODULE_LICENSE("GPL v2");
-
-static int __init davinci_init(void)
-{
- return platform_driver_probe(&davinci_driver, davinci_probe);
-}
-subsys_initcall(davinci_init);
-
-static void __exit davinci_exit(void)
-{
- platform_driver_unregister(&davinci_driver);
-}
-module_exit(davinci_exit);
+module_platform_driver(davinci_driver);