|
@@ -229,17 +229,6 @@ static int genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
|
|
|
-{
|
|
|
- return GENPD_DEV_CALLBACK(genpd, int, save_state, dev);
|
|
|
-}
|
|
|
-
|
|
|
-static int genpd_restore_dev(struct generic_pm_domain *genpd,
|
|
|
- struct device *dev)
|
|
|
-{
|
|
|
- return GENPD_DEV_CALLBACK(genpd, int, restore_state, dev);
|
|
|
-}
|
|
|
-
|
|
|
static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
|
|
|
unsigned long val, void *ptr)
|
|
|
{
|
|
@@ -371,6 +360,52 @@ static void genpd_power_off_work_fn(struct work_struct *work)
|
|
|
mutex_unlock(&genpd->lock);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
|
|
|
+ * @dev: Device to handle.
|
|
|
+ */
|
|
|
+static int __genpd_runtime_suspend(struct device *dev)
|
|
|
+{
|
|
|
+ int (*cb)(struct device *__dev);
|
|
|
+
|
|
|
+ if (dev->type && dev->type->pm)
|
|
|
+ cb = dev->type->pm->runtime_suspend;
|
|
|
+ else if (dev->class && dev->class->pm)
|
|
|
+ cb = dev->class->pm->runtime_suspend;
|
|
|
+ else if (dev->bus && dev->bus->pm)
|
|
|
+ cb = dev->bus->pm->runtime_suspend;
|
|
|
+ else
|
|
|
+ cb = NULL;
|
|
|
+
|
|
|
+ if (!cb && dev->driver && dev->driver->pm)
|
|
|
+ cb = dev->driver->pm->runtime_suspend;
|
|
|
+
|
|
|
+ return cb ? cb(dev) : 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
|
|
|
+ * @dev: Device to handle.
|
|
|
+ */
|
|
|
+static int __genpd_runtime_resume(struct device *dev)
|
|
|
+{
|
|
|
+ int (*cb)(struct device *__dev);
|
|
|
+
|
|
|
+ if (dev->type && dev->type->pm)
|
|
|
+ cb = dev->type->pm->runtime_resume;
|
|
|
+ else if (dev->class && dev->class->pm)
|
|
|
+ cb = dev->class->pm->runtime_resume;
|
|
|
+ else if (dev->bus && dev->bus->pm)
|
|
|
+ cb = dev->bus->pm->runtime_resume;
|
|
|
+ else
|
|
|
+ cb = NULL;
|
|
|
+
|
|
|
+ if (!cb && dev->driver && dev->driver->pm)
|
|
|
+ cb = dev->driver->pm->runtime_resume;
|
|
|
+
|
|
|
+ return cb ? cb(dev) : 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
|
|
|
* @dev: Device to suspend.
|
|
@@ -409,13 +444,13 @@ static int genpd_runtime_suspend(struct device *dev)
|
|
|
if (runtime_pm)
|
|
|
time_start = ktime_get();
|
|
|
|
|
|
- ret = genpd_save_dev(genpd, dev);
|
|
|
+ ret = __genpd_runtime_suspend(dev);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
ret = genpd_stop_dev(genpd, dev);
|
|
|
if (ret) {
|
|
|
- genpd_restore_dev(genpd, dev);
|
|
|
+ __genpd_runtime_resume(dev);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -491,7 +526,7 @@ static int genpd_runtime_resume(struct device *dev)
|
|
|
if (ret)
|
|
|
goto err_poweroff;
|
|
|
|
|
|
- ret = genpd_restore_dev(genpd, dev);
|
|
|
+ ret = __genpd_runtime_resume(dev);
|
|
|
if (ret)
|
|
|
goto err_stop;
|
|
|
|
|
@@ -1427,54 +1462,6 @@ out:
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
|
|
|
|
|
|
-/* Default device callbacks for generic PM domains. */
|
|
|
-
|
|
|
-/**
|
|
|
- * pm_genpd_default_save_state - Default "save device state" for PM domains.
|
|
|
- * @dev: Device to handle.
|
|
|
- */
|
|
|
-static int pm_genpd_default_save_state(struct device *dev)
|
|
|
-{
|
|
|
- int (*cb)(struct device *__dev);
|
|
|
-
|
|
|
- if (dev->type && dev->type->pm)
|
|
|
- cb = dev->type->pm->runtime_suspend;
|
|
|
- else if (dev->class && dev->class->pm)
|
|
|
- cb = dev->class->pm->runtime_suspend;
|
|
|
- else if (dev->bus && dev->bus->pm)
|
|
|
- cb = dev->bus->pm->runtime_suspend;
|
|
|
- else
|
|
|
- cb = NULL;
|
|
|
-
|
|
|
- if (!cb && dev->driver && dev->driver->pm)
|
|
|
- cb = dev->driver->pm->runtime_suspend;
|
|
|
-
|
|
|
- return cb ? cb(dev) : 0;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * pm_genpd_default_restore_state - Default PM domains "restore device state".
|
|
|
- * @dev: Device to handle.
|
|
|
- */
|
|
|
-static int pm_genpd_default_restore_state(struct device *dev)
|
|
|
-{
|
|
|
- int (*cb)(struct device *__dev);
|
|
|
-
|
|
|
- if (dev->type && dev->type->pm)
|
|
|
- cb = dev->type->pm->runtime_resume;
|
|
|
- else if (dev->class && dev->class->pm)
|
|
|
- cb = dev->class->pm->runtime_resume;
|
|
|
- else if (dev->bus && dev->bus->pm)
|
|
|
- cb = dev->bus->pm->runtime_resume;
|
|
|
- else
|
|
|
- cb = NULL;
|
|
|
-
|
|
|
- if (!cb && dev->driver && dev->driver->pm)
|
|
|
- cb = dev->driver->pm->runtime_resume;
|
|
|
-
|
|
|
- return cb ? cb(dev) : 0;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* pm_genpd_init - Initialize a generic I/O PM domain object.
|
|
|
* @genpd: PM domain object to initialize.
|
|
@@ -1520,8 +1507,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
|
|
|
genpd->domain.ops.restore_early = pm_genpd_resume_early;
|
|
|
genpd->domain.ops.restore = pm_genpd_resume;
|
|
|
genpd->domain.ops.complete = pm_genpd_complete;
|
|
|
- genpd->dev_ops.save_state = pm_genpd_default_save_state;
|
|
|
- genpd->dev_ops.restore_state = pm_genpd_default_restore_state;
|
|
|
|
|
|
if (genpd->flags & GENPD_FLAG_PM_CLK) {
|
|
|
genpd->dev_ops.stop = pm_clk_suspend;
|