This patch fixes langwell otg and udc runtime pm usage imbalance problem which sees runtime pm usage count decrements on every otg b-device hotplug (when peripheral driver is loaded).
pci_set_power_state() calls are also removed since that is redundent to what pci rpm code already does. removed interrupt re-enable in runtime resume, it is not needed since interrupts are enabled during rpm suspend. use delayed version of langwell_otg_phy_low_power() when programming phcd (phy clock disable) since it takes 2-4 ms delay for otgsc and otgcfg (scu sram) to sync. otherwise, phcd programming will fail when the two registers are not in sync. Signed-off-by: Jacob Pan <jacob.jun....@linux.intel.com> --- drivers/usb/gadget/langwell_udc.c | 14 ++++++-------- drivers/usb/otg/langwell_otg.c | 7 +++---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 2b3277c..56b8442 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c @@ -1568,6 +1568,7 @@ static ssize_t show_langwell_udc(struct device *_dev, next = buf; size = PAGE_SIZE; + pm_runtime_get(_dev); spin_lock_irqsave(&dev->lock, flags); /* driver basic information */ @@ -1792,6 +1793,8 @@ static ssize_t show_langwell_udc(struct device *_dev, } spin_unlock_irqrestore(&dev->lock, flags); + pm_runtime_put(_dev); + return PAGE_SIZE - size; } static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL); @@ -1908,6 +1911,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (unlikely(!driver || !driver->unbind || !driver->disconnect)) return -EINVAL; + pm_runtime_get(&dev->pdev->dev); + /* exit PHY low power suspend */ langwell_phy_low_power(dev, 0); @@ -1933,6 +1938,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; + pm_runtime_put(&dev->pdev->dev); dev_info(&dev->pdev->dev, "unregistered driver '%s'\n", driver->driver.name); @@ -3484,9 +3490,6 @@ static int langwell_udc_runtime_suspend(struct device *device) /* 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__); @@ -3504,9 +3507,6 @@ static int langwell_udc_runtime_resume(struct device *device) pdev = to_pci_dev(device); - /* set device D0 power state */ - pci_set_power_state(pdev, PCI_D0); - /* restore PCI state */ pci_restore_state(pdev); @@ -3714,8 +3714,6 @@ static int intel_mid_stop_peripheral(struct intel_mid_otg_xceiv *iotg) spin_unlock_irqrestore(&dev->lock, flags); } - pm_runtime_put(&dev->pdev->dev); - dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__); return 0; } diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c index ae7a51f..a450952 100644 --- a/drivers/usb/otg/langwell_otg.c +++ b/drivers/usb/otg/langwell_otg.c @@ -2374,10 +2374,9 @@ static int langwell_otg_runtime_suspend(struct device *dev) case OTG_STATE_A_IDLE: case OTG_STATE_B_IDLE: /* Transceiver handle it itself */ - langwell_otg_phy_low_power(1); + langwell_otg_phy_low_power_wait(1); pci_save_state(pdev); pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); break; case OTG_STATE_A_WAIT_BCON: case OTG_STATE_A_HOST: @@ -2387,6 +2386,7 @@ static int langwell_otg_runtime_suspend(struct device *dev) break; case OTG_STATE_A_PERIPHERAL: case OTG_STATE_B_PERIPHERAL: + langwell_otg_phy_low_power_wait(1); if (lnw->iotg.runtime_suspend_peripheral) ret = lnw->iotg.runtime_suspend_peripheral(&lnw->iotg); break; @@ -2408,14 +2408,12 @@ static int langwell_otg_runtime_resume(struct device *dev) pdev = to_pci_dev(dev); - langwell_otg_intr(1); langwell_otg_phy_low_power(0); switch (lnw->iotg.otg.state) { case OTG_STATE_A_IDLE: case OTG_STATE_B_IDLE: /* Transceiver handle it itself */ - pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) @@ -2432,6 +2430,7 @@ static int langwell_otg_runtime_resume(struct device *dev) case OTG_STATE_B_PERIPHERAL: if (lnw->iotg.runtime_resume_peripheral) ret = lnw->iotg.runtime_resume_peripheral(&lnw->iotg); + langwell_otg_phy_low_power(0); break; default: break; -- 1.7.1 _______________________________________________ MeeGo-kernel mailing list MeeGo-kernel@lists.meego.com http://lists.meego.com/listinfo/meego-kernel