diff options
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 39fd95833eb8..f824336def5c 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1090,29 +1090,6 @@ void musb_stop(struct musb *musb) | |||
1090 | musb_platform_try_idle(musb, 0); | 1090 | musb_platform_try_idle(musb, 0); |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | static void musb_shutdown(struct platform_device *pdev) | ||
1094 | { | ||
1095 | struct musb *musb = dev_to_musb(&pdev->dev); | ||
1096 | unsigned long flags; | ||
1097 | |||
1098 | pm_runtime_get_sync(musb->controller); | ||
1099 | |||
1100 | musb_host_cleanup(musb); | ||
1101 | musb_gadget_cleanup(musb); | ||
1102 | |||
1103 | spin_lock_irqsave(&musb->lock, flags); | ||
1104 | musb_platform_disable(musb); | ||
1105 | musb_generic_disable(musb); | ||
1106 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1107 | |||
1108 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
1109 | musb_platform_exit(musb); | ||
1110 | |||
1111 | pm_runtime_put(musb->controller); | ||
1112 | /* FIXME power down */ | ||
1113 | } | ||
1114 | |||
1115 | |||
1116 | /*-------------------------------------------------------------------------*/ | 1093 | /*-------------------------------------------------------------------------*/ |
1117 | 1094 | ||
1118 | /* | 1095 | /* |
@@ -1702,7 +1679,7 @@ EXPORT_SYMBOL_GPL(musb_dma_completion); | |||
1702 | #define use_dma 0 | 1679 | #define use_dma 0 |
1703 | #endif | 1680 | #endif |
1704 | 1681 | ||
1705 | static void (*musb_phy_callback)(enum musb_vbus_id_status status); | 1682 | static int (*musb_phy_callback)(enum musb_vbus_id_status status); |
1706 | 1683 | ||
1707 | /* | 1684 | /* |
1708 | * musb_mailbox - optional phy notifier function | 1685 | * musb_mailbox - optional phy notifier function |
@@ -1711,11 +1688,12 @@ static void (*musb_phy_callback)(enum musb_vbus_id_status status); | |||
1711 | * Optionally gets called from the USB PHY. Note that the USB PHY must be | 1688 | * Optionally gets called from the USB PHY. Note that the USB PHY must be |
1712 | * disabled at the point the phy_callback is registered or unregistered. | 1689 | * disabled at the point the phy_callback is registered or unregistered. |
1713 | */ | 1690 | */ |
1714 | void musb_mailbox(enum musb_vbus_id_status status) | 1691 | int musb_mailbox(enum musb_vbus_id_status status) |
1715 | { | 1692 | { |
1716 | if (musb_phy_callback) | 1693 | if (musb_phy_callback) |
1717 | musb_phy_callback(status); | 1694 | return musb_phy_callback(status); |
1718 | 1695 | ||
1696 | return -ENODEV; | ||
1719 | }; | 1697 | }; |
1720 | EXPORT_SYMBOL_GPL(musb_mailbox); | 1698 | EXPORT_SYMBOL_GPL(musb_mailbox); |
1721 | 1699 | ||
@@ -2028,11 +2006,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2028 | musb_readl = musb_default_readl; | 2006 | musb_readl = musb_default_readl; |
2029 | musb_writel = musb_default_writel; | 2007 | musb_writel = musb_default_writel; |
2030 | 2008 | ||
2031 | /* We need musb_read/write functions initialized for PM */ | ||
2032 | pm_runtime_use_autosuspend(musb->controller); | ||
2033 | pm_runtime_set_autosuspend_delay(musb->controller, 200); | ||
2034 | pm_runtime_enable(musb->controller); | ||
2035 | |||
2036 | /* The musb_platform_init() call: | 2009 | /* The musb_platform_init() call: |
2037 | * - adjusts musb->mregs | 2010 | * - adjusts musb->mregs |
2038 | * - sets the musb->isr | 2011 | * - sets the musb->isr |
@@ -2134,6 +2107,16 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2134 | if (musb->ops->phy_callback) | 2107 | if (musb->ops->phy_callback) |
2135 | musb_phy_callback = musb->ops->phy_callback; | 2108 | musb_phy_callback = musb->ops->phy_callback; |
2136 | 2109 | ||
2110 | /* | ||
2111 | * We need musb_read/write functions initialized for PM. | ||
2112 | * Note that at least 2430 glue needs autosuspend delay | ||
2113 | * somewhere above 300 ms for the hardware to idle properly | ||
2114 | * after disconnecting the cable in host mode. Let's use | ||
2115 | * 500 ms for some margin. | ||
2116 | */ | ||
2117 | pm_runtime_use_autosuspend(musb->controller); | ||
2118 | pm_runtime_set_autosuspend_delay(musb->controller, 500); | ||
2119 | pm_runtime_enable(musb->controller); | ||
2137 | pm_runtime_get_sync(musb->controller); | 2120 | pm_runtime_get_sync(musb->controller); |
2138 | 2121 | ||
2139 | status = usb_phy_init(musb->xceiv); | 2122 | status = usb_phy_init(musb->xceiv); |
@@ -2237,13 +2220,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) | |||
2237 | if (status) | 2220 | if (status) |
2238 | goto fail5; | 2221 | goto fail5; |
2239 | 2222 | ||
2240 | pm_runtime_put(musb->controller); | 2223 | pm_runtime_mark_last_busy(musb->controller); |
2241 | 2224 | pm_runtime_put_autosuspend(musb->controller); | |
2242 | /* | ||
2243 | * For why this is currently needed, see commit 3e43a0725637 | ||
2244 | * ("usb: musb: core: add pm_runtime_irq_safe()") | ||
2245 | */ | ||
2246 | pm_runtime_irq_safe(musb->controller); | ||
2247 | 2225 | ||
2248 | return 0; | 2226 | return 0; |
2249 | 2227 | ||
@@ -2265,7 +2243,9 @@ fail2_5: | |||
2265 | usb_phy_shutdown(musb->xceiv); | 2243 | usb_phy_shutdown(musb->xceiv); |
2266 | 2244 | ||
2267 | err_usb_phy_init: | 2245 | err_usb_phy_init: |
2246 | pm_runtime_dont_use_autosuspend(musb->controller); | ||
2268 | pm_runtime_put_sync(musb->controller); | 2247 | pm_runtime_put_sync(musb->controller); |
2248 | pm_runtime_disable(musb->controller); | ||
2269 | 2249 | ||
2270 | fail2: | 2250 | fail2: |
2271 | if (musb->irq_wake) | 2251 | if (musb->irq_wake) |
@@ -2273,7 +2253,6 @@ fail2: | |||
2273 | musb_platform_exit(musb); | 2253 | musb_platform_exit(musb); |
2274 | 2254 | ||
2275 | fail1: | 2255 | fail1: |
2276 | pm_runtime_disable(musb->controller); | ||
2277 | dev_err(musb->controller, | 2256 | dev_err(musb->controller, |
2278 | "musb_init_controller failed with status %d\n", status); | 2257 | "musb_init_controller failed with status %d\n", status); |
2279 | 2258 | ||
@@ -2312,6 +2291,7 @@ static int musb_remove(struct platform_device *pdev) | |||
2312 | { | 2291 | { |
2313 | struct device *dev = &pdev->dev; | 2292 | struct device *dev = &pdev->dev; |
2314 | struct musb *musb = dev_to_musb(dev); | 2293 | struct musb *musb = dev_to_musb(dev); |
2294 | unsigned long flags; | ||
2315 | 2295 | ||
2316 | /* this gets called on rmmod. | 2296 | /* this gets called on rmmod. |
2317 | * - Host mode: host may still be active | 2297 | * - Host mode: host may still be active |
@@ -2319,17 +2299,26 @@ static int musb_remove(struct platform_device *pdev) | |||
2319 | * - OTG mode: both roles are deactivated (or never-activated) | 2299 | * - OTG mode: both roles are deactivated (or never-activated) |
2320 | */ | 2300 | */ |
2321 | musb_exit_debugfs(musb); | 2301 | musb_exit_debugfs(musb); |
2322 | musb_shutdown(pdev); | ||
2323 | musb_phy_callback = NULL; | ||
2324 | |||
2325 | if (musb->dma_controller) | ||
2326 | musb_dma_controller_destroy(musb->dma_controller); | ||
2327 | |||
2328 | usb_phy_shutdown(musb->xceiv); | ||
2329 | 2302 | ||
2330 | cancel_work_sync(&musb->irq_work); | 2303 | cancel_work_sync(&musb->irq_work); |
2331 | cancel_delayed_work_sync(&musb->finish_resume_work); | 2304 | cancel_delayed_work_sync(&musb->finish_resume_work); |
2332 | cancel_delayed_work_sync(&musb->deassert_reset_work); | 2305 | cancel_delayed_work_sync(&musb->deassert_reset_work); |
2306 | pm_runtime_get_sync(musb->controller); | ||
2307 | musb_host_cleanup(musb); | ||
2308 | musb_gadget_cleanup(musb); | ||
2309 | spin_lock_irqsave(&musb->lock, flags); | ||
2310 | musb_platform_disable(musb); | ||
2311 | musb_generic_disable(musb); | ||
2312 | spin_unlock_irqrestore(&musb->lock, flags); | ||
2313 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | ||
2314 | pm_runtime_dont_use_autosuspend(musb->controller); | ||
2315 | pm_runtime_put_sync(musb->controller); | ||
2316 | pm_runtime_disable(musb->controller); | ||
2317 | musb_platform_exit(musb); | ||
2318 | musb_phy_callback = NULL; | ||
2319 | if (musb->dma_controller) | ||
2320 | musb_dma_controller_destroy(musb->dma_controller); | ||
2321 | usb_phy_shutdown(musb->xceiv); | ||
2333 | musb_free(musb); | 2322 | musb_free(musb); |
2334 | device_init_wakeup(dev, 0); | 2323 | device_init_wakeup(dev, 0); |
2335 | return 0; | 2324 | return 0; |
@@ -2429,7 +2418,8 @@ static void musb_restore_context(struct musb *musb) | |||
2429 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); | 2418 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); |
2430 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); | 2419 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); |
2431 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); | 2420 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); |
2432 | musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); | 2421 | if (musb->context.devctl & MUSB_DEVCTL_SESSION) |
2422 | musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); | ||
2433 | 2423 | ||
2434 | for (i = 0; i < musb->config->num_eps; ++i) { | 2424 | for (i = 0; i < musb->config->num_eps; ++i) { |
2435 | struct musb_hw_ep *hw_ep; | 2425 | struct musb_hw_ep *hw_ep; |
@@ -2612,7 +2602,6 @@ static struct platform_driver musb_driver = { | |||
2612 | }, | 2602 | }, |
2613 | .probe = musb_probe, | 2603 | .probe = musb_probe, |
2614 | .remove = musb_remove, | 2604 | .remove = musb_remove, |
2615 | .shutdown = musb_shutdown, | ||
2616 | }; | 2605 | }; |
2617 | 2606 | ||
2618 | module_platform_driver(musb_driver); | 2607 | module_platform_driver(musb_driver); |