Closed gmarull closed 3 years ago
Note that no STM32 drivers implement actual device PM as of today.
Well, gpio driver does... That's PM_DEVICE_RUNTIME actually.
But I agree on the point. We should be able to enable only PM w/o PM_DEVICE
Note that no STM32 drivers implement actual device PM as of today.
~Well, gpio driver does...~ That's PM_DEVICE_RUNTIME actually. But I agree on the point. We should be able to enable only PM w/o PM_DEVICE
You're right, I missed that one.
Note that no STM32 drivers implement actual device PM as of today.
~Well, gpio driver does...~ That's PM_DEVICE_RUNTIME actually. But I agree on the point. We should be able to enable only PM w/o PM_DEVICE
Actually, the code will not do PM when doing system PM (because low power is used for the PM state STM32 handles) but will do PM when using the runtime API. I think this illustrates quite well the problem of having LOW_POWER and SUSPEND that in theory should do different things, but the way they are handled forces drivers to start using the "fall through pattern" just in case. @ceolin
It is clear a problem these drivers need to enable CONFIG_DEVICE_PM
to workaround the system PM. These options can be selected independently if needed.
Regarding the low power, I don't see a problem it as a major problem, from the subsystem perspective it is a hint to the device to save energy. It is up to the device decide what to do with it. That is something that will always be device specific, even if we had only SUSPEND
devices would still may interpret it in different manners (they may have multiple saving states).
The subsystem uses LOW_POWER
when the sleep state is shallow and it needs to wake up fast, drivers can use it to set their equivalent state collaborating with the overall system.
This discussion is not particular to this issue, but I see pros/cons in have multiple device states. The policy manager for devices can solve this problem. The proposed solution (https://github.com/zephyrproject-rtos/zephyr/pull/37823) is just replicating the current behavior, but we can device power states information per device in DT and make the policy consume it.
The problem of having both LOW_POWER
and SUSPEND
and treating them independently can cause problems. For example, a device can decide to just implement LOW_POWER
, SUSPEND
or both. Let's take a system with N devices, each implementing a random combination of the previous list. Now the system goes to a low power state where SUSPEND
is used to put devices into a low power state. There will be a subset of devices, those implementing LOW_POWER
only, that will just be left ON even though they can be put into a state that would save some power. The same would happen if LOW_POWER
is used. The policy proposal in #37823 doesn't help to solve such cases. If there are multiple low power states, as there are now, the PM subsystem must be smart enough to take advantage of all cases. We can't move this problem to devices forcing to handle all cases, since then there's virtually no difference between LOW_POWER
and SUSPEND
states.
The problem of having both
LOW_POWER
andSUSPEND
and treating them independently can cause problems. For example, a device can decide to just implementLOW_POWER
,SUSPEND
or both. Let's take a system with N devices, each implementing a random combination of the previous list. Now the system goes to a low power state whereSUSPEND
is used to put devices into a low power state. There will be a subset of devices, those implementingLOW_POWER
only, that will just be left ON even though they can be put into a state that would save some power. The same would happen ifLOW_POWER
is used.
Note that the system power states documentation says what is more or less expected from a device when the system goes to state.
/**
* @brief Runtime idle state
*
* Runtime idle is a system sleep state in which all of the cores
* enter deepest possible idle state and wait for interrupts, no
* requirements for the devices, leaving them at the states where
* they are.
*
* @note This state is correlated with ACPI S0ix state
*/
PM_STATE_RUNTIME_IDLE,
/**
* @brief Suspend to idle state
*
* The system goes through a normal platform suspend where it puts
* all of the cores in deepest possible idle state and *may* puts peripherals
* into low-power states. No operating state is lost (ie. the cpu core
* does not lose execution context), so the system can go back to where
* it left off easily enough.
*
* @note This state is correlated with ACPI S1 state
*/
PM_STATE_SUSPEND_TO_IDLE,
The policy proposal in #37823 doesn't help to solve such cases. If there are multiple low power states, as there are now, the PM
It does not solve the problem as I stated there, but it is one step further, if the the information about which states a device implements were available the policy could be smarter.
subsystem must be smart enough to take advantage of all cases. We can't move this problem to devices forcing to handle all
How exactly the subsystem must be smart ? Removing LOW_POWER
the only thing that the subsystem will be able to do is suspend or not suspend. All the hard work will still needed to be implemented by the device.
cases, since then there's virtually no difference between
LOW_POWER
andSUSPEND
states.
What you mean here ? That devices are only active or suspended ? Or that most drivers were handling both states are the same ?
The problem of having both
LOW_POWER
andSUSPEND
and treating them independently can cause problems. For example, a device can decide to just implementLOW_POWER
,SUSPEND
or both. Let's take a system with N devices, each implementing a random combination of the previous list. Now the system goes to a low power state whereSUSPEND
is used to put devices into a low power state. There will be a subset of devices, those implementingLOW_POWER
only, that will just be left ON even though they can be put into a state that would save some power. The same would happen ifLOW_POWER
is used.Note that the system power states documentation says what is more or less expected from a device when the system goes to state.
/** * @brief Runtime idle state * * Runtime idle is a system sleep state in which all of the cores * enter deepest possible idle state and wait for interrupts, no * requirements for the devices, leaving them at the states where * they are. * * @note This state is correlated with ACPI S0ix state */ PM_STATE_RUNTIME_IDLE, /** * @brief Suspend to idle state * * The system goes through a normal platform suspend where it puts * all of the cores in deepest possible idle state and *may* puts peripherals * into low-power states. No operating state is lost (ie. the cpu core * does not lose execution context), so the system can go back to where * it left off easily enough. * * @note This state is correlated with ACPI S1 state */ PM_STATE_SUSPEND_TO_IDLE,
The system PM code doesn't seem to follow these specs:
PM_STATE_RUNTIME_IDLE
: "no requirements for the devices, leaving them at the states where they are.". Now: they are all called to set LOW_POWER
state.There is also some lack of clarity:
PM_STATE_SUSPEND_TO_IDLE
: "...into low-power states". Which states?. Now: LOW_POWER
.The policy proposal in #37823 doesn't help to solve such cases. If there are multiple low power states, as there are now, the PM
It does not solve the problem as I stated there, but it is one step further, if the the information about which states a device implements were available the policy could be smarter.
subsystem must be smart enough to take advantage of all cases. We can't move this problem to devices forcing to handle all
How exactly the subsystem must be smart ? Removing
LOW_POWER
the only thing that the subsystem will be able to do is suspend or not suspend. All the hard work will still needed to be implemented by the device.
System can decide to fall back to, e.g. SUSPEND
if TURN_OFF
is not supported when turning the system off. Or use LOW_POWER
if SUSPEND
is not implemented, etc. As of today, this is effectively deferred to the drivers, which led to "handle all just in case" pattern. This has many associated problems, e.g.:
TURN_OFF
will turn off or suspend really). I could be turning off a sensor, but I actually see it just drawing a bit less milliwatts. However, the API states that device is disconnected.SUSPEND
, it should not be called again, since it doesn't know what else to do, really. If I call TURN_OFF
, 1. no power configuration can change, 2. it could fail (maybe comms need to be resumed some special way?)cases, since then there's virtually no difference between
LOW_POWER
andSUSPEND
states.What you mean here ? That devices are only active or suspended ? Or that most drivers were handling both states are the same ?
A driver that just supports one of the actions, LOW_POWER
or SUSPEND
is basically forced to handle both the same way in practice. For example, STM32 only makes use of PM_STATE_SUSPEND_TO_IDLE
, which in turn only uses PM_DEVICE_ACTION_LOW_POWER
. This means that all devices that want to have a chance of entering low power mode in such system, need to handle LOW_POWER
. Things just get worse if we consider the runtime API, where only SUSPEND
is considered.
So to summarize, I'd prefer a system that just has SUSPEND
handled properly than a system that in theory offers one more level, but that in practice, it is not handled consistently.
Describe the bug
Some STM32 series (g0, l0, l4, l5, wb, wl) require
CONFIG_PM_DEVICE
ifCONFIG_PM=y
. However, one should be able to have system PM enabled (CONFIG_PM=y
) without the need ofCONFIG_PM_DEVICE
. It turns out that the device PM hooks are used in some cases, e.g. UART, to block system suspension until the peripheral is done. For more context, see https://github.com/zephyrproject-rtos/zephyr/pull/38383#discussion_r705402367. https://github.com/zephyrproject-rtos/zephyr/pull/38432 proposes an alternative solution that should allow disablingCONFIG_PM_DEVICE
even whenCONFIG_PM=y
.To Reproduce
Look at:
Expected behavior
CONFIG_PM_DEVICE
should not be a requirement to enableCONFIG_PM
.Impact
Logs and console output
N/A
Environment (please complete the following information):
Additional context
https://github.com/zephyrproject-rtos/zephyr/issues/38382 https://github.com/zephyrproject-rtos/zephyr/pull/38383 https://github.com/zephyrproject-rtos/zephyr/pull/38432