diff options
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r-- | drivers/usb/musb/am35x.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/blackfin.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/da8xx.c | 7 | ||||
-rw-r--r-- | drivers/usb/musb/davinci.c | 9 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.c | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_core.h | 2 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 9 | ||||
-rw-r--r-- | drivers/usb/musb/musb_gadget.c | 14 | ||||
-rw-r--r-- | drivers/usb/musb/musb_host.c | 6 | ||||
-rw-r--r-- | drivers/usb/musb/omap2430.c | 124 | ||||
-rw-r--r-- | drivers/usb/musb/tusb6010.c | 9 | ||||
-rw-r--r-- | drivers/usb/musb/ux500.c | 7 |
12 files changed, 128 insertions, 75 deletions
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 9f3eda91ea4d..7a95ab87ac00 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -29,6 +29,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/clk.h> +#include <linux/err.h> #include <linux/io.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> @@ -364,8 +365,8 @@ static int am35x_musb_init(struct musb *musb) return -ENODEV; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) return -ENODEV; if (is_host_enabled(musb)) @@ -406,7 +407,7 @@ static int am35x_musb_exit(struct musb *musb) if (data->set_phy_power) data->set_phy_power(0); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a087ed6c3be9..428e6aa3e78a 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -15,6 +15,7 @@ #include <linux/list.h> #include <linux/gpio.h> #include <linux/io.h> +#include <linux/err.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/prefetch.h> @@ -415,8 +416,8 @@ static int bfin_musb_init(struct musb *musb) gpio_direction_output(musb->config->gpio_vrsel, 0); usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) { + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) { gpio_free(musb->config->gpio_vrsel); return -ENODEV; } @@ -440,7 +441,7 @@ static int bfin_musb_exit(struct musb *musb) { gpio_free(musb->config->gpio_vrsel); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 8bd9566f3fbb..0f9fcec4e1d3 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -29,6 +29,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/clk.h> +#include <linux/err.h> #include <linux/io.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> @@ -425,8 +426,8 @@ static int da8xx_musb_init(struct musb *musb) goto fail; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) goto fail; if (is_host_enabled(musb)) @@ -458,7 +459,7 @@ static int da8xx_musb_exit(struct musb *musb) phy_off(); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 9d63ba4d10d6..472c8b42d38b 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -28,6 +28,7 @@ #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> @@ -385,8 +386,8 @@ static int davinci_musb_init(struct musb *musb) u32 revision; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) goto unregister; musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,7 +445,7 @@ static int davinci_musb_init(struct musb *musb) return 0; fail: - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); unregister: usb_nop_xceiv_unregister(); return -ENODEV; @@ -494,7 +495,7 @@ static int davinci_musb_exit(struct musb *musb) phy_off(); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index db3dff854b71..26f1befb4896 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1909,7 +1909,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) /* The musb_platform_init() call: * - adjusts musb->mregs and musb->isr if needed, * - may initialize an integrated tranceiver - * - initializes musb->xceiv, usually by otg_get_transceiver() + * - initializes musb->xceiv, usually by otg_get_phy() * - stops powering VBUS * * There are various transceiver configurations. Blackfin, diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index f4a40f001c88..dbcdeea30f09 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -327,7 +327,6 @@ struct musb { irqreturn_t (*isr)(int, void *); struct work_struct irq_work; - struct work_struct otg_notifier_work; u16 hwvers; /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ @@ -373,7 +372,6 @@ struct musb { u16 int_tx; struct usb_phy *xceiv; - u8 xceiv_event; int nIrq; unsigned irq_wake:1; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 23db42db761a..217808d9fbe1 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -31,6 +31,7 @@ #include <linux/init.h> #include <linux/io.h> +#include <linux/err.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/pm_runtime.h> @@ -376,8 +377,8 @@ static int dsps_musb_init(struct musb *musb) /* NOP driver needs change if supporting dual instance */ usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) return -ENODEV; /* Returns zero if e.g. not clocked */ @@ -409,7 +410,7 @@ static int dsps_musb_init(struct musb *musb) return 0; err0: - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return status; } @@ -430,7 +431,7 @@ static int dsps_musb_exit(struct musb *musb) data->set_phy_power(0); /* NOP driver needs change if supporting dual instance */ - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 95918dacc99a..f7194cf65aba 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -328,6 +328,13 @@ static void txstate(struct musb *musb, struct musb_request *req) musb_ep = req->ep; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* we shouldn't get here while DMA is active ... but we do ... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "dma pending...\n"); @@ -650,6 +657,13 @@ static void rxstate(struct musb *musb, struct musb_request *req) len = musb_ep->packet_sz; + /* Check if EP is disabled */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "ep:%s disabled - ignore request\n", + musb_ep->end_point.name); + return; + } + /* We shouldn't get here while DMA is active, but we do... */ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { dev_dbg(musb->controller, "DMA pending...\n"); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index e090c799d87b..4bb717d0bd41 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1746,7 +1746,11 @@ void musb_host_rx(struct musb *musb, u8 epnum) c->channel_release(dma); hw_ep->rx_channel = NULL; dma = NULL; - /* REVISIT reset CSR */ + val = musb_readw(epio, MUSB_RXCSR); + val &= ~(MUSB_RXCSR_DMAENAB + | MUSB_RXCSR_H_AUTOREQ + | MUSB_RXCSR_AUTOCLEAR); + musb_writew(epio, MUSB_RXCSR, val); } } #endif /* Mentor DMA */ diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c7785e81254c..5fdb9da8dd56 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -34,6 +34,7 @@ #include <linux/dma-mapping.h> #include <linux/pm_runtime.h> #include <linux/err.h> +#include <linux/usb/musb-omap.h> #include "musb_core.h" #include "omap2430.h" @@ -41,9 +42,13 @@ struct omap2430_glue { struct device *dev; struct platform_device *musb; + enum omap_musb_vbus_id_status status; + struct work_struct omap_musb_mailbox_work; }; #define glue_to_musb(g) platform_get_drvdata(g->musb) +struct omap2430_glue *_glue; + static struct timer_list musb_idle_timer; static void musb_do_idle(unsigned long _musb) @@ -223,50 +228,63 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } -static int musb_otg_notifications(struct notifier_block *nb, - unsigned long event, void *unused) +void omap_musb_mailbox(enum omap_musb_vbus_id_status status) { - struct musb *musb = container_of(nb, struct musb, nb); + struct omap2430_glue *glue = _glue; + struct musb *musb = glue_to_musb(glue); - musb->xceiv_event = event; - schedule_work(&musb->otg_notifier_work); + glue->status = status; + if (!musb) { + dev_err(glue->dev, "musb core is not yet ready\n"); + return; + } - return NOTIFY_OK; + schedule_work(&glue->omap_musb_mailbox_work); } +EXPORT_SYMBOL_GPL(omap_musb_mailbox); -static void musb_otg_notifier_work(struct work_struct *data_notifier_work) +static void omap_musb_set_mailbox(struct omap2430_glue *glue) { - struct musb *musb = container_of(data_notifier_work, struct musb, otg_notifier_work); + struct musb *musb = glue_to_musb(glue); struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; + struct usb_otg *otg = musb->xceiv->otg; - switch (musb->xceiv_event) { - case USB_EVENT_ID: - dev_dbg(musb->controller, "ID GND\n"); + switch (glue->status) { + case OMAP_MUSB_ID_GROUND: + dev_dbg(dev, "ID GND\n"); + otg->default_a = true; + musb->xceiv->state = OTG_STATE_A_IDLE; + musb->xceiv->last_event = USB_EVENT_ID; if (!is_otg_enabled(musb) || musb->gadget_driver) { - pm_runtime_get_sync(musb->controller); + pm_runtime_get_sync(dev); usb_phy_init(musb->xceiv); omap2430_musb_set_vbus(musb, 1); } break; - case USB_EVENT_VBUS: - dev_dbg(musb->controller, "VBUS Connect\n"); + case OMAP_MUSB_VBUS_VALID: + dev_dbg(dev, "VBUS Connect\n"); + otg->default_a = false; + musb->xceiv->state = OTG_STATE_B_IDLE; + musb->xceiv->last_event = USB_EVENT_VBUS; if (musb->gadget_driver) - pm_runtime_get_sync(musb->controller); + pm_runtime_get_sync(dev); usb_phy_init(musb->xceiv); break; - case USB_EVENT_NONE: - dev_dbg(musb->controller, "VBUS Disconnect\n"); + case OMAP_MUSB_ID_FLOAT: + case OMAP_MUSB_VBUS_OFF: + dev_dbg(dev, "VBUS Disconnect\n"); + musb->xceiv->last_event = USB_EVENT_NONE; if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) if (musb->gadget_driver) { - pm_runtime_mark_last_busy(musb->controller); - pm_runtime_put_autosuspend(musb->controller); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } if (data->interface_type == MUSB_INTERFACE_UTMI) { @@ -276,15 +294,24 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) usb_phy_shutdown(musb->xceiv); break; default: - dev_dbg(musb->controller, "ID float\n"); + dev_dbg(dev, "ID float\n"); } } + +static void omap_musb_mailbox_work(struct work_struct *mailbox_work) +{ + struct omap2430_glue *glue = container_of(mailbox_work, + struct omap2430_glue, omap_musb_mailbox_work); + omap_musb_set_mailbox(glue); +} + static int omap2430_musb_init(struct musb *musb) { u32 l; int status = 0; struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -292,14 +319,12 @@ 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. */ - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) { + musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } - INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work); - status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); @@ -326,14 +351,11 @@ static int omap2430_musb_init(struct musb *musb) musb_readl(musb->mregs, OTG_INTERFSEL), musb_readl(musb->mregs, OTG_SIMENABLE)); - musb->nb.notifier_call = musb_otg_notifications; - status = usb_register_notifier(musb->xceiv, &musb->nb); - - if (status) - dev_dbg(musb->controller, "notification register failed\n"); - setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); + if (glue->status != OMAP_MUSB_UNKNOWN) + omap_musb_set_mailbox(glue); + pm_runtime_put_noidle(musb->controller); return 0; @@ -346,12 +368,13 @@ static void omap2430_musb_enable(struct musb *musb) u8 devctl; unsigned long timeout = jiffies + msecs_to_jiffies(1000); struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; - switch (musb->xceiv->last_event) { + switch (glue->status) { - case USB_EVENT_ID: + case OMAP_MUSB_ID_GROUND: usb_phy_init(musb->xceiv); if (data->interface_type != MUSB_INTERFACE_UTMI) break; @@ -370,7 +393,7 @@ static void omap2430_musb_enable(struct musb *musb) } break; - case USB_EVENT_VBUS: + case OMAP_MUSB_VBUS_VALID: usb_phy_init(musb->xceiv); break; @@ -381,17 +404,18 @@ static void omap2430_musb_enable(struct musb *musb) static void omap2430_musb_disable(struct musb *musb) { - if (musb->xceiv->last_event) + struct device *dev = musb->controller; + struct omap2430_glue *glue = dev_get_drvdata(dev->parent); + + if (glue->status != OMAP_MUSB_UNKNOWN) usb_phy_shutdown(musb->xceiv); } static int omap2430_musb_exit(struct musb *musb) { del_timer_sync(&musb_idle_timer); - cancel_work_sync(&musb->otg_notifier_work); omap2430_low_level_exit(musb); - usb_put_transceiver(musb->xceiv); return 0; } @@ -418,7 +442,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) struct omap2430_glue *glue; int ret = -ENOMEM; - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(&pdev->dev, "failed to allocate glue context\n"); goto err0; @@ -427,7 +451,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) musb = platform_device_alloc("musb-hdrc", -1); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err1; + goto err0; } musb->dev.parent = &pdev->dev; @@ -436,22 +460,31 @@ static int __devinit omap2430_probe(struct platform_device *pdev) glue->dev = &pdev->dev; glue->musb = musb; + glue->status = OMAP_MUSB_UNKNOWN; pdata->platform_ops = &omap2430_ops; platform_set_drvdata(pdev, glue); + /* + * REVISIT if we ever have two instances of the wrapper, we will be + * in big trouble + */ + _glue = glue; + + INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work); + ret = platform_device_add_resources(musb, pdev->resource, pdev->num_resources); if (ret) { dev_err(&pdev->dev, "failed to add resources\n"); - goto err2; + goto err1; } ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); if (ret) { dev_err(&pdev->dev, "failed to add platform_data\n"); - goto err2; + goto err1; } pm_runtime_enable(&pdev->dev); @@ -459,16 +492,13 @@ static int __devinit omap2430_probe(struct platform_device *pdev) ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); - goto err2; + goto err1; } return 0; -err2: - platform_device_put(musb); - err1: - kfree(glue); + platform_device_put(musb); err0: return ret; @@ -478,9 +508,9 @@ static int __devexit omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); + cancel_work_sync(&glue->omap_musb_mailbox_work); platform_device_del(glue->musb); platform_device_put(glue->musb); - kfree(glue); return 0; } @@ -546,7 +576,7 @@ static int __init omap2430_init(void) { return platform_driver_register(&omap2430_driver); } -module_init(omap2430_init); +subsys_initcall(omap2430_init); static void __exit omap2430_exit(void) { diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index de1355946a83..1a1bd9cf40c5 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> +#include <linux/err.h> #include <linux/init.h> #include <linux/prefetch.h> #include <linux/usb.h> @@ -1078,8 +1079,8 @@ static int tusb_musb_init(struct musb *musb) int ret; usb_nop_xceiv_register(); - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) return -ENODEV; pdev = to_platform_device(musb->controller); @@ -1130,7 +1131,7 @@ done: if (sync) iounmap(sync); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); } return ret; @@ -1146,7 +1147,7 @@ static int tusb_musb_exit(struct musb *musb) iounmap(musb->sync_va); - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); return 0; } diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index aa09dd417b94..a8c0fadce1b0 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -23,6 +23,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/clk.h> +#include <linux/err.h> #include <linux/io.h> #include <linux/platform_device.h> @@ -37,8 +38,8 @@ struct ux500_glue { static int ux500_musb_init(struct musb *musb) { - musb->xceiv = usb_get_transceiver(); - if (!musb->xceiv) { + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) { pr_err("HS USB OTG: no transceiver configured\n"); return -ENODEV; } @@ -48,7 +49,7 @@ static int ux500_musb_init(struct musb *musb) static int ux500_musb_exit(struct musb *musb) { - usb_put_transceiver(musb->xceiv); + usb_put_phy(musb->xceiv); return 0; } |