PM / Sleep: Simplify generic system suspend callbacks
The pm_runtime_suspended() check in __pm_generic_call() doesn't really help and may cause problems to happen, because in some cases the system suspend callbacks need to be called even if the given device has been suspended by runtime PM. For example, if the device generally supports remote wakeup and is not enabled to wake up the system from sleep, it should be prevented from generating wakeup signals during system suspend and that has to be done by the suspend callbacks that the pm_runtime_suspended() check prevents from being executed. Similarly, it may not be a good idea to unconditionally change the runtime PM status of the device to 'active' in __pm_generic_resume(), because the driver may want to leave the device in the 'suspended' state, depending on what happened to it before the system suspend and whether or not it is enabled to wake up the system. For the above reasons, remove the pm_runtime_suspended() check from __pm_generic_call() and remove the code changing the device's runtime PM status from __pm_generic_resume(). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
This commit is contained in:
parent
cf007e3526
commit
8ca6d9bcc8
|
@ -97,16 +97,16 @@ int pm_generic_prepare(struct device *dev)
|
||||||
* @event: PM transition of the system under way.
|
* @event: PM transition of the system under way.
|
||||||
* @bool: Whether or not this is the "noirq" stage.
|
* @bool: Whether or not this is the "noirq" stage.
|
||||||
*
|
*
|
||||||
* If the device has not been suspended at run time, execute the
|
* Execute the suspend/freeze/poweroff/thaw callback provided by the driver of
|
||||||
* suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and
|
* @dev, if defined, and return its error code. Return 0 if the callback is
|
||||||
* return its error code. Otherwise, return zero.
|
* not present.
|
||||||
*/
|
*/
|
||||||
static int __pm_generic_call(struct device *dev, int event, bool noirq)
|
static int __pm_generic_call(struct device *dev, int event, bool noirq)
|
||||||
{
|
{
|
||||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||||
int (*callback)(struct device *);
|
int (*callback)(struct device *);
|
||||||
|
|
||||||
if (!pm || pm_runtime_suspended(dev))
|
if (!pm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -217,14 +217,12 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
|
||||||
* @bool: Whether or not this is the "noirq" stage.
|
* @bool: Whether or not this is the "noirq" stage.
|
||||||
*
|
*
|
||||||
* Execute the resume/resotre callback provided by the @dev's driver, if
|
* Execute the resume/resotre callback provided by the @dev's driver, if
|
||||||
* defined. If it returns 0, change the device's runtime PM status to 'active'.
|
* defined, and return its error code. Return 0 if the callback is not present.
|
||||||
* Return the callback's error code.
|
|
||||||
*/
|
*/
|
||||||
static int __pm_generic_resume(struct device *dev, int event, bool noirq)
|
static int __pm_generic_resume(struct device *dev, int event, bool noirq)
|
||||||
{
|
{
|
||||||
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
|
||||||
int (*callback)(struct device *);
|
int (*callback)(struct device *);
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!pm)
|
if (!pm)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -241,17 +239,7 @@ static int __pm_generic_resume(struct device *dev, int event, bool noirq)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!callback)
|
return callback ? callback(dev) : 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = callback(dev);
|
|
||||||
if (!ret && !noirq && pm_runtime_enabled(dev)) {
|
|
||||||
pm_runtime_disable(dev);
|
|
||||||
pm_runtime_set_active(dev);
|
|
||||||
pm_runtime_enable(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue