usb: dwc3: Resume parent before resuming child device while in host mode

Consider a scenario where a peripheral connected to the host gets
runtime suspended because of no bus activity. When the device tries
to enter suspend/deep sleep from this state and if it fails to suspend
PM framework calls pm_resume of the suspended device. Currently
xhci_plat_resume will call xhci_resume but it will fail since the parent
(dwc3) is not resumed.

Fix this by resuming glue driver and core by performing pm_runtime_resume
on xhci-plat device.

Change-Id: I71349fa88bce65fa9ec9bceb7c42ef79db763a84
Signed-off-by: Pratham Pratap <prathampratap@codeaurora.org>
This commit is contained in:
Pratham Pratap 2020-11-04 19:45:33 +05:30
commit 89e628cc40
2 changed files with 8 additions and 13 deletions

View file

@ -1997,12 +1997,13 @@ static int dwc3_resume(struct device *dev)
/* Check if platform glue driver handling PM, if not then handle here */
if (!dwc3_notify_event(dwc, DWC3_CORE_PM_RESUME_EVENT, 0)) {
/*
* If the core was in host mode during suspend, then set the
* runtime PM state as active to reflect actual state of device
* which is now out of LPM. This allows runtime_suspend later.
* If the core was in host mode during suspend, then perform
* runtime resume which will do resume and set the runtime PM
* state as active to reflect actual state of device which
* is now out of LPM. This allows runtime_suspend later.
*/
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST)
goto runtime_set_active;
pm_runtime_resume(dev);
return 0;
}
@ -2013,11 +2014,6 @@ static int dwc3_resume(struct device *dev)
if (ret)
return ret;
runtime_set_active:
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
return 0;
}
#endif /* CONFIG_PM_SLEEP */

View file

@ -436,10 +436,9 @@ static int xhci_plat_resume(struct device *dev)
if (ret)
return ret;
ret = xhci_resume(xhci, false);
pm_runtime_disable(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
ret = pm_runtime_resume(dev);
if (ret)
dev_err(dev, "failed to resume xhci-plat (%d)\n", ret);
return ret;
}