diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 15:04:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-16 15:04:26 -0700 |
commit | 971f115a50afbe409825c9f3399d5a3b9aca4381 (patch) | |
tree | cb42dc07a032e325f22b64d961587c081225c6d6 /drivers/usb/musb/musb_core.c | |
parent | 2e270d84223262a38d4755c61d55f5c73ea89e56 (diff) | |
parent | 500132a0f26ad7d9916102193cbc6c1b1becb373 (diff) |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (172 commits)
USB: Add support for SuperSpeed isoc endpoints
xhci: Clean up cycle bit math used during stalls.
xhci: Fix cycle bit calculation during stall handling.
xhci: Update internal dequeue pointers after stalls.
USB: Disable auto-suspend for USB 3.0 hubs.
USB: Remove bogus USB_PORT_STAT_SUPER_SPEED symbol.
xhci: Return canceled URBs immediately when host is halted.
xhci: Fixes for suspend/resume of shared HCDs.
xhci: Fix re-init on power loss after resume.
xhci: Make roothub functions deal with device removal.
xhci: Limit roothub ports to 15 USB3 & 31 USB2 ports.
xhci: Return a USB 3.0 hub descriptor for USB3 roothub.
xhci: Register second xHCI roothub.
xhci: Change xhci_find_slot_id_by_port() API.
xhci: Refactor bus suspend state into a struct.
xhci: Index with a port array instead of PORTSC addresses.
USB: Set usb_hcd->state and flags for shared roothubs.
usb: Make core allocate resources per PCI-device.
usb: Store bus type in usb_hcd, not in driver flags.
usb: Change usb_hcd->bandwidth_mutex to a pointer.
...
Diffstat (limited to 'drivers/usb/musb/musb_core.c')
-rw-r--r-- | drivers/usb/musb/musb_core.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c292d5c499e..a914010d9d1 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1950,31 +1950,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail0; } - switch (plat->mode) { - case MUSB_HOST: -#ifdef CONFIG_USB_MUSB_HDRC_HCD - break; -#else - goto bad_config; -#endif - case MUSB_PERIPHERAL: -#ifdef CONFIG_USB_GADGET_MUSB_HDRC - break; -#else - goto bad_config; -#endif - case MUSB_OTG: -#ifdef CONFIG_USB_MUSB_OTG - break; -#else -bad_config: -#endif - default: - dev_err(dev, "incompatible Kconfig role setting\n"); - status = -EINVAL; - goto fail0; - } - /* allocate */ musb = allocate_instance(dev, plat->config, ctrl); if (!musb) { @@ -1982,6 +1957,10 @@ bad_config: goto fail0; } + pm_runtime_use_autosuspend(musb->controller); + pm_runtime_set_autosuspend_delay(musb->controller, 200); + pm_runtime_enable(musb->controller); + spin_lock_init(&musb->lock); musb->board_mode = plat->mode; musb->board_set_power = plat->set_power; @@ -2117,6 +2096,8 @@ bad_config: if (status < 0) goto fail3; + pm_runtime_put(musb->controller); + status = musb_init_debugfs(musb); if (status < 0) goto fail4; @@ -2216,9 +2197,11 @@ static int __exit musb_remove(struct platform_device *pdev) * - Peripheral mode: peripheral is deactivated (or never-activated) * - OTG mode: both roles are deactivated (or never-activated) */ + pm_runtime_get_sync(musb->controller); musb_exit_debugfs(musb); musb_shutdown(pdev); + pm_runtime_put(musb->controller); musb_free(musb); iounmap(ctrl_base); device_init_wakeup(&pdev->dev, 0); @@ -2404,9 +2387,41 @@ static int musb_resume_noirq(struct device *dev) return 0; } +static int musb_runtime_suspend(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + + musb_save_context(musb); + + return 0; +} + +static int musb_runtime_resume(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + static int first = 1; + + /* + * When pm_runtime_get_sync called for the first time in driver + * init, some of the structure is still not initialized which is + * used in restore function. But clock needs to be + * enabled before any register access, so + * pm_runtime_get_sync has to be called. + * Also context restore without save does not make + * any sense + */ + if (!first) + musb_restore_context(musb); + first = 0; + + return 0; +} + static const struct dev_pm_ops musb_dev_pm_ops = { .suspend = musb_suspend, .resume_noirq = musb_resume_noirq, + .runtime_suspend = musb_runtime_suspend, + .runtime_resume = musb_runtime_resume, }; #define MUSB_DEV_PM_OPS (&musb_dev_pm_ops) |