|
@@ -551,6 +551,35 @@ bool dev_pm_may_skip_resume(struct device *dev)
|
|
|
return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE;
|
|
|
}
|
|
|
|
|
|
+static pm_callback_t dpm_subsys_resume_noirq_cb(struct device *dev,
|
|
|
+ pm_message_t state,
|
|
|
+ const char **info_p)
|
|
|
+{
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
+
|
|
|
+ if (dev->pm_domain) {
|
|
|
+ info = "noirq power domain ";
|
|
|
+ callback = pm_noirq_op(&dev->pm_domain->ops, state);
|
|
|
+ } else if (dev->type && dev->type->pm) {
|
|
|
+ info = "noirq type ";
|
|
|
+ callback = pm_noirq_op(dev->type->pm, state);
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ info = "noirq class ";
|
|
|
+ callback = pm_noirq_op(dev->class->pm, state);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ info = "noirq bus ";
|
|
|
+ callback = pm_noirq_op(dev->bus->pm, state);
|
|
|
+ } else {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info_p)
|
|
|
+ *info_p = info;
|
|
|
+
|
|
|
+ return callback;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* device_resume_noirq - Execute a "noirq resume" callback for given device.
|
|
|
* @dev: Device to handle.
|
|
@@ -562,8 +591,8 @@ bool dev_pm_may_skip_resume(struct device *dev)
|
|
|
*/
|
|
|
static int device_resume_noirq(struct device *dev, pm_message_t state, bool async)
|
|
|
{
|
|
|
- pm_callback_t callback = NULL;
|
|
|
- const char *info = NULL;
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
int error = 0;
|
|
|
|
|
|
TRACE_DEVICE(dev);
|
|
@@ -577,19 +606,7 @@ static int device_resume_noirq(struct device *dev, pm_message_t state, bool asyn
|
|
|
|
|
|
dpm_wait_for_superior(dev, async);
|
|
|
|
|
|
- if (dev->pm_domain) {
|
|
|
- info = "noirq power domain ";
|
|
|
- callback = pm_noirq_op(&dev->pm_domain->ops, state);
|
|
|
- } else if (dev->type && dev->type->pm) {
|
|
|
- info = "noirq type ";
|
|
|
- callback = pm_noirq_op(dev->type->pm, state);
|
|
|
- } else if (dev->class && dev->class->pm) {
|
|
|
- info = "noirq class ";
|
|
|
- callback = pm_noirq_op(dev->class->pm, state);
|
|
|
- } else if (dev->bus && dev->bus->pm) {
|
|
|
- info = "noirq bus ";
|
|
|
- callback = pm_noirq_op(dev->bus->pm, state);
|
|
|
- }
|
|
|
+ callback = dpm_subsys_resume_noirq_cb(dev, state, &info);
|
|
|
|
|
|
if (!callback && dev->driver && dev->driver->pm) {
|
|
|
info = "noirq driver ";
|
|
@@ -704,6 +721,35 @@ void dpm_resume_noirq(pm_message_t state)
|
|
|
dpm_noirq_end();
|
|
|
}
|
|
|
|
|
|
+static pm_callback_t dpm_subsys_resume_early_cb(struct device *dev,
|
|
|
+ pm_message_t state,
|
|
|
+ const char **info_p)
|
|
|
+{
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
+
|
|
|
+ if (dev->pm_domain) {
|
|
|
+ info = "early power domain ";
|
|
|
+ callback = pm_late_early_op(&dev->pm_domain->ops, state);
|
|
|
+ } else if (dev->type && dev->type->pm) {
|
|
|
+ info = "early type ";
|
|
|
+ callback = pm_late_early_op(dev->type->pm, state);
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ info = "early class ";
|
|
|
+ callback = pm_late_early_op(dev->class->pm, state);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ info = "early bus ";
|
|
|
+ callback = pm_late_early_op(dev->bus->pm, state);
|
|
|
+ } else {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info_p)
|
|
|
+ *info_p = info;
|
|
|
+
|
|
|
+ return callback;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* device_resume_early - Execute an "early resume" callback for given device.
|
|
|
* @dev: Device to handle.
|
|
@@ -714,8 +760,8 @@ void dpm_resume_noirq(pm_message_t state)
|
|
|
*/
|
|
|
static int device_resume_early(struct device *dev, pm_message_t state, bool async)
|
|
|
{
|
|
|
- pm_callback_t callback = NULL;
|
|
|
- const char *info = NULL;
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
int error = 0;
|
|
|
|
|
|
TRACE_DEVICE(dev);
|
|
@@ -729,19 +775,7 @@ static int device_resume_early(struct device *dev, pm_message_t state, bool asyn
|
|
|
|
|
|
dpm_wait_for_superior(dev, async);
|
|
|
|
|
|
- if (dev->pm_domain) {
|
|
|
- info = "early power domain ";
|
|
|
- callback = pm_late_early_op(&dev->pm_domain->ops, state);
|
|
|
- } else if (dev->type && dev->type->pm) {
|
|
|
- info = "early type ";
|
|
|
- callback = pm_late_early_op(dev->type->pm, state);
|
|
|
- } else if (dev->class && dev->class->pm) {
|
|
|
- info = "early class ";
|
|
|
- callback = pm_late_early_op(dev->class->pm, state);
|
|
|
- } else if (dev->bus && dev->bus->pm) {
|
|
|
- info = "early bus ";
|
|
|
- callback = pm_late_early_op(dev->bus->pm, state);
|
|
|
- }
|
|
|
+ callback = dpm_subsys_resume_early_cb(dev, state, &info);
|
|
|
|
|
|
if (!callback && dev->driver && dev->driver->pm) {
|
|
|
info = "early driver ";
|
|
@@ -1128,6 +1162,35 @@ static void dpm_superior_set_must_resume(struct device *dev)
|
|
|
device_links_read_unlock(idx);
|
|
|
}
|
|
|
|
|
|
+static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev,
|
|
|
+ pm_message_t state,
|
|
|
+ const char **info_p)
|
|
|
+{
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
+
|
|
|
+ if (dev->pm_domain) {
|
|
|
+ info = "noirq power domain ";
|
|
|
+ callback = pm_noirq_op(&dev->pm_domain->ops, state);
|
|
|
+ } else if (dev->type && dev->type->pm) {
|
|
|
+ info = "noirq type ";
|
|
|
+ callback = pm_noirq_op(dev->type->pm, state);
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ info = "noirq class ";
|
|
|
+ callback = pm_noirq_op(dev->class->pm, state);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ info = "noirq bus ";
|
|
|
+ callback = pm_noirq_op(dev->bus->pm, state);
|
|
|
+ } else {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info_p)
|
|
|
+ *info_p = info;
|
|
|
+
|
|
|
+ return callback;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* __device_suspend_noirq - Execute a "noirq suspend" callback for given device.
|
|
|
* @dev: Device to handle.
|
|
@@ -1139,8 +1202,8 @@ static void dpm_superior_set_must_resume(struct device *dev)
|
|
|
*/
|
|
|
static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async)
|
|
|
{
|
|
|
- pm_callback_t callback = NULL;
|
|
|
- const char *info = NULL;
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
int error = 0;
|
|
|
|
|
|
TRACE_DEVICE(dev);
|
|
@@ -1159,19 +1222,7 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
|
|
|
if (dev->power.syscore || dev->power.direct_complete)
|
|
|
goto Complete;
|
|
|
|
|
|
- if (dev->pm_domain) {
|
|
|
- info = "noirq power domain ";
|
|
|
- callback = pm_noirq_op(&dev->pm_domain->ops, state);
|
|
|
- } else if (dev->type && dev->type->pm) {
|
|
|
- info = "noirq type ";
|
|
|
- callback = pm_noirq_op(dev->type->pm, state);
|
|
|
- } else if (dev->class && dev->class->pm) {
|
|
|
- info = "noirq class ";
|
|
|
- callback = pm_noirq_op(dev->class->pm, state);
|
|
|
- } else if (dev->bus && dev->bus->pm) {
|
|
|
- info = "noirq bus ";
|
|
|
- callback = pm_noirq_op(dev->bus->pm, state);
|
|
|
- }
|
|
|
+ callback = dpm_subsys_suspend_noirq_cb(dev, state, &info);
|
|
|
|
|
|
if (!callback && dev->driver && dev->driver->pm) {
|
|
|
info = "noirq driver ";
|
|
@@ -1306,6 +1357,35 @@ int dpm_suspend_noirq(pm_message_t state)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev,
|
|
|
+ pm_message_t state,
|
|
|
+ const char **info_p)
|
|
|
+{
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
+
|
|
|
+ if (dev->pm_domain) {
|
|
|
+ info = "late power domain ";
|
|
|
+ callback = pm_late_early_op(&dev->pm_domain->ops, state);
|
|
|
+ } else if (dev->type && dev->type->pm) {
|
|
|
+ info = "late type ";
|
|
|
+ callback = pm_late_early_op(dev->type->pm, state);
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ info = "late class ";
|
|
|
+ callback = pm_late_early_op(dev->class->pm, state);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ info = "late bus ";
|
|
|
+ callback = pm_late_early_op(dev->bus->pm, state);
|
|
|
+ } else {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info_p)
|
|
|
+ *info_p = info;
|
|
|
+
|
|
|
+ return callback;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* __device_suspend_late - Execute a "late suspend" callback for given device.
|
|
|
* @dev: Device to handle.
|
|
@@ -1316,8 +1396,8 @@ int dpm_suspend_noirq(pm_message_t state)
|
|
|
*/
|
|
|
static int __device_suspend_late(struct device *dev, pm_message_t state, bool async)
|
|
|
{
|
|
|
- pm_callback_t callback = NULL;
|
|
|
- const char *info = NULL;
|
|
|
+ pm_callback_t callback;
|
|
|
+ const char *info;
|
|
|
int error = 0;
|
|
|
|
|
|
TRACE_DEVICE(dev);
|
|
@@ -1338,19 +1418,7 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
|
|
|
if (dev->power.syscore || dev->power.direct_complete)
|
|
|
goto Complete;
|
|
|
|
|
|
- if (dev->pm_domain) {
|
|
|
- info = "late power domain ";
|
|
|
- callback = pm_late_early_op(&dev->pm_domain->ops, state);
|
|
|
- } else if (dev->type && dev->type->pm) {
|
|
|
- info = "late type ";
|
|
|
- callback = pm_late_early_op(dev->type->pm, state);
|
|
|
- } else if (dev->class && dev->class->pm) {
|
|
|
- info = "late class ";
|
|
|
- callback = pm_late_early_op(dev->class->pm, state);
|
|
|
- } else if (dev->bus && dev->bus->pm) {
|
|
|
- info = "late bus ";
|
|
|
- callback = pm_late_early_op(dev->bus->pm, state);
|
|
|
- }
|
|
|
+ callback = dpm_subsys_suspend_late_cb(dev, state, &info);
|
|
|
|
|
|
if (!callback && dev->driver && dev->driver->pm) {
|
|
|
info = "late driver ";
|