Runtime Power Management Framework for I/O Devices

  1. 2009-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.

  1. 2010 Alan Stern <stern@rowland.harvard.edu>

  1. 2014 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>

1. Introduction

Support for runtime power management (runtime PM) of I/O devices is provided at the power management core (PM core) level by means of:

  • The power management workqueue pm_wq in which bus types and device drivers can put their PM-related work items. It is strongly recommended that pm_wq be used for queuing all work items related to runtime PM, because this allows them to be synchronized with system-wide power transitions (suspend to RAM, hibernation and resume from system sleep states). pm_wq is declared in include/linux/pm_runtime.h and defined in kernel/power/main.c.

  • A number of runtime PM fields in the ‘power’ member of ‘struct device’ (which is of the type ‘struct dev_pm_info’, defined in include/linux/pm.h) that can be used for synchronizing runtime PM operations with one another.

  • Three device runtime PM callbacks in ‘struct dev_pm_ops’ (defined in include/linux/pm.h).

  • A set of helper functions defined in drivers/base/power/runtime.c that can be used for carrying out runtime PM operations in such a way that the synchronization between them is taken care of by the PM core. Bus types and device drivers are encouraged to use these functions.

The runtime PM callbacks present in ‘struct dev_pm_ops’, the device runtime PM fields of ‘struct dev_pm_info’ and the core helper functions provided for runtime PM are described below.

2. Device Runtime PM Callbacks

There are three device runtime PM callbacks defined in ‘struct dev_pm_ops’:

struct dev_pm_ops {
      ...
      int (*runtime_suspend)(struct device *dev);
      int (*runtime_resume)(struct device *dev);
      int (*runtime_idle)(struct device *dev);
      ...
};

Most device drivers only need to implement ->runtime_suspend() and ->runtime_resume(). The ->runtime_idle() callback is optional and rarely implemented by peripheral device drivers, as the PM core automatically handles suspension and autosuspend when ->runtime_idle() is omitted (or returns 0).

Subsystem and Driver Callbacks

The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are executed by the PM core for the device’s subsystem that may be either of the following:

  1. PM domain of the device, if the device’s PM domain object, dev->pm_domain, is present.

  2. Device type of the device, if both dev->type and dev->type->pm are present.

  3. Device class of the device, if both dev->class and dev->class->pm are present.

  4. Bus type of the device, if both dev->bus and dev->bus->pm are present.

If the subsystem chosen by applying the above rules doesn’t provide the relevant callback, the PM core will invoke the corresponding driver callback stored in dev->driver->pm directly (if present).

The PM core always checks which callback to use in the order given above, so the priority order of callbacks from high to low is: PM domain, device type, class and bus type. Moreover, the high-priority one will always take precedence over a low-priority one. The PM domain, bus type, device type and class callbacks are referred to as subsystem-level callbacks in what follows.

By default, the callbacks are always invoked in process context with interrupts enabled. However, the pm_runtime_irq_safe() helper function can be used to tell the PM core that it is safe to run the ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks for the given device in atomic context with interrupts disabled. This implies that the callback routines in question must not block or sleep, but it also means that the synchronous helper functions listed at the end of Section 4 may be used for that device within an interrupt handler or generally in an atomic context.

Callback Semantics

The subsystem-level suspend callback, if present, is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include executing the device driver’s own ->runtime_suspend() callback (from the PM core’s point of view it is not necessary to implement a ->runtime_suspend() callback in a device driver as long as the subsystem-level suspend callback knows what to do to handle the device).

  • Once the subsystem-level suspend callback (or the driver suspend callback, if invoked directly) has completed successfully for the given device, the PM core regards the device as suspended, which need not mean that it has been put into a low power state. It is supposed to mean, however, that the device will not process data and will not communicate with the CPU(s) and RAM until the appropriate resume callback is executed for it. The runtime PM status of a device after successful execution of the suspend callback is ‘suspended’.

  • If the suspend callback returns -EBUSY or -EAGAIN, the device’s runtime PM status remains ‘active’, which means that the device _must_ be fully operational afterwards.

  • If the suspend callback returns an error code different from -EBUSY and -EAGAIN, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device until its status is directly set to either ‘active’, or ‘suspended’ (the PM core provides special helper functions for this purpose).

In particular, if the driver requires remote wakeup capability (i.e. hardware mechanism allowing the device to request a change of its power state, such as PCI PME) for proper functioning and device_can_wakeup() returns ‘false’ for the device, then ->runtime_suspend() should return -EBUSY. On the other hand, if device_can_wakeup() returns ‘true’ for the device and the device is put into a low-power state during the execution of the suspend callback, it is expected that remote wakeup will be enabled for the device. Generally, remote wakeup should be enabled for all input devices put into low-power states at run time.

The subsystem-level resume callback, if present, is entirely responsible for handling the resume of the device as appropriate, which may, but need not include executing the device driver’s own ->runtime_resume() callback (from the PM core’s point of view it is not necessary to implement a ->runtime_resume() callback in a device driver as long as the subsystem-level resume callback knows what to do to handle the device).

  • Once the subsystem-level resume callback (or the driver resume callback, if invoked directly) has completed successfully, the PM core regards the device as fully operational, which means that the device _must_ be able to complete I/O operations as needed. The runtime PM status of the device is then ‘active’.

  • If the resume callback returns an error code, the PM core regards this as a fatal error and will refuse to run the helper functions described in Section 4 for the device, until its status is directly set to either ‘active’, or ‘suspended’ (by means of special helper functions provided by the PM core for this purpose).

The idle callback (a subsystem-level one, if present, or the driver one) is executed by the PM core whenever the device appears to be idle, which is indicated to the PM core by two counters, the device’s usage counter and the counter of ‘active’ children of the device.

  • If any of these counters is decreased using a helper function provided by the PM core and it turns out to be equal to zero, the other counter is checked. If that counter also is equal to zero, the PM core executes the idle callback with the device as its argument.

The action performed by the idle callback is totally dependent on the subsystem (or driver) in question, but the expected and recommended action is to check if the device can be suspended (i.e. if all of the conditions necessary for suspending the device are satisfied) and to queue up a suspend request for the device in that case. If there is no idle callback, or if the callback returns 0, then the PM core will attempt to carry out a runtime suspend of the device, also respecting devices configured for autosuspend. In essence this means a call to pm_runtime_autosuspend().

To prevent this suspension (for example, if the callback routine has scheduled a delayed suspend or determined the device cannot be idle), the routine must return a non-zero value (typically -EBUSY or -EAGAIN). Unlike ->runtime_suspend() and ->runtime_resume(), the PM core does not treat negative return codes from ->runtime_idle() as a fatal device error; any non-zero value simply stops the PM core from suspending the device.

Core Guarantees and Synchronization Rules

The helper functions provided by the PM core, described in Section 4, guarantee that the following constraints are met with respect to runtime PM callbacks for one device:

  1. The callbacks are mutually exclusive (e.g. it is forbidden to execute ->runtime_suspend() in parallel with ->runtime_resume() or with another instance of ->runtime_suspend() for the same device) with the exception that ->runtime_suspend() or ->runtime_resume() can be executed in parallel with ->runtime_idle() (although ->runtime_idle() will not be started while any of the other callbacks is being executed for the same device).

  2. ->runtime_idle() and ->runtime_suspend() can only be executed for ‘active’ devices (i.e. the PM core will only execute ->runtime_idle() or ->runtime_suspend() for the devices the runtime PM status of which is ‘active’).

  3. ->runtime_idle() and ->runtime_suspend() can only be executed for a device the usage counter of which is equal to zero _and_ either the counter of ‘active’ children of which is equal to zero, or the ‘power.ignore_children’ flag of which is set.

  4. ->runtime_resume() can only be executed for ‘suspended’ devices (i.e. the PM core will only execute ->runtime_resume() for the devices the runtime PM status of which is ‘suspended’).

Additionally, the helper functions provided by the PM core obey the following rules:

  • If ->runtime_suspend() is about to be executed or there’s a pending request to execute it, ->runtime_idle() will not be executed for the same device.

  • A request to execute or to schedule the execution of ->runtime_suspend() will cancel any pending requests to execute ->runtime_idle() for the same device.

  • If ->runtime_resume() is about to be executed or there’s a pending request to execute it, the other callbacks will not be executed for the same device.

  • A request to execute ->runtime_resume() will cancel any pending or scheduled requests to execute the other callbacks for the same device, except for scheduled autosuspends.

3. Runtime PM Device Fields

Device PM fields are found in ‘struct dev_pm_info’, as defined in include/linux/pm.h. Many of those fields track runtime PM configuration and state.

struct dev_pm_info

Device power management information.

Definition:

struct dev_pm_info {
    pm_message_t power_state;
    bool can_wakeup:1;
    bool async_suspend:1;
    bool in_dpm_list:1;
    bool is_prepared:1;
    bool is_suspended:1;
    bool is_noirq_suspended:1;
    bool is_late_suspended:1;
    bool no_pm:1;
    bool early_init:1;
    bool direct_complete:1;
    u32 driver_flags;
    spinlock_t lock;
#ifdef CONFIG_PM_SLEEP;
    struct list_head        entry;
    struct completion       completion;
    struct wakeup_source    *wakeup;
    bool work_in_progress;
    bool wakeup_path:1;
    bool syscore:1;
    bool no_pm_callbacks:1;
    bool smart_suspend:1;
    bool must_resume:1;
    bool may_skip_resume:1;
    bool out_band_wakeup:1;
    bool strict_midlayer:1;
#else;
    bool should_wakeup:1;
#endif;
#ifdef CONFIG_PM;
    struct hrtimer          suspend_timer;
    u64 timer_expires;
    struct work_struct      work;
    wait_queue_head_t wait_queue;
    struct wake_irq         *wakeirq;
    atomic_t usage_count;
    atomic_t child_count;
    unsigned int            disable_depth:3;
    bool idle_notification:1;
    bool request_pending:1;
    bool deferred_resume:1;
    bool needs_force_resume:1;
    bool runtime_auto:1;
    bool ignore_children:1;
    bool no_callbacks:1;
    bool irq_safe:1;
    bool use_autosuspend:1;
    bool timer_autosuspends:1;
    bool memalloc_noio:1;
    unsigned int            links_count;
    enum rpm_request        request;
    enum rpm_status         runtime_status;
    enum rpm_status         last_status;
    int runtime_error;
    int autosuspend_delay;
    u64 last_busy;
    u64 active_time;
    u64 suspended_time;
    u64 accounting_timestamp;
#endif;
    struct pm_subsys_data   *subsys_data;
    void (*set_latency_tolerance)(struct device *, s32);
    struct dev_pm_qos       *qos;
    bool detach_power_off:1;
};

Members

power_state

Legacy power state (mostly unused in modern kernels).

can_wakeup

Device is capable of generating wakeup signals.

async_suspend

Device can be suspended and resumed asynchronously.

in_dpm_list

Device is on the dpm_list.

is_prepared

Device’s ->prepare() callback has run successfully.

is_suspended

Device is suspended during a system sleep transition.

is_noirq_suspended

Device’s noirq suspend callback has run successfully.

is_late_suspended

Device’s late suspend callback has run successfully.

no_pm

Device does not participate in power management transitions.

early_init

Device was initialized before standard PM initialization.

direct_complete

Device can skip suspend/resume callbacks and remain runtime-suspended during system sleep.

driver_flags

Driver flags (e.g. DPM_FLAG_SMART_SUSPEND) set at probe time.

lock

Spinlock used for synchronizing PM state transitions and runtime PM operations.

entry

List head for device power management lists.

completion

Completion for synchronization during asynchronous system suspend/resume.

wakeup

Wakeup source object associated with the device.

work_in_progress

Asynchronous PM operation in progress.

wakeup_path

Device is in the wakeup path or can wake the system up.

syscore

Device participates in syscore power management operations.

no_pm_callbacks

Device has no PM callbacks; handled by parent or subsystem.

smart_suspend

Driver requested smart-suspend behavior.

must_resume

Device must be resumed during system resume.

may_skip_resume

Set by subsystems to indicate driver resume callbacks may be skipped.

out_band_wakeup

Out-of-band wakeup is supported.

strict_midlayer

Middle layer code does not want callbacks invoked via pm_runtime_force_suspend() / pm_runtime_force_resume().

should_wakeup

Wakeup flag when system sleep is not enabled.

suspend_timer

High-resolution timer used for scheduling delayed runtime suspend and autosuspend requests.

timer_expires

Timer expiration time in nanoseconds monotonic time (runtime PM).

work

Work structure used for queuing up requests into pm_wq (runtime PM).

wait_queue

Wait queue used if any helper functions need to wait for another state change to complete (runtime PM).

wakeirq

Dedicated wakeup interrupt for the device.

usage_count

Device runtime PM usage counter.

child_count

Count of active children of the device (runtime PM).

disable_depth

Disable counter for runtime PM (runtime PM is enabled when this is 0; initial value is 1).

idle_notification

Set if ->runtime_idle() is being executed.

request_pending

Set if a work item is queued into pm_wq (runtime PM).

deferred_resume

Set if ->runtime_resume() should run as soon as ->runtime_suspend() completes.

needs_force_resume

Indicates the device was forced into suspend by pm_runtime_force_suspend() and must be resumed by pm_runtime_force_resume().

runtime_auto

User space has allowed the driver to power manage the device at runtime via sysfs control attribute; also can be set by pm_runtime_allow() or pm_runtime_forbid().

ignore_children

If set, the value of child_count is ignored for runtime suspend and idle decisions.

no_callbacks

Indicates the device does not use runtime PM callbacks.

irq_safe

Indicates runtime PM callbacks will be invoked with the spinlock held and interrupts disabled.

use_autosuspend

Indicates the device driver supports delayed runtime autosuspend.

timer_autosuspends

Indicates the runtime PM core should attempt an autosuspend rather than a normal suspend when the timer expires.

memalloc_noio

Indicates memory allocation during runtime PM transitions must avoid I/O (GFP_NOIO).

links_count

Number of device links that require runtime PM coordination.

request

Type of pending runtime PM request (valid if request_pending is set).

runtime_status

Runtime PM status of the device.

last_status

Last status captured before disabling runtime PM, or RPM_BLOCKED / RPM_INVALID.

runtime_error

Fatal error code returned by a failing callback, blocking helpers until cleared.

autosuspend_delay

Delay time in milliseconds to be used for runtime autosuspend.

last_busy

Timestamp in nanoseconds when pm_runtime_mark_last_busy() was last called. Used in calculating inactivity periods for autosuspend.

active_time

Accumulated time in nanoseconds spent in RPM_ACTIVE state.

suspended_time

Accumulated time in nanoseconds spent in RPM_SUSPENDED state.

accounting_timestamp

Timestamp in nanoseconds of the last runtime PM state accounting update.

subsys_data

Subsystem-specific power management data.

set_latency_tolerance

Callback for setting latency tolerance.

qos

Per-device PM Quality of Service (QoS) constraints.

detach_power_off

Indicates device should be detached from PM domain on power off.

Description

Device power management information stored in the “power” member of struct device.

4. Runtime PM Device Helper Functions

The following runtime PM helper functions are defined in drivers/base/power/runtime.c and include/linux/pm_runtime.h:

u64 pm_runtime_autosuspend_expiration(struct device *dev)

Get a device’s autosuspend-delay expiration time.

Parameters

struct device *dev

Device to handle.

Description

Compute the autosuspend-delay expiration time based on the device’s power.last_busy time. If the delay has already expired or is disabled (negative) or the power.use_autosuspend flag isn’t set, return 0. Otherwise return the expiration time in nanoseconds.

This function may be called either with or without dev->power.lock held. Either way it can be racy, since power.last_busy may be updated at any time.

void pm_runtime_set_memalloc_noio(struct device *dev, bool enable)

Set a device’s memalloc_noio flag.

Parameters

struct device *dev

Device to handle.

bool enable

True for setting the flag and False for clearing the flag.

Description

Set the flag for all devices in the path from the device to the root device in the device tree if enable is true, otherwise clear the flag for devices in the path whose siblings don’t set the flag.

The function should only be called by block device, or network device driver for solving the deadlock problem during runtime resume/suspend:

If memory allocation with GFP_KERNEL is called inside runtime resume/suspend callback of any one of its ancestors(or the block device itself), the deadlock may be triggered inside the memory allocation since it might not complete until the block device becomes active and the involved page I/O finishes. The situation is pointed out first by Alan Stern. Network device are involved in iSCSI kind of situation.

The lock of dev_hotplug_mutex is held in the function for handling hotplug race because pm_runtime_set_memalloc_noio() may be called in async probe().

The function should be called between device_add() and device_del() on the affected device(block/network device).

int pm_schedule_suspend(struct device *dev, unsigned int delay)

Set up a timer to submit a suspend request in future.

Parameters

struct device *dev

Device to suspend.

unsigned int delay

Time to wait before submitting a suspend request, in milliseconds.

Return

  • 1: Success; dev is already RPM_SUSPENDED.

  • 0: Success.

  • Error code on failure.

int __pm_runtime_idle(struct device *dev, int rpmflags)

Core entry point for runtime idle operations.

Parameters

struct device *dev

Device to send idle notification for.

int rpmflags

Flag bits.

Description

Carry out an idle check for dev, either synchronous or asynchronous. If RPM_GET_PUT is set in rpmflags, decrement the device’s usage count first, proceeding with idle notification only if the counter drops to zero.

This routine may be called in atomic context if the RPM_ASYNC flag is set, or if pm_runtime_irq_safe() has been called.

int __pm_runtime_suspend(struct device *dev, int rpmflags)

Core entry point for runtime put/suspend operations.

Parameters

struct device *dev

Device to suspend.

int rpmflags

Flag bits.

Description

Carry out a suspend operation for dev, either synchronous or asynchronous. If RPM_GET_PUT is set in rpmflags, decrement the device’s usage count first, proceeding with suspend only if the counter drops to zero.

This routine may be called in atomic context if the RPM_ASYNC flag is set, or if pm_runtime_irq_safe() has been called.

int __pm_runtime_resume(struct device *dev, int rpmflags)

Core entry point for runtime resume operations.

Parameters

struct device *dev

Device to resume.

int rpmflags

Flag bits.

Description

Carry out a runtime resume operation for dev, either synchronous or asynchronous. If RPM_GET_PUT is set in rpmflags, increment the device’s usage count first, then bring the device to RPM_ACTIVE state.

This routine may be called in atomic context if the RPM_ASYNC flag is set, or if pm_runtime_irq_safe() has been called.

int pm_runtime_get_if_active(struct device *dev)

Conditionally bump up runtime PM usage counter.

Parameters

struct device *dev

Target device.

Description

Increment the runtime PM usage counter of dev if its runtime PM status is already RPM_ACTIVE.

Return

  • -EINVAL: Runtime PM is disabled for dev. The usage counter is not incremented.

  • 1: Success; usage counter is incremented.

  • 0: dev was not active.

int pm_runtime_get_if_in_use(struct device *dev)

Conditionally bump up runtime PM usage counter.

Parameters

struct device *dev

Target device.

Description

Increment the runtime PM usage counter of dev if it is “in use.” A device is considered in use if its runtime PM status is RPM_ACTIVE and its runtime PM usage counter is greater than 0, or if it is not ignoring children and its active child count is nonzero.

Return

  • -EINVAL: Runtime PM is disabled for dev. The usage counter is not incremented.

  • 1: Success; usage counter is incremented.

  • 0: dev was not in use; usage counter is not incremented.

int __pm_runtime_set_status(struct device *dev, unsigned int status)

Set runtime PM status of a device and clear errors.

Parameters

struct device *dev

Device to handle.

unsigned int status

New runtime PM status of the device.

Description

If runtime PM of the device is disabled or its power.runtime_error field is different from zero, the status may be changed either to RPM_ACTIVE, or to RPM_SUSPENDED, as long as that reflects the actual state of the device. However, if the device has a parent and the parent is not active, and the parent’s power.ignore_children flag is unset, the device’s status cannot be set to RPM_ACTIVE, so -EBUSY is returned in that case.

If successful, __pm_runtime_set_status() clears the power.runtime_error field and the device parent’s counter of unsuspended children is modified to reflect the new status. If the new status is RPM_SUSPENDED, an idle notification request for the parent is submitted.

If dev has any suppliers (as reflected by device links to them), and status is RPM_ACTIVE, they will be activated upfront and if the activation of one of them fails, the status of dev will be changed to RPM_SUSPENDED (instead of the status value) and the suppliers will be deactivated on exit. The error returned by the failing supplier activation will be returned in that case.

void pm_runtime_barrier(struct device *dev)

Flush pending requests and wait for completions.

Parameters

struct device *dev

Device to handle.

Description

If the device has a pending resume request, resume it synchronously. For all other request types, cancel any queued request, and wait for running operations to complete.

Note that this is intentionally asymmetric, as it guarantees any queued asynchronous resume request will complete, but it may cancel asynchronous suspend requests.

void pm_runtime_enable(struct device *dev)

Enable runtime PM for a device.

Parameters

struct device *dev

Device to handle.

Description

Enable runtime PM transitions for dev by decrementing its disable counter. Once the counter reaches zero, the PM core is permitted to execute runtime PM callbacks for dev as power conditions change.

Callers should ensure that the device’s runtime PM status accurately reflects its physical hardware state (via pm_runtime_set_active() or pm_runtime_set_suspended()) before enabling runtime PM.

int devm_pm_runtime_set_active_enabled(struct device *dev)

set_active version of devm_pm_runtime_enable.

Parameters

struct device *dev

Device to handle.

int devm_pm_runtime_enable(struct device *dev)

devres-enabled version of pm_runtime_enable.

Parameters

struct device *dev

Device to handle.

NOTE

this will also handle calling pm_runtime_dont_use_autosuspend() for you at driver exit time if needed.

int devm_pm_runtime_get_noresume(struct device *dev)

devres-enabled version of pm_runtime_get_noresume.

Parameters

struct device *dev

Device to handle.

void pm_runtime_forbid(struct device *dev)

Block runtime PM of a device.

Parameters

struct device *dev

Device to handle.

Description

Resume dev if already suspended and block runtime suspend of dev in such a way that it can be unblocked via the /sys/devices/.../power/control interface, or otherwise by calling pm_runtime_allow().

Calling this function many times in a row has the same effect as calling it once.

void pm_runtime_allow(struct device *dev)

Unblock runtime PM of a device.

Parameters

struct device *dev

Device to handle.

Description

Unblock runtime suspend of dev after it has been blocked by pm_runtime_forbid() (for instance, if it has been blocked via the /sys/devices/.../power/control interface), check if dev can be suspended and suspend it in that case.

Calling this function many times in a row has the same effect as calling it once.

void pm_runtime_no_callbacks(struct device *dev)

Ignore runtime PM callbacks for a device.

Parameters

struct device *dev

Device to handle.

Description

Set the power.no_callbacks flag, which tells the PM core that this device is power-managed through its parent and has no runtime PM callbacks of its own. The runtime sysfs attributes will be removed.

void pm_runtime_irq_safe(struct device *dev)

Leave interrupts disabled during callbacks.

Parameters

struct device *dev

Device to handle

Description

Set the power.irq_safe flag, which tells the PM core that the ->runtime_suspend() and ->runtime_resume() callbacks for this device should always be invoked with the spinlock held and interrupts disabled. It also causes the parent’s usage counter to be permanently incremented, preventing the parent from runtime suspending -- otherwise an irq-safe child might have to wait for a non-irq-safe parent.

void pm_runtime_set_autosuspend_delay(struct device *dev, int delay)

Set a device’s autosuspend_delay value.

Parameters

struct device *dev

Device to handle.

int delay

Value of the new delay in milliseconds.

Description

Set the device’s power.autosuspend_delay value. If it changes to negative and the power.use_autosuspend flag is set, prevent runtime suspends. If it changes the other way, allow runtime suspends.

void __pm_runtime_use_autosuspend(struct device *dev, bool use)

Set a device’s use_autosuspend flag.

Parameters

struct device *dev

Device to handle.

bool use

New value for use_autosuspend.

Description

Set the device’s power.use_autosuspend flag, and allow or prevent runtime suspends as needed.

int pm_runtime_force_suspend(struct device *dev)

Force a device into suspend state if needed.

Parameters

struct device *dev

Device to suspend.

Description

Disable runtime PM so we safely can check the device’s runtime PM status and if it is active, invoke its ->runtime_suspend callback to suspend it and change its runtime PM status field to RPM_SUSPENDED. Also, if the device’s usage and children counters don’t indicate that the device was in use before the system-wide transition under way, decrement its parent’s children counter (if there is a parent). Keep runtime PM disabled to preserve the state unless we encounter errors.

Typically this function may be invoked from a system suspend callback to make sure the device is put into low power state and it should only be used during system-wide PM transitions to sleep states. It assumes that the analogous pm_runtime_force_resume() will be used to resume the device.

int pm_runtime_force_resume(struct device *dev)

Force a device into resume state if needed.

Parameters

struct device *dev

Device to resume.

Description

This function expects that either pm_runtime_force_suspend() has put the device into a low-power state prior to calling it, or the device had been runtime-suspended before the preceding system-wide suspend transition and it was left in suspend during that transition.

The actions carried out by pm_runtime_force_suspend(), or by a runtime suspend in general, are reversed and the device is brought back into full power if it is expected to be used on system resume, which is the case when its needs_force_resume flag is set or when its smart_suspend flag is set and its runtime PM status is “active”.

In other cases, the resume is deferred to be managed via runtime PM.

Typically, this function may be invoked from a system resume callback.

void pm_suspend_ignore_children(struct device *dev, bool enable)

Set runtime PM behavior regarding children.

Parameters

struct device *dev

Target device.

bool enable

Whether or not to ignore possible dependencies on children.

Description

The dependencies of dev on its children will not be taken into account by the runtime PM framework going forward if enable is true, or they will be taken into account otherwise.

void pm_runtime_get_noresume(struct device *dev)

Bump up runtime PM usage counter of a device.

Parameters

struct device *dev

Target device.

void pm_runtime_put_noidle(struct device *dev)

Drop runtime PM usage counter of a device.

Parameters

struct device *dev

Target device.

Description

Decrement the runtime PM usage counter of dev unless it is 0 already.

bool pm_runtime_suspended(struct device *dev)

Check whether or not a device is runtime-suspended.

Parameters

struct device *dev

Target device.

Description

Note that the return value of this function can only be trusted if it is called under the runtime PM lock of dev or under conditions in which runtime PM cannot be either disabled or enabled for dev and its runtime PM status cannot change.

Return

  • true: dev has runtime PM enabled and its status is RPM_SUSPENDED.

  • false: Otherwise.

bool pm_runtime_active(struct device *dev)

Check whether or not a device is runtime-active.

Parameters

struct device *dev

Target device.

Description

Note that the return value of this function can only be trusted if it is called under the runtime PM lock of dev or under conditions in which runtime PM cannot be either disabled or enabled for dev and its runtime PM status cannot change.

Return

  • true: Runtime PM is disabled for dev or its status is RPM_ACTIVE.

  • false: Otherwise.

bool pm_runtime_status_suspended(struct device *dev)

Check if runtime PM status is “suspended”.

Parameters

struct device *dev

Target device.

Description

Note that the return value of this function can only be trusted if it is called under the runtime PM lock of dev or under conditions in which the runtime PM status of dev cannot change.

Return

  • true: Runtime PM status of dev is RPM_SUSPENDED.

  • false: Otherwise.

bool pm_runtime_enabled(struct device *dev)

Check if runtime PM is enabled.

Parameters

struct device *dev

Target device.

Description

Note that the return value of this function can only be trusted if it is called under the runtime PM lock of dev or under conditions in which runtime PM cannot be either disabled or enabled for dev.

Return

  • true: Runtime PM is enabled for dev.

  • false: Otherwise.

bool pm_runtime_blocked(struct device *dev)

Check if runtime PM enabling is blocked.

Parameters

struct device *dev

Target device.

Description

Do not call this function outside system suspend/resume code paths.

Return

  • true: Runtime PM enabling is blocked for dev.

  • false: Otherwise.

bool pm_runtime_has_no_callbacks(struct device *dev)

Check if runtime PM callbacks may be present.

Parameters

struct device *dev

Target device.

Return

  • true: dev is marked as having no runtime PM callbacks.

  • false: Otherwise.

void pm_runtime_mark_last_busy(struct device *dev)

Update the last access time of a device.

Parameters

struct device *dev

Target device.

Description

Update the last access time of dev used by the runtime PM autosuspend mechanism to the current time as returned by ktime_get_mono_fast_ns().

bool pm_runtime_is_irq_safe(struct device *dev)

Check if runtime PM can work in interrupt context.

Parameters

struct device *dev

Target device.

Return

  • true: dev has been marked as an “IRQ-safe” device, in which case its runtime PM callbacks can be expected to work correctly from interrupt handlers.

  • false: Otherwise.

int pm_runtime_idle(struct device *dev)

Conditionally initiate autosuspend of a device or suspend it.

Parameters

struct device *dev

Target device.

Description

Invoke the “idle check” callback of dev and, depending on its return value, initiate autosuspend of dev or suspend it (depending on whether or not autosuspend has been enabled for it).

Return

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change ongoing or device not in RPM_ACTIVE state.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM idle and suspend callbacks.

int pm_runtime_suspend(struct device *dev)

Suspend a device synchronously.

Parameters

struct device *dev

Target device.

Return

  • 1: Success; device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM suspend callbacks.

int pm_runtime_autosuspend(struct device *dev)

Update the last access time and initiate autosuspend of a device.

Parameters

struct device *dev

Target device.

Description

First update the last access time, then initiate autosuspend of dev or suspend it (depending on whether or not autosuspend is enabled for it) without engaging its “idle check” callback.

Return

  • 1: Success; device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM suspend callbacks.

int pm_runtime_resume(struct device *dev)

Resume a device synchronously.

Parameters

struct device *dev

Target device.

Return

  • 1: Success; dev is already RPM_ACTIVE.

  • 0: Success.

  • Error code on failure.

int pm_request_idle(struct device *dev)

Request an asynchronous idle check for a device.

Parameters

struct device *dev

Target device.

Description

Asynchronously request the PM core to evaluate whether dev can be idled or suspended, invoking its ->runtime_idle() callback if provided.

Return

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change ongoing or device not in RPM_ACTIVE state.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

int pm_request_resume(struct device *dev)

Request an asynchronous runtime resume for a device.

Parameters

struct device *dev

Target device.

Description

Asynchronously request the PM core to resume dev to RPM_ACTIVE state without modifying its usage counter.

Return

  • 1: Success; dev is already RPM_ACTIVE.

  • 0: Success.

  • Error code on failure.

int pm_request_autosuspend(struct device *dev)

Update access time and request delayed suspension.

Parameters

struct device *dev

Target device.

Description

Update the last access time of dev and asynchronously request the PM core to suspend it after the autosuspend delay has elapsed.

Return

  • 1: Success; device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

int pm_runtime_get(struct device *dev)

Increment usage counter and request asynchronous resume.

Parameters

struct device *dev

Target device.

Description

Increment the runtime PM usage counter of dev and, if the device is currently suspended, asynchronously request the PM core to resume it.

Return

  • 1: Success; dev is already RPM_ACTIVE.

  • 0: Success; runtime-resume was queued.

  • Error code on failure.

int pm_runtime_get_sync(struct device *dev)

Bump up usage counter of a device and resume it.

Parameters

struct device *dev

Target device.

Description

Bump up the runtime PM usage counter of dev and carry out runtime-resume of it synchronously.

Note that the runtime PM usage counter of dev remains incremented in all cases, even if it returns an error code. Consider using pm_runtime_resume_and_get() instead, especially if the return value is checked by the caller, as this is likely to result in cleaner code.

Return

  • 1: Success; dev is already RPM_ACTIVE.

  • 0: Success.

  • Error code on failure.

int pm_runtime_resume_and_get(struct device *dev)

Bump up usage counter of a device and resume it.

Parameters

struct device *dev

Target device.

Description

Resume dev synchronously and if that is successful, increment its runtime PM usage counter.

Return

  • 0: Success; dev is active and its usage counter has been incremented.

  • Negative error code on failure; usage counter is unchanged.

void pm_runtime_put(struct device *dev)

Drop device usage counter and request asynchronous idle check.

Parameters

struct device *dev

Target device.

Description

Decrement the runtime PM usage counter of dev. If the counter reaches zero and the device has no active child dependencies, asynchronously request the PM core to idle or suspend the device.

int __pm_runtime_put_autosuspend(struct device *dev)

Drop device usage counter and queue autosuspend if 0.

Parameters

struct device *dev

Target device.

Description

Decrement the runtime PM usage counter of dev and if it turns out to be equal to 0, queue up a work item for dev like in pm_request_autosuspend().

Return

  • 1: Success. Usage counter dropped to zero, but device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

int pm_runtime_put_autosuspend(struct device *dev)

Update the last access time, drop usage counter and request autosuspend.

Parameters

struct device *dev

Target device.

Description

Update the last access time of dev and decrement its runtime PM usage counter. If the counter drops to zero, asynchronously request the PM core to suspend the device once its autosuspend delay has elapsed.

Return

  • 1: Success. Usage counter dropped to zero, but device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

int pm_runtime_put_sync(struct device *dev)

Drop device usage counter and run “idle check” if 0.

Parameters

struct device *dev

Target device.

Description

Decrement the runtime PM usage counter of dev. If the counter drops to zero, synchronously evaluate and trigger idle/suspend handling.

Note that this does not update the last access time, but it does respect existing autosuspend timers. If dev uses autosuspend, consider using pm_runtime_put_sync_autosuspend() or pm_runtime_put_sync_suspend() instead.

The runtime PM usage counter of dev remains decremented in all cases, even if it returns an error code.

Return

  • 1: Success. Usage counter dropped to zero, but device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM suspend callbacks.

int pm_runtime_put_sync_suspend(struct device *dev)

Drop device usage counter and suspend if 0.

Parameters

struct device *dev

Target device.

Description

Decrement the runtime PM usage counter of dev. If the counter drops to zero, suspend the device synchronously.

This API differs from pm_runtime_put_sync() and pm_runtime_put_sync_autosuspend() in that it ignores any outstanding autosuspend delays.

The runtime PM usage counter of dev remains decremented in all cases, even if it returns an error code.

Return

  • 1: Success. Usage counter dropped to zero, but device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM suspend callbacks.

int pm_runtime_put_sync_autosuspend(struct device *dev)

Update the last access time of a device, drop device usage counter and autosuspend if 0.

Parameters

struct device *dev

Target device.

Description

Update the last access time of dev and decrement its runtime PM usage counter. If the counter drops to zero, synchronously suspend the device (or schedule autosuspend if the delay has not elapsed).

Prefer this API over pm_runtime_put_sync() for devices that use autosuspend.

The runtime PM usage counter of dev remains decremented in all cases, even if it returns an error code.

Return

  • 1: Success. Usage counter dropped to zero, but device was already suspended.

  • 0: Success.

  • -EINVAL: Runtime PM error.

  • -EACCES: Runtime PM disabled.

  • -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status change ongoing.

  • -EBUSY: Runtime PM child_count non-zero.

  • -EPERM: Device PM QoS resume latency 0.

  • -EINPROGRESS: Suspend already in progress.

  • -ENOSYS: CONFIG_PM not enabled.

  • Other values and conditions for the above values are possible as returned by Runtime PM suspend callbacks.

int pm_runtime_set_active(struct device *dev)

Set runtime PM status to “active” and clear errors.

Parameters

struct device *dev

Target device.

Description

Set the runtime PM status of dev to RPM_ACTIVE and ensure that its dependencies will be taken into account. Also clear the device’s error status (dev->power.runtime_error).

It is only valid to call this function if runtime PM is disabled or if dev->power.runtime_error is set.

This will fail if suppliers cannot be resumed, or if the parent is not in the correct state.

Return

  • 0: Success.

  • Error code on failure.

int pm_runtime_set_suspended(struct device *dev)

Set runtime PM status to “suspended” and clear errors.

Parameters

struct device *dev

Target device.

Description

Set the runtime PM status of dev to RPM_SUSPENDED and ensure that its dependencies will be taken into account. Also clear the device’s error status (dev->power.runtime_error).

It is only valid to call this function if runtime PM is disabled or if dev->power.runtime_error is set.

Return

  • 0: Success.

  • Error code on failure.

void pm_runtime_disable(struct device *dev)

Disable runtime PM for a device.

Parameters

struct device *dev

Target device.

Description

Prevent the runtime PM framework from working with dev by incrementing its “disable” counter.

If the counter is zero when this function runs and there is a pending runtime resume request for dev, it will be resumed. If the counter is still zero at that point, this function cancels all pending runtime PM requests for dev and waits for its runtime PM operations to complete (if any).

For each invocation of this function for dev, there must be a matching pm_runtime_enable() call, so that runtime PM is eventually enabled for it again.

void pm_runtime_use_autosuspend(struct device *dev)

Allow autosuspend to be used for a device.

Parameters

struct device *dev

Target device.

Description

Allow the runtime PM autosuspend mechanism to be used for dev whenever requested (or “autosuspend” will be handled as direct runtime-suspend for it).

NOTE

It’s important to undo this with pm_runtime_dont_use_autosuspend() at driver exit time unless your driver initially enabled pm_runtime with devm_pm_runtime_enable() (which handles it for you).

void pm_runtime_dont_use_autosuspend(struct device *dev)

Prevent autosuspend from being used.

Parameters

struct device *dev

Target device.

Description

Prevent the runtime PM autosuspend mechanism from being used for dev which means that “autosuspend” will be handled as direct runtime-suspend for it going forward.

It is safe to execute the following helper functions from interrupt context:

If pm_runtime_irq_safe() has been called for a device then the following helper functions may also be used in interrupt context:

5. Runtime PM Initialization, Device Probing and Removal

Initially, the runtime PM is disabled for all devices, which means that the majority of the runtime PM helper functions described in Section 4 will return -EACCES until pm_runtime_enable() is called for the device.

In addition to that, the initial runtime PM status of all devices is ‘suspended’, but it need not reflect the actual physical state of the device. Thus, if the device is initially active (i.e. it is able to process I/O), its runtime PM status must be changed to ‘active’, with the help of pm_runtime_set_active(), before pm_runtime_enable() is called for the device.

However, if the device has a parent and the parent’s runtime PM is enabled, calling pm_runtime_set_active() for the device will affect the parent, unless the parent’s ‘power.ignore_children’ flag is set. Namely, in that case the parent won’t be able to suspend at run time, using the PM core’s helper functions, as long as the child’s status is ‘active’, even if the child’s runtime PM is still disabled (i.e. pm_runtime_enable() hasn’t been called for the child yet or pm_runtime_disable() has been called for it). For this reason, once pm_runtime_set_active() has been called for the device, pm_runtime_enable() should be called for it too as soon as reasonably possible or its runtime PM status should be changed back to ‘suspended’ with the help of pm_runtime_set_suspended().

If the default initial runtime PM status of the device (i.e. ‘suspended’) reflects the actual state of the device, its bus type’s or its driver’s ->probe() callback will likely need to wake it up using one of the PM core’s helper functions described in Section 4. In that case, pm_runtime_resume() should be used. Of course, for this purpose the device’s runtime PM has to be enabled earlier by calling pm_runtime_enable().

Note, if the device may execute pm_runtime calls during the probe (such as if it is registered with a subsystem that may call back in) then the pm_runtime_resume_and_get() call paired with a pm_runtime_put() call will be appropriate to ensure that the device is not put back to sleep during the probe. This can happen with systems such as the network device layer.

It may be desirable to suspend the device once ->probe() has finished. Therefore the driver core uses the asynchronous pm_request_idle() to submit a request to execute the subsystem-level idle callback for the device at that time. A driver that makes use of the runtime autosuspend feature may want to update the last busy mark before returning from ->probe().

Moreover, the driver core prevents runtime PM callbacks from racing with the bus notifier callback in __device_release_driver(), which is necessary because the notifier is used by some subsystems to carry out operations affecting the runtime PM functionality. It does so by calling pm_runtime_get_sync() before driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications. This resumes the device if it’s in the suspended state and prevents it from being suspended again while those routines are being executed.

To allow bus types and drivers to put devices into the suspended state by calling pm_runtime_suspend() from their ->remove() routines, the driver core executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER notifications in __device_release_driver(). This requires bus types and drivers to make their ->remove() callbacks avoid races with runtime PM directly, but it also allows more flexibility in the handling of devices during the removal of their drivers.

Drivers in ->remove() callback should undo the runtime PM changes done in ->probe(). Usually this means calling pm_runtime_disable(), pm_runtime_dont_use_autosuspend() etc. Alternatively, drivers can use devm_pm_runtime_enable() during probe, which automatically takes care of calling pm_runtime_disable() and pm_runtime_dont_use_autosuspend() upon driver detachment.

The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control attribute to “on”, which causes pm_runtime_forbid() to be called. In principle, this mechanism may also be used by the driver to effectively turn off the runtime power management of the device until the user space turns it on. Namely, during the initialization the driver can make sure that the runtime PM status of the device is ‘active’ and call pm_runtime_forbid(). It should be noted, however, that if the user space has already intentionally changed the value of /sys/devices/.../power/control to “auto” to allow the driver to power manage the device at run time, the driver may confuse it by using pm_runtime_forbid() this way.

6. Runtime PM and System Sleep

Runtime PM and system sleep (i.e., system suspend and hibernation, also known as suspend-to-RAM and suspend-to-disk) interact with each other in a couple of ways. If a device is active when a system sleep starts, everything is straightforward. But what should happen if the device is already suspended?

The device may have different wake-up settings for runtime PM and system sleep. For example, remote wake-up may be enabled for runtime suspend but disallowed for system sleep (device_may_wakeup(dev) returns ‘false’). When this happens, the subsystem-level system suspend callback is responsible for changing the device’s wake-up setting (it may leave that to the device driver’s system suspend routine). It may be necessary to resume the device and suspend it again in order to do so. The same is true if the driver uses different power levels or other settings for runtime suspend and system sleep.

During system resume, the simplest approach is to bring all devices back to full power, even if they had been suspended before the system suspend began. There are several reasons for this, including:

  • The device might need to switch power levels, wake-up settings, etc.

  • Remote wake-up events might have been lost by the firmware.

  • The device’s children may need the device to be at full power in order to resume themselves.

  • The driver’s idea of the device state may not agree with the device’s physical state. This can happen during resume from hibernation.

  • The device might need to be reset.

  • Even though the device was suspended, if its usage counter was > 0 then most likely it would need a runtime resume in the near future anyway.

If the device had been suspended before the system suspend began and it’s brought back to full power during resume, then its runtime PM status will have to be updated to reflect the actual post-system sleep status. The way to do this is:

  • pm_runtime_disable(dev);

  • pm_runtime_set_active(dev);

  • pm_runtime_enable(dev);

The PM core always increments the runtime usage counter before calling the ->suspend() callback and decrements it after calling the ->resume() callback. Hence disabling runtime PM temporarily like this will not cause any runtime suspend attempts to be permanently lost. If the usage count goes to zero following the return of the ->resume() callback, the ->runtime_idle() callback will be invoked as usual.

On some systems, however, system sleep is not entered through a global firmware or hardware operation. Instead, all hardware components are put into low-power states directly by the kernel in a coordinated way. Then, the system sleep state effectively follows from the states the hardware components end up in and the system is woken up from that state by a hardware interrupt or a similar mechanism entirely under the kernel’s control. As a result, the kernel never gives control away and the states of all devices during resume are precisely known to it. If that is the case and none of the situations listed above takes place (in particular, if the system is not waking up from hibernation), it may be more efficient to leave the devices that had been suspended before the system suspend began in the suspended state.

To this end, the PM core provides a mechanism allowing some coordination between different levels of device hierarchy. Namely, if a system suspend .prepare() callback returns a positive number for a device, that indicates to the PM core that the device appears to be runtime-suspended and its state is fine, so it may be left in runtime suspend provided that all of its descendants are also left in runtime suspend. If that happens, the PM core will not execute any system suspend and resume callbacks for all of those devices, except for the .complete() callback, which is then entirely responsible for handling the device as appropriate. This only applies to system suspend transitions that are not related to hibernation (see Device Power Management Basics for more information).

The PM core does its best to reduce the probability of race conditions between the runtime PM and system suspend/resume (and hibernation) callbacks by carrying out the following operations:

  • During system suspend pm_runtime_get_noresume() is called for every device right before executing the subsystem-level .prepare() callback for it and pm_runtime_barrier() is called for every device right before executing the subsystem-level .suspend() callback for it. In addition to that, the PM core disables runtime PM for every device right before executing the subsystem-level .suspend_late() callback for it.

  • During system resume pm_runtime_enable() and pm_runtime_put() are called for every device right after executing the subsystem-level .resume_early() callback and right after executing the subsystem-level .complete() callback for it, respectively.

7. Generic subsystem callbacks

Subsystems may wish to conserve code space by using the set of generic power management callbacks provided by the PM core, defined in drivers/base/power/generic_ops.c:

int pm_generic_runtime_suspend(struct device *dev)

Generic runtime suspend callback for subsystems.

Parameters

struct device *dev

Device to suspend.

Description

If PM operations are defined for the dev’s driver and they include ->runtime_suspend(), execute it and return its error code. Otherwise, return 0.

int pm_generic_runtime_resume(struct device *dev)

Generic runtime resume callback for subsystems.

Parameters

struct device *dev

Device to resume.

Description

If PM operations are defined for the dev’s driver and they include ->runtime_resume(), execute it and return its error code. Otherwise, return 0.

int pm_generic_suspend_noirq(struct device *dev)

Generic suspend_noirq callback for subsystems.

Parameters

struct device *dev

Device to suspend.

int pm_generic_suspend_late(struct device *dev)

Generic suspend_late callback for subsystems.

Parameters

struct device *dev

Device to suspend.

int pm_generic_suspend(struct device *dev)

Generic suspend callback for subsystems.

Parameters

struct device *dev

Device to suspend.

int pm_generic_freeze_noirq(struct device *dev)

Generic freeze_noirq callback for subsystems.

Parameters

struct device *dev

Device to freeze.

int pm_generic_freeze(struct device *dev)

Generic freeze callback for subsystems.

Parameters

struct device *dev

Device to freeze.

int pm_generic_poweroff_noirq(struct device *dev)

Generic poweroff_noirq callback for subsystems.

Parameters

struct device *dev

Device to handle.

int pm_generic_poweroff_late(struct device *dev)

Generic poweroff_late callback for subsystems.

Parameters

struct device *dev

Device to handle.

int pm_generic_poweroff(struct device *dev)

Generic poweroff callback for subsystems.

Parameters

struct device *dev

Device to handle.

int pm_generic_thaw_noirq(struct device *dev)

Generic thaw_noirq callback for subsystems.

Parameters

struct device *dev

Device to thaw.

int pm_generic_thaw(struct device *dev)

Generic thaw callback for subsystems.

Parameters

struct device *dev

Device to thaw.

int pm_generic_resume_noirq(struct device *dev)

Generic resume_noirq callback for subsystems.

Parameters

struct device *dev

Device to resume.

int pm_generic_resume_early(struct device *dev)

Generic resume_early callback for subsystems.

Parameters

struct device *dev

Device to resume.

int pm_generic_resume(struct device *dev)

Generic resume callback for subsystems.

Parameters

struct device *dev

Device to resume.

int pm_generic_restore_noirq(struct device *dev)

Generic restore_noirq callback for subsystems.

Parameters

struct device *dev

Device to restore.

int pm_generic_restore_early(struct device *dev)

Generic restore_early callback for subsystems.

Parameters

struct device *dev

Device to resume.

int pm_generic_restore(struct device *dev)

Generic restore callback for subsystems.

Parameters

struct device *dev

Device to restore.

These functions are the defaults used by the PM core if a subsystem doesn’t provide its own callbacks for ->runtime_idle(), ->runtime_suspend(), ->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(), ->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(), ->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() in the subsystem-level dev_pm_ops structure.

Device drivers that wish to use the same function as a system suspend, freeze, poweroff and runtime suspend callback, and similarly for system resume, thaw, restore, and runtime resume, can achieve similar behaviour with the help of the DEFINE_RUNTIME_DEV_PM_OPS() macro defined in include/linux/pm_runtime.h (possibly setting its last argument to NULL).

8. “No-Callback” Devices

Some “devices” are only logical sub-devices of their parent and cannot be power-managed on their own. (The prototype example is a USB interface. Entire USB devices can go into low-power mode or send wake-up requests, but neither is possible for individual interfaces.) The drivers for these devices have no need of runtime PM callbacks; if the callbacks did exist, ->runtime_suspend() and ->runtime_resume() would always return 0 without doing anything else and ->runtime_idle() would always call pm_runtime_suspend().

Subsystems can tell the PM core about these devices by calling pm_runtime_no_callbacks(). This should be done after the device structure is initialized and before it is registered (although after device registration is also okay). The routine will set the device’s power.no_callbacks flag and prevent the non-debugging runtime PM sysfs attributes from being created.

When power.no_callbacks is set, the PM core will not invoke the ->runtime_idle(), ->runtime_suspend(), or ->runtime_resume() callbacks. Instead it will assume that suspends and resumes always succeed and that idle devices should be suspended.

As a consequence, the PM core will never directly inform the device’s subsystem or driver about runtime power changes. Instead, the driver for the device’s parent must take responsibility for telling the device’s driver when the parent’s power state changes.

Note that, in some cases it may not be desirable for subsystems/drivers to call pm_runtime_no_callbacks() for their devices. This could be because a subset of the runtime PM callbacks needs to be implemented, a platform dependent PM domain could get attached to the device or that the device is power managed through a supplier device link. For these reasons and to avoid boilerplate code in subsystems/drivers, the PM core allows runtime PM callbacks to be unassigned. More precisely, if a callback pointer is NULL, the PM core will act as though there was a callback and it returned 0.

9. Autosuspend, or automatically-delayed suspends

Changing a device’s power state isn’t free; it requires both time and energy. A device should be put in a low-power state only when there’s some reason to think it will remain in that state for a substantial time. A common heuristic says that a device which hasn’t been used for a while is liable to remain unused; following this advice, drivers should not allow devices to be suspended at runtime until they have been inactive for some minimum period. Even when the heuristic ends up being non-optimal, it will still prevent devices from “bouncing” too rapidly between low-power and full-power states.

The term “autosuspend” is an historical remnant. It doesn’t mean that the device is automatically suspended (the subsystem or driver still has to call the appropriate PM routines); rather it means that runtime suspends will automatically be delayed until the desired period of inactivity has elapsed.

Inactivity is determined based on the power.last_busy field. The desired length of the inactivity period is a matter of policy. Subsystems can set this length initially by calling pm_runtime_set_autosuspend_delay(), but after device registration the length should be controlled by user space, using the /sys/devices/.../power/autosuspend_delay_ms attribute.

In order to use autosuspend, subsystems or drivers must call pm_runtime_use_autosuspend() (preferably before registering the device), and thereafter they should use the various *_autosuspend() helper functions instead of the non-autosuspend counterparts:

Instead of: pm_runtime_suspend    use: pm_runtime_autosuspend;
Instead of: pm_schedule_suspend   use: pm_request_autosuspend;
Instead of: pm_runtime_put        use: pm_runtime_put_autosuspend;
Instead of: pm_runtime_put_sync   use: pm_runtime_put_sync_autosuspend.

Drivers may also continue to use the non-autosuspend helper functions; they will behave normally, which means sometimes taking the autosuspend delay into account (see pm_runtime_idle()). The autosuspend variants of the functions also call pm_runtime_mark_last_busy().

Under some circumstances a driver or subsystem may want to prevent a device from autosuspending immediately, even though the usage counter is zero and the autosuspend delay time has expired. If the ->runtime_suspend() callback returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is in the future (as it normally would be if the callback invoked pm_runtime_mark_last_busy()), the PM core will automatically reschedule the autosuspend. The ->runtime_suspend() callback can’t do this rescheduling itself because no suspend requests of any kind are accepted while the device is suspending (i.e., while the callback is running).

The implementation is well suited for asynchronous use in interrupt contexts. However such use inevitably involves races, because the PM core can’t synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. This synchronization must be handled by the driver, using its private lock. Here is a schematic pseudo-code example:

foo_read_or_write(struct foo_priv *foo, void *data)
{
        lock(&foo->private_lock);
        add_request_to_io_queue(foo, data);
        if (foo->num_pending_requests++ == 0)
                pm_runtime_get(&foo->dev);
        if (!foo->is_suspended)
                foo_process_next_request(foo);
        unlock(&foo->private_lock);
}

foo_io_completion(struct foo_priv *foo, void *req)
{
        lock(&foo->private_lock);
        if (--foo->num_pending_requests == 0)
                pm_runtime_put_autosuspend(&foo->dev);
        else
                foo_process_next_request(foo);
        unlock(&foo->private_lock);
        /* Send req result back to the user ... */
}

int foo_runtime_suspend(struct device *dev)
{
        struct foo_priv *foo = container_of(dev, ...);
        int ret = 0;

        lock(&foo->private_lock);
        if (foo->num_pending_requests > 0) {
                ret = -EBUSY;
        } else {
                /* ... suspend the device ... */
                foo->is_suspended = 1;
        }
        unlock(&foo->private_lock);
        return ret;
}

int foo_runtime_resume(struct device *dev)
{
        struct foo_priv *foo = container_of(dev, ...);

        lock(&foo->private_lock);
        /* ... resume the device ... */
        foo->is_suspended = 0;
        pm_runtime_mark_last_busy(&foo->dev);
        if (foo->num_pending_requests > 0)
                foo_process_next_request(foo);
        unlock(&foo->private_lock);
        return 0;
}

The important point is that after foo_io_completion() asks for an autosuspend, the foo_runtime_suspend() callback may race with foo_read_or_write(). Therefore foo_runtime_suspend() has to check whether there are any pending I/O requests (while holding the private lock) before allowing the suspend to proceed.

In addition, the power.autosuspend_delay field can be changed by user space at any time. If a driver cares about this, it can call pm_runtime_autosuspend_expiration() from within the ->runtime_suspend() callback while holding its private lock. If the function returns a nonzero value then the delay has not yet expired and the callback should return -EAGAIN.