Skip to content

Commit

Permalink
Merge branches 'acpi-scan', 'acpi-pnp' and 'acpi-sleep'
Browse files Browse the repository at this point in the history
* acpi-scan:
  ACPI: scan: Add Intel Baytrail Mailbox Device to acpi_ignore_dep_ids
  ACPI: scan: Avoid unnecessary second pass in acpi_bus_scan()
  ACPI: scan: Defer enumeration of devices with _DEP lists
  ACPI: scan: Evaluate _DEP before adding the device

* acpi-pnp:
  ACPI: PNP: compare the string length in the matching_id()

* acpi-sleep:
  ACPI: PM: s2idle: Move x86-specific code to the x86 directory
  ACPI: PM: s2idle: Add AMD support to handle _DSM
  • Loading branch information
Rafael J. Wysocki committed Dec 22, 2020
4 parents aab7ce2 + 9272e97 + b08221c + fef9867 commit 538fcf5
Show file tree
Hide file tree
Showing 6 changed files with 598 additions and 330 deletions.
1 change: 1 addition & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ acpi-y += property.o
acpi-$(CONFIG_X86) += acpi_cmos_rtc.o
acpi-$(CONFIG_X86) += x86/apple.o
acpi-$(CONFIG_X86) += x86/utils.o
acpi-$(CONFIG_X86) += x86/s2idle.o
acpi-$(CONFIG_DEBUG_FS) += debugfs.o
acpi-y += acpi_lpat.o
acpi-$(CONFIG_ACPI_LPIT) += acpi_lpit.o
Expand Down
3 changes: 3 additions & 0 deletions drivers/acpi/acpi_pnp.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ static bool matching_id(const char *idstr, const char *list_id)
{
int i;

if (strlen(idstr) != strlen(list_id))
return false;

if (memcmp(idstr, list_id, 3))
return false;

Expand Down
143 changes: 106 additions & 37 deletions drivers/acpi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info,
/* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */
static const char * const acpi_ignore_dep_ids[] = {
"PNP0D80", /* Windows-compatible System Power Management Controller */
"INT33BD", /* Intel Baytrail Mailbox Device */
NULL
};

Expand Down Expand Up @@ -1635,8 +1636,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
device_initialize(&device->dev);
dev_set_uevent_suppress(&device->dev, true);
acpi_init_coherency(device);
/* Assume there are unmet deps until acpi_device_dep_initialize() runs */
device->dep_unmet = 1;
}

void acpi_device_add_finalize(struct acpi_device *device)
Expand Down Expand Up @@ -1842,32 +1841,36 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev)
}
}

static void acpi_device_dep_initialize(struct acpi_device *adev)
static u32 acpi_scan_check_dep(acpi_handle handle)
{
struct acpi_dep_data *dep;
struct acpi_handle_list dep_devices;
acpi_status status;
u32 count;
int i;

adev->dep_unmet = 0;

if (!acpi_has_method(adev->handle, "_DEP"))
return;
/*
* Check for _HID here to avoid deferring the enumeration of:
* 1. PCI devices.
* 2. ACPI nodes describing USB ports.
* Still, checking for _HID catches more then just these cases ...
*/
if (!acpi_has_method(handle, "_DEP") || !acpi_has_method(handle, "_HID"))
return 0;

status = acpi_evaluate_reference(adev->handle, "_DEP", NULL,
&dep_devices);
status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices);
if (ACPI_FAILURE(status)) {
dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n");
return;
acpi_handle_debug(handle, "Failed to evaluate _DEP.\n");
return 0;
}

for (i = 0; i < dep_devices.count; i++) {
for (count = 0, i = 0; i < dep_devices.count; i++) {
struct acpi_device_info *info;
int skip;
struct acpi_dep_data *dep;
bool skip;

status = acpi_get_object_info(dep_devices.handles[i], &info);
if (ACPI_FAILURE(status)) {
dev_dbg(&adev->dev, "Error reading _DEP device info\n");
acpi_handle_debug(handle, "Error reading _DEP device info\n");
continue;
}

Expand All @@ -1877,26 +1880,45 @@ static void acpi_device_dep_initialize(struct acpi_device *adev)
if (skip)
continue;

dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL);
dep = kzalloc(sizeof(*dep), GFP_KERNEL);
if (!dep)
return;
continue;

count++;

dep->supplier = dep_devices.handles[i];
dep->consumer = adev->handle;
adev->dep_unmet++;
dep->consumer = handle;

mutex_lock(&acpi_dep_list_lock);
list_add_tail(&dep->node , &acpi_dep_list);
mutex_unlock(&acpi_dep_list_lock);
}

return count;
}

static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **return_value)
static void acpi_scan_dep_init(struct acpi_device *adev)
{
struct acpi_dep_data *dep;

mutex_lock(&acpi_dep_list_lock);

list_for_each_entry(dep, &acpi_dep_list, node) {
if (dep->consumer == adev->handle)
adev->dep_unmet++;
}

mutex_unlock(&acpi_dep_list_lock);
}

static bool acpi_bus_scan_second_pass;

static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
struct acpi_device **adev_p)
{
struct acpi_device *device = NULL;
int type;
unsigned long long sta;
int type;
int result;

acpi_bus_get_device(handle, &device);
Expand All @@ -1912,20 +1934,42 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
return AE_OK;
}

if (type == ACPI_BUS_TYPE_DEVICE && check_dep) {
u32 count = acpi_scan_check_dep(handle);
/* Bail out if the number of recorded dependencies is not 0. */
if (count > 0) {
acpi_bus_scan_second_pass = true;
return AE_CTRL_DEPTH;
}
}

acpi_add_single_object(&device, handle, type, sta);
if (!device)
return AE_CTRL_DEPTH;

acpi_scan_init_hotplug(device);
acpi_device_dep_initialize(device);
if (!check_dep)
acpi_scan_dep_init(device);

out:
if (!*return_value)
*return_value = device;
out:
if (!*adev_p)
*adev_p = device;

return AE_OK;
}

static acpi_status acpi_bus_check_add_1(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **ret_p)
{
return acpi_bus_check_add(handle, true, (struct acpi_device **)ret_p);
}

static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used,
void *not_used, void **ret_p)
{
return acpi_bus_check_add(handle, false, (struct acpi_device **)ret_p);
}

static void acpi_default_enumeration(struct acpi_device *device)
{
/*
Expand Down Expand Up @@ -1993,12 +2037,16 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
return ret;
}

static void acpi_bus_attach(struct acpi_device *device)
static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
{
struct acpi_device *child;
bool skip = !first_pass && device->flags.visited;
acpi_handle ejd;
int ret;

if (skip)
goto ok;

if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd)))
register_dock_dependent_device(device, ejd);

Expand Down Expand Up @@ -2045,9 +2093,9 @@ static void acpi_bus_attach(struct acpi_device *device)

ok:
list_for_each_entry(child, &device->children, node)
acpi_bus_attach(child);
acpi_bus_attach(child, first_pass);

if (device->handler && device->handler->hotplug.notify_online)
if (!skip && device->handler && device->handler->hotplug.notify_online)
device->handler->hotplug.notify_online(device);
}

Expand All @@ -2065,7 +2113,8 @@ void acpi_walk_dep_device_list(acpi_handle handle)

adev->dep_unmet--;
if (!adev->dep_unmet)
acpi_bus_attach(adev);
acpi_bus_attach(adev, true);

list_del(&dep->node);
kfree(dep);
}
Expand All @@ -2090,17 +2139,37 @@ EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);
*/
int acpi_bus_scan(acpi_handle handle)
{
void *device = NULL;
struct acpi_device *device = NULL;

acpi_bus_scan_second_pass = false;

if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
/* Pass 1: Avoid enumerating devices with missing dependencies. */

if (ACPI_SUCCESS(acpi_bus_check_add(handle, true, &device)))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
acpi_bus_check_add, NULL, NULL, &device);
acpi_bus_check_add_1, NULL, NULL,
(void **)&device);

if (!device)
return -ENODEV;

if (device) {
acpi_bus_attach(device);
acpi_bus_attach(device, true);

if (!acpi_bus_scan_second_pass)
return 0;
}
return -ENODEV;

/* Pass 2: Enumerate all of the remaining devices. */

device = NULL;

if (ACPI_SUCCESS(acpi_bus_check_add(handle, false, &device)))
acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
acpi_bus_check_add_2, NULL, NULL,
(void **)&device);

acpi_bus_attach(device, false);

return 0;
}
EXPORT_SYMBOL(acpi_bus_scan);

Expand Down
Loading

0 comments on commit 538fcf5

Please sign in to comment.