Re: [PATCH v1 1/7] ACPI: scan: Stop calling acpi_bus_init_power() early

Andy Shevchenko <[email protected]>
Newsgroups org.kernel.vger.linux-acpi,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.linux-pm
Organization Intel Finland Oy - BIC 0357606-4 - c/o Alberga Business Park, 6 krs, Bertel Jungin Aukio 5, 02600 Espoo
Message-ID <[email protected]>
On Mon, Aug 31, 2026 at 06:24:45PM +0200, Rafael J. Wysocki wrote:
> From: "Rafael J. Wysocki" <[email protected]>
> 
> There is a problem, introduced by commit 9d9bcae47fd5 ("ACPI: delay
> enumeration of devices with a _DEP pointing to an INT3472 device")
> inadvertently, that causes devices with missing dependencies to be
> put into power state D0 prematurely on some systems [1].
> 
> Namely, acpi_bus_init_power() called by acpi_bus_get_power_flags()
> during the early initialization of ACPI device objects, may discover
> that all of the power resources needed by the given device to be in
> power state D0 are initially on, so it will reference count those
> power resources and transition the device into D0.  Later, if
> acpi_bus_attach() running for that device notices that it has missing
> dependencies, the enumeration of it will be deferred and its
> power_manageable flag will be cleared, even though it is still in D0
> at that point.
> 
> After the dependencies in question have been met, acpi_bus_attach()
> will run again for the device and now it will call
> acpi_bus_init_power() that will take additional references to the
> power resources used by the device in D0.  These additional
> references prevent the power resources from being turned off when
> the device goes into D3hot/D3cold.
> 
> To address this, stop calling acpi_bus_init_power() from
> acpi_bus_get_power_flags(), but also take the initialization of
> PCI devices into account, which needs to be done because they
> are initialized and bound to their ACPI companions before
> calling acpi_bus_attach() for the latter.
> 
> To that end, notice that each PCI device discovered on the bus
> is put into power state D0 via pci_power_up() which involves
> invoking acpi_device_set_power().  The initial ACPI power state of
> the device needs to be known at that point to carry out the power
> transition of it properly, so modify acpi_device_set_power() to
> call acpi_bus_init_power() upfront if the device's ACPI power
> state is still unknown.
> 
> Also use the ACPI power state tracking to decide whether or not
> acpi_bus_init_power() needs to be called by acpi_bus_attach()
> instead of using the "initialized" flag of the ACPI device object
> for this purpose, which is fragile and inconvenient, and stop
> clearing the power_manageable flag for devices with unmet
> dependencies, which is not necessary.
> 
> While at it, add a debug message pringing statement to
> acpi_bus_init_power() to facilitate diagnostics.

...

> +	if (device->power.state == ACPI_STATE_UNKNOWN &&
> +	    acpi_bus_init_power(device)) {
> +		device->flags.power_manageable = 0;
> +		return -ENODEV;
> +	}

In this form it might be harder to catch the side effect of the conditional.
I would split it into two:


	if (device->power.state == ACPI_STATE_UNKNOWN) {
		int result;

		result = acpi_bus_init_power(device);
		if (result) {
			device->flags.power_manageable = 0;
			return result; // shouldn't we instead of return -ENODEV?
		}
	}

...

> +	if (device->flags.power_manageable &&
> +	    device->power.state == ACPI_STATE_UNKNOWN &&
> +	    acpi_bus_init_power(device))
> +		device->flags.power_manageable = 0;

In the similar way. And it might be even worth to have a helper to deduplicate
this check and setting?

static inline int ...()
{
	int result;

	if (device->power.state != ACPI_STATE_UNKNOWN)
		return 0;

	result = acpi_bus_init_power(device);
	if (result)
		device->flags.power_manageable = 0;

	return result;
}

-- 
With Best Regards,
Andy Shevchenko
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.