* [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling
@ 2026-09-02 19:21 Rafael J. Wysocki
2026-09-02 19:24 ` [PATCH v2 1/6] ACPI: PM: Drop parent state update from acpi_device_get_power() Rafael J. Wysocki
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:21 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
Hi All,
This is an update of
https://lore.kernel.org/linux-acpi/3435655.aeNJFYEL58@rafael.j.wysocki/
that adds one patch, drops two patches, and addresses review comments in
some other patches in the series.
The new patch drops an unneeded parent power state update that may lead to
issues in theory from acpi_device_get_power().
One of the patches dropped from the original series is not necessary any
more after addressing review comments in patch [2/6], and the other one
might introduced some issues pointed out by Sashiko.
Overall, the series aims at addressing a few issues present in the core ACPI
device enumeration code, mostly related to the acpi_bus_attach() function.
The first one is that, on some systems, ACPI power management is initialized
twice for devices that have missing dependencies to start with. An attempt
to address this issue had been made during the 7.3 merge window, but it had
to be reverted [1]. The approach used here is roughly the same as in the
reverted commit, but it takes PCI devices (which are a special case) into
account.
In addition to the above, ACPI power management may be initialized prematurely
for device objects whose parents are not ready for enumeration.
The other issues are that flags are unnecessarily cleared by acpi_bus_attach()
for devices with missing dependencies, the "initialized" ACPI device object
flag is not particularly useful, the "visited" ACPI device object flag is
used for two different things which is confusing at best, and PCI devices
are handled by acpi_bus_attach() like any other devices which is a mistake.
Please see the changelogs of individual patches for details.
Thanks!
Link: https://lore.kernel.org/linux-acpi/20260820-acpi-power-resource-ref-fix-v2-1-29818173ea13@linux.spacemit.com/ [1]
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/6] ACPI: PM: Drop parent state update from acpi_device_get_power()
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
@ 2026-09-02 19:24 ` Rafael J. Wysocki
2026-09-02 19:26 ` [PATCH v2 2/6] ACPI: scan: Stop calling acpi_bus_init_power() early Rafael J. Wysocki
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:24 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
The parent state update in acpi_device_get_power(), that occurs when the
child device turns out to be in D0 and the parent's power state is still
unknown, is highly questionable because it may cause the reference
counters of the power resources used by the parent in D0 (if any) to
underflow when the parent goes into a low-power state later. Moreover,
there is no reason to do it on reads from the real_power_state sysfs
attribute of the child.
That check had been added by commit 8f7412a792bc ("ACPI / PM: Infer
parent power state from child if unknown, v2") before starting to
handle the "missing _PSC and no power resources" case directly in
acpi_bus_init_power(), as of commit b3785492268f ("ACPI / PM: Do not
power manage devices in unknown initial states"). It is not necessary
any more and commit b3785492268f should have removed it.
Drop it now.
Fixes: b3785492268f ("ACPI / PM: Do not power manage devices in unknown initial states")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
New patch in v2.
---
drivers/acpi/device_pm.c | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index aa55ecfc2923..4269735aadde 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -75,15 +75,14 @@ static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state)
int acpi_device_get_power(struct acpi_device *device, int *state)
{
int result = ACPI_STATE_UNKNOWN;
- struct acpi_device *parent;
int error;
if (!device || !state)
return -EINVAL;
- parent = acpi_dev_parent(device);
-
if (!device->flags.power_manageable) {
+ struct acpi_device *parent = acpi_dev_parent(device);
+
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*state = parent ? parent->power.state : ACPI_STATE_D0;
goto out;
@@ -119,16 +118,6 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
result = psc > ACPI_STATE_D2 ? ACPI_STATE_D3_HOT : psc;
}
- /*
- * If we were unsure about the device parent's power state up to this
- * point, the fact that the device is in D0 implies that the parent has
- * to be in D0 too, except if ignore_parent is set.
- */
- if (!device->power.flags.ignore_parent && parent &&
- parent->power.state == ACPI_STATE_UNKNOWN &&
- result == ACPI_STATE_D0)
- parent->power.state = ACPI_STATE_D0;
-
*state = result;
out:
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/6] ACPI: scan: Stop calling acpi_bus_init_power() early
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
2026-09-02 19:24 ` [PATCH v2 1/6] ACPI: PM: Drop parent state update from acpi_device_get_power() Rafael J. Wysocki
@ 2026-09-02 19:26 ` Rafael J. Wysocki
2026-09-02 19:30 ` [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach() Rafael J. Wysocki
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:26 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
There is a problem, introduced by commit 9d9bcae47fd5 ("ACPI: delay
enumeration of devices with a _DEP pointing to an INT3472 device")
inadvertently, that devices with missing dependencies may be put
into power state D0 prematurely [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()
runs again for the device and now it calls acpi_bus_init_power() that
takes 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.
Another problem, related to the previous one, is that ACPI power state
initialization may be carried out for devices whose parents are not
ready for enumeration which may lead to initialization ordering issues.
To address both, 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
acpi_bus_attach() is called 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() if the given PCI device has an ACPI companion
with flags.power_manageable set. 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
the device's power state needs to be initialized in acpi_bus_attach()
instead of using the "initialized" flag of the ACPI device object
for this purpose, which is fragile and inconvenient. Also stop
clearing the power_manageable flag for devices with unmet
dependencies and poison the power state as "disabled" if the
initialization of it fails, which may not be recoverable.
While at it, add a debug message printing statement to
acpi_bus_init_power() to facilitate diagnostics.
Fixes: 9d9bcae47fd5 ("ACPI: delay enumeration of devices with a _DEP pointing to an INT3472 device")
Link: https://lore.kernel.org/linux-acpi/20260820-acpi-power-resource-ref-fix-v2-1-29818173ea13@linux.spacemit.com/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v1 -> v2:
* Address Sashiko review comments:
https://lore.kernel.org/linux-pci/20260831201426.92F091F000E9@smtp.kernel.org/
---
drivers/acpi/device_pm.c | 56 +++++++++++++++++++++++++++++++++-------
drivers/acpi/scan.c | 15 +++--------
2 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 4269735aadde..e13096cfd790 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -23,6 +23,8 @@
#include "fan.h"
#include "internal.h"
+#define ACPI_D_STATE_DISABLED ACPI_D_STATE_COUNT
+
/**
* acpi_power_state_string - String representation of ACPI device power state.
* @state: ACPI device power state to return the string representation of.
@@ -157,6 +159,15 @@ int acpi_device_set_power(struct acpi_device *device, int state)
|| (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL;
+ if (device->power.state == ACPI_D_STATE_DISABLED)
+ return -ENXIO;
+
+ if (device->power.state == ACPI_STATE_UNKNOWN) {
+ result = acpi_bus_init_power(device);
+ if (result)
+ return result;
+ }
+
acpi_handle_debug(device->handle, "Power state change: %s -> %s\n",
acpi_power_state_string(device->power.state),
acpi_power_state_string(state));
@@ -293,20 +304,11 @@ int acpi_bus_set_power(acpi_handle handle, int state)
}
EXPORT_SYMBOL(acpi_bus_set_power);
-int acpi_bus_init_power(struct acpi_device *device)
+static int acpi_device_init_power(struct acpi_device *device)
{
int state;
int result;
- if (!device)
- return -EINVAL;
-
- device->power.state = ACPI_STATE_UNKNOWN;
- if (!acpi_device_is_present(device)) {
- device->flags.initialized = false;
- return -ENXIO;
- }
-
result = acpi_device_get_power(device, &state);
if (result)
return result;
@@ -340,9 +342,43 @@ int acpi_bus_init_power(struct acpi_device *device)
state = ACPI_STATE_D0;
}
device->power.state = state;
+
+ acpi_handle_debug(device->handle, "Initial power state: %s\n",
+ acpi_power_state_string(state));
+
return 0;
}
+int acpi_bus_init_power(struct acpi_device *device)
+{
+ static DEFINE_MUTEX(init_power_lock);
+ int result;
+
+ /*
+ * This is done to prevent power state initialization from being carried
+ * out twice in parallel for the same device (not impossible, but very
+ * unlikely).
+ */
+ guard(mutex)(&init_power_lock);
+
+ if (device->power.state != ACPI_STATE_UNKNOWN)
+ return 0;
+
+ /*
+ * The ACPI device power state can be only initialized once. If this
+ * fails, ACPI power management will not be used for the device going
+ * forward.
+ */
+ result = acpi_device_init_power(device);
+ if (result) {
+ device->power.state = ACPI_D_STATE_DISABLED;
+ acpi_handle_info(device->handle,
+ "Failed to determine initial power state, ACPI PM disabled\n");
+ }
+
+ return result;
+}
+
/**
* acpi_device_fix_up_power - Force device with missing _PSC into D0.
* @device: Device object whose power state is to be fixed up.
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f48715ed827c..4586f1798685 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1145,8 +1145,7 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
}
- if (acpi_bus_init_power(device))
- device->flags.power_manageable = 0;
+ device->power.state = ACPI_STATE_UNKNOWN;
}
static void acpi_bus_get_flags(struct acpi_device *device)
@@ -2354,9 +2353,7 @@ 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)) {
- device->flags.initialized = false;
acpi_device_clear_enumerated(device);
- device->flags.power_manageable = 0;
return 0;
}
if (device->handler)
@@ -2364,16 +2361,10 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
acpi_ec_register_opregions(device);
- if (!device->flags.initialized) {
- device->flags.power_manageable =
- device->power.states[ACPI_STATE_D0].flags.valid;
- if (acpi_bus_init_power(device))
- device->flags.power_manageable = 0;
+ acpi_bus_init_power(device);
- device->flags.initialized = true;
- } else if (device->flags.visited) {
+ if (device->flags.visited)
goto ok;
- }
ret = acpi_scan_attach_handler(device);
if (ret < 0)
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach()
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
2026-09-02 19:24 ` [PATCH v2 1/6] ACPI: PM: Drop parent state update from acpi_device_get_power() Rafael J. Wysocki
2026-09-02 19:26 ` [PATCH v2 2/6] ACPI: scan: Stop calling acpi_bus_init_power() early Rafael J. Wysocki
@ 2026-09-02 19:30 ` Rafael J. Wysocki
2026-09-03 7:27 ` Andy Shevchenko
2026-09-02 19:33 ` [PATCH v2 4/6] ACPI: scan: Add ACPI device enumerated marker Rafael J. Wysocki
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:30 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
There are two conditionals in acpi_bus_attach() that can be combined,
which slightly reduces the overhead and makes the code a bit easier
to follow, so do that.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
v1 -> v2:
* Reverse checks to avoid multiple negations (Andy)
* Rebase on top of the new [2/6]
Link to the v1:
https://lore.kernel.org/linux-pci/2021470.taCxCBeP46@rafael.j.wysocki/
---
drivers/acpi/scan.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 4586f1798685..7208cc515866 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2370,13 +2370,8 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
if (ret < 0)
return 0;
- if (ret > 0 && !device->flags.enumeration_by_parent) {
- acpi_device_set_enumerated(device);
- goto ok;
- }
-
- if (device->pnp.type.platform_id || device->pnp.type.backlight ||
- device->flags.enumeration_by_parent)
+ if (device->flags.enumeration_by_parent ||
+ (!ret && (device->pnp.type.platform_id || device->pnp.type.backlight)))
acpi_default_enumeration(device);
else
acpi_device_set_enumerated(device);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 4/6] ACPI: scan: Add ACPI device enumerated marker
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
` (2 preceding siblings ...)
2026-09-02 19:30 ` [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach() Rafael J. Wysocki
@ 2026-09-02 19:33 ` Rafael J. Wysocki
2026-09-02 19:35 ` [PATCH v2 5/6] ACPI: scan: Adjust and rename acpi_bus_attach() Rafael J. Wysocki
2026-09-02 19:36 ` [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly Rafael J. Wysocki
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:33 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Currently, the "visited" flag of ACPI device objects has two roles.
One of them is to indicate that the given ACPI device object has been
enumerated, which basically means that either it has been associated
with a "physical" device representation, or there is no matching
"physical" device representation for it. The other one is to
indicate that acpi_bus_attach() has processed the device. That dual
purpose leads to some confusion regarding when that flag should be set
and cleared and by whom.
To address that confusion, add a new bool field called "enumerated"
to struct acpi_device for the purpose of indicating whether or not
the given ACPI device object has been enumerated. Accordingly, switch
over acpi_device_enumerated() and acpi_device_set/clear_enumerated() to
operate on that field and the "visited" flag will now be only used
internally by the core ACPI device enumeration code.
Namely, acpi_bus_attach() will set flags.visited for a given ACPI
device object after it has been completely processed by that function
and regardless of its current status it needs to be "unattached", for
example by acpi_scan_check_and_detach(), so that acpi_bus_attach() can
process it again.
The rule regarding flags.visited and the "enumerated" field is that the
latter cannot be set until the former has been set and they need to be
cleared in reverse order.
This allows a couple of checks to be dropped from acpi_bus_attach()
and its first_pass argument is not needed any more.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peixin Xie <peixin.xie@linux.spacemit.com>
---
v1 -> v2:
* Rebase on top of the new [2-3/6]
* Drop quote characters from the subject (unnecessary and may get
in the way in future)
* Add tag from Peixin Xie
Link to the v1:
https://lore.kernel.org/linux-pci/48339705.fMDQidcC6G@rafael.j.wysocki/
---
drivers/acpi/scan.c | 28 +++++++++++++---------------
include/acpi/acpi_bus.h | 3 ++-
include/linux/acpi.h | 4 ++--
3 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7208cc515866..2e853add5e60 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -266,8 +266,8 @@ static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p)
if (acpi_device_is_enabled(adev))
return 0;
- /* Skip device that have not been enumerated. */
- if (!acpi_device_enumerated(adev)) {
+ /* Skip device that have not been prepared for enumeration. */
+ if (!adev->flags.visited) {
dev_dbg(&adev->dev, "Still not enumerated\n");
return 0;
}
@@ -287,6 +287,7 @@ static int acpi_scan_check_and_detach(struct acpi_device *adev, void *p)
if (!(flags & ACPI_SCAN_CHECK_FLAG_EJECT)) {
adev->handler = NULL;
acpi_device_clear_enumerated(adev);
+ adev->flags.visited = 0;
}
return 0;
}
@@ -305,6 +306,7 @@ static int acpi_bus_post_eject(struct acpi_device *adev, void *not_used)
}
acpi_device_clear_enumerated(adev);
+ adev->flags.visited = 0;
return 0;
}
@@ -2338,46 +2340,42 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
return ret;
}
-static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
+static int acpi_bus_attach(struct acpi_device *device, void *not_used)
{
- bool skip = !first_pass && device->flags.visited;
acpi_handle ejd;
+ bool skip;
int ret;
+ skip = !!device->flags.visited;
if (skip)
- goto ok;
+ goto children;
if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd)))
register_dock_dependent_device(device, ejd);
acpi_bus_get_status(device);
/* Skip devices that are not ready for enumeration (e.g. not present) */
- if (!acpi_dev_ready_for_enumeration(device)) {
- acpi_device_clear_enumerated(device);
+ if (!acpi_dev_ready_for_enumeration(device))
return 0;
- }
- if (device->handler)
- goto ok;
acpi_ec_register_opregions(device);
acpi_bus_init_power(device);
- if (device->flags.visited)
- goto ok;
-
ret = acpi_scan_attach_handler(device);
if (ret < 0)
return 0;
+ device->flags.visited = 1;
+
if (device->flags.enumeration_by_parent ||
(!ret && (device->pnp.type.platform_id || device->pnp.type.backlight)))
acpi_default_enumeration(device);
else
acpi_device_set_enumerated(device);
-ok:
- acpi_dev_for_each_child(device, acpi_bus_attach, first_pass);
+children:
+ acpi_dev_for_each_child(device, acpi_bus_attach, NULL);
if (!skip && device->handler && device->handler->hotplug.notify_online)
device->handler->hotplug.notify_online(device);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 1a45e0d521d8..46ac4a33ae2c 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -468,6 +468,7 @@ struct acpi_device {
struct list_head physical_node_list;
struct mutex physical_node_lock;
void (*remove)(struct acpi_device *);
+ bool enumerated;
};
/* Non-device subnode */
@@ -654,7 +655,7 @@ void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
static inline bool acpi_device_enumerated(struct acpi_device *adev)
{
- return adev && adev->flags.initialized && adev->flags.visited;
+ return adev && adev->flags.initialized && adev->enumerated;
}
/*
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ddacac812094..2e9e49e2e665 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -782,12 +782,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *,
static inline void acpi_device_set_enumerated(struct acpi_device *adev)
{
- adev->flags.visited = true;
+ adev->enumerated = true;
}
static inline void acpi_device_clear_enumerated(struct acpi_device *adev)
{
- adev->flags.visited = false;
+ adev->enumerated = false;
}
enum acpi_reconfig_event {
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 5/6] ACPI: scan: Adjust and rename acpi_bus_attach()
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
` (3 preceding siblings ...)
2026-09-02 19:33 ` [PATCH v2 4/6] ACPI: scan: Add ACPI device enumerated marker Rafael J. Wysocki
@ 2026-09-02 19:35 ` Rafael J. Wysocki
2026-09-02 19:36 ` [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly Rafael J. Wysocki
5 siblings, 0 replies; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:35 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
After previous changes, the second argument of acpi_bus_attach() is
ignored and none of its callers checks its return value, so rename
it to attach_subtree(), add a void wrapper around it called
acpi_scan_attach(), and adjust its callers to invoke that wrapper.
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peixin Xie <peixin.xie@linux.spacemit.com>
---
v1 -> v2:
* Add tag from Peixin Xie
---
drivers/acpi/scan.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2e853add5e60..f4718b0207e0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2340,7 +2340,7 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
return ret;
}
-static int acpi_bus_attach(struct acpi_device *device, void *not_used)
+static int attach_subtree(struct acpi_device *device, void *not_used)
{
acpi_handle ejd;
bool skip;
@@ -2374,8 +2374,10 @@ static int acpi_bus_attach(struct acpi_device *device, void *not_used)
else
acpi_device_set_enumerated(device);
+ acpi_handle_debug(device->handle, "Scanning complete\n");
+
children:
- acpi_dev_for_each_child(device, acpi_bus_attach, NULL);
+ acpi_dev_for_each_child(device, attach_subtree, NULL);
if (!skip && device->handler && device->handler->hotplug.notify_online)
device->handler->hotplug.notify_online(device);
@@ -2383,6 +2385,11 @@ static int acpi_bus_attach(struct acpi_device *device, void *not_used)
return 0;
}
+static void acpi_scan_attach(struct acpi_device *adev)
+{
+ attach_subtree(adev, NULL);
+}
+
static int acpi_dev_get_next_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
{
struct acpi_device **adev_p = data;
@@ -2414,7 +2421,7 @@ static void acpi_scan_clear_dep_fn(void *dev, async_cookie_t cookie)
struct acpi_device *adev = to_acpi_device(dev);
acpi_scan_lock_acquire();
- acpi_bus_attach(adev, (void *)true);
+ acpi_scan_attach(adev);
acpi_scan_lock_release();
acpi_dev_put(adev);
@@ -2427,7 +2434,7 @@ static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
/*
* Async schedule the deferred acpi_scan_clear_dep_fn() since:
- * - acpi_bus_attach() needs to hold acpi_scan_lock which cannot
+ * - acpi_scan_attach() needs to run under acpi_scan_lock which cannot
* be acquired under acpi_dep_list_lock (held here)
* - the deferred work at boot stage is ensured to be finished
* before userspace init task by the async_synchronize_full()
@@ -2568,7 +2575,7 @@ static void acpi_scan_postponed_branch(acpi_handle handle)
*/
acpi_mipi_init_crs_csi2_swnodes();
- acpi_bus_attach(adev, NULL);
+ acpi_scan_attach(adev);
}
static void acpi_scan_postponed(void)
@@ -2725,7 +2732,7 @@ int acpi_bus_scan(acpi_handle handle)
acpi_mipi_scan_crs_csi2();
acpi_mipi_init_crs_csi2_swnodes();
- acpi_bus_attach(device, (void *)true);
+ acpi_scan_attach(device);
/* Pass 2: Enumerate all of the remaining devices. */
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
` (4 preceding siblings ...)
2026-09-02 19:35 ` [PATCH v2 5/6] ACPI: scan: Adjust and rename acpi_bus_attach() Rafael J. Wysocki
@ 2026-09-02 19:36 ` Rafael J. Wysocki
2026-09-03 8:12 ` Andy Shevchenko
5 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2026-09-02 19:36 UTC (permalink / raw)
To: Linux ACPI
Cc: Linux PM, LKML, Mika Westerberg, Peixin Xie, Sakari Ailus,
Lukas Wunner, Ilpo Järvinen, Linux PCI, Bjorn Helgaas,
Hans de Goede, Andy Shevchenko
From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
The ACPI companions of PCI devices are associated with the corresponding
PCI devices before being processed by acpi_scan_attach() and by the time
they are passed to attach_subtree(), the PCI devices associated with
them have been already enumerated and initialized.
Accordingly, it is not necessary or even useful to check their status in
attach_subtree(), so do not do that.
Fixes: 2c22e6520ac8 ("ACPI / scan: Use direct recurrence for device hierarchy walks")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Peixin Xie <peixin.xie@linux.spacemit.com>
---
v1 -> v2:
* Use pci_name() (Andy)
* Add tag from Peixin Xie
---
drivers/acpi/scan.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f4718b0207e0..34f7f477a25a 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -20,6 +20,7 @@
#include <linux/kthread.h>
#include <linux/dmi.h>
#include <linux/dma-map-ops.h>
+#include <linux/pci.h>
#include <linux/platform_data/x86/apple.h>
#include <linux/pgtable.h>
#include <linux/crc32.h>
@@ -2342,6 +2343,7 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
static int attach_subtree(struct acpi_device *device, void *not_used)
{
+ struct pci_dev *pci;
acpi_handle ejd;
bool skip;
int ret;
@@ -2353,10 +2355,26 @@ static int attach_subtree(struct acpi_device *device, void *not_used)
if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd)))
register_dock_dependent_device(device, ejd);
- acpi_bus_get_status(device);
- /* Skip devices that are not ready for enumeration (e.g. not present) */
- if (!acpi_dev_ready_for_enumeration(device))
- return 0;
+ /*
+ * If the given ACPI device object has been already associated with a
+ * PCI device found on the bus, its status is effectively "present
+ * and functional".
+ */
+ pci = acpi_dev_get_pci_dev(device);
+ if (pci) {
+ acpi_handle_debug(device->handle, "PCI companion %s found\n",
+ pci_name(pci));
+
+ pci_dev_put(pci);
+ } else {
+ acpi_bus_get_status(device);
+ /*
+ * Skip devices that are not ready for enumeration (e.g. not
+ * present).
+ */
+ if (!acpi_dev_ready_for_enumeration(device))
+ return 0;
+ }
acpi_ec_register_opregions(device);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach()
2026-09-02 19:30 ` [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach() Rafael J. Wysocki
@ 2026-09-03 7:27 ` Andy Shevchenko
0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2026-09-03 7:27 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux ACPI, Linux PM, LKML, Mika Westerberg, Peixin Xie,
Sakari Ailus, Lukas Wunner, Ilpo Järvinen, Linux PCI,
Bjorn Helgaas, Hans de Goede
On Wed, Sep 02, 2026 at 09:30:00PM +0200, Rafael J. Wysocki wrote:
> There are two conditionals in acpi_bus_attach() that can be combined,
> which slightly reduces the overhead and makes the code a bit easier
> to follow, so do that.
>
> No intentional functional impact.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly
2026-09-02 19:36 ` [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly Rafael J. Wysocki
@ 2026-09-03 8:12 ` Andy Shevchenko
0 siblings, 0 replies; 9+ messages in thread
From: Andy Shevchenko @ 2026-09-03 8:12 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linux ACPI, Linux PM, LKML, Mika Westerberg, Peixin Xie,
Sakari Ailus, Lukas Wunner, Ilpo Järvinen, Linux PCI,
Bjorn Helgaas, Hans de Goede
On Wed, Sep 02, 2026 at 09:36:54PM +0200, Rafael J. Wysocki wrote:
> The ACPI companions of PCI devices are associated with the corresponding
> PCI devices before being processed by acpi_scan_attach() and by the time
> they are passed to attach_subtree(), the PCI devices associated with
> them have been already enumerated and initialized.
>
> Accordingly, it is not necessary or even useful to check their status in
> attach_subtree(), so do not do that.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-09-03 8:12 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 19:21 [PATCH v2 0/6] ACPI: scan: Adjust power management initialization and PCI devices handling Rafael J. Wysocki
2026-09-02 19:24 ` [PATCH v2 1/6] ACPI: PM: Drop parent state update from acpi_device_get_power() Rafael J. Wysocki
2026-09-02 19:26 ` [PATCH v2 2/6] ACPI: scan: Stop calling acpi_bus_init_power() early Rafael J. Wysocki
2026-09-02 19:30 ` [PATCH v2 3/6] ACPI: scan: Combine two conditionals in acpi_bus_attach() Rafael J. Wysocki
2026-09-03 7:27 ` Andy Shevchenko
2026-09-02 19:33 ` [PATCH v2 4/6] ACPI: scan: Add ACPI device enumerated marker Rafael J. Wysocki
2026-09-02 19:35 ` [PATCH v2 5/6] ACPI: scan: Adjust and rename acpi_bus_attach() Rafael J. Wysocki
2026-09-02 19:36 ` [PATCH v2 6/6] ACPI: scan: Take PCI device enumeration into account directly Rafael J. Wysocki
2026-09-03 8:12 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox