aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiebing Li <hao.wu@intel.com>2010-12-09 10:37:46 +0000
committerAlan Cox <alan@linux.intel.com>2010-12-09 10:37:46 +0000
commit1a0a53c98e0975b910ac71700437b911e07afb24 (patch)
tree46913aee4f2702b351c3d5a180c4a6b1d84aa9b0
parente99b058b1a76a860c6ac544bec45806349c2bf52 (diff)
downloadmrst-s0i3-test-1a0a53c98e0975b910ac71700437b911e07afb24.tar.gz
mrst-s0i3-test-1a0a53c98e0975b910ac71700437b911e07afb24.tar.xz
mrst-s0i3-test-1a0a53c98e0975b910ac71700437b911e07afb24.zip
usb: langwell_udc: add runtime pm support for otg
This patch enables runtime pm support for langwell_udc controller driver. Signed-off-by: Jiebing Li <jiebing.li@intel.com> Signed-off-by: Hao Wu <hao.wu@intel.com>
-rw-r--r--drivers/usb/gadget/langwell_udc.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index bf23704bd85..76c9129b8a7 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -2765,6 +2765,9 @@ static void handle_bus_suspend(struct langwell_udc *dev)
{
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+ if (dev->usb_state == USB_STATE_SUSPENDED)
+ return;
+
dev->resume_state = dev->usb_state;
dev->usb_state = USB_STATE_SUSPENDED;
@@ -2784,6 +2787,8 @@ static void handle_bus_suspend(struct langwell_udc *dev)
}
}
+ pm_runtime_put(&dev->pdev->dev);
+
/* enter PHY low power suspend */
langwell_phy_low_power(dev, 1);
@@ -2817,6 +2822,8 @@ static void handle_bus_resume(struct langwell_udc *dev)
}
}
+ pm_runtime_get(&dev->pdev->dev);
+
dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
}
@@ -3460,6 +3467,67 @@ static int langwell_udc_resume(struct pci_dev *pdev)
}
+#ifdef CONFIG_PM_RUNTIME
+/* device controller runtime suspend */
+static int langwell_udc_runtime_suspend(struct device *device)
+{
+ struct langwell_udc *dev = the_controller;
+ struct pci_dev *pdev;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ pdev = to_pci_dev(device);
+
+ /* save PCI state */
+ pci_save_state(pdev);
+
+ /* disable PCI device */
+ pci_disable_device(pdev);
+
+ /* set device power state */
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ dev->vbus_active = 0;
+
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+}
+
+
+/* device controller runtime resume */
+static int langwell_udc_runtime_resume(struct device *device)
+{
+ struct langwell_udc *dev = the_controller;
+ struct pci_dev *pdev;
+
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+ pdev = to_pci_dev(device);
+
+ /* set device D0 power state */
+ pci_set_power_state(pdev, PCI_D0);
+
+ /* restore PCI state */
+ pci_restore_state(pdev);
+
+ /* enable PCI device */
+ if (pci_enable_device(pdev) < 0)
+ return -ENODEV;
+
+ dev->vbus_active = 1;
+
+ dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
+ return 0;
+}
+
+#else
+
+#define langwell_udc_runtime_suspend NULL
+#define langwell_udc_runtime_resume NULL
+
+#endif
+
+
/* pci driver shutdown */
static void langwell_udc_shutdown(struct pci_dev *pdev)
{
@@ -3499,7 +3567,16 @@ static const struct pci_device_id pci_ids[] = { {
MODULE_DEVICE_TABLE(pci, pci_ids);
+static const struct dev_pm_ops langwell_udc_pm_ops = {
+ .runtime_suspend = langwell_udc_runtime_suspend,
+ .runtime_resume = langwell_udc_runtime_resume,
+};
+
+
static struct pci_driver langwell_pci_driver = {
+ .driver = {
+ .pm = &langwell_udc_pm_ops,
+ },
.name = (char *) driver_name,
.id_table = pci_ids,