From: Jiebing Li <hao.wu@xxxxxxxxx> This patch enables runtime pm support for langwell_udc controller driver. Signed-off-by: Jiebing Li <jiebing.li@xxxxxxxxx> Signed-off-by: Hao Wu <hao.wu@xxxxxxxxx> --- drivers/usb/gadget/langwell_udc.c | 77 +++++++++++++++++++++++++++++++++++++ 1 files changed, 77 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index e5d11e9..e3e689c 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__); } @@ -3459,6 +3466,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) { @@ -3498,7 +3566,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, -- 1.6.0.6 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html