2019-05-27 14:55:05 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* pm.h - Power management interface
|
|
|
|
*
|
|
|
|
* Copyright (C) 2000 Andrew Henroid
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _LINUX_PM_H
|
|
|
|
#define _LINUX_PM_H
|
|
|
|
|
2022-01-08 02:17:20 +08:00
|
|
|
#include <linux/export.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/list.h>
|
2009-08-19 05:38:32 +08:00
|
|
|
#include <linux/workqueue.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/wait.h>
|
|
|
|
#include <linux/timer.h>
|
2018-12-14 22:22:25 +08:00
|
|
|
#include <linux/hrtimer.h>
|
PM: Asynchronous suspend and resume of devices
Theoretically, the total time of system sleep transitions (suspend
to RAM, hibernation) can be reduced by running suspend and resume
callbacks of device drivers in parallel with each other. However,
there are dependencies between devices such that we're not allowed
to suspend the parent of a device before suspending the device
itself. Analogously, we're not allowed to resume a device before
resuming its parent.
The most straightforward way to take these dependencies into accout
is to start the async threads used for suspending and resuming
devices at the core level, so that async_schedule() is called for
each suspend and resume callback supposed to be executed
asynchronously.
For this purpose, introduce a new device flag, power.async_suspend,
used to mark the devices whose suspend and resume callbacks are to be
executed asynchronously (ie. in parallel with the main suspend/resume
thread and possibly in parallel with each other) and helper function
device_enable_async_suspend() allowing one to set power.async_suspend
for given device (power.async_suspend is unset by default for all
devices). For each device with the power.async_suspend flag set the
PM core will use async_schedule() to execute its suspend and resume
callbacks.
The async threads started for different devices as a result of
calling async_schedule() are synchronized with each other and with
the main suspend/resume thread with the help of completions, in the
following way:
(1) There is a completion, power.completion, for each device object.
(2) Each device's completion is reset before calling async_schedule()
for the device or, in the case of devices with the
power.async_suspend flags unset, before executing the device's
suspend and resume callbacks.
(3) During suspend, right before running the bus type, device type
and device class suspend callbacks for the device, the PM core
waits for the completions of all the device's children to be
completed.
(4) During resume, right before running the bus type, device type and
device class resume callbacks for the device, the PM core waits
for the completion of the device's parent to be completed.
(5) The PM core completes power.completion for each device right
after the bus type, device type and device class suspend (or
resume) callbacks executed for the device have returned.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2010-01-24 05:23:32 +08:00
|
|
|
#include <linux/completion.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Callbacks for platform drivers to implement.
|
|
|
|
*/
|
|
|
|
extern void (*pm_power_off)(void);
|
|
|
|
|
2013-02-04 21:37:20 +08:00
|
|
|
struct device; /* we have a circular dep with device.h */
|
|
|
|
#ifdef CONFIG_VT_CONSOLE_SLEEP
|
|
|
|
extern void pm_vt_switch_required(struct device *dev, bool required);
|
|
|
|
extern void pm_vt_switch_unregister(struct device *dev);
|
|
|
|
#else
|
|
|
|
static inline void pm_vt_switch_required(struct device *dev, bool required)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
static inline void pm_vt_switch_unregister(struct device *dev)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_VT_CONSOLE_SLEEP */
|
|
|
|
|
2022-04-23 06:58:11 +08:00
|
|
|
#ifdef CONFIG_CXL_SUSPEND
|
|
|
|
bool cxl_mem_active(void);
|
|
|
|
#else
|
|
|
|
static inline bool cxl_mem_active(void)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* Device power management
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2010-09-26 05:35:15 +08:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
extern const char power_group_name[]; /* = "power" */
|
|
|
|
#else
|
|
|
|
#define power_group_name NULL
|
|
|
|
#endif
|
|
|
|
|
2005-09-04 06:56:57 +08:00
|
|
|
typedef struct pm_message {
|
|
|
|
int event;
|
|
|
|
} pm_message_t;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
/**
|
2017-02-02 08:30:49 +08:00
|
|
|
* struct dev_pm_ops - device PM callbacks.
|
2011-11-24 04:20:32 +08:00
|
|
|
*
|
|
|
|
* @prepare: The principal role of this callback is to prevent new children of
|
|
|
|
* the device from being registered after it has returned (the driver's
|
|
|
|
* subsystem and generally the rest of the kernel is supposed to prevent
|
|
|
|
* new calls to the probe method from being made too once @prepare() has
|
|
|
|
* succeeded). If @prepare() detects a situation it cannot handle (e.g.
|
|
|
|
* registration of a child already in progress), it may return -EAGAIN, so
|
|
|
|
* that the PM core can execute it once again (e.g. after a new child has
|
|
|
|
* been registered) to recover from the race condition.
|
|
|
|
* This method is executed for all kinds of suspend transitions and is
|
|
|
|
* followed by one of the suspend callbacks: @suspend(), @freeze(), or
|
PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily
Currently, some subsystems (e.g. PCI and the ACPI PM domain) have to
resume all runtime-suspended devices during system suspend, mostly
because those devices may need to be reprogrammed due to different
wakeup settings for system sleep and for runtime PM.
For some devices, though, it's OK to remain in runtime suspend
throughout a complete system suspend/resume cycle (if the device was in
runtime suspend at the start of the cycle). We would like to do this
whenever possible, to avoid the overhead of extra power-up and power-down
events.
However, problems may arise because the device's descendants may require
it to be at full power at various points during the cycle. Therefore the
most straightforward way to do this safely is if the device and all its
descendants can remain runtime suspended until the complete stage of
system resume.
To this end, introduce a new device PM flag, power.direct_complete
and modify the PM core to use that flag as follows.
If the ->prepare() callback of a device returns a positive number,
the PM core will regard that as an indication that it may leave the
device runtime-suspended. It will then check if the system power
transition in progress is a suspend (and not hibernation in particular)
and if the device is, indeed, runtime-suspended. In that case, the PM
core will set the device's power.direct_complete flag. Otherwise it
will clear power.direct_complete for the device and it also will later
clear it for the device's parent (if there's one).
Next, the PM core will not invoke the ->suspend() ->suspend_late(),
->suspend_irq(), ->resume_irq(), ->resume_early(), or ->resume()
callbacks for all devices having power.direct_complete set. It
will invoke their ->complete() callbacks, however, and those
callbacks are then responsible for resuming the devices as
appropriate, if necessary. For example, in some cases they may
need to queue up runtime resume requests for the devices using
pm_request_resume().
Changelog partly based on an Alan Stern's description of the idea
(http://marc.info/?l=linux-pm&m=139940466625569&w=2).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
2014-05-16 08:46:50 +08:00
|
|
|
* @poweroff(). If the transition is a suspend to memory or standby (that
|
|
|
|
* is, not related to hibernation), the return value of @prepare() may be
|
|
|
|
* used to indicate to the PM core to leave the device in runtime suspend
|
|
|
|
* if applicable. Namely, if @prepare() returns a positive number, the PM
|
|
|
|
* core will understand that as a declaration that the device appears to be
|
|
|
|
* runtime-suspended and it may be left in that state during the entire
|
|
|
|
* transition and during the subsequent resume if all of its descendants
|
|
|
|
* are left in runtime suspend too. If that happens, @complete() will be
|
|
|
|
* executed directly after @prepare() and it must ensure the proper
|
|
|
|
* functioning of the device after the system resume.
|
|
|
|
* The PM core executes subsystem-level @prepare() for all devices before
|
|
|
|
* starting to invoke suspend callbacks for any of them, so generally
|
|
|
|
* devices may be assumed to be functional or to respond to runtime resume
|
|
|
|
* requests while @prepare() is being executed. However, device drivers
|
|
|
|
* may NOT assume anything about the availability of user space at that
|
|
|
|
* time and it is NOT valid to request firmware from within @prepare()
|
|
|
|
* (it's too late to do that). It also is NOT valid to allocate
|
2011-11-24 04:20:32 +08:00
|
|
|
* substantial amounts of memory from @prepare() in the GFP_KERNEL mode.
|
|
|
|
* [To work around these limitations, drivers may register suspend and
|
|
|
|
* hibernation notifiers to be executed before the freezing of tasks.]
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
|
|
|
* @complete: Undo the changes made by @prepare(). This method is executed for
|
|
|
|
* all kinds of resume transitions, following one of the resume callbacks:
|
|
|
|
* @resume(), @thaw(), @restore(). Also called if the state transition
|
2011-11-24 04:20:32 +08:00
|
|
|
* fails before the driver's suspend callback: @suspend(), @freeze() or
|
|
|
|
* @poweroff(), can be executed (e.g. if the suspend callback fails for one
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* of the other devices that the PM core has unsuccessfully attempted to
|
|
|
|
* suspend earlier).
|
2011-11-24 04:20:32 +08:00
|
|
|
* The PM core executes subsystem-level @complete() after it has executed
|
PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily
Currently, some subsystems (e.g. PCI and the ACPI PM domain) have to
resume all runtime-suspended devices during system suspend, mostly
because those devices may need to be reprogrammed due to different
wakeup settings for system sleep and for runtime PM.
For some devices, though, it's OK to remain in runtime suspend
throughout a complete system suspend/resume cycle (if the device was in
runtime suspend at the start of the cycle). We would like to do this
whenever possible, to avoid the overhead of extra power-up and power-down
events.
However, problems may arise because the device's descendants may require
it to be at full power at various points during the cycle. Therefore the
most straightforward way to do this safely is if the device and all its
descendants can remain runtime suspended until the complete stage of
system resume.
To this end, introduce a new device PM flag, power.direct_complete
and modify the PM core to use that flag as follows.
If the ->prepare() callback of a device returns a positive number,
the PM core will regard that as an indication that it may leave the
device runtime-suspended. It will then check if the system power
transition in progress is a suspend (and not hibernation in particular)
and if the device is, indeed, runtime-suspended. In that case, the PM
core will set the device's power.direct_complete flag. Otherwise it
will clear power.direct_complete for the device and it also will later
clear it for the device's parent (if there's one).
Next, the PM core will not invoke the ->suspend() ->suspend_late(),
->suspend_irq(), ->resume_irq(), ->resume_early(), or ->resume()
callbacks for all devices having power.direct_complete set. It
will invoke their ->complete() callbacks, however, and those
callbacks are then responsible for resuming the devices as
appropriate, if necessary. For example, in some cases they may
need to queue up runtime resume requests for the devices using
pm_request_resume().
Changelog partly based on an Alan Stern's description of the idea
(http://marc.info/?l=linux-pm&m=139940466625569&w=2).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
2014-05-16 08:46:50 +08:00
|
|
|
* the appropriate resume callbacks for all devices. If the corresponding
|
|
|
|
* @prepare() at the beginning of the suspend transition returned a
|
|
|
|
* positive number and the device was left in runtime suspend (without
|
|
|
|
* executing any suspend and resume callbacks for it), @complete() will be
|
|
|
|
* the only callback executed for the device during resume. In that case,
|
|
|
|
* @complete() must be prepared to do whatever is necessary to ensure the
|
|
|
|
* proper functioning of the device after the system resume. To this end,
|
|
|
|
* @complete() can check the power.direct_complete flag of the device to
|
|
|
|
* learn whether (unset) or not (set) the previous suspend and resume
|
|
|
|
* callbacks have been executed for it.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
|
|
|
* @suspend: Executed before putting the system into a sleep state in which the
|
2011-11-24 04:20:32 +08:00
|
|
|
* contents of main memory are preserved. The exact action to perform
|
|
|
|
* depends on the device's subsystem (PM domain, device type, class or bus
|
|
|
|
* type), but generally the device must be quiescent after subsystem-level
|
|
|
|
* @suspend() has returned, so that it doesn't do any I/O or DMA.
|
|
|
|
* Subsystem-level @suspend() is executed for all devices after invoking
|
|
|
|
* subsystem-level @prepare() for all of them.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @suspend_late: Continue operations started by @suspend(). For a number of
|
|
|
|
* devices @suspend_late() may point to the same callback routine as the
|
|
|
|
* runtime suspend callback.
|
|
|
|
*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* @resume: Executed after waking the system up from a sleep state in which the
|
2011-11-24 04:20:32 +08:00
|
|
|
* contents of main memory were preserved. The exact action to perform
|
|
|
|
* depends on the device's subsystem, but generally the driver is expected
|
|
|
|
* to start working again, responding to hardware events and software
|
|
|
|
* requests (the device itself may be left in a low-power state, waiting
|
|
|
|
* for a runtime resume to occur). The state of the device at the time its
|
|
|
|
* driver's @resume() callback is run depends on the platform and subsystem
|
|
|
|
* the device belongs to. On most platforms, there are no restrictions on
|
|
|
|
* availability of resources like clocks during @resume().
|
|
|
|
* Subsystem-level @resume() is executed for all devices after invoking
|
|
|
|
* subsystem-level @resume_noirq() for all of them.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @resume_early: Prepare to execute @resume(). For a number of devices
|
|
|
|
* @resume_early() may point to the same callback routine as the runtime
|
|
|
|
* resume callback.
|
|
|
|
*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* @freeze: Hibernation-specific, executed before creating a hibernation image.
|
2011-11-24 04:20:32 +08:00
|
|
|
* Analogous to @suspend(), but it should not enable the device to signal
|
|
|
|
* wakeup events or change its power state. The majority of subsystems
|
|
|
|
* (with the notable exception of the PCI bus type) expect the driver-level
|
|
|
|
* @freeze() to save the device settings in memory to be used by @restore()
|
|
|
|
* during the subsequent resume from hibernation.
|
|
|
|
* Subsystem-level @freeze() is executed for all devices after invoking
|
|
|
|
* subsystem-level @prepare() for all of them.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @freeze_late: Continue operations started by @freeze(). Analogous to
|
|
|
|
* @suspend_late(), but it should not enable the device to signal wakeup
|
|
|
|
* events or change its power state.
|
|
|
|
*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* @thaw: Hibernation-specific, executed after creating a hibernation image OR
|
2011-11-24 04:20:32 +08:00
|
|
|
* if the creation of an image has failed. Also executed after a failing
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* attempt to restore the contents of main memory from such an image.
|
|
|
|
* Undo the changes made by the preceding @freeze(), so the device can be
|
|
|
|
* operated in the same way as immediately before the call to @freeze().
|
2011-11-24 04:20:32 +08:00
|
|
|
* Subsystem-level @thaw() is executed for all devices after invoking
|
|
|
|
* subsystem-level @thaw_noirq() for all of them. It also may be executed
|
|
|
|
* directly after @freeze() in case of a transition error.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @thaw_early: Prepare to execute @thaw(). Undo the changes made by the
|
|
|
|
* preceding @freeze_late().
|
|
|
|
*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* @poweroff: Hibernation-specific, executed after saving a hibernation image.
|
2011-11-24 04:20:32 +08:00
|
|
|
* Analogous to @suspend(), but it need not save the device's settings in
|
|
|
|
* memory.
|
|
|
|
* Subsystem-level @poweroff() is executed for all devices after invoking
|
|
|
|
* subsystem-level @prepare() for all of them.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @poweroff_late: Continue operations started by @poweroff(). Analogous to
|
|
|
|
* @suspend_late(), but it need not save the device's settings in memory.
|
|
|
|
*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* @restore: Hibernation-specific, executed after restoring the contents of main
|
2011-11-24 04:20:32 +08:00
|
|
|
* memory from a hibernation image, analogous to @resume().
|
|
|
|
*
|
2012-01-30 03:38:29 +08:00
|
|
|
* @restore_early: Prepare to execute @restore(), analogous to @resume_early().
|
|
|
|
*
|
2011-11-24 04:20:32 +08:00
|
|
|
* @suspend_noirq: Complete the actions started by @suspend(). Carry out any
|
|
|
|
* additional operations required for suspending the device that might be
|
|
|
|
* racing with its driver's interrupt handler, which is guaranteed not to
|
|
|
|
* run while @suspend_noirq() is being executed.
|
|
|
|
* It generally is expected that the device will be in a low-power state
|
|
|
|
* (appropriate for the target system sleep state) after subsystem-level
|
|
|
|
* @suspend_noirq() has returned successfully. If the device can generate
|
|
|
|
* system wakeup signals and is enabled to wake up the system, it should be
|
|
|
|
* configured to do so at that time. However, depending on the platform
|
2012-01-30 03:38:29 +08:00
|
|
|
* and device's subsystem, @suspend() or @suspend_late() may be allowed to
|
|
|
|
* put the device into the low-power state and configure it to generate
|
|
|
|
* wakeup signals, in which case it generally is not necessary to define
|
|
|
|
* @suspend_noirq().
|
2011-11-24 04:20:32 +08:00
|
|
|
*
|
|
|
|
* @resume_noirq: Prepare for the execution of @resume() by carrying out any
|
|
|
|
* operations required for resuming the device that might be racing with
|
|
|
|
* its driver's interrupt handler, which is guaranteed not to run while
|
|
|
|
* @resume_noirq() is being executed.
|
|
|
|
*
|
|
|
|
* @freeze_noirq: Complete the actions started by @freeze(). Carry out any
|
|
|
|
* additional operations required for freezing the device that might be
|
|
|
|
* racing with its driver's interrupt handler, which is guaranteed not to
|
|
|
|
* run while @freeze_noirq() is being executed.
|
2012-01-30 03:38:29 +08:00
|
|
|
* The power state of the device should not be changed by either @freeze(),
|
|
|
|
* or @freeze_late(), or @freeze_noirq() and it should not be configured to
|
|
|
|
* signal system wakeup by any of these callbacks.
|
2011-11-24 04:20:32 +08:00
|
|
|
*
|
|
|
|
* @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
|
|
|
|
* operations required for thawing the device that might be racing with its
|
|
|
|
* driver's interrupt handler, which is guaranteed not to run while
|
|
|
|
* @thaw_noirq() is being executed.
|
|
|
|
*
|
|
|
|
* @poweroff_noirq: Complete the actions started by @poweroff(). Analogous to
|
|
|
|
* @suspend_noirq(), but it need not save the device's settings in memory.
|
|
|
|
*
|
|
|
|
* @restore_noirq: Prepare for the execution of @restore() by carrying out any
|
|
|
|
* operations required for thawing the device that might be racing with its
|
|
|
|
* driver's interrupt handler, which is guaranteed not to run while
|
|
|
|
* @restore_noirq() is being executed. Analogous to @resume_noirq().
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*
|
2009-08-19 05:38:32 +08:00
|
|
|
* @runtime_suspend: Prepare the device for a condition in which it won't be
|
|
|
|
* able to communicate with the CPU(s) and RAM due to power management.
|
2011-11-24 04:20:32 +08:00
|
|
|
* This need not mean that the device should be put into a low-power state.
|
2009-08-19 05:38:32 +08:00
|
|
|
* For example, if the device is behind a link which is about to be turned
|
|
|
|
* off, the device may remain at full power. If the device does go to low
|
2011-11-24 04:20:32 +08:00
|
|
|
* power and is capable of generating runtime wakeup events, remote wakeup
|
|
|
|
* (i.e., a hardware mechanism allowing the device to request a change of
|
|
|
|
* its power state via an interrupt) should be enabled for it.
|
2009-08-19 05:38:32 +08:00
|
|
|
*
|
|
|
|
* @runtime_resume: Put the device into the fully active state in response to a
|
2011-11-24 04:20:32 +08:00
|
|
|
* wakeup event generated by hardware or at the request of software. If
|
|
|
|
* necessary, put the device into the full-power state and restore its
|
2009-08-19 05:38:32 +08:00
|
|
|
* registers, so that it is fully operational.
|
|
|
|
*
|
2011-11-24 04:20:32 +08:00
|
|
|
* @runtime_idle: Device appears to be inactive and it might be put into a
|
2014-03-18 04:26:11 +08:00
|
|
|
* low-power state if all of the necessary conditions are satisfied.
|
|
|
|
* Check these conditions, and return 0 if it's appropriate to let the PM
|
|
|
|
* core queue a suspend request for the device.
|
2011-11-24 04:20:32 +08:00
|
|
|
*
|
2017-02-02 08:30:49 +08:00
|
|
|
* Several device power state transitions are externally visible, affecting
|
|
|
|
* the state of pending I/O queues and (for drivers that touch hardware)
|
|
|
|
* interrupts, wakeups, DMA, and other hardware state. There may also be
|
|
|
|
* internal transitions to various low-power modes which are transparent
|
|
|
|
* to the rest of the driver stack (such as a driver that's ON gating off
|
|
|
|
* clocks which are not in active use).
|
2011-11-24 04:20:32 +08:00
|
|
|
*
|
2017-02-02 08:30:49 +08:00
|
|
|
* The externally visible transitions are handled with the help of callbacks
|
|
|
|
* included in this structure in such a way that, typically, two levels of
|
|
|
|
* callbacks are involved. First, the PM core executes callbacks provided by PM
|
|
|
|
* domains, device types, classes and bus types. They are the subsystem-level
|
|
|
|
* callbacks expected to execute callbacks provided by device drivers, although
|
|
|
|
* they may choose not to do that. If the driver callbacks are executed, they
|
|
|
|
* have to collaborate with the subsystem-level callbacks to achieve the goals
|
|
|
|
* appropriate for the given system transition, given transition phase and the
|
|
|
|
* subsystem the device belongs to.
|
|
|
|
*
|
|
|
|
* All of the above callbacks, except for @complete(), return error codes.
|
|
|
|
* However, the error codes returned by @resume(), @thaw(), @restore(),
|
|
|
|
* @resume_noirq(), @thaw_noirq(), and @restore_noirq(), do not cause the PM
|
|
|
|
* core to abort the resume transition during which they are returned. The
|
|
|
|
* error codes returned in those cases are only printed to the system logs for
|
|
|
|
* debugging purposes. Still, it is recommended that drivers only return error
|
|
|
|
* codes from their resume methods in case of an unrecoverable failure (i.e.
|
|
|
|
* when the device being handled refuses to resume and becomes unusable) to
|
|
|
|
* allow the PM core to be modified in the future, so that it can avoid
|
|
|
|
* attempting to handle devices that failed to resume and their children.
|
|
|
|
*
|
|
|
|
* It is allowed to unregister devices while the above callbacks are being
|
|
|
|
* executed. However, a callback routine MUST NOT try to unregister the device
|
|
|
|
* it was called for, although it may unregister children of that device (for
|
|
|
|
* example, if it detects that a child was unplugged while the system was
|
|
|
|
* asleep).
|
|
|
|
*
|
|
|
|
* There also are callbacks related to runtime power management of devices.
|
|
|
|
* Again, as a rule these callbacks are executed by the PM core for subsystems
|
|
|
|
* (PM domains, device types, classes and bus types) and the subsystem-level
|
|
|
|
* callbacks are expected to invoke the driver callbacks. Moreover, the exact
|
|
|
|
* actions to be performed by a device driver's callbacks generally depend on
|
|
|
|
* the platform and subsystem the device belongs to.
|
|
|
|
*
|
2019-06-13 18:10:36 +08:00
|
|
|
* Refer to Documentation/power/runtime_pm.rst for more information about the
|
2017-02-02 08:30:49 +08:00
|
|
|
* role of the @runtime_suspend(), @runtime_resume() and @runtime_idle()
|
|
|
|
* callbacks in device runtime power management.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*/
|
2008-10-07 04:46:05 +08:00
|
|
|
struct dev_pm_ops {
|
|
|
|
int (*prepare)(struct device *dev);
|
|
|
|
void (*complete)(struct device *dev);
|
|
|
|
int (*suspend)(struct device *dev);
|
|
|
|
int (*resume)(struct device *dev);
|
|
|
|
int (*freeze)(struct device *dev);
|
|
|
|
int (*thaw)(struct device *dev);
|
|
|
|
int (*poweroff)(struct device *dev);
|
|
|
|
int (*restore)(struct device *dev);
|
2012-01-30 03:38:29 +08:00
|
|
|
int (*suspend_late)(struct device *dev);
|
|
|
|
int (*resume_early)(struct device *dev);
|
|
|
|
int (*freeze_late)(struct device *dev);
|
|
|
|
int (*thaw_early)(struct device *dev);
|
|
|
|
int (*poweroff_late)(struct device *dev);
|
|
|
|
int (*restore_early)(struct device *dev);
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
int (*suspend_noirq)(struct device *dev);
|
|
|
|
int (*resume_noirq)(struct device *dev);
|
|
|
|
int (*freeze_noirq)(struct device *dev);
|
|
|
|
int (*thaw_noirq)(struct device *dev);
|
|
|
|
int (*poweroff_noirq)(struct device *dev);
|
|
|
|
int (*restore_noirq)(struct device *dev);
|
2009-08-19 05:38:32 +08:00
|
|
|
int (*runtime_suspend)(struct device *dev);
|
|
|
|
int (*runtime_resume)(struct device *dev);
|
|
|
|
int (*runtime_idle)(struct device *dev);
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
};
|
|
|
|
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
#define SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
.suspend = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.resume = pm_sleep_ptr(resume_fn), \
|
|
|
|
.freeze = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.thaw = pm_sleep_ptr(resume_fn), \
|
|
|
|
.poweroff = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.restore = pm_sleep_ptr(resume_fn),
|
|
|
|
|
|
|
|
#define LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
.suspend_late = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.resume_early = pm_sleep_ptr(resume_fn), \
|
|
|
|
.freeze_late = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.thaw_early = pm_sleep_ptr(resume_fn), \
|
|
|
|
.poweroff_late = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.restore_early = pm_sleep_ptr(resume_fn),
|
|
|
|
|
|
|
|
#define NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
.suspend_noirq = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.resume_noirq = pm_sleep_ptr(resume_fn), \
|
|
|
|
.freeze_noirq = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.thaw_noirq = pm_sleep_ptr(resume_fn), \
|
|
|
|
.poweroff_noirq = pm_sleep_ptr(suspend_fn), \
|
|
|
|
.restore_noirq = pm_sleep_ptr(resume_fn),
|
|
|
|
|
|
|
|
#define RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
|
|
|
|
.runtime_suspend = suspend_fn, \
|
|
|
|
.runtime_resume = resume_fn, \
|
|
|
|
.runtime_idle = idle_fn,
|
|
|
|
|
2010-03-07 04:28:37 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
2010-03-07 04:28:37 +08:00
|
|
|
#else
|
|
|
|
#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
|
|
|
#endif
|
|
|
|
|
2013-12-10 21:37:42 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
#define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
2013-12-10 21:37:42 +08:00
|
|
|
#else
|
|
|
|
#define SET_LATE_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
|
|
|
#endif
|
|
|
|
|
2015-04-28 02:24:30 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
#define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
2015-04-28 02:24:30 +08:00
|
|
|
#else
|
|
|
|
#define SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn)
|
|
|
|
#endif
|
|
|
|
|
2014-12-04 07:34:11 +08:00
|
|
|
#ifdef CONFIG_PM
|
2010-03-07 04:28:37 +08:00
|
|
|
#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
|
2010-03-07 04:28:37 +08:00
|
|
|
#else
|
|
|
|
#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn)
|
|
|
|
#endif
|
|
|
|
|
2022-01-08 02:17:20 +08:00
|
|
|
#define _DEFINE_DEV_PM_OPS(name, \
|
|
|
|
suspend_fn, resume_fn, \
|
|
|
|
runtime_suspend_fn, runtime_resume_fn, idle_fn) \
|
|
|
|
const struct dev_pm_ops name = { \
|
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
RUNTIME_PM_OPS(runtime_suspend_fn, runtime_resume_fn, idle_fn) \
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_PM
|
2023-06-11 23:51:00 +08:00
|
|
|
#define _EXPORT_DEV_PM_OPS(name, license, ns) \
|
2022-08-09 01:40:38 +08:00
|
|
|
const struct dev_pm_ops name; \
|
2023-06-11 23:51:00 +08:00
|
|
|
__EXPORT_SYMBOL(name, license, ns); \
|
2022-08-09 01:40:38 +08:00
|
|
|
const struct dev_pm_ops name
|
2023-02-14 00:50:05 +08:00
|
|
|
#define EXPORT_PM_FN_GPL(name) EXPORT_SYMBOL_GPL(name)
|
|
|
|
#define EXPORT_PM_FN_NS_GPL(name, ns) EXPORT_SYMBOL_NS_GPL(name, ns)
|
2022-01-08 02:17:20 +08:00
|
|
|
#else
|
2023-06-11 23:51:00 +08:00
|
|
|
#define _EXPORT_DEV_PM_OPS(name, license, ns) \
|
2022-08-09 01:40:38 +08:00
|
|
|
static __maybe_unused const struct dev_pm_ops __static_##name
|
2023-02-14 00:50:05 +08:00
|
|
|
#define EXPORT_PM_FN_GPL(name)
|
|
|
|
#define EXPORT_PM_FN_NS_GPL(name, ns)
|
2022-01-08 02:17:20 +08:00
|
|
|
#endif
|
|
|
|
|
2022-08-09 01:40:38 +08:00
|
|
|
#define EXPORT_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "", "")
|
kbuild: generate KSYMTAB entries by modpost
Commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing
CONFIG_MODULE_REL_CRCS") made modpost output CRCs in the same way
whether the EXPORT_SYMBOL() is placed in *.c or *.S.
For further cleanups, this commit applies a similar approach to the
entire data structure of EXPORT_SYMBOL().
The EXPORT_SYMBOL() compilation is split into two stages.
When a source file is compiled, EXPORT_SYMBOL() will be converted into
a dummy symbol in the .export_symbol section.
For example,
EXPORT_SYMBOL(foo);
EXPORT_SYMBOL_NS_GPL(bar, BAR_NAMESPACE);
will be encoded into the following assembly code:
.section ".export_symbol","a"
__export_symbol_foo:
.asciz "" /* license */
.asciz "" /* name space */
.balign 8
.quad foo /* symbol reference */
.previous
.section ".export_symbol","a"
__export_symbol_bar:
.asciz "GPL" /* license */
.asciz "BAR_NAMESPACE" /* name space */
.balign 8
.quad bar /* symbol reference */
.previous
They are mere markers to tell modpost the name, license, and namespace
of the symbols. They will be dropped from the final vmlinux and modules
because the *(.export_symbol) will go into /DISCARD/ in the linker script.
Then, modpost extracts all the information about EXPORT_SYMBOL() from the
.export_symbol section, and generates the final C code:
KSYMTAB_FUNC(foo, "", "");
KSYMTAB_FUNC(bar, "_gpl", "BAR_NAMESPACE");
KSYMTAB_FUNC() (or KSYMTAB_DATA() if it is data) is expanded to struct
kernel_symbol that will be linked to the vmlinux or a module.
With this change, EXPORT_SYMBOL() works in the same way for *.c and *.S
files, providing the following benefits.
[1] Deprecate EXPORT_DATA_SYMBOL()
In the old days, EXPORT_SYMBOL() was only available in C files. To export
a symbol in *.S, EXPORT_SYMBOL() was placed in a separate *.c file.
arch/arm/kernel/armksyms.c is one example written in the classic manner.
Commit 22823ab419d8 ("EXPORT_SYMBOL() for asm") removed this limitation.
Since then, EXPORT_SYMBOL() can be placed close to the symbol definition
in *.S files. It was a nice improvement.
However, as that commit mentioned, you need to use EXPORT_DATA_SYMBOL()
for data objects on some architectures.
In the new approach, modpost checks symbol's type (STT_FUNC or not),
and outputs KSYMTAB_FUNC() or KSYMTAB_DATA() accordingly.
There are only two users of EXPORT_DATA_SYMBOL:
EXPORT_DATA_SYMBOL_GPL(empty_zero_page) (arch/ia64/kernel/head.S)
EXPORT_DATA_SYMBOL(ia64_ivt) (arch/ia64/kernel/ivt.S)
They are transformed as follows and output into .vmlinux.export.c
KSYMTAB_DATA(empty_zero_page, "_gpl", "");
KSYMTAB_DATA(ia64_ivt, "", "");
The other EXPORT_SYMBOL users in ia64 assembly are output as
KSYMTAB_FUNC().
EXPORT_DATA_SYMBOL() is now deprecated.
[2] merge <linux/export.h> and <asm-generic/export.h>
There are two similar header implementations:
include/linux/export.h for .c files
include/asm-generic/export.h for .S files
Ideally, the functionality should be consistent between them, but they
tend to diverge.
Commit 8651ec01daed ("module: add support for symbol namespaces.") did
not support the namespace for *.S files.
This commit shifts the essential implementation part to C, which supports
EXPORT_SYMBOL_NS() for *.S files.
<asm/export.h> and <asm-generic/export.h> will remain as a wrapper of
<linux/export.h> for a while.
They will be removed after #include <asm/export.h> directives are all
replaced with #include <linux/export.h>.
[3] Implement CONFIG_TRIM_UNUSED_KSYMS in one-pass algorithm (by a later commit)
When CONFIG_TRIM_UNUSED_KSYMS is enabled, Kbuild recursively traverses
the directory tree to determine which EXPORT_SYMBOL to trim. If an
EXPORT_SYMBOL turns out to be unused by anyone, Kbuild begins the
second traverse, where some source files are recompiled with their
EXPORT_SYMBOL() tuned into a no-op.
We can do this better now; modpost can selectively emit KSYMTAB entries
that are really used by modules.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
2023-06-11 23:50:52 +08:00
|
|
|
#define EXPORT_GPL_DEV_PM_OPS(name) _EXPORT_DEV_PM_OPS(name, "GPL", "")
|
2022-08-09 01:40:38 +08:00
|
|
|
#define EXPORT_NS_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "", #ns)
|
kbuild: generate KSYMTAB entries by modpost
Commit 7b4537199a4a ("kbuild: link symbol CRCs at final link, removing
CONFIG_MODULE_REL_CRCS") made modpost output CRCs in the same way
whether the EXPORT_SYMBOL() is placed in *.c or *.S.
For further cleanups, this commit applies a similar approach to the
entire data structure of EXPORT_SYMBOL().
The EXPORT_SYMBOL() compilation is split into two stages.
When a source file is compiled, EXPORT_SYMBOL() will be converted into
a dummy symbol in the .export_symbol section.
For example,
EXPORT_SYMBOL(foo);
EXPORT_SYMBOL_NS_GPL(bar, BAR_NAMESPACE);
will be encoded into the following assembly code:
.section ".export_symbol","a"
__export_symbol_foo:
.asciz "" /* license */
.asciz "" /* name space */
.balign 8
.quad foo /* symbol reference */
.previous
.section ".export_symbol","a"
__export_symbol_bar:
.asciz "GPL" /* license */
.asciz "BAR_NAMESPACE" /* name space */
.balign 8
.quad bar /* symbol reference */
.previous
They are mere markers to tell modpost the name, license, and namespace
of the symbols. They will be dropped from the final vmlinux and modules
because the *(.export_symbol) will go into /DISCARD/ in the linker script.
Then, modpost extracts all the information about EXPORT_SYMBOL() from the
.export_symbol section, and generates the final C code:
KSYMTAB_FUNC(foo, "", "");
KSYMTAB_FUNC(bar, "_gpl", "BAR_NAMESPACE");
KSYMTAB_FUNC() (or KSYMTAB_DATA() if it is data) is expanded to struct
kernel_symbol that will be linked to the vmlinux or a module.
With this change, EXPORT_SYMBOL() works in the same way for *.c and *.S
files, providing the following benefits.
[1] Deprecate EXPORT_DATA_SYMBOL()
In the old days, EXPORT_SYMBOL() was only available in C files. To export
a symbol in *.S, EXPORT_SYMBOL() was placed in a separate *.c file.
arch/arm/kernel/armksyms.c is one example written in the classic manner.
Commit 22823ab419d8 ("EXPORT_SYMBOL() for asm") removed this limitation.
Since then, EXPORT_SYMBOL() can be placed close to the symbol definition
in *.S files. It was a nice improvement.
However, as that commit mentioned, you need to use EXPORT_DATA_SYMBOL()
for data objects on some architectures.
In the new approach, modpost checks symbol's type (STT_FUNC or not),
and outputs KSYMTAB_FUNC() or KSYMTAB_DATA() accordingly.
There are only two users of EXPORT_DATA_SYMBOL:
EXPORT_DATA_SYMBOL_GPL(empty_zero_page) (arch/ia64/kernel/head.S)
EXPORT_DATA_SYMBOL(ia64_ivt) (arch/ia64/kernel/ivt.S)
They are transformed as follows and output into .vmlinux.export.c
KSYMTAB_DATA(empty_zero_page, "_gpl", "");
KSYMTAB_DATA(ia64_ivt, "", "");
The other EXPORT_SYMBOL users in ia64 assembly are output as
KSYMTAB_FUNC().
EXPORT_DATA_SYMBOL() is now deprecated.
[2] merge <linux/export.h> and <asm-generic/export.h>
There are two similar header implementations:
include/linux/export.h for .c files
include/asm-generic/export.h for .S files
Ideally, the functionality should be consistent between them, but they
tend to diverge.
Commit 8651ec01daed ("module: add support for symbol namespaces.") did
not support the namespace for *.S files.
This commit shifts the essential implementation part to C, which supports
EXPORT_SYMBOL_NS() for *.S files.
<asm/export.h> and <asm-generic/export.h> will remain as a wrapper of
<linux/export.h> for a while.
They will be removed after #include <asm/export.h> directives are all
replaced with #include <linux/export.h>.
[3] Implement CONFIG_TRIM_UNUSED_KSYMS in one-pass algorithm (by a later commit)
When CONFIG_TRIM_UNUSED_KSYMS is enabled, Kbuild recursively traverses
the directory tree to determine which EXPORT_SYMBOL to trim. If an
EXPORT_SYMBOL turns out to be unused by anyone, Kbuild begins the
second traverse, where some source files are recompiled with their
EXPORT_SYMBOL() tuned into a no-op.
We can do this better now; modpost can selectively emit KSYMTAB entries
that are really used by modules.
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
2023-06-11 23:50:52 +08:00
|
|
|
#define EXPORT_NS_GPL_DEV_PM_OPS(name, ns) _EXPORT_DEV_PM_OPS(name, "GPL", #ns)
|
2022-08-09 01:40:38 +08:00
|
|
|
|
2009-08-06 05:59:59 +08:00
|
|
|
/*
|
|
|
|
* Use this if you want to use the same suspend and resume callbacks for suspend
|
|
|
|
* to RAM and hibernation.
|
2022-01-08 02:17:20 +08:00
|
|
|
*
|
|
|
|
* If the underlying dev_pm_ops struct symbol has to be exported, use
|
|
|
|
* EXPORT_SIMPLE_DEV_PM_OPS() or EXPORT_GPL_SIMPLE_DEV_PM_OPS() instead.
|
2009-08-06 05:59:59 +08:00
|
|
|
*/
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
#define DEFINE_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
|
2022-01-08 02:17:20 +08:00
|
|
|
_DEFINE_DEV_PM_OPS(name, suspend_fn, resume_fn, NULL, NULL, NULL)
|
|
|
|
|
|
|
|
#define EXPORT_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
|
2022-08-09 01:40:38 +08:00
|
|
|
EXPORT_DEV_PM_OPS(name) = { \
|
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
}
|
2022-01-08 02:17:20 +08:00
|
|
|
#define EXPORT_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
|
2022-08-09 01:40:38 +08:00
|
|
|
EXPORT_GPL_DEV_PM_OPS(name) = { \
|
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
}
|
2022-04-01 22:06:04 +08:00
|
|
|
#define EXPORT_NS_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
|
2022-08-09 01:40:38 +08:00
|
|
|
EXPORT_NS_DEV_PM_OPS(name, ns) = { \
|
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
}
|
2022-04-01 22:06:04 +08:00
|
|
|
#define EXPORT_NS_GPL_SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn, ns) \
|
2022-08-09 01:40:38 +08:00
|
|
|
EXPORT_NS_GPL_DEV_PM_OPS(name, ns) = { \
|
|
|
|
SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
}
|
2010-03-07 04:28:37 +08:00
|
|
|
|
2022-01-08 02:17:18 +08:00
|
|
|
/* Deprecated. Use DEFINE_SIMPLE_DEV_PM_OPS() instead. */
|
|
|
|
#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
|
|
|
|
const struct dev_pm_ops __maybe_unused name = { \
|
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
}
|
|
|
|
|
2010-03-07 04:28:37 +08:00
|
|
|
/*
|
|
|
|
* Use this for defining a set of PM operations to be used in all situations
|
2014-02-20 16:00:32 +08:00
|
|
|
* (system suspend, hibernation or runtime PM).
|
2012-02-13 23:29:47 +08:00
|
|
|
* NOTE: In general, system suspend callbacks, .suspend() and .resume(), should
|
|
|
|
* be different from the corresponding runtime PM callbacks, .runtime_suspend(),
|
|
|
|
* and .runtime_resume(), because .runtime_suspend() always works on an already
|
|
|
|
* quiescent device, while .suspend() should assume that the device may be doing
|
|
|
|
* something when it is called (it should ensure that the device will be
|
|
|
|
* quiescent after it has returned). Therefore it's better to point the "late"
|
|
|
|
* suspend and "early" resume callback pointers, .suspend_late() and
|
|
|
|
* .resume_early(), to the same routines as .runtime_suspend() and
|
|
|
|
* .runtime_resume(), respectively (and analogously for hibernation).
|
2022-01-08 02:17:18 +08:00
|
|
|
*
|
2022-01-08 02:17:21 +08:00
|
|
|
* Deprecated. You most likely don't want this macro. Use
|
|
|
|
* DEFINE_RUNTIME_DEV_PM_OPS() instead.
|
2010-03-07 04:28:37 +08:00
|
|
|
*/
|
|
|
|
#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
|
2020-07-16 20:42:49 +08:00
|
|
|
const struct dev_pm_ops __maybe_unused name = { \
|
2010-03-07 04:28:37 +08:00
|
|
|
SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \
|
|
|
|
SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \
|
2009-08-06 05:59:59 +08:00
|
|
|
}
|
|
|
|
|
PM: core: Redefine pm_ptr() macro
The pm_ptr() macro was previously conditionally defined, according to
the value of the CONFIG_PM option. This meant that the pointed structure
was either referenced (if CONFIG_PM was set), or never referenced (if
CONFIG_PM was not set), causing it to be detected as unused by the
compiler.
This worked fine, but required the __maybe_unused compiler attribute to
be used to every symbol pointed to by a pointer wrapped with pm_ptr().
We can do better. With this change, the pm_ptr() is now defined the
same, independently of the value of CONFIG_PM. It now uses the (?:)
ternary operator to conditionally resolve to its argument. Since the
condition is known at compile time, the compiler will then choose to
discard the unused symbols, which won't need to be tagged with
__maybe_unused anymore.
This pm_ptr() macro is usually used with pointers to dev_pm_ops
structures created with SIMPLE_DEV_PM_OPS() or similar macros. These do
use a __maybe_unused flag, which is now useless with this change, so it
later can be removed. However in the meantime it causes no harm, and all
the drivers still compile fine with the new pm_ptr() macro.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:20:59 +08:00
|
|
|
#define pm_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM), (_ptr))
|
PM: core: Add new *_PM_OPS macros, deprecate old ones
This commit introduces the following macros:
SYSTEM_SLEEP_PM_OPS()
LATE_SYSTEM_SLEEP_PM_OPS()
NOIRQ_SYSTEM_SLEEP_PM_OPS()
RUNTIME_PM_OPS()
These new macros are very similar to their SET_*_PM_OPS() equivalent.
They however differ in the fact that the callbacks they set will always
be seen as referenced by the compiler. This means that the callback
functions don't need to be wrapped with a #ifdef CONFIG_PM guard, or
tagged with __maybe_unused, to prevent the compiler from complaining
about unused static symbols. The compiler will then simply evaluate at
compile time whether or not these symbols are dead code.
The callbacks that are only useful with CONFIG_PM_SLEEP is enabled, are
now also wrapped with a new pm_sleep_ptr() macro, which is inspired from
pm_ptr(). This is needed for drivers that use different callbacks for
sleep and runtime PM, to handle the case where CONFIG_PM is set and
CONFIG_PM_SLEEP is not.
This commit also deprecates the following macros:
SIMPLE_DEV_PM_OPS()
UNIVERSAL_DEV_PM_OPS()
And introduces the following macros:
DEFINE_SIMPLE_DEV_PM_OPS()
DEFINE_UNIVERSAL_DEV_PM_OPS()
These macros are similar to the functions they were created to replace,
with the following differences:
- They use the new macros introduced above, and as such always
reference the provided callback functions.
- They are not tagged with __maybe_unused. They are meant to be used
with pm_ptr() or pm_sleep_ptr() for DEFINE_UNIVERSAL_DEV_PM_OPS()
and DEFINE_SIMPLE_DEV_PM_OPS() respectively.
- They declare the symbol static, since every driver seems to do that
anyway; and if a non-static use-case is needed an indirection pointer
could be used.
The point of this change, is to progressively switch from a code model
where PM callbacks are all protected behind CONFIG_PM guards, to a code
model where the PM callbacks are always seen by the compiler, but
discarded if not used.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-07 08:21:00 +08:00
|
|
|
#define pm_sleep_ptr(_ptr) PTR_IF(IS_ENABLED(CONFIG_PM_SLEEP), (_ptr))
|
2020-07-16 20:42:48 +08:00
|
|
|
|
2017-02-02 08:30:49 +08:00
|
|
|
/*
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* PM_EVENT_ messages
|
|
|
|
*
|
|
|
|
* The following PM_EVENT_ messages are defined for the internal use of the PM
|
|
|
|
* core, in order to provide a mechanism allowing the high level suspend and
|
|
|
|
* hibernation code to convey the necessary information to the device PM core
|
|
|
|
* code:
|
|
|
|
*
|
|
|
|
* ON No transition.
|
|
|
|
*
|
2014-03-18 04:26:10 +08:00
|
|
|
* FREEZE System is going to hibernate, call ->prepare() and ->freeze()
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
* for all devices.
|
|
|
|
*
|
|
|
|
* SUSPEND System is going to suspend, call ->prepare() and ->suspend()
|
|
|
|
* for all devices.
|
|
|
|
*
|
|
|
|
* HIBERNATE Hibernation image has been saved, call ->prepare() and
|
|
|
|
* ->poweroff() for all devices.
|
|
|
|
*
|
|
|
|
* QUIESCE Contents of main memory are going to be restored from a (loaded)
|
|
|
|
* hibernation image, call ->prepare() and ->freeze() for all
|
|
|
|
* devices.
|
|
|
|
*
|
|
|
|
* RESUME System is resuming, call ->resume() and ->complete() for all
|
|
|
|
* devices.
|
|
|
|
*
|
|
|
|
* THAW Hibernation image has been created, call ->thaw() and
|
|
|
|
* ->complete() for all devices.
|
|
|
|
*
|
|
|
|
* RESTORE Contents of main memory have been restored from a hibernation
|
|
|
|
* image, call ->restore() and ->complete() for all devices.
|
|
|
|
*
|
|
|
|
* RECOVER Creation of a hibernation image or restoration of the main
|
|
|
|
* memory contents from a hibernation image has failed, call
|
|
|
|
* ->thaw() and ->complete() for all devices.
|
2008-07-24 12:28:37 +08:00
|
|
|
*
|
|
|
|
* The following PM_EVENT_ messages are defined for internal use by
|
|
|
|
* kernel subsystems. They are never issued by the PM core.
|
|
|
|
*
|
|
|
|
* USER_SUSPEND Manual selective suspend was issued by userspace.
|
|
|
|
*
|
|
|
|
* USER_RESUME Manual selective resume was issued by userspace.
|
|
|
|
*
|
|
|
|
* REMOTE_WAKEUP Remote-wakeup request was received from the device.
|
|
|
|
*
|
|
|
|
* AUTO_SUSPEND Automatic (device idle) runtime suspend was
|
|
|
|
* initiated by the subsystem.
|
|
|
|
*
|
|
|
|
* AUTO_RESUME Automatic (device needed) runtime resume was
|
|
|
|
* requested by a driver.
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
*/
|
|
|
|
|
2011-09-30 04:29:44 +08:00
|
|
|
#define PM_EVENT_INVALID (-1)
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
#define PM_EVENT_ON 0x0000
|
2014-03-18 04:26:10 +08:00
|
|
|
#define PM_EVENT_FREEZE 0x0001
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
#define PM_EVENT_SUSPEND 0x0002
|
|
|
|
#define PM_EVENT_HIBERNATE 0x0004
|
|
|
|
#define PM_EVENT_QUIESCE 0x0008
|
|
|
|
#define PM_EVENT_RESUME 0x0010
|
|
|
|
#define PM_EVENT_THAW 0x0020
|
|
|
|
#define PM_EVENT_RESTORE 0x0040
|
|
|
|
#define PM_EVENT_RECOVER 0x0080
|
2008-07-24 12:28:37 +08:00
|
|
|
#define PM_EVENT_USER 0x0100
|
|
|
|
#define PM_EVENT_REMOTE 0x0200
|
|
|
|
#define PM_EVENT_AUTO 0x0400
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
|
2008-07-24 12:28:37 +08:00
|
|
|
#define PM_EVENT_SLEEP (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE)
|
|
|
|
#define PM_EVENT_USER_SUSPEND (PM_EVENT_USER | PM_EVENT_SUSPEND)
|
|
|
|
#define PM_EVENT_USER_RESUME (PM_EVENT_USER | PM_EVENT_RESUME)
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PM_EVENT_REMOTE_RESUME (PM_EVENT_REMOTE | PM_EVENT_RESUME)
|
2008-07-24 12:28:37 +08:00
|
|
|
#define PM_EVENT_AUTO_SUSPEND (PM_EVENT_AUTO | PM_EVENT_SUSPEND)
|
|
|
|
#define PM_EVENT_AUTO_RESUME (PM_EVENT_AUTO | PM_EVENT_RESUME)
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
|
2011-09-30 04:29:44 +08:00
|
|
|
#define PMSG_INVALID ((struct pm_message){ .event = PM_EVENT_INVALID, })
|
2008-07-24 12:28:37 +08:00
|
|
|
#define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, })
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, })
|
|
|
|
#define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, })
|
|
|
|
#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, })
|
|
|
|
#define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, })
|
|
|
|
#define PMSG_RESUME ((struct pm_message){ .event = PM_EVENT_RESUME, })
|
|
|
|
#define PMSG_THAW ((struct pm_message){ .event = PM_EVENT_THAW, })
|
|
|
|
#define PMSG_RESTORE ((struct pm_message){ .event = PM_EVENT_RESTORE, })
|
|
|
|
#define PMSG_RECOVER ((struct pm_message){ .event = PM_EVENT_RECOVER, })
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PMSG_USER_SUSPEND ((struct pm_message) \
|
2008-07-24 12:28:37 +08:00
|
|
|
{ .event = PM_EVENT_USER_SUSPEND, })
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PMSG_USER_RESUME ((struct pm_message) \
|
2008-07-24 12:28:37 +08:00
|
|
|
{ .event = PM_EVENT_USER_RESUME, })
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PMSG_REMOTE_RESUME ((struct pm_message) \
|
2008-07-24 12:28:37 +08:00
|
|
|
{ .event = PM_EVENT_REMOTE_RESUME, })
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PMSG_AUTO_SUSPEND ((struct pm_message) \
|
2008-07-24 12:28:37 +08:00
|
|
|
{ .event = PM_EVENT_AUTO_SUSPEND, })
|
2008-11-18 00:14:19 +08:00
|
|
|
#define PMSG_AUTO_RESUME ((struct pm_message) \
|
2008-07-24 12:28:37 +08:00
|
|
|
{ .event = PM_EVENT_AUTO_RESUME, })
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
|
2011-08-20 05:49:48 +08:00
|
|
|
#define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0)
|
|
|
|
|
2017-02-02 08:30:49 +08:00
|
|
|
/*
|
2009-08-19 05:38:32 +08:00
|
|
|
* Device run-time power management status.
|
|
|
|
*
|
|
|
|
* These status labels are used internally by the PM core to indicate the
|
|
|
|
* current status of a device with respect to the PM core operations. They do
|
|
|
|
* not reflect the actual power state of the device or its status as seen by the
|
|
|
|
* driver.
|
|
|
|
*
|
|
|
|
* RPM_ACTIVE Device is fully operational. Indicates that the device
|
|
|
|
* bus type's ->runtime_resume() callback has completed
|
|
|
|
* successfully.
|
|
|
|
*
|
|
|
|
* RPM_SUSPENDED Device bus type's ->runtime_suspend() callback has
|
|
|
|
* completed successfully. The device is regarded as
|
|
|
|
* suspended.
|
|
|
|
*
|
|
|
|
* RPM_RESUMING Device bus type's ->runtime_resume() callback is being
|
|
|
|
* executed.
|
|
|
|
*
|
|
|
|
* RPM_SUSPENDING Device bus type's ->runtime_suspend() callback is being
|
|
|
|
* executed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum rpm_status {
|
PM: runtime: Capture device status before disabling runtime PM
In some cases (for example, during system-wide suspend and resume of
devices) it is useful to know whether or not runtime PM has ever been
enabled for a given device and, if so, what the runtime PM status of
it had been right before runtime PM was disabled for it last time.
For this reason, introduce a new struct dev_pm_info field called
last_status that will be used for capturing the runtime PM status of
the device when its power.disable_depth counter changes from 0 to 1.
The new field will be set to RPM_INVALID to start with and whenever
power.disable_depth changes from 1 to 0, so it will be valid only
when runtime PM of the device is currently disabled, but it has been
enabled at least once.
Immediately use power.last_status in rpm_resume() to make it handle
the case when PM runtime is disabled for the device, but its runtime
PM status is RPM_ACTIVE more consistently. Namely, make it return 1
if power.last_status is also equal to RPM_ACTIVE in that case (the
idea being that if the status was RPM_ACTIVE last time when
power.disable_depth was changing from 0 to 1 and it is still
RPM_ACTIVE, it can be assumed to reflect what happened to the device
last time when it was using runtime PM) and -EACCES otherwise.
Update the documentation to provide a description of last_status and
change the description of pm_runtime_resume() in it to reflect the
new behavior of rpm_active().
While at it, rearrange the code in pm_runtime_enable() to be more
straightforward and replace the WARN() macro in it with a pr_warn()
invocation which is less disruptive.
Link: https://lore.kernel.org/linux-pm/20211026222626.39222-1-ulf.hansson@linaro.org/t/#u
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-08 02:54:32 +08:00
|
|
|
RPM_INVALID = -1,
|
2009-08-19 05:38:32 +08:00
|
|
|
RPM_ACTIVE = 0,
|
|
|
|
RPM_RESUMING,
|
|
|
|
RPM_SUSPENDED,
|
|
|
|
RPM_SUSPENDING,
|
|
|
|
};
|
|
|
|
|
2017-02-02 08:30:49 +08:00
|
|
|
/*
|
2009-08-19 05:38:32 +08:00
|
|
|
* Device run-time power management request types.
|
|
|
|
*
|
|
|
|
* RPM_REQ_NONE Do nothing.
|
|
|
|
*
|
|
|
|
* RPM_REQ_IDLE Run the device bus type's ->runtime_idle() callback
|
|
|
|
*
|
|
|
|
* RPM_REQ_SUSPEND Run the device bus type's ->runtime_suspend() callback
|
|
|
|
*
|
2010-09-26 05:35:21 +08:00
|
|
|
* RPM_REQ_AUTOSUSPEND Same as RPM_REQ_SUSPEND, but not until the device has
|
|
|
|
* been inactive for as long as power.autosuspend_delay
|
|
|
|
*
|
2009-08-19 05:38:32 +08:00
|
|
|
* RPM_REQ_RESUME Run the device bus type's ->runtime_resume() callback
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum rpm_request {
|
|
|
|
RPM_REQ_NONE = 0,
|
|
|
|
RPM_REQ_IDLE,
|
|
|
|
RPM_REQ_SUSPEND,
|
2010-09-26 05:35:21 +08:00
|
|
|
RPM_REQ_AUTOSUSPEND,
|
2009-08-19 05:38:32 +08:00
|
|
|
RPM_REQ_RESUME,
|
|
|
|
};
|
|
|
|
|
2010-09-23 04:09:10 +08:00
|
|
|
struct wakeup_source;
|
PM / Wakeirq: Add automated device wake IRQ handling
Turns out we can automate the handling for the device_may_wakeup()
quite a bit by using the kernel wakeup source list as suggested
by Rafael J. Wysocki <rjw@rjwysocki.net>.
And as some hardware has separate dedicated wake-up interrupt
in addition to the IO interrupt, we can automate the handling by
adding a generic threaded interrupt handler that just calls the
device PM runtime to wake up the device.
This allows dropping code from device drivers as we currently
are doing it in multiple ways, and often wrong.
For most drivers, we should be able to drop the following
boilerplate code from runtime_suspend and runtime_resume
functions:
...
device_init_wakeup(dev, true);
...
if (device_may_wakeup(dev))
enable_irq_wake(irq);
...
if (device_may_wakeup(dev))
disable_irq_wake(irq);
...
device_init_wakeup(dev, false);
...
We can replace it with just the following init and exit
time code:
...
device_init_wakeup(dev, true);
dev_pm_set_wake_irq(dev, irq);
...
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
...
And for hardware with dedicated wake-up interrupts:
...
device_init_wakeup(dev, true);
dev_pm_set_dedicated_wake_irq(dev, irq);
...
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
...
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-19 06:40:29 +08:00
|
|
|
struct wake_irq;
|
2014-11-14 15:41:32 +08:00
|
|
|
struct pm_domain_data;
|
2011-08-25 21:34:12 +08:00
|
|
|
|
2011-08-25 21:33:50 +08:00
|
|
|
struct pm_subsys_data {
|
|
|
|
spinlock_t lock;
|
2011-08-25 21:34:01 +08:00
|
|
|
unsigned int refcount;
|
2011-08-25 21:33:50 +08:00
|
|
|
#ifdef CONFIG_PM_CLK
|
2021-01-26 03:29:18 +08:00
|
|
|
unsigned int clock_op_might_sleep;
|
|
|
|
struct mutex clock_mutex;
|
2011-08-25 21:33:50 +08:00
|
|
|
struct list_head clock_list;
|
|
|
|
#endif
|
2011-08-25 21:34:12 +08:00
|
|
|
#ifdef CONFIG_PM_GENERIC_DOMAINS
|
2011-09-27 02:22:02 +08:00
|
|
|
struct pm_domain_data *domain_data;
|
2011-08-25 21:34:12 +08:00
|
|
|
#endif
|
2011-08-25 21:33:50 +08:00
|
|
|
};
|
|
|
|
|
PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags
The motivation for this change is to provide a way to work around
a problem with the direct-complete mechanism used for avoiding
system suspend/resume handling for devices in runtime suspend.
The problem is that some middle layer code (the PCI bus type and
the ACPI PM domain in particular) returns positive values from its
system suspend ->prepare callbacks regardless of whether the driver's
->prepare returns a positive value or 0, which effectively prevents
drivers from being able to control the direct-complete feature.
Some drivers need that control, however, and the PCI bus type has
grown its own flag to deal with this issue, but since it is not
limited to PCI, it is better to address it by adding driver flags at
the core level.
To that end, add a driver_flags field to struct dev_pm_info for flags
that can be set by device drivers at the probe time to inform the PM
core and/or bus types, PM domains and so on on the capabilities and/or
preferences of device drivers. Also add two static inline helpers
for setting that field and testing it against a given set of flags
and make the driver core clear it automatically on driver remove
and probe failures.
Define and document two PM driver flags related to the direct-
complete feature: NEVER_SKIP and SMART_PREPARE that can be used,
respectively, to indicate to the PM core that the direct-complete
mechanism should never be used for the device and to inform the
middle layer code (bus types, PM domains etc) that it can only
request the PM core to use the direct-complete mechanism for
the device (by returning a positive value from its ->prepare
callback) if it also has been requested by the driver.
While at it, make the core check pm_runtime_suspended() when
setting power.direct_complete so that it doesn't need to be
checked by ->prepare callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-10-25 20:12:29 +08:00
|
|
|
/*
|
|
|
|
* Driver flags to control system suspend/resume behavior.
|
|
|
|
*
|
|
|
|
* These flags can be set by device drivers at the probe time. They need not be
|
|
|
|
* cleared by the drivers as the driver core will take care of that.
|
|
|
|
*
|
2020-04-19 00:53:01 +08:00
|
|
|
* NO_DIRECT_COMPLETE: Do not apply direct-complete optimization to the device.
|
2020-04-19 00:55:32 +08:00
|
|
|
* SMART_PREPARE: Take the driver ->prepare callback return value into account.
|
|
|
|
* SMART_SUSPEND: Avoid resuming the device from runtime suspend.
|
|
|
|
* MAY_SKIP_RESUME: Allow driver "noirq" and "early" callbacks to be skipped.
|
|
|
|
*
|
|
|
|
* See Documentation/driver-api/pm/devices.rst for details.
|
PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags
The motivation for this change is to provide a way to work around
a problem with the direct-complete mechanism used for avoiding
system suspend/resume handling for devices in runtime suspend.
The problem is that some middle layer code (the PCI bus type and
the ACPI PM domain in particular) returns positive values from its
system suspend ->prepare callbacks regardless of whether the driver's
->prepare returns a positive value or 0, which effectively prevents
drivers from being able to control the direct-complete feature.
Some drivers need that control, however, and the PCI bus type has
grown its own flag to deal with this issue, but since it is not
limited to PCI, it is better to address it by adding driver flags at
the core level.
To that end, add a driver_flags field to struct dev_pm_info for flags
that can be set by device drivers at the probe time to inform the PM
core and/or bus types, PM domains and so on on the capabilities and/or
preferences of device drivers. Also add two static inline helpers
for setting that field and testing it against a given set of flags
and make the driver core clear it automatically on driver remove
and probe failures.
Define and document two PM driver flags related to the direct-
complete feature: NEVER_SKIP and SMART_PREPARE that can be used,
respectively, to indicate to the PM core that the direct-complete
mechanism should never be used for the device and to inform the
middle layer code (bus types, PM domains etc) that it can only
request the PM core to use the direct-complete mechanism for
the device (by returning a positive value from its ->prepare
callback) if it also has been requested by the driver.
While at it, make the core check pm_runtime_suspended() when
setting power.direct_complete so that it doesn't need to be
checked by ->prepare callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-10-25 20:12:29 +08:00
|
|
|
*/
|
2020-04-19 00:53:01 +08:00
|
|
|
#define DPM_FLAG_NO_DIRECT_COMPLETE BIT(0)
|
2017-11-18 22:31:49 +08:00
|
|
|
#define DPM_FLAG_SMART_PREPARE BIT(1)
|
|
|
|
#define DPM_FLAG_SMART_SUSPEND BIT(2)
|
2020-04-19 00:53:20 +08:00
|
|
|
#define DPM_FLAG_MAY_SKIP_RESUME BIT(3)
|
PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags
The motivation for this change is to provide a way to work around
a problem with the direct-complete mechanism used for avoiding
system suspend/resume handling for devices in runtime suspend.
The problem is that some middle layer code (the PCI bus type and
the ACPI PM domain in particular) returns positive values from its
system suspend ->prepare callbacks regardless of whether the driver's
->prepare returns a positive value or 0, which effectively prevents
drivers from being able to control the direct-complete feature.
Some drivers need that control, however, and the PCI bus type has
grown its own flag to deal with this issue, but since it is not
limited to PCI, it is better to address it by adding driver flags at
the core level.
To that end, add a driver_flags field to struct dev_pm_info for flags
that can be set by device drivers at the probe time to inform the PM
core and/or bus types, PM domains and so on on the capabilities and/or
preferences of device drivers. Also add two static inline helpers
for setting that field and testing it against a given set of flags
and make the driver core clear it automatically on driver remove
and probe failures.
Define and document two PM driver flags related to the direct-
complete feature: NEVER_SKIP and SMART_PREPARE that can be used,
respectively, to indicate to the PM core that the direct-complete
mechanism should never be used for the device and to inform the
middle layer code (bus types, PM domains etc) that it can only
request the PM core to use the direct-complete mechanism for
the device (by returning a positive value from its ->prepare
callback) if it also has been requested by the driver.
While at it, make the core check pm_runtime_suspended() when
setting power.direct_complete so that it doesn't need to be
checked by ->prepare callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-10-25 20:12:29 +08:00
|
|
|
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
struct dev_pm_info {
|
|
|
|
pm_message_t power_state;
|
2009-08-19 05:38:32 +08:00
|
|
|
unsigned int can_wakeup:1;
|
2010-12-16 07:51:21 +08:00
|
|
|
unsigned int async_suspend:1;
|
driver core: Functional dependencies tracking support
Currently, there is a problem with taking functional dependencies
between devices into account.
What I mean by a "functional dependency" is when the driver of device
B needs device A to be functional and (generally) its driver to be
present in order to work properly. This has certain consequences
for power management (suspend/resume and runtime PM ordering) and
shutdown ordering of these devices. In general, it also implies that
the driver of A needs to be working for B to be probed successfully
and it cannot be unbound from the device before the B's driver.
Support for representing those functional dependencies between
devices is added here to allow the driver core to track them and act
on them in certain cases where applicable.
The argument for doing that in the driver core is that there are
quite a few distinct use cases involving device dependencies, they
are relatively hard to get right in a driver (if one wants to
address all of them properly) and it only gets worse if multiplied
by the number of drivers potentially needing to do it. Morever, at
least one case (asynchronous system suspend/resume) cannot be handled
in a single driver at all, because it requires the driver of A to
wait for B to suspend (during system suspend) and the driver of B to
wait for A to resume (during system resume).
For this reason, represent dependencies between devices as "links",
with the help of struct device_link objects each containing pointers
to the "linked" devices, a list node for each of them, status
information, flags, and an RCU head for synchronization.
Also add two new list heads, representing the lists of links to the
devices that depend on the given one (consumers) and to the devices
depended on by it (suppliers), and a "driver presence status" field
(needed for figuring out initial states of device links) to struct
device.
The entire data structure consisting of all of the lists of link
objects for all devices is protected by a mutex (for link object
addition/removal and for list walks during device driver probing
and removal) and by SRCU (for list walking in other case that will
be introduced by subsequent change sets). If CONFIG_SRCU is not
selected, however, an rwsem is used for protecting the entire data
structure.
In addition, each link object has an internal status field whose
value reflects whether or not drivers are bound to the devices
pointed to by the link or probing/removal of their drivers is in
progress etc. That field is only modified under the device links
mutex, but it may be read outside of it in some cases (introduced by
subsequent change sets), so modifications of it are annotated with
WRITE_ONCE().
New links are added by calling device_link_add() which takes three
arguments: pointers to the devices in question and flags. In
particular, if DL_FLAG_STATELESS is set in the flags, the link status
is not to be taken into account for this link and the driver core
will not manage it. In turn, if DL_FLAG_AUTOREMOVE is set in the
flags, the driver core will remove the link automatically when the
consumer device driver unbinds from it.
One of the actions carried out by device_link_add() is to reorder
the lists used for device shutdown and system suspend/resume to
put the consumer device along with all of its children and all of
its consumers (and so on, recursively) to the ends of those lists
in order to ensure the right ordering between all of the supplier
and consumer devices.
For this reason, it is not possible to create a link between two
devices if the would-be supplier device already depends on the
would-be consumer device as either a direct descendant of it or a
consumer of one of its direct descendants or one of its consumers
and so on.
There are two types of link objects, persistent and non-persistent.
The persistent ones stay around until one of the target devices is
deleted, while the non-persistent ones are removed automatically when
the consumer driver unbinds from its device (ie. they are assumed to
be valid only as long as the consumer device has a driver bound to
it). Persistent links are created by default and non-persistent
links are created when the DL_FLAG_AUTOREMOVE flag is passed
to device_link_add().
Both persistent and non-persistent device links can be deleted
with an explicit call to device_link_del().
Links created without the DL_FLAG_STATELESS flag set are managed
by the driver core using a simple state machine. There are 5 states
each link can be in: DORMANT (unused), AVAILABLE (the supplier driver
is present and functional), CONSUMER_PROBE (the consumer driver is
probing), ACTIVE (both supplier and consumer drivers are present and
functional), and SUPPLIER_UNBIND (the supplier driver is unbinding).
The driver core updates the link state automatically depending on
what happens to the linked devices and for each link state specific
actions are taken in addition to that.
For example, if the supplier driver unbinds from its device, the
driver core will also unbind the drivers of all of its consumers
automatically under the assumption that they cannot function
properly without the supplier. Analogously, the driver core will
only allow the consumer driver to bind to its device if the
supplier driver is present and functional (ie. the link is in
the AVAILABLE state). If that's not the case, it will rely on
the existing deferred probing mechanism to wait for the supplier
driver to become available.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-10-31 00:32:16 +08:00
|
|
|
bool in_dpm_list:1; /* Owned by the PM core */
|
2011-06-19 02:22:23 +08:00
|
|
|
bool is_prepared:1; /* Owned by the PM core */
|
2011-06-19 04:42:09 +08:00
|
|
|
bool is_suspended:1; /* Ditto */
|
2014-02-18 10:28:44 +08:00
|
|
|
bool is_noirq_suspended:1;
|
|
|
|
bool is_late_suspended:1;
|
2019-02-15 02:29:10 +08:00
|
|
|
bool no_pm:1;
|
2012-08-06 07:45:11 +08:00
|
|
|
bool early_init:1; /* Owned by the PM core */
|
PM / sleep: Mechanism to avoid resuming runtime-suspended devices unnecessarily
Currently, some subsystems (e.g. PCI and the ACPI PM domain) have to
resume all runtime-suspended devices during system suspend, mostly
because those devices may need to be reprogrammed due to different
wakeup settings for system sleep and for runtime PM.
For some devices, though, it's OK to remain in runtime suspend
throughout a complete system suspend/resume cycle (if the device was in
runtime suspend at the start of the cycle). We would like to do this
whenever possible, to avoid the overhead of extra power-up and power-down
events.
However, problems may arise because the device's descendants may require
it to be at full power at various points during the cycle. Therefore the
most straightforward way to do this safely is if the device and all its
descendants can remain runtime suspended until the complete stage of
system resume.
To this end, introduce a new device PM flag, power.direct_complete
and modify the PM core to use that flag as follows.
If the ->prepare() callback of a device returns a positive number,
the PM core will regard that as an indication that it may leave the
device runtime-suspended. It will then check if the system power
transition in progress is a suspend (and not hibernation in particular)
and if the device is, indeed, runtime-suspended. In that case, the PM
core will set the device's power.direct_complete flag. Otherwise it
will clear power.direct_complete for the device and it also will later
clear it for the device's parent (if there's one).
Next, the PM core will not invoke the ->suspend() ->suspend_late(),
->suspend_irq(), ->resume_irq(), ->resume_early(), or ->resume()
callbacks for all devices having power.direct_complete set. It
will invoke their ->complete() callbacks, however, and those
callbacks are then responsible for resuming the devices as
appropriate, if necessary. For example, in some cases they may
need to queue up runtime resume requests for the devices using
pm_request_resume().
Changelog partly based on an Alan Stern's description of the idea
(http://marc.info/?l=linux-pm&m=139940466625569&w=2).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
2014-05-16 08:46:50 +08:00
|
|
|
bool direct_complete:1; /* Owned by the PM core */
|
PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags
The motivation for this change is to provide a way to work around
a problem with the direct-complete mechanism used for avoiding
system suspend/resume handling for devices in runtime suspend.
The problem is that some middle layer code (the PCI bus type and
the ACPI PM domain in particular) returns positive values from its
system suspend ->prepare callbacks regardless of whether the driver's
->prepare returns a positive value or 0, which effectively prevents
drivers from being able to control the direct-complete feature.
Some drivers need that control, however, and the PCI bus type has
grown its own flag to deal with this issue, but since it is not
limited to PCI, it is better to address it by adding driver flags at
the core level.
To that end, add a driver_flags field to struct dev_pm_info for flags
that can be set by device drivers at the probe time to inform the PM
core and/or bus types, PM domains and so on on the capabilities and/or
preferences of device drivers. Also add two static inline helpers
for setting that field and testing it against a given set of flags
and make the driver core clear it automatically on driver remove
and probe failures.
Define and document two PM driver flags related to the direct-
complete feature: NEVER_SKIP and SMART_PREPARE that can be used,
respectively, to indicate to the PM core that the direct-complete
mechanism should never be used for the device and to inform the
middle layer code (bus types, PM domains etc) that it can only
request the PM core to use the direct-complete mechanism for
the device (by returning a positive value from its ->prepare
callback) if it also has been requested by the driver.
While at it, make the core check pm_runtime_suspended() when
setting power.direct_complete so that it doesn't need to be
checked by ->prepare callbacks.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-10-25 20:12:29 +08:00
|
|
|
u32 driver_flags;
|
2010-09-23 04:09:10 +08:00
|
|
|
spinlock_t lock;
|
2009-08-19 05:38:32 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
struct list_head entry;
|
PM: Asynchronous suspend and resume of devices
Theoretically, the total time of system sleep transitions (suspend
to RAM, hibernation) can be reduced by running suspend and resume
callbacks of device drivers in parallel with each other. However,
there are dependencies between devices such that we're not allowed
to suspend the parent of a device before suspending the device
itself. Analogously, we're not allowed to resume a device before
resuming its parent.
The most straightforward way to take these dependencies into accout
is to start the async threads used for suspending and resuming
devices at the core level, so that async_schedule() is called for
each suspend and resume callback supposed to be executed
asynchronously.
For this purpose, introduce a new device flag, power.async_suspend,
used to mark the devices whose suspend and resume callbacks are to be
executed asynchronously (ie. in parallel with the main suspend/resume
thread and possibly in parallel with each other) and helper function
device_enable_async_suspend() allowing one to set power.async_suspend
for given device (power.async_suspend is unset by default for all
devices). For each device with the power.async_suspend flag set the
PM core will use async_schedule() to execute its suspend and resume
callbacks.
The async threads started for different devices as a result of
calling async_schedule() are synchronized with each other and with
the main suspend/resume thread with the help of completions, in the
following way:
(1) There is a completion, power.completion, for each device object.
(2) Each device's completion is reset before calling async_schedule()
for the device or, in the case of devices with the
power.async_suspend flags unset, before executing the device's
suspend and resume callbacks.
(3) During suspend, right before running the bus type, device type
and device class suspend callbacks for the device, the PM core
waits for the completions of all the device's children to be
completed.
(4) During resume, right before running the bus type, device type and
device class resume callbacks for the device, the PM core waits
for the completion of the device's parent to be completed.
(5) The PM core completes power.completion for each device right
after the bus type, device type and device class suspend (or
resume) callbacks executed for the device have returned.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2010-01-24 05:23:32 +08:00
|
|
|
struct completion completion;
|
2010-09-23 04:09:10 +08:00
|
|
|
struct wakeup_source *wakeup;
|
2011-10-17 05:34:36 +08:00
|
|
|
bool wakeup_path:1;
|
2012-08-13 20:00:25 +08:00
|
|
|
bool syscore:1;
|
2016-01-07 23:46:14 +08:00
|
|
|
bool no_pm_callbacks:1; /* Owned by the PM core */
|
2017-11-18 22:31:49 +08:00
|
|
|
unsigned int must_resume:1; /* Owned by the PM core */
|
|
|
|
unsigned int may_skip_resume:1; /* Set by subsystems */
|
2011-02-24 18:10:01 +08:00
|
|
|
#else
|
|
|
|
unsigned int should_wakeup:1;
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
#endif
|
2014-11-28 05:38:05 +08:00
|
|
|
#ifdef CONFIG_PM
|
2018-12-14 22:22:25 +08:00
|
|
|
struct hrtimer suspend_timer;
|
2020-09-19 00:55:18 +08:00
|
|
|
u64 timer_expires;
|
2009-08-19 05:38:32 +08:00
|
|
|
struct work_struct work;
|
|
|
|
wait_queue_head_t wait_queue;
|
PM / Wakeirq: Add automated device wake IRQ handling
Turns out we can automate the handling for the device_may_wakeup()
quite a bit by using the kernel wakeup source list as suggested
by Rafael J. Wysocki <rjw@rjwysocki.net>.
And as some hardware has separate dedicated wake-up interrupt
in addition to the IO interrupt, we can automate the handling by
adding a generic threaded interrupt handler that just calls the
device PM runtime to wake up the device.
This allows dropping code from device drivers as we currently
are doing it in multiple ways, and often wrong.
For most drivers, we should be able to drop the following
boilerplate code from runtime_suspend and runtime_resume
functions:
...
device_init_wakeup(dev, true);
...
if (device_may_wakeup(dev))
enable_irq_wake(irq);
...
if (device_may_wakeup(dev))
disable_irq_wake(irq);
...
device_init_wakeup(dev, false);
...
We can replace it with just the following init and exit
time code:
...
device_init_wakeup(dev, true);
dev_pm_set_wake_irq(dev, irq);
...
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
...
And for hardware with dedicated wake-up interrupts:
...
device_init_wakeup(dev, true);
dev_pm_set_dedicated_wake_irq(dev, irq);
...
dev_pm_clear_wake_irq(dev);
device_init_wakeup(dev, false);
...
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2015-05-19 06:40:29 +08:00
|
|
|
struct wake_irq *wakeirq;
|
2009-08-19 05:38:32 +08:00
|
|
|
atomic_t usage_count;
|
|
|
|
atomic_t child_count;
|
|
|
|
unsigned int disable_depth:3;
|
|
|
|
unsigned int idle_notification:1;
|
|
|
|
unsigned int request_pending:1;
|
|
|
|
unsigned int deferred_resume:1;
|
2021-05-05 19:09:15 +08:00
|
|
|
unsigned int needs_force_resume:1;
|
2010-01-24 05:02:51 +08:00
|
|
|
unsigned int runtime_auto:1;
|
2016-04-08 19:40:53 +08:00
|
|
|
bool ignore_children:1;
|
2010-09-26 05:35:15 +08:00
|
|
|
unsigned int no_callbacks:1;
|
2010-12-01 07:14:42 +08:00
|
|
|
unsigned int irq_safe:1;
|
2010-09-26 05:35:21 +08:00
|
|
|
unsigned int use_autosuspend:1;
|
|
|
|
unsigned int timer_autosuspends:1;
|
2013-02-23 08:34:11 +08:00
|
|
|
unsigned int memalloc_noio:1;
|
2016-10-31 00:32:43 +08:00
|
|
|
unsigned int links_count;
|
2009-08-19 05:38:32 +08:00
|
|
|
enum rpm_request request;
|
|
|
|
enum rpm_status runtime_status;
|
PM: runtime: Capture device status before disabling runtime PM
In some cases (for example, during system-wide suspend and resume of
devices) it is useful to know whether or not runtime PM has ever been
enabled for a given device and, if so, what the runtime PM status of
it had been right before runtime PM was disabled for it last time.
For this reason, introduce a new struct dev_pm_info field called
last_status that will be used for capturing the runtime PM status of
the device when its power.disable_depth counter changes from 0 to 1.
The new field will be set to RPM_INVALID to start with and whenever
power.disable_depth changes from 1 to 0, so it will be valid only
when runtime PM of the device is currently disabled, but it has been
enabled at least once.
Immediately use power.last_status in rpm_resume() to make it handle
the case when PM runtime is disabled for the device, but its runtime
PM status is RPM_ACTIVE more consistently. Namely, make it return 1
if power.last_status is also equal to RPM_ACTIVE in that case (the
idea being that if the status was RPM_ACTIVE last time when
power.disable_depth was changing from 0 to 1 and it is still
RPM_ACTIVE, it can be assumed to reflect what happened to the device
last time when it was using runtime PM) and -EACCES otherwise.
Update the documentation to provide a description of last_status and
change the description of pm_runtime_resume() in it to reflect the
new behavior of rpm_active().
While at it, rearrange the code in pm_runtime_enable() to be more
straightforward and replace the WARN() macro in it with a pr_warn()
invocation which is less disruptive.
Link: https://lore.kernel.org/linux-pm/20211026222626.39222-1-ulf.hansson@linaro.org/t/#u
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2021-12-08 02:54:32 +08:00
|
|
|
enum rpm_status last_status;
|
2009-08-19 05:38:32 +08:00
|
|
|
int runtime_error;
|
2010-09-26 05:35:21 +08:00
|
|
|
int autosuspend_delay;
|
2018-12-14 22:22:25 +08:00
|
|
|
u64 last_busy;
|
2019-01-23 15:50:14 +08:00
|
|
|
u64 active_time;
|
|
|
|
u64 suspended_time;
|
|
|
|
u64 accounting_timestamp;
|
2009-08-19 05:38:32 +08:00
|
|
|
#endif
|
2011-08-25 21:33:50 +08:00
|
|
|
struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
void (*set_latency_tolerance)(struct device *, s32);
|
2012-10-23 07:07:27 +08:00
|
|
|
struct dev_pm_qos *qos;
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
};
|
|
|
|
|
2011-08-25 21:34:01 +08:00
|
|
|
extern int dev_pm_get_subsys_data(struct device *dev);
|
2015-01-30 01:39:05 +08:00
|
|
|
extern void dev_pm_put_subsys_data(struct device *dev);
|
2010-07-19 08:01:06 +08:00
|
|
|
|
2017-02-02 08:30:49 +08:00
|
|
|
/**
|
|
|
|
* struct dev_pm_domain - power management domain representation.
|
driver core / PM: Add PM domain callbacks for device setup/cleanup
If PM domains are in use, it may be necessary to prepare the code
handling a PM domain for driver probing. For example, in some
cases device drivers rely on the ability to power on the devices
with the help of the IO runtime PM framework and the PM domain
code needs to be ready for that. Also, if that code has not been
fully initialized yet, the driver probing should be deferred.
Moreover, after the probing is complete, it may be necessary to
put the PM domain in question into the state reflecting the current
needs of the devices in it, for example, so that power is not drawn
in vain. The same should be done after removing a driver from
a device, as the PM domain state may need to be changed to reflect
the new situation.
For these reasons, introduce new PM domain callbacks, ->activate,
->sync and ->dismiss called, respectively, before probing for a
device driver, after the probing has completed successfully and
if the probing has failed or the driver has been removed.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-20 20:59:27 +08:00
|
|
|
*
|
2017-02-02 08:30:49 +08:00
|
|
|
* @ops: Power management operations associated with this domain.
|
PM / Domains: Introduce dev_pm_domain_start()
For a subsystem/driver that either doesn't support runtime PM or makes use
of pm_runtime_set_active() during ->probe(), may try to access its device
when probing, even if it may not be fully powered on from the PM domain's
point of view. This may be the case when the used PM domain is a genpd
provider, that implements genpd's ->start|stop() device callbacks.
There are cases where the subsystem/driver managed to avoid the above
problem, simply by calling pm_runtime_enable() and pm_runtime_get_sync()
during ->probe(). However, this approach comes with a drawback, especially
if the subsystem/driver implements a ->runtime_resume() callback.
More precisely, the subsystem/driver then needs to use a device flag, which
is checked in its ->runtime_resume() callback, as to avoid powering on its
resources the first time the callback is invoked. This is needed because
the subsystem/driver has already powered on the resources for the device,
during ->probe() and before it called pm_runtime_get_sync().
In a way to avoid this boilerplate code and the inefficient check for "if
(first_time_suspend)" in the ->runtime_resume() callback for these
subsystems/drivers, let's introduce and export a dev_pm_domain_start()
function, that may be called during ->probe() instead.
Moreover, let the dev_pm_domain_start() invoke an optional ->start()
callback, added to the struct dev_pm_domain, as to allow a PM domain
specific implementation.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-10-16 21:16:03 +08:00
|
|
|
* @start: Called when a user needs to start the device via the domain.
|
driver core / PM: Add PM domain callbacks for device setup/cleanup
If PM domains are in use, it may be necessary to prepare the code
handling a PM domain for driver probing. For example, in some
cases device drivers rely on the ability to power on the devices
with the help of the IO runtime PM framework and the PM domain
code needs to be ready for that. Also, if that code has not been
fully initialized yet, the driver probing should be deferred.
Moreover, after the probing is complete, it may be necessary to
put the PM domain in question into the state reflecting the current
needs of the devices in it, for example, so that power is not drawn
in vain. The same should be done after removing a driver from
a device, as the PM domain state may need to be changed to reflect
the new situation.
For these reasons, introduce new PM domain callbacks, ->activate,
->sync and ->dismiss called, respectively, before probing for a
device driver, after the probing has completed successfully and
if the probing has failed or the driver has been removed.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-20 20:59:27 +08:00
|
|
|
* @detach: Called when removing a device from the domain.
|
|
|
|
* @activate: Called before executing probe routines for bus types and drivers.
|
|
|
|
* @sync: Called after successful driver probe.
|
|
|
|
* @dismiss: Called after unsuccessful driver probe and after driver removal.
|
2017-02-02 08:30:49 +08:00
|
|
|
*
|
|
|
|
* Power domains provide callbacks that are executed during system suspend,
|
|
|
|
* hibernation, system resume and during runtime PM transitions instead of
|
|
|
|
* subsystem-level and driver-level callbacks.
|
2011-02-17 04:53:17 +08:00
|
|
|
*/
|
2011-06-23 07:52:55 +08:00
|
|
|
struct dev_pm_domain {
|
2011-02-17 04:53:17 +08:00
|
|
|
struct dev_pm_ops ops;
|
PM / Domains: Introduce dev_pm_domain_start()
For a subsystem/driver that either doesn't support runtime PM or makes use
of pm_runtime_set_active() during ->probe(), may try to access its device
when probing, even if it may not be fully powered on from the PM domain's
point of view. This may be the case when the used PM domain is a genpd
provider, that implements genpd's ->start|stop() device callbacks.
There are cases where the subsystem/driver managed to avoid the above
problem, simply by calling pm_runtime_enable() and pm_runtime_get_sync()
during ->probe(). However, this approach comes with a drawback, especially
if the subsystem/driver implements a ->runtime_resume() callback.
More precisely, the subsystem/driver then needs to use a device flag, which
is checked in its ->runtime_resume() callback, as to avoid powering on its
resources the first time the callback is invoked. This is needed because
the subsystem/driver has already powered on the resources for the device,
during ->probe() and before it called pm_runtime_get_sync().
In a way to avoid this boilerplate code and the inefficient check for "if
(first_time_suspend)" in the ->runtime_resume() callback for these
subsystems/drivers, let's introduce and export a dev_pm_domain_start()
function, that may be called during ->probe() instead.
Moreover, let the dev_pm_domain_start() invoke an optional ->start()
callback, added to the struct dev_pm_domain, as to allow a PM domain
specific implementation.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2019-10-16 21:16:03 +08:00
|
|
|
int (*start)(struct device *dev);
|
2014-09-20 02:27:34 +08:00
|
|
|
void (*detach)(struct device *dev, bool power_off);
|
driver core / PM: Add PM domain callbacks for device setup/cleanup
If PM domains are in use, it may be necessary to prepare the code
handling a PM domain for driver probing. For example, in some
cases device drivers rely on the ability to power on the devices
with the help of the IO runtime PM framework and the PM domain
code needs to be ready for that. Also, if that code has not been
fully initialized yet, the driver probing should be deferred.
Moreover, after the probing is complete, it may be necessary to
put the PM domain in question into the state reflecting the current
needs of the devices in it, for example, so that power is not drawn
in vain. The same should be done after removing a driver from
a device, as the PM domain state may need to be changed to reflect
the new situation.
For these reasons, introduce new PM domain callbacks, ->activate,
->sync and ->dismiss called, respectively, before probing for a
device driver, after the probing has completed successfully and
if the probing has failed or the driver has been removed.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-03-20 20:59:27 +08:00
|
|
|
int (*activate)(struct device *dev);
|
|
|
|
void (*sync)(struct device *dev);
|
|
|
|
void (*dismiss)(struct device *dev);
|
2011-02-17 04:53:17 +08:00
|
|
|
};
|
2010-07-19 08:01:06 +08:00
|
|
|
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
/*
|
|
|
|
* The PM_EVENT_ messages are also used by drivers implementing the legacy
|
|
|
|
* suspend framework, based on the ->suspend() and ->resume() callbacks common
|
|
|
|
* for suspend and hibernation transitions, according to the rules below.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Necessary, because several drivers use PM_EVENT_PRETHAW */
|
|
|
|
#define PM_EVENT_PRETHAW PM_EVENT_QUIESCE
|
|
|
|
|
|
|
|
/*
|
2006-08-15 14:11:04 +08:00
|
|
|
* One transition is triggered by resume(), after a suspend() call; the
|
|
|
|
* message is implicit:
|
|
|
|
*
|
|
|
|
* ON Driver starts working again, responding to hardware events
|
2014-03-18 04:26:10 +08:00
|
|
|
* and software requests. The hardware may have gone through
|
|
|
|
* a power-off reset, or it may have maintained state from the
|
|
|
|
* previous suspend() which the driver will rely on while
|
|
|
|
* resuming. On most platforms, there are no restrictions on
|
|
|
|
* availability of resources like clocks during resume().
|
2006-08-15 14:11:04 +08:00
|
|
|
*
|
|
|
|
* Other transitions are triggered by messages sent using suspend(). All
|
|
|
|
* these transitions quiesce the driver, so that I/O queues are inactive.
|
|
|
|
* That commonly entails turning off IRQs and DMA; there may be rules
|
|
|
|
* about how to quiesce that are specific to the bus or the device's type.
|
|
|
|
* (For example, network drivers mark the link state.) Other details may
|
|
|
|
* differ according to the message:
|
|
|
|
*
|
|
|
|
* SUSPEND Quiesce, enter a low power device state appropriate for
|
2014-03-18 04:26:10 +08:00
|
|
|
* the upcoming system state (such as PCI_D3hot), and enable
|
|
|
|
* wakeup events as appropriate.
|
2006-08-15 14:11:04 +08:00
|
|
|
*
|
2008-02-24 02:13:25 +08:00
|
|
|
* HIBERNATE Enter a low power device state appropriate for the hibernation
|
2014-03-18 04:26:10 +08:00
|
|
|
* state (eg. ACPI S4) and enable wakeup events as appropriate.
|
2008-02-24 02:13:25 +08:00
|
|
|
*
|
2006-08-15 14:11:04 +08:00
|
|
|
* FREEZE Quiesce operations so that a consistent image can be saved;
|
2014-03-18 04:26:10 +08:00
|
|
|
* but do NOT otherwise enter a low power device state, and do
|
|
|
|
* NOT emit system wakeup events.
|
2006-08-15 14:11:04 +08:00
|
|
|
*
|
|
|
|
* PRETHAW Quiesce as if for FREEZE; additionally, prepare for restoring
|
2014-03-18 04:26:10 +08:00
|
|
|
* the system from a snapshot taken after an earlier FREEZE.
|
|
|
|
* Some drivers will need to reset their hardware state instead
|
|
|
|
* of preserving it, to ensure that it's never mistaken for the
|
|
|
|
* state which that earlier snapshot had set up.
|
2006-08-15 14:11:04 +08:00
|
|
|
*
|
|
|
|
* A minimally power-aware driver treats all messages as SUSPEND, fully
|
|
|
|
* reinitializes its device during resume() -- whether or not it was reset
|
|
|
|
* during the suspend/resume cycle -- and can't issue wakeup events.
|
|
|
|
*
|
|
|
|
* More power-aware drivers may also use low power states at runtime as
|
|
|
|
* well as during system sleep states like PM_SUSPEND_STANDBY. They may
|
|
|
|
* be able to use wakeup events to exit from runtime low-power states,
|
|
|
|
* or from system low-power states such as standby or suspend-to-RAM.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
2011-03-24 05:16:41 +08:00
|
|
|
extern void device_pm_lock(void);
|
2012-01-30 03:38:29 +08:00
|
|
|
extern void dpm_resume_start(pm_message_t state);
|
2009-05-25 04:05:42 +08:00
|
|
|
extern void dpm_resume_end(pm_message_t state);
|
2014-09-30 08:21:34 +08:00
|
|
|
extern void dpm_resume_noirq(pm_message_t state);
|
|
|
|
extern void dpm_resume_early(pm_message_t state);
|
2011-05-18 05:26:00 +08:00
|
|
|
extern void dpm_resume(pm_message_t state);
|
|
|
|
extern void dpm_complete(pm_message_t state);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
Introduce new top level suspend and hibernation callbacks
Introduce 'struct pm_ops' and 'struct pm_ext_ops' ('ext' meaning
'extended') representing suspend and hibernation operations for bus
types, device classes, device types and device drivers.
Modify the PM core to use 'struct pm_ops' and 'struct pm_ext_ops'
objects, if defined, instead of the ->suspend(), ->resume(),
->suspend_late(), and ->resume_early() callbacks (the old callbacks
will be considered as legacy and gradually phased out).
The main purpose of doing this is to separate suspend (aka S2RAM and
standby) callbacks from hibernation callbacks in such a way that the
new callbacks won't take arguments and the semantics of each of them
will be clearly specified. This has been requested for multiple
times by many people, including Linus himself, and the reason is that
within the current scheme if ->resume() is called, for example, it's
difficult to say why it's been called (ie. is it a resume from RAM or
from hibernation or a suspend/hibernation failure etc.?).
The second purpose is to make the suspend/hibernation callbacks more
flexible so that device drivers can handle more than they can within
the current scheme. For example, some drivers may need to prevent
new children of the device from being registered before their
->suspend() callbacks are executed or they may want to carry out some
operations requiring the availability of some other devices, not
directly bound via the parent-child relationship, in order to prepare
for the execution of ->suspend(), etc.
Ultimately, we'd like to stop using the freezing of tasks for suspend
and therefore the drivers' suspend/hibernation code will have to take
care of the handling of the user space during suspend/hibernation.
That, in turn, would be difficult within the current scheme, without
the new ->prepare() and ->complete() callbacks.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
2008-05-21 05:00:01 +08:00
|
|
|
extern void device_pm_unlock(void);
|
2012-01-30 03:38:29 +08:00
|
|
|
extern int dpm_suspend_end(pm_message_t state);
|
2009-05-25 04:05:42 +08:00
|
|
|
extern int dpm_suspend_start(pm_message_t state);
|
2014-09-30 08:21:34 +08:00
|
|
|
extern int dpm_suspend_noirq(pm_message_t state);
|
|
|
|
extern int dpm_suspend_late(pm_message_t state);
|
2011-05-18 05:26:00 +08:00
|
|
|
extern int dpm_suspend(pm_message_t state);
|
|
|
|
extern int dpm_prepare(pm_message_t state);
|
2005-09-13 10:39:34 +08:00
|
|
|
|
2022-03-08 03:07:39 +08:00
|
|
|
extern void __suspend_report_result(const char *function, struct device *dev, void *fn, int ret);
|
2006-03-23 17:38:34 +08:00
|
|
|
|
2022-03-08 03:07:39 +08:00
|
|
|
#define suspend_report_result(dev, fn, ret) \
|
2006-03-23 17:38:34 +08:00
|
|
|
do { \
|
2022-03-08 03:07:39 +08:00
|
|
|
__suspend_report_result(__func__, dev, fn, ret); \
|
2006-03-23 17:38:34 +08:00
|
|
|
} while (0)
|
2005-10-24 14:02:20 +08:00
|
|
|
|
2010-09-23 04:10:57 +08:00
|
|
|
extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);
|
2012-08-17 22:06:59 +08:00
|
|
|
extern void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *));
|
2011-05-18 05:26:21 +08:00
|
|
|
|
|
|
|
extern int pm_generic_prepare(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_suspend_late(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_suspend_noirq(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_suspend(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_resume_early(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_resume_noirq(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_resume(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_freeze_noirq(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_freeze_late(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_freeze(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_thaw_noirq(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_thaw_early(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_thaw(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_restore_noirq(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_restore_early(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_restore(struct device *dev);
|
2011-07-02 04:12:59 +08:00
|
|
|
extern int pm_generic_poweroff_noirq(struct device *dev);
|
2012-01-30 03:38:41 +08:00
|
|
|
extern int pm_generic_poweroff_late(struct device *dev);
|
2011-05-18 05:26:21 +08:00
|
|
|
extern int pm_generic_poweroff(struct device *dev);
|
|
|
|
extern void pm_generic_complete(struct device *dev);
|
|
|
|
|
2020-04-19 00:52:30 +08:00
|
|
|
extern bool dev_pm_skip_resume(struct device *dev);
|
2020-04-19 00:52:48 +08:00
|
|
|
extern bool dev_pm_skip_suspend(struct device *dev);
|
PCI / PM: Take SMART_SUSPEND driver flag into account
Make the PCI bus type take DPM_FLAG_SMART_SUSPEND into account in its
system-wide PM callbacks and make sure that all code that should not
run in parallel with pci_pm_runtime_resume() is executed in the "late"
phases of system suspend, freeze and poweroff transitions.
[Note that the pm_runtime_suspended() check in pci_dev_keep_suspended()
is an optimization, because if is not passed, all of the subsequent
checks may be skipped and some of them are much more overhead in
general.]
Also use the observation that if the device is in runtime suspend
at the beginning of the "late" phase of a system-wide suspend-like
transition, its state cannot change going forward (runtime PM is
disabled for it at that time) until the transition is over and the
subsequent system-wide PM callbacks should be skipped for it (as
they generally assume the device to not be suspended), so add checks
for that in pci_pm_suspend_late/noirq(), pci_pm_freeze_late/noirq()
and pci_pm_poweroff_late/noirq().
Moreover, if pci_pm_resume_noirq() or pci_pm_restore_noirq() is
called during the subsequent system-wide resume transition and if
the device was left in runtime suspend previously, its runtime PM
status needs to be changed to "active" as it is going to be put
into the full-power state, so add checks for that too to these
functions.
In turn, if pci_pm_thaw_noirq() runs after the device has been
left in runtime suspend, the subsequent "thaw" callbacks need
to be skipped for it (as they may not work correctly with a
suspended device), so set the power.direct_complete flag for the
device then to make the PM core skip those callbacks.
In addition to the above add a core helper for checking if
DPM_FLAG_SMART_SUSPEND is set and the device runtime PM status is
"suspended" at the same time, which is done quite often in the new
code (and will be done elsewhere going forward too).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
2017-10-26 18:12:22 +08:00
|
|
|
|
2008-03-20 05:37:42 +08:00
|
|
|
#else /* !CONFIG_PM_SLEEP */
|
|
|
|
|
2009-03-04 19:44:00 +08:00
|
|
|
#define device_pm_lock() do {} while (0)
|
|
|
|
#define device_pm_unlock() do {} while (0)
|
|
|
|
|
2009-05-25 04:05:42 +08:00
|
|
|
static inline int dpm_suspend_start(pm_message_t state)
|
2008-03-20 05:37:42 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-03-08 03:07:39 +08:00
|
|
|
#define suspend_report_result(dev, fn, ret) do {} while (0)
|
2008-03-20 05:37:42 +08:00
|
|
|
|
2010-09-23 04:10:57 +08:00
|
|
|
static inline int device_pm_wait_for_dev(struct device *a, struct device *b)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2011-05-18 05:26:21 +08:00
|
|
|
|
2012-08-17 22:06:59 +08:00
|
|
|
static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-02-19 20:09:21 +08:00
|
|
|
#define pm_generic_prepare NULL
|
|
|
|
#define pm_generic_suspend_late NULL
|
|
|
|
#define pm_generic_suspend_noirq NULL
|
|
|
|
#define pm_generic_suspend NULL
|
|
|
|
#define pm_generic_resume_early NULL
|
|
|
|
#define pm_generic_resume_noirq NULL
|
|
|
|
#define pm_generic_resume NULL
|
|
|
|
#define pm_generic_freeze_noirq NULL
|
|
|
|
#define pm_generic_freeze_late NULL
|
|
|
|
#define pm_generic_freeze NULL
|
|
|
|
#define pm_generic_thaw_noirq NULL
|
|
|
|
#define pm_generic_thaw_early NULL
|
|
|
|
#define pm_generic_thaw NULL
|
|
|
|
#define pm_generic_restore_noirq NULL
|
|
|
|
#define pm_generic_restore_early NULL
|
|
|
|
#define pm_generic_restore NULL
|
|
|
|
#define pm_generic_poweroff_noirq NULL
|
|
|
|
#define pm_generic_poweroff_late NULL
|
|
|
|
#define pm_generic_poweroff NULL
|
|
|
|
#define pm_generic_complete NULL
|
2008-03-20 05:37:42 +08:00
|
|
|
#endif /* !CONFIG_PM_SLEEP */
|
|
|
|
|
2009-03-04 19:44:00 +08:00
|
|
|
/* How to reorder dpm_list after device_move() */
|
|
|
|
enum dpm_order {
|
|
|
|
DPM_ORDER_NONE,
|
|
|
|
DPM_ORDER_DEV_AFTER_PARENT,
|
|
|
|
DPM_ORDER_PARENT_BEFORE_DEV,
|
|
|
|
DPM_ORDER_DEV_LAST,
|
|
|
|
};
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif /* _LINUX_PM_H */
|