2022-04-05 01:17:57

by Rafael J. Wysocki

[permalink] [raw]
Subject: [PATCH v1 0/3] ACPI: PCI: PM: Power up PCI devices with ACPI companions upfront

Hi All,

There are cases in which the power state of a PCI device depends on an ACPI
power resource (or more of them) in such a way that when the given power
resource is in the "off" state, the PCI device depending on it is in D3cold.

On some systems, the initial state of these power resources is "off", so the
kernel should not access the config space of PCI devices depending on them,
until the power resources in question are turned "on", but currently that is
not respected during PCI device enumeration. Namely, the PCI device
enumeration code walks the entire bus and enumerates all of the devices it
can find, including the ones whose initial power state in principle depends on
the ACPI power resources in the "off" state.

Apparently, most of the time, the config space of such devices is accessible
regardless of the state of the ACPI power resource associated with the PCI
device, so the device enumeration is successful, but there are two potential
issues related to this behavior. First off, even if the given PCI device
is accessible when the ACPI power resource depended on by it is "off",
changing its configuration may confuse the platform firmware and lead to
problems when the ACPI power resource in question is turned "on". Second,
the PCI device may not be actually accessible at all when the ACPI power
resource depended on by it is "off", in which case it won't be found during
the PCI enumeration of devices.

This patch series addresses that problem by turning "on" all ACPI power
resources depended on by PCI devices before attempting to access the config
space of those devices for the first time.

The first two patches introduce the requisite machinery and the actual change
of behavior is done in the last patch.

Thanks!





2022-04-05 01:39:41

by Rafael J. Wysocki

[permalink] [raw]
Subject: [PATCH v1 2/3] ACPI: PM: Introduce acpi_dev_power_up_children_with_adr()

From: Rafael J. Wysocki <[email protected]>

Introduce a function powering up all of the children of a given ACPI
device object that are power-manageable and hold valid _ADR ACPI
objects so as to make it possible to prepare the corresponding
"physical" devices for enumeration carried out by a bus type driver,
like PCI.

This function will be used in a subsequent change set.

Signed-off-by: Rafael J. Wysocki <[email protected]>
---
drivers/acpi/device_pm.c | 30 ++++++++++++++++++++++++++++++
include/acpi/acpi_bus.h | 1 +
2 files changed, 31 insertions(+)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -427,6 +427,36 @@ bool acpi_bus_power_manageable(acpi_hand
}
EXPORT_SYMBOL(acpi_bus_power_manageable);

+static int acpi_power_up_if_adr_present(struct device *dev, void *not_used)
+{
+ struct acpi_device *adev;
+
+ adev = to_acpi_device(dev);
+ if (!(adev->flags.power_manageable && adev->pnp.type.bus_address))
+ return 0;
+
+ acpi_handle_debug(adev->handle, "Power state: %s\n",
+ acpi_power_state_string(adev->power.state));
+
+ if (adev->power.state == ACPI_STATE_D3_COLD)
+ return acpi_device_set_power(adev, ACPI_STATE_D0);
+
+ return 0;
+}
+
+/**
+ * acpi_dev_power_up_children_with_adr - Power up childres with valid _ADR
+ * @adev: Parent ACPI device object.
+ *
+ * Change the power states of the direct children of @adev that are in D3cold
+ * and hold valid _ADR objects to D0 in order to allow bus (e.g. PCI)
+ * enumeration code to access them.
+ */
+void acpi_dev_power_up_children_with_adr(struct acpi_device *adev)
+{
+ acpi_dev_for_each_child(adev, acpi_power_up_if_adr_present, NULL);
+}
+
#ifdef CONFIG_PM
static DEFINE_MUTEX(acpi_pm_notifier_lock);
static DEFINE_MUTEX(acpi_pm_notifier_install_lock);
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -525,6 +525,7 @@ int acpi_device_fix_up_power(struct acpi
int acpi_bus_update_power(acpi_handle handle, int *state_p);
int acpi_device_update_power(struct acpi_device *device, int *state_p);
bool acpi_bus_power_manageable(acpi_handle handle);
+void acpi_dev_power_up_children_with_adr(struct acpi_device *adev);
int acpi_device_power_add_dependent(struct acpi_device *adev,
struct device *dev);
void acpi_device_power_remove_dependent(struct acpi_device *adev,



2022-04-06 10:03:17

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v1 0/3] ACPI: PCI: PM: Power up PCI devices with ACPI companions upfront

On Tue, Apr 5, 2022 at 1:45 PM Mika Westerberg
<[email protected]> wrote:
>
> Hi Rafael,
>
> On Mon, Apr 04, 2022 at 05:20:30PM +0200, Rafael J. Wysocki wrote:
> > Hi All,
> >
> > There are cases in which the power state of a PCI device depends on an ACPI
> > power resource (or more of them) in such a way that when the given power
> > resource is in the "off" state, the PCI device depending on it is in D3cold.
> >
> > On some systems, the initial state of these power resources is "off", so the
> > kernel should not access the config space of PCI devices depending on them,
> > until the power resources in question are turned "on", but currently that is
> > not respected during PCI device enumeration. Namely, the PCI device
> > enumeration code walks the entire bus and enumerates all of the devices it
> > can find, including the ones whose initial power state in principle depends on
> > the ACPI power resources in the "off" state.
>
> I guess these devices do not have _PRE() method either.

Personally, I haven't seen any ACPI tables containing any _PRE yet.

> > Apparently, most of the time, the config space of such devices is accessible
> > regardless of the state of the ACPI power resource associated with the PCI
> > device, so the device enumeration is successful, but there are two potential
> > issues related to this behavior. First off, even if the given PCI device
> > is accessible when the ACPI power resource depended on by it is "off",
> > changing its configuration may confuse the platform firmware and lead to
> > problems when the ACPI power resource in question is turned "on". Second,
> > the PCI device may not be actually accessible at all when the ACPI power
> > resource depended on by it is "off", in which case it won't be found during
> > the PCI enumeration of devices.
> >
> > This patch series addresses that problem by turning "on" all ACPI power
> > resources depended on by PCI devices before attempting to access the config
> > space of those devices for the first time.
>
> Makes sense.
>
> For the series,
>
> Reviewed-by: Mika Westerberg <[email protected]>

Thanks!

2022-04-06 13:47:14

by Mika Westerberg

[permalink] [raw]
Subject: Re: [PATCH v1 0/3] ACPI: PCI: PM: Power up PCI devices with ACPI companions upfront

Hi Rafael,

On Mon, Apr 04, 2022 at 05:20:30PM +0200, Rafael J. Wysocki wrote:
> Hi All,
>
> There are cases in which the power state of a PCI device depends on an ACPI
> power resource (or more of them) in such a way that when the given power
> resource is in the "off" state, the PCI device depending on it is in D3cold.
>
> On some systems, the initial state of these power resources is "off", so the
> kernel should not access the config space of PCI devices depending on them,
> until the power resources in question are turned "on", but currently that is
> not respected during PCI device enumeration. Namely, the PCI device
> enumeration code walks the entire bus and enumerates all of the devices it
> can find, including the ones whose initial power state in principle depends on
> the ACPI power resources in the "off" state.

I guess these devices do not have _PRE() method either.

> Apparently, most of the time, the config space of such devices is accessible
> regardless of the state of the ACPI power resource associated with the PCI
> device, so the device enumeration is successful, but there are two potential
> issues related to this behavior. First off, even if the given PCI device
> is accessible when the ACPI power resource depended on by it is "off",
> changing its configuration may confuse the platform firmware and lead to
> problems when the ACPI power resource in question is turned "on". Second,
> the PCI device may not be actually accessible at all when the ACPI power
> resource depended on by it is "off", in which case it won't be found during
> the PCI enumeration of devices.
>
> This patch series addresses that problem by turning "on" all ACPI power
> resources depended on by PCI devices before attempting to access the config
> space of those devices for the first time.

Makes sense.

For the series,

Reviewed-by: Mika Westerberg <[email protected]>