Commit bf325f95 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Len Brown

ACPI / PM: Register power resource devices as soon as they are needed

Depending on the organization of the ACPI namespace, power resource
device objects may generally be scanned after the "regular" device
objects that they are referred from through _PRn.  This, in turn, may
cause acpi_bus_get_power_flags() to attempt to access them through
acpi_bus_init_power() before they are registered (and initialized by
acpi_power_driver).  [This is not a theoretical issue, it actually
happens for one PnP device on my testbed HP nx6325.]

To fix this problem, make acpi_bus_get_power_flags() attempt to
register power resource devices as soon as they have been found in
the _PRn output for any other devices.
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 97d9a9e9
...@@ -847,6 +847,8 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) ...@@ -847,6 +847,8 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
return 0; return 0;
} }
static void acpi_bus_add_power_resource(acpi_handle handle);
static int acpi_bus_get_power_flags(struct acpi_device *device) static int acpi_bus_get_power_flags(struct acpi_device *device)
{ {
acpi_status status = 0; acpi_status status = 0;
...@@ -875,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) ...@@ -875,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
acpi_evaluate_reference(device->handle, object_name, NULL, acpi_evaluate_reference(device->handle, object_name, NULL,
&ps->resources); &ps->resources);
if (ps->resources.count) { if (ps->resources.count) {
int j;
device->power.flags.power_resources = 1; device->power.flags.power_resources = 1;
ps->flags.valid = 1; ps->flags.valid = 1;
for (j = 0; j < ps->resources.count; j++)
acpi_bus_add_power_resource(ps->resources.handles[j]);
} }
/* Evaluate "_PSx" to see if we can do explicit sets */ /* Evaluate "_PSx" to see if we can do explicit sets */
...@@ -1323,6 +1329,20 @@ static int acpi_add_single_object(struct acpi_device **child, ...@@ -1323,6 +1329,20 @@ static int acpi_add_single_object(struct acpi_device **child,
#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
static void acpi_bus_add_power_resource(acpi_handle handle)
{
struct acpi_bus_ops ops = {
.acpi_op_add = 1,
.acpi_op_start = 1,
};
struct acpi_device *device = NULL;
acpi_bus_get_device(handle, &device);
if (!device)
acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
ACPI_STA_DEFAULT, &ops);
}
static int acpi_bus_type_and_status(acpi_handle handle, int *type, static int acpi_bus_type_and_status(acpi_handle handle, int *type,
unsigned long long *sta) unsigned long long *sta)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment