summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@stericsson.com>2011-10-27 14:36:49 +0200
committerLinus WALLEIJ <linus.walleij@stericsson.com>2011-10-27 16:35:34 +0200
commitdbcf2d4cfd7b08f1c051f3bf220c291f21022349 (patch)
tree36cc74664c120f509dd9ac9179d6a823508c2683 /arch
parentf33507227b86ed3ee1a836a679e58a7672603a93 (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.c90
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)