Commit 9bd717c0 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-runtime' into pm-for-linus

* pm-runtime:
  PM / Runtime: Handle .runtime_suspend() failure correctly
  PM / Runtime: Fix kerneldoc comment for rpm_suspend()
  PM / Runtime: Update document about callbacks
parents 7811ac27 857b36c7
...@@ -43,13 +43,18 @@ struct dev_pm_ops { ...@@ -43,13 +43,18 @@ struct dev_pm_ops {
... ...
}; };
The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks
executed by the PM core for either the device type, or the class (if the device are executed by the PM core for either the power domain, or the device type
type's struct dev_pm_ops object does not exist), or the bus type (if the (if the device power domain's struct dev_pm_ops does not exist), or the class
device type's and class' struct dev_pm_ops objects do not exist) of the given (if the device power domain's and type's struct dev_pm_ops object does not
device (this allows device types to override callbacks provided by bus types or exist), or the bus type (if the device power domain's, type's and class'
classes if necessary). The bus type, device type and class callbacks are struct dev_pm_ops objects do not exist) of the given device, so the priority
referred to as subsystem-level callbacks in what follows. order of callbacks from high to low is that power domain callbacks, device
type callbacks, class callbacks and bus type callbacks, and the high priority
one will take precedence over low priority one. The bus type, device type and
class callbacks are referred to as subsystem-level callbacks in what follows,
and generally speaking, the power domain callbacks are used for representing
power domains within a SoC.
By default, the callbacks are always invoked in process context with interrupts By default, the callbacks are always invoked in process context with interrupts
enabled. However, subsystems can use the pm_runtime_irq_safe() helper function enabled. However, subsystems can use the pm_runtime_irq_safe() helper function
......
...@@ -286,14 +286,16 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) ...@@ -286,14 +286,16 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
* @dev: Device to suspend. * @dev: Device to suspend.
* @rpmflags: Flag bits. * @rpmflags: Flag bits.
* *
* Check if the device's runtime PM status allows it to be suspended. If * Check if the device's runtime PM status allows it to be suspended.
* another suspend has been started earlier, either return immediately or wait * Cancel a pending idle notification, autosuspend or suspend. If
* for it to finish, depending on the RPM_NOWAIT and RPM_ASYNC flags. Cancel a * another suspend has been started earlier, either return immediately
* pending idle notification. If the RPM_ASYNC flag is set then queue a * or wait for it to finish, depending on the RPM_NOWAIT and RPM_ASYNC
* suspend request; otherwise run the ->runtime_suspend() callback directly. * flags. If the RPM_ASYNC flag is set then queue a suspend request;
* If a deferred resume was requested while the callback was running then carry * otherwise run the ->runtime_suspend() callback directly. When
* it out; otherwise send an idle notification for the device (if the suspend * ->runtime_suspend succeeded, if a deferred resume was requested while
* failed) or for its parent (if the suspend succeeded). * the callback was running then carry it out, otherwise send an idle
* notification for its parent (if the suspend succeeded and both
* ignore_children of parent->power and irq_safe of dev->power are not set).
* *
* This function must be called under dev->power.lock with interrupts disabled. * This function must be called under dev->power.lock with interrupts disabled.
*/ */
...@@ -418,15 +420,16 @@ static int rpm_suspend(struct device *dev, int rpmflags) ...@@ -418,15 +420,16 @@ static int rpm_suspend(struct device *dev, int rpmflags)
dev->power.runtime_error = 0; dev->power.runtime_error = 0;
else else
pm_runtime_cancel_pending(dev); pm_runtime_cancel_pending(dev);
} else { wake_up_all(&dev->power.wait_queue);
goto out;
}
no_callback: no_callback:
__update_runtime_status(dev, RPM_SUSPENDED); __update_runtime_status(dev, RPM_SUSPENDED);
pm_runtime_deactivate_timer(dev); pm_runtime_deactivate_timer(dev);
if (dev->parent) { if (dev->parent) {
parent = dev->parent; parent = dev->parent;
atomic_add_unless(&parent->power.child_count, -1, 0); atomic_add_unless(&parent->power.child_count, -1, 0);
}
} }
wake_up_all(&dev->power.wait_queue); wake_up_all(&dev->power.wait_queue);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment