Handling inconsistent Power Domain States with Deferred Power-Off in Device Drivers
by tsenthilnath from LinuxQuestions.org on (#6PFDG)
Hello everyone,
I'm facing a challenge with power management in the Linux kernel, involving the AMBA bus driver and the UART PL011 driver.
### Scenario:
The issue occurs with a UART device, where two drivers are involved:
Driver 1: AMBA bus driver (`drivers/amba/bus.c`)
Driver 2: UART PL011 driver (`drivers/tty/serial/amba-pl011.c`)
Hereis the sequence of events:
1. Driver 1 (AMBA bus driver) attaches the UART device to read the peripheral-id. This triggers the GenPD to power on the device (`genpd->status = GENPD_STATE_ON`). The attach happens at [line 141](https://git.kernel.org/pub/scm/linux...c?h=v6.10#n141) in the AMBA bus driver.
2. Driver 1 then detaches the device, scheduling a power-off operation using `genpd_queue_power_off_work(pd);`. The device's power-off is deferred, and the status is not immediately set to `GENPD_STATE_OFF`. The detach happens at [line 203](https://git.kernel.org/pub/scm/linux...c?h=v6.10#n203).
3. Before the deferred power-off occurs, **Driver 2 (UART PL011 driver)** attaches to the UART device. GenPD finds `genpd->status` is set to `GENPD_STATE_ON`, assuming the device is powered on and therefore does not power it on again.
4. Eventually, the deferred power-off is executed, setting `genpd->status = GENPD_STATE_OFF`, and the device is powered down.
This creates an inconsistency: UART-Driver assumes the device is on, but it is actually powered off after the deferred operation, potentially leading to malfunctioning.
### Question:
What is the best approach to resolve this issue, either by modifications in the genPD driver or through adjustments in the AMBA bus driver and UART PL011 driver? I'm looking for solutions that ensure the power domain status accurately reflects the current and intended state of the device, even when deferred power-off operations are in play.
Consideration I have is:
- Introducing a transitional state (e.g., `GENPD_STATE_POWERING_OFF`) in the genPD driver and return error to UART-Driver when the UART-Driver try to attach and let the UART-Driver return -EPROBE_DEFER to the kernel, so the Kernel will have an opportunity to come back and probe again.
I would appreciate any guidance or best practices from the community on managing such scenarios, especially any existing mechanisms in the Linux kernel that can help.
Thank you!
I'm facing a challenge with power management in the Linux kernel, involving the AMBA bus driver and the UART PL011 driver.
### Scenario:
The issue occurs with a UART device, where two drivers are involved:
Driver 1: AMBA bus driver (`drivers/amba/bus.c`)
Driver 2: UART PL011 driver (`drivers/tty/serial/amba-pl011.c`)
Hereis the sequence of events:
1. Driver 1 (AMBA bus driver) attaches the UART device to read the peripheral-id. This triggers the GenPD to power on the device (`genpd->status = GENPD_STATE_ON`). The attach happens at [line 141](https://git.kernel.org/pub/scm/linux...c?h=v6.10#n141) in the AMBA bus driver.
2. Driver 1 then detaches the device, scheduling a power-off operation using `genpd_queue_power_off_work(pd);`. The device's power-off is deferred, and the status is not immediately set to `GENPD_STATE_OFF`. The detach happens at [line 203](https://git.kernel.org/pub/scm/linux...c?h=v6.10#n203).
3. Before the deferred power-off occurs, **Driver 2 (UART PL011 driver)** attaches to the UART device. GenPD finds `genpd->status` is set to `GENPD_STATE_ON`, assuming the device is powered on and therefore does not power it on again.
4. Eventually, the deferred power-off is executed, setting `genpd->status = GENPD_STATE_OFF`, and the device is powered down.
This creates an inconsistency: UART-Driver assumes the device is on, but it is actually powered off after the deferred operation, potentially leading to malfunctioning.
### Question:
What is the best approach to resolve this issue, either by modifications in the genPD driver or through adjustments in the AMBA bus driver and UART PL011 driver? I'm looking for solutions that ensure the power domain status accurately reflects the current and intended state of the device, even when deferred power-off operations are in play.
Consideration I have is:
- Introducing a transitional state (e.g., `GENPD_STATE_POWERING_OFF`) in the genPD driver and return error to UART-Driver when the UART-Driver try to attach and let the UART-Driver return -EPROBE_DEFER to the kernel, so the Kernel will have an opportunity to come back and probe again.
I would appreciate any guidance or best practices from the community on managing such scenarios, especially any existing mechanisms in the Linux kernel that can help.
Thank you!