diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/Kconfig | 5 | ||||
-rw-r--r-- | drivers/usb/musb/am35x.c | 63 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 13 | ||||
-rw-r--r-- | drivers/usb/musb/da8xx.c | 49 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 59 | ||||
-rw-r--r-- | drivers/usb/musb/musb_am335x.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 26 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 172 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 96 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_virthub.c | 19 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 54 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 49 | ||||
-rw-r--r-- | drivers/usb/musb/ux500.c | 15 |
16 files changed, 263 insertions, 369 deletions
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 57dfc0c..c258a97 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -75,7 +75,6 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" depends on ARCH_OMAP2PLUS - select GENERIC_PHY config USB_MUSB_AM35X tristate "AM35x" @@ -91,7 +90,7 @@ config USB_MUSB_BLACKFIN depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523) config USB_MUSB_UX500 - tristate "Ux500 platforms" + tristate "U8500 and U5500" endchoice @@ -113,7 +112,7 @@ choice allow using DMA on multiplatform kernels. config USB_UX500_DMA - bool 'ST Ericsson Ux500' + bool 'ST Ericsson U8500 and U5500' depends on USB_MUSB_UX500 help Enable DMA transfers on UX500 platforms. diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index ca45b39..5c310c6 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -89,6 +89,7 @@ struct am35x_glue { struct clk *phy_clk; struct clk *clk; }; +#define glue_to_musb(g) platform_get_drvdata(g->musb) /* * am35x_musb_enable - enable interrupts @@ -451,18 +452,14 @@ static const struct musb_platform_ops am35x_ops = { .set_vbus = am35x_musb_set_vbus, }; -static const struct platform_device_info am35x_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; +static u64 am35x_dmamask = DMA_BIT_MASK(32); static int am35x_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); struct platform_device *musb; struct am35x_glue *glue; - struct platform_device_info pinfo; + struct clk *phy_clk; struct clk *clk; @@ -474,6 +471,12 @@ static int am35x_probe(struct platform_device *pdev) goto err0; } + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); + goto err1; + } + phy_clk = clk_get(&pdev->dev, "fck"); if (IS_ERR(phy_clk)) { dev_err(&pdev->dev, "failed to get PHY clock\n"); @@ -500,7 +503,12 @@ static int am35x_probe(struct platform_device *pdev) goto err6; } + musb->dev.parent = &pdev->dev; + musb->dev.dma_mask = &am35x_dmamask; + musb->dev.coherent_dma_mask = am35x_dmamask; + glue->dev = &pdev->dev; + glue->musb = musb; glue->phy_clk = phy_clk; glue->clk = clk; @@ -508,17 +516,22 @@ static int am35x_probe(struct platform_device *pdev) platform_set_drvdata(pdev, glue); - pinfo = am35x_dev_info; - pinfo.parent = &pdev->dev; - pinfo.res = pdev->resource; - pinfo.num_res = pdev->num_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); + ret = platform_device_add_resources(musb, pdev->resource, + pdev->num_resources); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err7; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err7; + } + + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); goto err7; } @@ -537,6 +550,9 @@ err4: clk_put(phy_clk); err3: + platform_device_put(musb); + +err1: kfree(glue); err0: @@ -599,16 +615,23 @@ static int am35x_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(am35x_pm_ops, am35x_suspend, am35x_resume); +static struct dev_pm_ops am35x_pm_ops = { + .suspend = am35x_suspend, + .resume = am35x_resume, +}; + +#define DEV_PM_OPS &am35x_pm_ops +#else +#define DEV_PM_OPS NULL +#endif static struct platform_driver am35x_driver = { .probe = am35x_probe, .remove = am35x_remove, .driver = { .name = "musb-am35x", - .pm = &am35x_pm_ops, + .pm = DEV_PM_OPS, }, }; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index d9692f7..72e2056 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -561,16 +561,23 @@ static int bfin_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(bfin_pm_ops, bfin_suspend, bfin_resume); +static struct dev_pm_ops bfin_pm_ops = { + .suspend = bfin_suspend, + .resume = bfin_resume, +}; + +#define DEV_PM_OPS &bfin_pm_ops +#else +#define DEV_PM_OPS NULL +#endif static struct platform_driver bfin_driver = { .probe = bfin_probe, .remove = __exit_p(bfin_remove), .driver = { .name = "musb-blackfin", - .pm = &bfin_pm_ops, + .pm = DEV_PM_OPS, }, }; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 2f2c1cb..d9ddf41 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -472,11 +472,7 @@ static const struct musb_platform_ops da8xx_ops = { .set_vbus = da8xx_musb_set_vbus, }; -static const struct platform_device_info da8xx_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; +static u64 da8xx_dmamask = DMA_BIT_MASK(32); static int da8xx_probe(struct platform_device *pdev) { @@ -484,7 +480,7 @@ static int da8xx_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); struct platform_device *musb; struct da8xx_glue *glue; - struct platform_device_info pinfo; + struct clk *clk; int ret = -ENOMEM; @@ -495,6 +491,12 @@ static int da8xx_probe(struct platform_device *pdev) goto err0; } + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); + goto err1; + } + clk = clk_get(&pdev->dev, "usb20"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clock\n"); @@ -508,7 +510,12 @@ static int da8xx_probe(struct platform_device *pdev) goto err4; } + musb->dev.parent = &pdev->dev; + musb->dev.dma_mask = &da8xx_dmamask; + musb->dev.coherent_dma_mask = da8xx_dmamask; + glue->dev = &pdev->dev; + glue->musb = musb; glue->clk = clk; pdata->platform_ops = &da8xx_ops; @@ -528,17 +535,22 @@ static int da8xx_probe(struct platform_device *pdev) musb_resources[1].end = pdev->resource[1].end; musb_resources[1].flags = pdev->resource[1].flags; - pinfo = da8xx_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); + ret = platform_device_add_resources(musb, musb_resources, + ARRAY_SIZE(musb_resources)); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err5; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err5; + } + + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); goto err5; } @@ -551,6 +563,9 @@ err4: clk_put(clk); err3: + platform_device_put(musb); + +err1: kfree(glue); err0: diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 1121fd7..ed0834e 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -505,19 +505,14 @@ static const struct musb_platform_ops davinci_ops = { .set_vbus = davinci_musb_set_vbus, }; -static const struct platform_device_info davinci_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; +static u64 davinci_dmamask = DMA_BIT_MASK(32); static int davinci_probe(struct platform_device *pdev) { - struct resource musb_resources[3]; + struct resource musb_resources[2]; 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; @@ -528,6 +523,12 @@ static int davinci_probe(struct platform_device *pdev) goto err0; } + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + 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"); @@ -541,7 +542,12 @@ static int davinci_probe(struct platform_device *pdev) 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; @@ -561,26 +567,22 @@ static int davinci_probe(struct platform_device *pdev) 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); + ret = platform_device_add_resources(musb, musb_resources, + ARRAY_SIZE(musb_resources)); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err5; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err5; + } + + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); goto err5; } @@ -593,6 +595,9 @@ err4: clk_put(clk); err3: + platform_device_put(musb); + +err1: kfree(glue); err0: diff --git a/drivers/usb/musb/musb_am335x.c b/drivers/usb/musb/musb_am335x.c index 8be9b02..41ac5b5 100644 --- a/drivers/usb/musb/musb_am335x.c +++ b/drivers/usb/musb/musb_am335x.c @@ -46,7 +46,7 @@ static struct platform_driver am335x_child_driver = { .remove = am335x_child_remove, .driver = { .name = "am335x-usb-childs", - .of_match_table = am335x_child_of_match, + .of_match_table = of_match_ptr(am335x_child_of_match), }, }; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4d4499b..cd70cc8 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -617,7 +617,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */ default: s = "VALID"; break; - } s; }), + }; s; }), VBUSERR_RETRY_COUNT - musb->vbuserr_retry, musb->port1_status); @@ -1809,6 +1809,8 @@ static void musb_free(struct musb *musb) disable_irq_wake(musb->nIrq); free_irq(musb->nIrq, musb); } + if (musb->dma_controller) + dma_controller_destroy(musb->dma_controller); musb_host_free(musb); } @@ -1883,21 +1885,13 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) pm_runtime_get_sync(musb->controller); - if (use_dma && dev->dma_mask) { + if (use_dma && dev->dma_mask) musb->dma_controller = dma_controller_create(musb, musb->mregs); - if (IS_ERR(musb->dma_controller)) { - status = PTR_ERR(musb->dma_controller); - goto fail2_5; - } - } /* be sure interrupts are disabled before connecting ISR */ musb_platform_disable(musb); musb_generic_disable(musb); - /* Init IRQ workqueue before request_irq */ - INIT_WORK(&musb->irq_work, musb_irq_work); - /* setup musb parts of the core (especially endpoints) */ status = musb_core_init(plat->config->multipoint ? MUSB_CONTROLLER_MHDRC @@ -1907,6 +1901,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); + /* Init IRQ workqueue before request_irq */ + INIT_WORK(&musb->irq_work, musb_irq_work); + /* attach to the IRQ */ if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) { dev_err(dev, "request_irq %d failed!\n", nIrq); @@ -1949,8 +1946,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status < 0) goto fail3; status = musb_gadget_setup(musb); - if (status) - musb_host_cleanup(musb); break; default: dev_err(dev, "unsupported port mode %d\n", musb->port_mode); @@ -1977,13 +1972,10 @@ fail5: fail4: musb_gadget_cleanup(musb); - musb_host_cleanup(musb); fail3: - cancel_work_sync(&musb->irq_work); if (musb->dma_controller) dma_controller_destroy(musb->dma_controller); -fail2_5: pm_runtime_put_sync(musb->controller); fail2: @@ -2040,10 +2032,6 @@ static int musb_remove(struct platform_device *pdev) musb_exit_debugfs(musb); musb_shutdown(pdev); - if (musb->dma_controller) - dma_controller_destroy(musb->dma_controller); - - cancel_work_sync(&musb->irq_work); musb_free(musb); device_init_wakeup(dev, 0); return 0; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 29f7cd7..1c5bf75 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -46,7 +46,6 @@ #include <linux/usb.h> #include <linux/usb/otg.h> #include <linux/usb/musb.h> -#include <linux/phy/phy.h> struct musb; struct musb_hw_ep; @@ -342,7 +341,6 @@ struct musb { u16 int_tx; struct usb_phy *xceiv; - struct phy *phy; int nIrq; unsigned irq_wake:1; diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index a12bd30..ae95974 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -38,7 +38,6 @@ struct cppi41_dma_channel { u32 prog_len; u32 transferred; u32 packet_sz; - struct list_head tx_check; }; #define MUSB_DMA_NUM_CHANNELS 15 @@ -48,8 +47,6 @@ struct cppi41_dma_controller { struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; struct musb *musb; - struct hrtimer early_tx; - struct list_head early_tx_list; u32 rx_mode; u32 tx_mode; u32 auto_req; @@ -99,27 +96,31 @@ static void update_rx_toggle(struct cppi41_dma_channel *cppi41_channel) cppi41_channel->usb_toggle = toggle; } -static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep) +static void cppi41_dma_callback(void *private_data) { - u8 epnum = hw_ep->epnum; - struct musb *musb = hw_ep->musb; - void __iomem *epio = musb->endpoints[epnum].regs; - u16 csr; + struct dma_channel *channel = private_data; + struct cppi41_dma_channel *cppi41_channel = channel->private_data; + struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; + struct musb *musb = hw_ep->musb; + unsigned long flags; + struct dma_tx_state txstate; + u32 transferred; - csr = musb_readw(epio, MUSB_TXCSR); - if (csr & MUSB_TXCSR_TXPKTRDY) - return false; - return true; -} + spin_lock_irqsave(&musb->lock, flags); -static void cppi41_dma_callback(void *private_data); + dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, + &txstate); + transferred = cppi41_channel->prog_len - txstate.residue; + cppi41_channel->transferred += transferred; -static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) -{ - struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; - struct musb *musb = hw_ep->musb; + dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", + hw_ep->epnum, cppi41_channel->transferred, + cppi41_channel->total_len); + + update_rx_toggle(cppi41_channel); - if (!cppi41_channel->prog_len) { + if (cppi41_channel->transferred == cppi41_channel->total_len || + transferred < cppi41_channel->packet_sz) { /* done, complete */ cppi41_channel->channel.actual_len = @@ -149,11 +150,13 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) remain_bytes, direction, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (WARN_ON(!dma_desc)) + if (WARN_ON(!dma_desc)) { + spin_unlock_irqrestore(&musb->lock, flags); return; + } dma_desc->callback = cppi41_dma_callback; - dma_desc->callback_param = &cppi41_channel->channel; + dma_desc->callback_param = channel; cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); dma_async_issue_pending(dc); @@ -163,117 +166,6 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) musb_writew(epio, MUSB_RXCSR, csr); } } -} - -static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer) -{ - struct cppi41_dma_controller *controller; - struct cppi41_dma_channel *cppi41_channel, *n; - struct musb *musb; - unsigned long flags; - enum hrtimer_restart ret = HRTIMER_NORESTART; - - controller = container_of(timer, struct cppi41_dma_controller, - early_tx); - musb = controller->musb; - - spin_lock_irqsave(&musb->lock, flags); - list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list, - tx_check) { - bool empty; - struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; - - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) { - list_del_init(&cppi41_channel->tx_check); - cppi41_trans_done(cppi41_channel); - } - } - - if (!list_empty(&controller->early_tx_list)) { - ret = HRTIMER_RESTART; - hrtimer_forward_now(&controller->early_tx, - ktime_set(0, 150 * NSEC_PER_USEC)); - } - - spin_unlock_irqrestore(&musb->lock, flags); - return ret; -} - -static void cppi41_dma_callback(void *private_data) -{ - struct dma_channel *channel = private_data; - struct cppi41_dma_channel *cppi41_channel = channel->private_data; - struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; - struct musb *musb = hw_ep->musb; - unsigned long flags; - struct dma_tx_state txstate; - u32 transferred; - bool empty; - - spin_lock_irqsave(&musb->lock, flags); - - dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie, - &txstate); - transferred = cppi41_channel->prog_len - txstate.residue; - cppi41_channel->transferred += transferred; - - dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n", - hw_ep->epnum, cppi41_channel->transferred, - cppi41_channel->total_len); - - update_rx_toggle(cppi41_channel); - - if (cppi41_channel->transferred == cppi41_channel->total_len || - transferred < cppi41_channel->packet_sz) - cppi41_channel->prog_len = 0; - - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) { - cppi41_trans_done(cppi41_channel); - } else { - struct cppi41_dma_controller *controller; - /* - * On AM335x it has been observed that the TX interrupt fires - * too early that means the TXFIFO is not yet empty but the DMA - * engine says that it is done with the transfer. We don't - * receive a FIFO empty interrupt so the only thing we can do is - * to poll for the bit. On HS it usually takes 2us, on FS around - * 110us - 150us depending on the transfer size. - * We spin on HS (no longer than than 25us and setup a timer on - * FS to check for the bit and complete the transfer. - */ - controller = cppi41_channel->controller; - - if (musb->g.speed == USB_SPEED_HIGH) { - unsigned wait = 25; - - do { - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) - break; - wait--; - if (!wait) - break; - udelay(1); - } while (1); - - empty = musb_is_tx_fifo_empty(hw_ep); - if (empty) { - cppi41_trans_done(cppi41_channel); - goto out; - } - } - list_add_tail(&cppi41_channel->tx_check, - &controller->early_tx_list); - if (!hrtimer_active(&controller->early_tx)) { - hrtimer_start_range_ns(&controller->early_tx, - ktime_set(0, 140 * NSEC_PER_USEC), - 40 * NSEC_PER_USEC, - HRTIMER_MODE_REL); - } - } -out: spin_unlock_irqrestore(&musb->lock, flags); } @@ -472,8 +364,6 @@ static int cppi41_is_compatible(struct dma_channel *channel, u16 maxpacket, WARN_ON(1); return 1; } - if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK) - return 0; if (cppi41_channel->is_tx) return 1; /* AM335x Advisory 1.0.13. No workaround for device RX mode */ @@ -498,7 +388,6 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE) return 0; - list_del_init(&cppi41_channel->tx_check); if (is_tx) { csr = musb_readw(epio, MUSB_TXCSR); csr &= ~MUSB_TXCSR_DMAENAB; @@ -595,7 +484,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) if (ret) goto err; - ret = -EINVAL; if (port > MUSB_DMA_NUM_CHANNELS || !port) goto err; if (is_tx) @@ -606,7 +494,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) cppi41_channel->controller = controller; cppi41_channel->port_num = port; cppi41_channel->is_tx = is_tx; - INIT_LIST_HEAD(&cppi41_channel->tx_check); musb_dma = &cppi41_channel->channel; musb_dma->private_data = cppi41_channel; @@ -616,7 +503,6 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) dc = dma_request_slave_channel(dev, str); if (!dc) { dev_err(dev, "Falied to request %s.\n", str); - ret = -EPROBE_DEFER; goto err; } cppi41_channel->dc = dc; @@ -624,7 +510,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) return 0; err: cppi41_release_all_dma_chans(controller); - return ret; + return -EINVAL; } void dma_controller_destroy(struct dma_controller *c) @@ -632,7 +518,6 @@ void dma_controller_destroy(struct dma_controller *c) struct cppi41_dma_controller *controller = container_of(c, struct cppi41_dma_controller, controller); - hrtimer_cancel(&controller->early_tx); cppi41_dma_controller_stop(controller); kfree(controller); } @@ -641,7 +526,7 @@ struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) { struct cppi41_dma_controller *controller; - int ret = 0; + int ret; if (!musb->controller->of_node) { dev_err(musb->controller, "Need DT for the DMA engine.\n"); @@ -652,9 +537,6 @@ struct dma_controller *dma_controller_create(struct musb *musb, if (!controller) goto kzalloc_fail; - hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - controller->early_tx.function = cppi41_recheck_tx_req; - INIT_LIST_HEAD(&controller->early_tx_list); controller->musb = musb; controller->controller.channel_alloc = cppi41_dma_channel_allocate; @@ -671,7 +553,5 @@ struct dma_controller *dma_controller_create(struct musb *musb, plat_get_fail: kfree(controller); kzalloc_fail: - if (ret == -EPROBE_DEFER) - return ERR_PTR(ret); return NULL; } diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 1901f6f..bd4138d 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -121,43 +121,6 @@ struct dsps_glue { unsigned long last_timer; /* last timer data for each instance */ }; -static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) -{ - struct device *dev = musb->controller; - struct dsps_glue *glue = dev_get_drvdata(dev->parent); - - if (timeout == 0) - timeout = jiffies + msecs_to_jiffies(3); - - /* Never idle if active, or when VBUS timeout is not set as host */ - if (musb->is_active || (musb->a_wait_bcon == 0 && - musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { - dev_dbg(musb->controller, "%s active, deleting timer\n", - usb_otg_state_string(musb->xceiv->state)); - del_timer(&glue->timer); - glue->last_timer = jiffies; - return; - } - if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE) - return; - - if (!musb->g.dev.driver) - return; - - if (time_after(glue->last_timer, timeout) && - timer_pending(&glue->timer)) { - dev_dbg(musb->controller, - "Longer idle timer already pending, ignoring...\n"); - return; - } - glue->last_timer = timeout; - - dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", - usb_otg_state_string(musb->xceiv->state), - jiffies_to_msecs(timeout - jiffies)); - mod_timer(&glue->timer, timeout); -} - /** * dsps_musb_enable - enable interrupts */ @@ -180,7 +143,6 @@ static void dsps_musb_enable(struct musb *musb) /* Force the DRVVBUS IRQ so we can start polling for ID change. */ dsps_writel(reg_base, wrp->coreintr_set, (1 << wrp->drvvbus) << wrp->usb_shift); - dsps_musb_try_idle(musb, 0); } /** @@ -209,7 +171,6 @@ static void otg_timer(unsigned long _musb) const struct dsps_musb_wrapper *wrp = glue->wrp; u8 devctl; unsigned long flags; - int skip_session = 0; /* * We poll because DSPS IP's won't expose several OTG-critical @@ -222,12 +183,10 @@ static void otg_timer(unsigned long _musb) spin_lock_irqsave(&musb->lock, flags); switch (musb->xceiv->state) { case OTG_STATE_A_WAIT_BCON: - dsps_writeb(musb->mregs, MUSB_DEVCTL, 0); - skip_session = 1; - /* fall */ + devctl &= ~MUSB_DEVCTL_SESSION; + dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl); - case OTG_STATE_A_IDLE: - case OTG_STATE_B_IDLE: + devctl = dsps_readb(musb->mregs, MUSB_DEVCTL); if (devctl & MUSB_DEVCTL_BDEVICE) { musb->xceiv->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(musb); @@ -235,21 +194,60 @@ static void otg_timer(unsigned long _musb) musb->xceiv->state = OTG_STATE_A_IDLE; MUSB_HST_MODE(musb); } - if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session) - dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION); - mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ); break; case OTG_STATE_A_WAIT_VFALL: musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; dsps_writel(musb->ctrl_base, wrp->coreintr_set, MUSB_INTR_VBUSERROR << wrp->usb_shift); break; + case OTG_STATE_B_IDLE: + devctl = dsps_readb(mregs, MUSB_DEVCTL); + if (devctl & MUSB_DEVCTL_BDEVICE) + mod_timer(&glue->timer, + jiffies + wrp->poll_seconds * HZ); + else + musb->xceiv->state = OTG_STATE_A_IDLE; + break; default: break; } spin_unlock_irqrestore(&musb->lock, flags); } +static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout) +{ + struct device *dev = musb->controller; + struct dsps_glue *glue = dev_get_drvdata(dev->parent); + + if (timeout == 0) + timeout = jiffies + msecs_to_jiffies(3); + + /* Never idle if active, or when VBUS timeout is not set as host */ + if (musb->is_active || (musb->a_wait_bcon == 0 && + musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) { + dev_dbg(musb->controller, "%s active, deleting timer\n", + usb_otg_state_string(musb->xceiv->state)); + del_timer(&glue->timer); + glue->last_timer = jiffies; + return; + } + if (musb->port_mode == MUSB_PORT_MODE_HOST) + return; + + if (time_after(glue->last_timer, timeout) && + timer_pending(&glue->timer)) { + dev_dbg(musb->controller, + "Longer idle timer already pending, ignoring...\n"); + return; + } + glue->last_timer = timeout; + + dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n", + usb_otg_state_string(musb->xceiv->state), + jiffies_to_msecs(timeout - jiffies)); + mod_timer(&glue->timer, timeout); +} + static irqreturn_t dsps_interrupt(int irq, void *hci) { struct musb *musb = hci; @@ -445,7 +443,7 @@ static int get_musb_port_mode(struct device *dev) case USB_DR_MODE_OTG: default: return MUSB_PORT_MODE_DUAL_ROLE; - } + }; } static int dsps_create_musb_pdev(struct dsps_glue *glue, @@ -633,7 +631,7 @@ static struct platform_driver dsps_usbss_driver = { .remove = dsps_remove, .driver = { .name = "musb-dsps", - .of_match_table = musb_dsps_of_match, + .of_match_table = of_match_ptr(musb_dsps_of_match), }, }; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 32fb057..3671898 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1121,7 +1121,7 @@ static int musb_gadget_enable(struct usb_ep *ep, case USB_ENDPOINT_XFER_BULK: s = "bulk"; break; case USB_ENDPOINT_XFER_INT: s = "int"; break; default: s = "iso"; break; - } s; }), + }; s; }), musb_ep->is_in ? "IN" : "OUT", musb_ep->dma ? "dma, " : "", musb_ep->packet_sz); @@ -1796,11 +1796,7 @@ int musb_gadget_setup(struct musb *musb) /* this "gadget" abstracts/virtualizes the controller */ musb->g.name = musb_driver_name; -#if IS_ENABLED(CONFIG_USB_MUSB_DUAL_ROLE) musb->g.is_otg = 1; -#elif IS_ENABLED(CONFIG_USB_MUSB_GADGET) - musb->g.is_otg = 0; -#endif musb_g_init_endpoints(musb); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 6582a20..9a2b8c8 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -253,7 +253,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) case USB_ENDPOINT_XFER_BULK: s = "-bulk"; break; case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; default: s = "-intr"; break; - } s; }), + }; s; }), epnum, buf + offset, len); /* Configure endpoint */ diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 9af6bba..d1d6b83 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c @@ -220,23 +220,6 @@ int musb_hub_status_data(struct usb_hcd *hcd, char *buf) return retval; } -static int musb_has_gadget(struct musb *musb) -{ - /* - * In host-only mode we start a connection right away. In OTG mode - * we have to wait until we loaded a gadget. We don't really need a - * gadget if we operate as a host but we should not start a session - * as a device without a gadget or else we explode. - */ -#ifdef CONFIG_USB_MUSB_HOST - return 1; -#else - if (musb->port_mode == MUSB_PORT_MODE_HOST) - return 1; - return musb->g.dev.driver != NULL; -#endif -} - int musb_hub_control( struct usb_hcd *hcd, u16 typeReq, @@ -379,7 +362,7 @@ int musb_hub_control( * initialization logic, e.g. for OTG, or change any * logic relating to VBUS power-up. */ - if (!hcd->self.is_b_host && musb_has_gadget(musb)) + if (!hcd->self.is_b_host) musb_start(musb); break; case USB_PORT_FEAT_RESET: diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2a408cd..59d2245 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -38,7 +38,6 @@ #include <linux/delay.h> #include <linux/usb/musb-omap.h> #include <linux/usb/omap_control_usb.h> -#include <linux/of_platform.h> #include "musb_core.h" #include "omap2430.h" @@ -306,9 +305,6 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) default: dev_dbg(dev, "ID float\n"); } - - atomic_notifier_call_chain(&musb->xceiv->notifier, - musb->xceiv->last_event, NULL); } @@ -352,21 +348,11 @@ static int omap2430_musb_init(struct musb *musb) * up through ULPI. TWL4030-family PMICs include one, * which needs a driver, drivers aren't always needed. */ - if (dev->parent->of_node) { - musb->phy = devm_phy_get(dev->parent, "usb2-phy"); - - /* We can't totally remove musb->xceiv as of now because - * musb core uses xceiv.state and xceiv.otg. Once we have - * a separate state machine to handle otg, these can be moved - * out of xceiv and then we can start using the generic PHY - * framework - */ + if (dev->parent->of_node) musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, "usb-phy", 0); - } else { + else musb->xceiv = devm_usb_get_phy_dev(dev, 0); - musb->phy = devm_phy_get(dev, "usb"); - } if (IS_ERR(musb->xceiv)) { status = PTR_ERR(musb->xceiv); @@ -378,10 +364,6 @@ static int omap2430_musb_init(struct musb *musb) return -EPROBE_DEFER; } - if (IS_ERR(musb->phy)) { - pr_err("HS USB OTG: no PHY configured\n"); - return PTR_ERR(musb->phy); - } musb->isr = omap2430_musb_interrupt; status = pm_runtime_get_sync(dev); @@ -415,7 +397,7 @@ static int omap2430_musb_init(struct musb *musb) if (glue->status != OMAP_MUSB_UNKNOWN) omap_musb_set_mailbox(glue); - phy_init(musb->phy); + usb_phy_init(musb->xceiv); pm_runtime_put_noidle(musb->controller); return 0; @@ -478,7 +460,6 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); - phy_exit(musb->phy); return 0; } @@ -528,12 +509,8 @@ static int omap2430_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->musb = musb; glue->status = OMAP_MUSB_UNKNOWN; - glue->control_otghs = ERR_PTR(-ENODEV); if (np) { - struct device_node *control_node; - struct platform_device *control_pdev; - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(&pdev->dev, @@ -562,20 +539,22 @@ static int omap2430_probe(struct platform_device *pdev) of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); of_property_read_u32(np, "power", (u32 *)&pdata->power); config->multipoint = of_property_read_bool(np, "multipoint"); + pdata->has_mailbox = of_property_read_bool(np, + "ti,has-mailbox"); pdata->board_data = data; pdata->config = config; + } - control_node = of_parse_phandle(np, "ctrl-module", 0); - if (control_node) { - control_pdev = of_find_device_by_node(control_node); - if (!control_pdev) { - dev_err(&pdev->dev, "Failed to get control device\n"); - ret = -EINVAL; - goto err2; - } - glue->control_otghs = &control_pdev->dev; + if (pdata->has_mailbox) { + glue->control_otghs = omap_get_control_dev(); + if (IS_ERR(glue->control_otghs)) { + dev_vdbg(&pdev->dev, "Failed to get control device\n"); + ret = PTR_ERR(glue->control_otghs); + goto err2; } + } else { + glue->control_otghs = ERR_PTR(-ENODEV); } pdata->platform_ops = &omap2430_ops; @@ -659,7 +638,7 @@ static int omap2430_runtime_suspend(struct device *dev) OTG_INTERFSEL); omap2430_low_level_exit(musb); - phy_power_off(musb->phy); + usb_phy_set_suspend(musb->xceiv, 1); } return 0; @@ -674,7 +653,8 @@ static int omap2430_runtime_resume(struct device *dev) omap2430_low_level_init(musb); musb_writel(musb->mregs, OTG_INTERFSEL, musb->context.otg_interfsel); - phy_power_on(musb->phy); + + usb_phy_set_suspend(musb->xceiv, 0); } return 0; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 4432314..b3b3ed7 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1152,11 +1152,7 @@ static const struct musb_platform_ops tusb_ops = { .set_vbus = tusb_musb_set_vbus, }; -static const struct platform_device_info tusb_dev_info = { - .name = "musb-hdrc", - .id = PLATFORM_DEVID_AUTO, - .dma_mask = DMA_BIT_MASK(32), -}; +static u64 tusb_dmamask = DMA_BIT_MASK(32); static int tusb_probe(struct platform_device *pdev) { @@ -1164,7 +1160,7 @@ static int tusb_probe(struct platform_device *pdev) struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); struct platform_device *musb; struct tusb6010_glue *glue; - struct platform_device_info pinfo; + int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); @@ -1173,7 +1169,18 @@ static int tusb_probe(struct platform_device *pdev) goto err0; } + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); + goto err1; + } + + musb->dev.parent = &pdev->dev; + musb->dev.dma_mask = &tusb_dmamask; + musb->dev.coherent_dma_mask = tusb_dmamask; + glue->dev = &pdev->dev; + glue->musb = musb; pdata->platform_ops = &tusb_ops; @@ -1197,23 +1204,31 @@ static int tusb_probe(struct platform_device *pdev) musb_resources[2].end = pdev->resource[2].end; musb_resources[2].flags = pdev->resource[2].flags; - pinfo = tusb_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); + ret = platform_device_add_resources(musb, musb_resources, + ARRAY_SIZE(musb_resources)); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err3; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err3; + } + + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); goto err3; } return 0; err3: + platform_device_put(musb); + +err1: kfree(glue); err0: diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 122446b..59256b1 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -259,7 +259,7 @@ static int ux500_probe(struct platform_device *pdev) goto err1; } - clk = clk_get(&pdev->dev, NULL); + clk = clk_get(&pdev->dev, "usb"); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to get clock\n"); ret = PTR_ERR(clk); @@ -376,9 +376,16 @@ static int ux500_resume(struct device *dev) return 0; } -#endif -static SIMPLE_DEV_PM_OPS(ux500_pm_ops, ux500_suspend, ux500_resume); +static const struct dev_pm_ops ux500_pm_ops = { + .suspend = ux500_suspend, + .resume = ux500_resume, +}; + +#define DEV_PM_OPS (&ux500_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif static const struct of_device_id ux500_match[] = { { .compatible = "stericsson,db8500-musb", }, @@ -390,7 +397,7 @@ static struct platform_driver ux500_driver = { .remove = ux500_remove, .driver = { .name = "musb-ux500", - .pm = &ux500_pm_ops, + .pm = DEV_PM_OPS, .of_match_table = ux500_match, }, }; |