Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[pandora-kernel.git] / drivers / usb / musb / musb_core.c
index c292d5c..630ae7f 100644 (file)
@@ -1530,7 +1530,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 
 /*-------------------------------------------------------------------------*/
 
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || \
+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
        defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \
        defined(CONFIG_ARCH_U5500)
 
@@ -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)