diff options
author | Li Jun <jun.li@freescale.com> | 2015-01-15 20:17:07 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:21:32 +0800 |
commit | 11fe36e4b3277e0dab34d02b794b8b3cbde6a379 (patch) | |
tree | 8ebfa030ac258b8fe6a9e2f4fe275c3fc0377dc3 /drivers/usb/chipidea/core.c | |
parent | 64c1828b8ea46c89932cc4d2de9508f3d8180d64 (diff) |
MLK-10102-2 usb: chipidea: add suspend and resume routine for role driver
We may need to do extra things for system suspend/resume per different
roles(e.g. power lost during system sleep), so define system suspend/resume
handler for roles.
Signed-off-by: Peter Chen <peter.chen@freescale.com>
(cherry picked from commit cac6f339b30102c63f8bb5c56e77d5c7a6c6b4b5)
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r-- | drivers/usb/chipidea/core.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 9d8f69e41b30..5f10e58026cc 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -1210,6 +1210,10 @@ static int ci_suspend(struct device *dev) return 0; } + /* Extra routine per role before system suspend */ + if (ci->role != CI_ROLE_END && ci_role(ci)->suspend) + ci_role(ci)->suspend(ci); + if (device_may_wakeup(dev)) { if (ci_otg_is_fsm_mode(ci)) ci_otg_fsm_suspend_for_srp(ci); @@ -1226,8 +1230,18 @@ static int ci_suspend(struct device *dev) static int ci_resume(struct device *dev) { struct ci_hdrc *ci = dev_get_drvdata(dev); + bool power_lost = false; + u32 sample_reg_val; int ret; + /* Check if controller resume from power lost */ + sample_reg_val = hw_read(ci, OP_ENDPTLISTADDR, ~0); + if (sample_reg_val == 0) + power_lost = true; + else if (sample_reg_val == 0xFFFFFFFF) + /* Restore value 0 if it was set for power lost check */ + hw_write(ci, OP_ENDPTLISTADDR, ~0, 0); + if (device_may_wakeup(dev)) disable_irq_wake(ci->irq); @@ -1235,6 +1249,10 @@ static int ci_resume(struct device *dev) if (ret) return ret; + /* Extra routine per role after system resume */ + if (ci->role != CI_ROLE_END && ci_role(ci)->resume) + ci_role(ci)->resume(ci, power_lost); + if (ci->supports_runtime_pm) { pm_runtime_disable(dev); pm_runtime_set_active(dev); |