|
@@ -428,26 +428,17 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
|
|
|
pm_noirq_op(dev, &dev->pwr_domain->ops, state);
|
|
|
}
|
|
|
|
|
|
- if (dev->bus && dev->bus->pm) {
|
|
|
- pm_dev_dbg(dev, state, "EARLY ");
|
|
|
- error = pm_noirq_op(dev, dev->bus->pm, state);
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
if (dev->type && dev->type->pm) {
|
|
|
pm_dev_dbg(dev, state, "EARLY type ");
|
|
|
error = pm_noirq_op(dev, dev->type->pm, state);
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->class && dev->class->pm) {
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
pm_dev_dbg(dev, state, "EARLY class ");
|
|
|
error = pm_noirq_op(dev, dev->class->pm, state);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "EARLY ");
|
|
|
+ error = pm_noirq_op(dev, dev->bus->pm, state);
|
|
|
}
|
|
|
|
|
|
-End:
|
|
|
TRACE_RESUME(error);
|
|
|
return error;
|
|
|
}
|
|
@@ -528,36 +519,34 @@ static int device_resume(struct device *dev, pm_message_t state, bool async)
|
|
|
pm_op(dev, &dev->pwr_domain->ops, state);
|
|
|
}
|
|
|
|
|
|
- if (dev->bus) {
|
|
|
- if (dev->bus->pm) {
|
|
|
- pm_dev_dbg(dev, state, "");
|
|
|
- error = pm_op(dev, dev->bus->pm, state);
|
|
|
- } else if (dev->bus->resume) {
|
|
|
- pm_dev_dbg(dev, state, "legacy ");
|
|
|
- error = legacy_resume(dev, dev->bus->resume);
|
|
|
- }
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->type) {
|
|
|
- if (dev->type->pm) {
|
|
|
- pm_dev_dbg(dev, state, "type ");
|
|
|
- error = pm_op(dev, dev->type->pm, state);
|
|
|
- }
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
+ if (dev->type && dev->type->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "type ");
|
|
|
+ error = pm_op(dev, dev->type->pm, state);
|
|
|
+ goto End;
|
|
|
}
|
|
|
|
|
|
if (dev->class) {
|
|
|
if (dev->class->pm) {
|
|
|
pm_dev_dbg(dev, state, "class ");
|
|
|
error = pm_op(dev, dev->class->pm, state);
|
|
|
+ goto End;
|
|
|
} else if (dev->class->resume) {
|
|
|
pm_dev_dbg(dev, state, "legacy class ");
|
|
|
error = legacy_resume(dev, dev->class->resume);
|
|
|
+ goto End;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (dev->bus) {
|
|
|
+ if (dev->bus->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "");
|
|
|
+ error = pm_op(dev, dev->bus->pm, state);
|
|
|
+ } else if (dev->bus->resume) {
|
|
|
+ pm_dev_dbg(dev, state, "legacy ");
|
|
|
+ error = legacy_resume(dev, dev->bus->resume);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
End:
|
|
|
device_unlock(dev);
|
|
|
complete_all(&dev->power.completion);
|
|
@@ -644,19 +633,18 @@ static void device_complete(struct device *dev, pm_message_t state)
|
|
|
dev->pwr_domain->ops.complete(dev);
|
|
|
}
|
|
|
|
|
|
- if (dev->class && dev->class->pm && dev->class->pm->complete) {
|
|
|
- pm_dev_dbg(dev, state, "completing class ");
|
|
|
- dev->class->pm->complete(dev);
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->type && dev->type->pm && dev->type->pm->complete) {
|
|
|
+ if (dev->type && dev->type->pm) {
|
|
|
pm_dev_dbg(dev, state, "completing type ");
|
|
|
- dev->type->pm->complete(dev);
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->bus && dev->bus->pm && dev->bus->pm->complete) {
|
|
|
+ if (dev->type->pm->complete)
|
|
|
+ dev->type->pm->complete(dev);
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "completing class ");
|
|
|
+ if (dev->class->pm->complete)
|
|
|
+ dev->class->pm->complete(dev);
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
pm_dev_dbg(dev, state, "completing ");
|
|
|
- dev->bus->pm->complete(dev);
|
|
|
+ if (dev->bus->pm->complete)
|
|
|
+ dev->bus->pm->complete(dev);
|
|
|
}
|
|
|
|
|
|
device_unlock(dev);
|
|
@@ -741,27 +729,23 @@ static pm_message_t resume_event(pm_message_t sleep_state)
|
|
|
*/
|
|
|
static int device_suspend_noirq(struct device *dev, pm_message_t state)
|
|
|
{
|
|
|
- int error = 0;
|
|
|
-
|
|
|
- if (dev->class && dev->class->pm) {
|
|
|
- pm_dev_dbg(dev, state, "LATE class ");
|
|
|
- error = pm_noirq_op(dev, dev->class->pm, state);
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
+ int error;
|
|
|
|
|
|
if (dev->type && dev->type->pm) {
|
|
|
pm_dev_dbg(dev, state, "LATE type ");
|
|
|
error = pm_noirq_op(dev, dev->type->pm, state);
|
|
|
if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->bus && dev->bus->pm) {
|
|
|
+ return error;
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "LATE class ");
|
|
|
+ error = pm_noirq_op(dev, dev->class->pm, state);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
pm_dev_dbg(dev, state, "LATE ");
|
|
|
error = pm_noirq_op(dev, dev->bus->pm, state);
|
|
|
if (error)
|
|
|
- goto End;
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
if (dev->pwr_domain) {
|
|
@@ -769,8 +753,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
|
|
|
pm_noirq_op(dev, &dev->pwr_domain->ops, state);
|
|
|
}
|
|
|
|
|
|
-End:
|
|
|
- return error;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -857,25 +840,22 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
|
|
goto End;
|
|
|
}
|
|
|
|
|
|
+ if (dev->type && dev->type->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "type ");
|
|
|
+ error = pm_op(dev, dev->type->pm, state);
|
|
|
+ goto Domain;
|
|
|
+ }
|
|
|
+
|
|
|
if (dev->class) {
|
|
|
if (dev->class->pm) {
|
|
|
pm_dev_dbg(dev, state, "class ");
|
|
|
error = pm_op(dev, dev->class->pm, state);
|
|
|
+ goto Domain;
|
|
|
} else if (dev->class->suspend) {
|
|
|
pm_dev_dbg(dev, state, "legacy class ");
|
|
|
error = legacy_suspend(dev, state, dev->class->suspend);
|
|
|
+ goto Domain;
|
|
|
}
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->type) {
|
|
|
- if (dev->type->pm) {
|
|
|
- pm_dev_dbg(dev, state, "type ");
|
|
|
- error = pm_op(dev, dev->type->pm, state);
|
|
|
- }
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
}
|
|
|
|
|
|
if (dev->bus) {
|
|
@@ -886,11 +866,10 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
|
|
|
pm_dev_dbg(dev, state, "legacy ");
|
|
|
error = legacy_suspend(dev, state, dev->bus->suspend);
|
|
|
}
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
}
|
|
|
|
|
|
- if (dev->pwr_domain) {
|
|
|
+ Domain:
|
|
|
+ if (!error && dev->pwr_domain) {
|
|
|
pm_dev_dbg(dev, state, "power domain ");
|
|
|
pm_op(dev, &dev->pwr_domain->ops, state);
|
|
|
}
|
|
@@ -985,28 +964,27 @@ static int device_prepare(struct device *dev, pm_message_t state)
|
|
|
|
|
|
device_lock(dev);
|
|
|
|
|
|
- if (dev->bus && dev->bus->pm && dev->bus->pm->prepare) {
|
|
|
- pm_dev_dbg(dev, state, "preparing ");
|
|
|
- error = dev->bus->pm->prepare(dev);
|
|
|
- suspend_report_result(dev->bus->pm->prepare, error);
|
|
|
- if (error)
|
|
|
- goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->type && dev->type->pm && dev->type->pm->prepare) {
|
|
|
+ if (dev->type && dev->type->pm) {
|
|
|
pm_dev_dbg(dev, state, "preparing type ");
|
|
|
- error = dev->type->pm->prepare(dev);
|
|
|
+ if (dev->type->pm->prepare)
|
|
|
+ error = dev->type->pm->prepare(dev);
|
|
|
suspend_report_result(dev->type->pm->prepare, error);
|
|
|
if (error)
|
|
|
goto End;
|
|
|
- }
|
|
|
-
|
|
|
- if (dev->class && dev->class->pm && dev->class->pm->prepare) {
|
|
|
+ } else if (dev->class && dev->class->pm) {
|
|
|
pm_dev_dbg(dev, state, "preparing class ");
|
|
|
- error = dev->class->pm->prepare(dev);
|
|
|
+ if (dev->class->pm->prepare)
|
|
|
+ error = dev->class->pm->prepare(dev);
|
|
|
suspend_report_result(dev->class->pm->prepare, error);
|
|
|
if (error)
|
|
|
goto End;
|
|
|
+ } else if (dev->bus && dev->bus->pm) {
|
|
|
+ pm_dev_dbg(dev, state, "preparing ");
|
|
|
+ if (dev->bus->pm->prepare)
|
|
|
+ error = dev->bus->pm->prepare(dev);
|
|
|
+ suspend_report_result(dev->bus->pm->prepare, error);
|
|
|
+ if (error)
|
|
|
+ goto End;
|
|
|
}
|
|
|
|
|
|
if (dev->pwr_domain && dev->pwr_domain->ops.prepare) {
|