[PATCH] ACPI: scan: Drop power resource references for deferred devices
Peixin Xie <[email protected]> Tue, 11 Aug 2026 20:36:37 +0800
| Newsgroups | gmane.linux.ports.riscv,gmane.linux.acpi.devel,gmane.linux.kernel |
|---|---|
| Message-ID | <20260811-acpi-power-resource-ref-fix-v1-1-828f1c383831@linux.spacemit.com> |
acpi_bus_get_power_flags() initializes the device power state and takes references to any power resources required by that state. If the device is not ready for enumeration, acpi_bus_attach() parks it and clears power_manageable without dropping those references. When the dependency is later satisfied, power initialization takes the references again. The additional references prevent the resources from being turned off when the device enters D3. Transition the device to D3cold before clearing power_manageable to drop the references acquired during initial power state initialization. This is particularly easy to trigger on RISC-V, where dependencies on interrupt controllers are derived automatically from interrupt resources. Signed-off-by: Peixin Xie <[email protected]> --- This issue was reproduced on a SpacemiT K3 RISC-V platform. The affected device uses a power resource through _PR0 and has an automatically derived dependency on its interrupt controller. Before the change, the initial power initialization acquires a power resource reference. The device is then deferred, but that reference is not dropped. When the dependency becomes available, power initialization acquires another reference. Consequently, entering D3 only drops the reference count from 2 to 1 and _OFF is not evaluated: [ 0.403217] ACPI: \_SB_.USBD.PDPR: ACPI: PM: Power resource is on [ 0.409393] ACPI: \_SB_.USBD.PDPR: New power resource [ 0.419165] ACPI Debug: "ACPI USBD: entering PDPR._ON" [ 0.424495] ACPI: \_SB_.USBD.PDPR: ACPI: PM: Power resource turned on [ 0.431036] ACPI Debug: "ACPI USBD: entering _PS0" [ 0.790826] ACPI: \_SB_.USBD.PDPR: ACPI: PM: Power resource already on [ 0.801777] ACPI Debug: "ACPI USBD: entering _PS0" [ 0.995285] ACPI Debug: "ACPI USBD: entering _PS3" [ 1.005550] ACPI: \_SB_.USBD.PDPR: ACPI: PM: Power resource still in use After the change, the reference acquired before deferred enumeration is dropped, and _OFF is evaluated both when the device is deferred and when it later enters D3: [ 0.340111] ACPI Debug: "ACPI USBD: entering PDPR._ON" [ 0.345459] ACPI Debug: "ACPI USBD: entering _PS0" [ 0.350532] ACPI Debug: "ACPI USBD: entering PDPR._OFF" [ 0.742054] ACPI Debug: "ACPI USBD: entering PDPR._ON" [ 0.747282] ACPI Debug: "ACPI USBD: entering _PS0" [ 0.758664] ACPI Debug: "ACPI USBD: entering _PS3" [ 0.768959] ACPI Debug: "ACPI USBD: entering PDPR._OFF" --- drivers/acpi/scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9a7ac2eb9ce0..7a8404719fa1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2350,6 +2350,11 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass) acpi_bus_get_status(device); /* Skip devices that are not ready for enumeration (e.g. not present) */ if (!acpi_dev_ready_for_enumeration(device)) { + /* + * Drop power resource references acquired during initial + * power state initialization before parking the device. + */ + acpi_power_transition(device, ACPI_STATE_D3_COLD); device->flags.initialized = false; acpi_device_clear_enumerated(device); device->flags.power_manageable = 0; --- base-commit: d58772d8520c7ef247c4b95c9bd76d3a25da9ff5 change-id: 20260811-acpi-power-resource-ref-fix-2fa4798f590b Best regards, -- Peixin Xie <[email protected]>