diff options
author | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-10-27 14:36:49 +0200 |
---|---|---|
committer | Linus WALLEIJ <linus.walleij@stericsson.com> | 2011-10-27 16:35:34 +0200 |
commit | dbcf2d4cfd7b08f1c051f3bf220c291f21022349 (patch) | |
tree | 36cc74664c120f509dd9ac9179d6a823508c2683 /arch | |
parent | f33507227b86ed3ee1a836a679e58a7672603a93 (diff) |
mach-ux500: Fixup use of supend|resume_noirq
Changes needed due to the following commit:
PM: Limit race conditions between runtime PM and system sleep (v2)
Previously it was was possible for drivers doing pm_runtime_suspend
and pm_runtime_put_sync directly from it's suspend callbacks. Now
suspend_noirq shall be used, thus this is implemented for AMBA.
Additionally pm_runtime is now disabled during system suspend,
meaning "pm_runtime_status_suspended" must be used in
suspend|resume_noirq context instead of "pm_runtime_suspended".
Change-Id: Idda935d422884ecb3c4b6f5e415cd2e0077b06c7
Signed-off-by: Ulf Hansson <ulf.hansson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/35504
Reviewed-by: Linus WALLEIJ <linus.walleij@stericsson.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-ux500/pm/runtime.c | 90 |
1 files changed, 81 insertions, 9 deletions
diff --git a/arch/arm/mach-ux500/pm/runtime.c b/arch/arm/mach-ux500/pm/runtime.c index df5b10d1bef..4743229b7d8 100644 --- a/arch/arm/mach-ux500/pm/runtime.c +++ b/arch/arm/mach-ux500/pm/runtime.c @@ -165,7 +165,7 @@ static int ux500_pd_suspend_noirq(struct device *dev) return 0; /* Already is runtime suspended? Nothing to do. */ - if (pm_runtime_suspended(dev)) + if (pm_runtime_status_suspended(dev)) return 0; /* @@ -190,7 +190,7 @@ static int ux500_pd_resume_noirq(struct device *dev) * Already was runtime suspended? No need to resume here, runtime * resume will take care of it. */ - if (pm_runtime_suspended(dev)) + if (pm_runtime_status_suspended(dev)) return 0; /* @@ -201,6 +201,62 @@ static int ux500_pd_resume_noirq(struct device *dev) return ux500_pd_runtime_resume(dev); } +static int ux500_pd_amba_suspend_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret = 0; + bool is_suspended = pm_runtime_status_suspended(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->suspend_noirq; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_suspend_noirq(dev); + + if (!ret && !is_suspended) + ux500_pd_disable(prd); + + return ret; +} + +static int ux500_pd_amba_resume_noirq(struct device *dev) +{ + struct pm_runtime_data *prd = __to_prd(dev); + int (*callback)(struct device *) = NULL; + int ret = 0; + bool is_suspended = pm_runtime_status_suspended(dev); + + dev_vdbg(dev, "%s()\n", __func__); + + /* + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. + */ + if (dev->bus && dev->bus->pm) + callback = dev->bus->pm->resume_noirq; + + if (callback) + ret = callback(dev); + else + ret = pm_generic_resume_noirq(dev); + + if (!ret && !is_suspended) + ux500_pd_enable(prd); + + return ret; +} + static int ux500_pd_amba_runtime_suspend(struct device *dev) { struct pm_runtime_data *prd = __to_prd(dev); @@ -210,9 +266,9 @@ static int ux500_pd_amba_runtime_suspend(struct device *dev) dev_vdbg(dev, "%s()\n", __func__); /* - * Do not bypass AMBA bus runtime functions by calling generic runtime - * directly. A future fix could be to implement a - * "pm_bus_generic_runtime_*" API which we can use instead. + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. */ if (dev->bus && dev->bus->pm) callback = dev->bus->pm->runtime_suspend; @@ -239,9 +295,9 @@ static int ux500_pd_amba_runtime_resume(struct device *dev) ux500_pd_enable(prd); /* - * Do not bypass AMBA bus runtime functions by calling generic runtime - * directly. A future fix could be to implement a - * "pm_bus_generic_runtime_*" API which we can use instead. + * Do not bypass AMBA bus pm functions by calling generic + * pm directly. A future fix could be to implement a + * "pm_bus_generic_*" API which we can use instead. */ if (dev->bus && dev->bus->pm) callback = dev->bus->pm->runtime_resume; @@ -381,7 +437,23 @@ static int ux500_pd_bus_notify(struct notifier_block *nb, struct dev_power_domain ux500_amba_dev_power_domain = { .ops = { - USE_AMBA_PM_SLEEP_OPS + /* USE_AMBA_PM_SLEEP_OPS minus the two we replace */ + .prepare = amba_pm_prepare, + .complete = amba_pm_complete, + .suspend = amba_pm_suspend, + .resume = amba_pm_resume, + .freeze = amba_pm_freeze, + .thaw = amba_pm_thaw, + .poweroff = amba_pm_poweroff, + .restore = amba_pm_restore, + .freeze_noirq = amba_pm_freeze_noirq, + .thaw_noirq = amba_pm_thaw_noirq, + .poweroff_noirq = amba_pm_poweroff_noirq, + .restore_noirq = amba_pm_restore_noirq, + + .suspend_noirq = ux500_pd_amba_suspend_noirq, + .resume_noirq = ux500_pd_amba_resume_noirq, + SET_RUNTIME_PM_OPS(ux500_pd_amba_runtime_suspend, ux500_pd_amba_runtime_resume, ux500_pd_amba_runtime_idle) |