@@ -5,7 +5,7 @@
*
* This file is released under the GPLv2.
*/
-
+#define DEBUG
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/platform_device.h>
@@ -158,6 +158,8 @@ static int genpd_power_on(struct generic_pm_domain *genpd)
s64 elapsed_ns;
int ret;
+ pr_debug("%s: %s()\n", genpd->name, __func__);
+
if (!genpd->power_on)
return 0;
@@ -219,6 +221,10 @@ static int __pm_genpd_poweron(struct generic_pm_domain *genpd)
DEFINE_WAIT(wait);
int ret = 0;
+ pr_debug("%s: %s() status %u prepared %d spo %u\n",
+ genpd->name, __func__, genpd->status, genpd->prepared_count,
+ genpd->suspend_power_off);
+
/* If the domain's master is being waited for, we have to wait too. */
for (;;) {
prepare_to_wait(&genpd->status_wait_queue, &wait,
@@ -741,6 +747,20 @@ static int pm_genpd_runtime_resume(struct device *dev)
return 0;
}
+static int pm_genpd_runtime_set_status(struct device *dev)
+{
+ int ret;
+
+ dev_dbg(dev, "%s()\n", __func__);
+
+ if (pm_runtime_suspended(dev))
+ ret = pm_genpd_runtime_suspend(dev);
+ else
+ ret = pm_genpd_runtime_resume(dev);
+
+ return ret;
+}
+
static bool pd_ignore_unused;
static int __init pd_ignore_unused_setup(char *__unused)
{
@@ -1907,6 +1927,7 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
genpd->max_off_time_changed = true;
genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
+ genpd->domain.ops.runtime_set_status = pm_genpd_runtime_set_status;
genpd->domain.ops.prepare = pm_genpd_prepare;
genpd->domain.ops.suspend = pm_genpd_suspend;
genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
@@ -2223,7 +2244,6 @@ int genpd_dev_pm_attach(struct device *dev)
}
dev->pm_domain->detach = genpd_dev_pm_detach;
- pm_genpd_poweron(pd);
return 0;
}
@@ -981,6 +981,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
struct device *parent = dev->parent;
unsigned long flags;
bool notify_parent = false;
+ pm_callback_t callback;
int error = 0;
if (status != RPM_ACTIVE && status != RPM_SUSPENDED)
@@ -1029,6 +1030,10 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
out_set:
__update_runtime_status(dev, status);
dev->power.runtime_error = 0;
+ if (dev->power.no_callbacks)
+ goto out;
+ callback = RPM_GET_CALLBACK(dev, runtime_set_status);
+ rpm_callback(callback, dev);
out:
spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -316,6 +316,7 @@ struct dev_pm_ops {
int (*runtime_suspend)(struct device *dev);
int (*runtime_resume)(struct device *dev);
int (*runtime_idle)(struct device *dev);
+ int (*runtime_set_status)(struct device *dev);
};
#ifdef CONFIG_PM_SLEEP