Re: [linux-pm] [PATCH] ACPI / PM: Allow PCI root bridges to wake up the system

Rafael J. Wysocki
2009-08-31T19:40:25Z

On Sunday 30 August 2009, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rjw@sisk.pl>
>
> If PCI root bridge is declared in the ACPI tables as a wake-up
> device, allow it to wake up the system by default.
>
> This allows add-on PCI devices to work as wake-up devices on some
> systems, where PME# asserted by an add-on device causes the root
> bridge GPE to generate a wake-up event, without using
> /proc/acpi/wakeup to change the root bridge wake-up setting.

One piece is missing from the patch, I'll prepare an updated one shortly.

Thanks,
Rafael

> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
> ---
> drivers/acpi/glue.c | 3 +++
> drivers/acpi/pci_root.c | 25 +++++++++++++------------
> include/acpi/acpi_bus.h | 1 +
> 3 files changed, 17 insertions(+), 12 deletions(-)
>
> Index: linux-2.6/drivers/acpi/glue.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/glue.c
> +++ linux-2.6/drivers/acpi/glue.c
> @@ -168,6 +168,9 @@ static int acpi_bind_one(struct device *
> "physical_node");
> if (acpi_dev->wakeup.flags.valid) {
> device_set_wakeup_capable(dev, true);
> + /* Allow PCI root bridges to wake up the system. */
> + if (acpi_dev_is_root_bridge(acpi_dev))
> + acpi_dev->wakeup.state.enabled = true;
> device_set_wakeup_enable(dev,
> acpi_dev->wakeup.state.enabled);
> }
> Index: linux-2.6/drivers/acpi/pci_root.c
> ===================================================================
> --- linux-2.6.orig/drivers/acpi/pci_root.c
> +++ linux-2.6/drivers/acpi/pci_root.c
> @@ -138,26 +138,27 @@ acpi_handle acpi_get_pci_rootbridge_hand
> EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
>
> /**
> + * acpi_dev_is_root_bridge - determine if an ACPI device is a PCI root bridge
> + * @device: ACPI device to check.
> + */
> +bool acpi_dev_is_root_bridge(struct acpi_device *device)
> +{
> + return !acpi_match_device_ids(device, root_device_ids);
> +}
> +
> +/**
> * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
> - * @handle - the ACPI CA node in question.
> - *
> - * Note: we could make this API take a struct acpi_device * instead, but
> - * for now, it's more convenient to operate on an acpi_handle.
> + * @handle: the ACPI CA node in question.
> */
> int acpi_is_root_bridge(acpi_handle handle)
> {
> int ret;
> struct acpi_device *device;
>
> - ret = acpi_bus_get_device(handle, &device);
> + ret = !acpi_bus_get_device(handle, &device);
> if (ret)
> - return 0;
> -
> - ret = acpi_match_device_ids(device, root_device_ids);
> - if (ret)
> - return 0;
> - else
> - return 1;
> + ret = acpi_dev_is_root_bridge(device);
> + return ret;
> }
> EXPORT_SYMBOL_GPL(acpi_is_root_bridge);
>
> Index: linux-2.6/include/acpi/acpi_bus.h
> ===================================================================
> --- linux-2.6.orig/include/acpi/acpi_bus.h
> +++ linux-2.6/include/acpi/acpi_bus.h
> @@ -371,6 +371,7 @@ struct device *acpi_get_physical_device(
>
> /* helper */
> acpi_handle acpi_get_child(acpi_handle, acpi_integer);
> +bool acpi_dev_is_root_bridge(struct acpi_device *);
> int acpi_is_root_bridge(acpi_handle);
> acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
> #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))