mirror of https://gitee.com/openkylin/linux.git
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: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
97d9a9e9f5
commit
bf325f9538
|
@ -847,6 +847,8 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_bus_add_power_resource(acpi_handle handle);
|
||||
|
||||
static int acpi_bus_get_power_flags(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status = 0;
|
||||
|
@ -875,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
|
|||
acpi_evaluate_reference(device->handle, object_name, NULL,
|
||||
&ps->resources);
|
||||
if (ps->resources.count) {
|
||||
int j;
|
||||
|
||||
device->power.flags.power_resources = 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 */
|
||||
|
@ -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 | \
|
||||
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,
|
||||
unsigned long long *sta)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue