summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-07-29 20:58:52 +0300
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2022-07-29 20:58:52 +0300
commitd60b6b0bc00365ab338804213437785d269f777b (patch)
treee3a56a9fc3e2cd3ebc2301bdd9058a0bc2679270 /drivers/acpi
parent4f4179fcf420873002035cf1941d844c9e0e7cb3 (diff)
parente6bdbcc764af822ff7172a4a78d437dc433a0c74 (diff)
downloadlinux-d60b6b0bc00365ab338804213437785d269f777b.tar.xz
Merge branch 'acpi-bus'
Merge ACPI device object management changes for v5.20-rc1. - Use the facilities provided by the driver core and some additional helpers to handle the children of a given ACPI device object in multiple places instead of using the children and node list heads in struct acpi_device which is error prone (Rafael Wysocki). - Fix ACPI-related device reference counting issue in the hisi_lpc bus driver (Yang Yingliang). - Drop the children and node list heads that are not needed any more from struct acpi_device (Rafael Wysocki). - Drop driver member from struct acpi_device (Uwe Kleine-König). - Drop redundant check from acpi_device_remove() (Uwe Kleine-König). * acpi-bus: ACPI: bus: Drop unused list heads from struct acpi_device hisi_lpc: Use acpi_dev_for_each_child() bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe() ACPI: bus: Drop driver member of struct acpi_device ACPI: bus: Drop redundant check in acpi_device_remove() mfd: core: Use acpi_dev_for_each_child() ACPI / MMC: PM: Unify fixing up device power soundwire: Use acpi_dev_for_each_child() platform/x86/thinkpad_acpi: Use acpi_dev_for_each_child() ACPI: scan: Walk ACPI device's children using driver core ACPI: bus: Introduce acpi_dev_for_each_child_reverse() ACPI: video: Use acpi_dev_for_each_child() ACPI: bus: Export acpi_dev_for_each_child() to modules ACPI: property: Use acpi_dev_for_each_child() for child lookup ACPI: container: Use acpi_dev_for_each_child() USB: ACPI: Replace usb_acpi_find_port() with acpi_find_child_by_adr() thunderbolt: ACPI: Replace tb_acpi_find_port() with acpi_find_child_by_adr() ACPI: glue: Introduce acpi_find_child_by_adr() ACPI: glue: Introduce acpi_dev_has_children() ACPI: glue: Use acpi_dev_for_each_child()
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpi_video.c41
-rw-r--r--drivers/acpi/bus.c46
-rw-r--r--drivers/acpi/container.c17
-rw-r--r--drivers/acpi/device_pm.c22
-rw-r--r--drivers/acpi/device_sysfs.c2
-rw-r--r--drivers/acpi/glue.c133
-rw-r--r--drivers/acpi/property.c45
-rw-r--r--drivers/acpi/scan.c70
8 files changed, 224 insertions, 152 deletions
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index eaea733b368a..5cbe2196176d 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -1150,24 +1150,25 @@ acpi_video_get_device_type(struct acpi_video_bus *video,
return 0;
}
-static int
-acpi_video_bus_get_one_device(struct acpi_device *device,
- struct acpi_video_bus *video)
+static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg)
{
- unsigned long long device_id;
- int status, device_type;
- struct acpi_video_device *data;
+ struct acpi_video_bus *video = arg;
struct acpi_video_device_attrib *attribute;
+ struct acpi_video_device *data;
+ unsigned long long device_id;
+ acpi_status status;
+ int device_type;
- status =
- acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
- /* Some device omits _ADR, we skip them instead of fail */
+ status = acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
+ /* Skip devices without _ADR instead of failing. */
if (ACPI_FAILURE(status))
- return 0;
+ goto exit;
data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
- if (!data)
+ if (!data) {
+ dev_dbg(&device->dev, "Cannot attach\n");
return -ENOMEM;
+ }
strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -1230,7 +1231,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
list_add_tail(&data->entry, &video->video_device_list);
mutex_unlock(&video->device_list_lock);
- return status;
+exit:
+ video->child_count++;
+ return 0;
}
/*
@@ -1542,9 +1545,6 @@ static int
acpi_video_bus_get_devices(struct acpi_video_bus *video,
struct acpi_device *device)
{
- int status = 0;
- struct acpi_device *dev;
-
/*
* There are systems where video module known to work fine regardless
* of broken _DOD and ignoring returned value here doesn't cause
@@ -1552,16 +1552,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
*/
acpi_video_device_enumerate(video);
- list_for_each_entry(dev, &device->children, node) {
-
- status = acpi_video_bus_get_one_device(dev, video);
- if (status) {
- dev_err(&dev->dev, "Can't attach device\n");
- break;
- }
- video->child_count++;
- }
- return status;
+ return acpi_dev_for_each_child(device, acpi_video_bus_get_one_device, video);
}
/* acpi_video interface */
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e2db1bdd9dd2..901b2b7ce88b 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -464,7 +464,6 @@ out_free:
static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
{
struct acpi_device *adev;
- struct acpi_driver *driver;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
bool hotplug_event = false;
@@ -516,10 +515,13 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
if (!adev)
goto err;
- driver = adev->driver;
- if (driver && driver->ops.notify &&
- (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
- driver->ops.notify(adev, type);
+ if (adev->dev.driver) {
+ struct acpi_driver *driver = to_acpi_driver(adev->dev.driver);
+
+ if (driver && driver->ops.notify &&
+ (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
+ driver->ops.notify(adev, type);
+ }
if (!hotplug_event) {
acpi_bus_put_acpi_device(adev);
@@ -538,8 +540,9 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
static void acpi_notify_device(acpi_handle handle, u32 event, void *data)
{
struct acpi_device *device = data;
+ struct acpi_driver *acpi_drv = to_acpi_driver(device->dev.driver);
- device->driver->ops.notify(device, event);
+ acpi_drv->ops.notify(device, event);
}
static void acpi_notify_device_fixed(void *data)
@@ -1032,8 +1035,6 @@ static int acpi_device_probe(struct device *dev)
if (ret)
return ret;
- acpi_dev->driver = acpi_drv;
-
pr_debug("Driver [%s] successfully bound to device [%s]\n",
acpi_drv->name, acpi_dev->pnp.bus_id);
@@ -1043,7 +1044,6 @@ static int acpi_device_probe(struct device *dev)
if (acpi_drv->ops.remove)
acpi_drv->ops.remove(acpi_dev);
- acpi_dev->driver = NULL;
acpi_dev->driver_data = NULL;
return ret;
}
@@ -1059,15 +1059,14 @@ static int acpi_device_probe(struct device *dev)
static void acpi_device_remove(struct device *dev)
{
struct acpi_device *acpi_dev = to_acpi_device(dev);
- struct acpi_driver *acpi_drv = acpi_dev->driver;
+ struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
+
+ if (acpi_drv->ops.notify)
+ acpi_device_remove_notify_handler(acpi_dev);
+
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev);
- if (acpi_drv) {
- if (acpi_drv->ops.notify)
- acpi_device_remove_notify_handler(acpi_dev);
- if (acpi_drv->ops.remove)
- acpi_drv->ops.remove(acpi_dev);
- }
- acpi_dev->driver = NULL;
acpi_dev->driver_data = NULL;
put_device(dev);
@@ -1101,6 +1100,7 @@ static int acpi_dev_for_one_check(struct device *dev, void *context)
return adwc->fn(to_acpi_device(dev), adwc->data);
}
+EXPORT_SYMBOL_GPL(acpi_dev_for_each_child);
int acpi_dev_for_each_child(struct acpi_device *adev,
int (*fn)(struct acpi_device *, void *), void *data)
@@ -1113,6 +1113,18 @@ int acpi_dev_for_each_child(struct acpi_device *adev,
return device_for_each_child(&adev->dev, &adwc, acpi_dev_for_one_check);
}
+int acpi_dev_for_each_child_reverse(struct acpi_device *adev,
+ int (*fn)(struct acpi_device *, void *),
+ void *data)
+{
+ struct acpi_dev_walk_context adwc = {
+ .fn = fn,
+ .data = data,
+ };
+
+ return device_for_each_child_reverse(&adev->dev, &adwc, acpi_dev_for_one_check);
+}
+
/* --------------------------------------------------------------------------
Initialization/Cleanup
-------------------------------------------------------------------------- */
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index ccaa647ac3d4..5b7e3b9ae370 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -23,17 +23,18 @@ static const struct acpi_device_id container_device_ids[] = {
#ifdef CONFIG_ACPI_CONTAINER
-static int acpi_container_offline(struct container_dev *cdev)
+static int check_offline(struct acpi_device *adev, void *not_used)
{
- struct acpi_device *adev = ACPI_COMPANION(&cdev->dev);
- struct acpi_device *child;
+ if (acpi_scan_is_offline(adev, false))
+ return 0;
- /* Check all of the dependent devices' physical companions. */
- list_for_each_entry(child, &adev->children, node)
- if (!acpi_scan_is_offline(child, false))
- return -EBUSY;
+ return -EBUSY;
+}
- return 0;
+static int acpi_container_offline(struct container_dev *cdev)
+{
+ /* Check all of the dependent devices' physical companions. */
+ return acpi_dev_for_each_child(ACPI_COMPANION(&cdev->dev), check_offline, NULL);
}
static void acpi_container_release(struct device *dev)
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 130b5f4a50a3..9dce1245689c 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -369,6 +369,28 @@ int acpi_device_fix_up_power(struct acpi_device *device)
}
EXPORT_SYMBOL_GPL(acpi_device_fix_up_power);
+static int fix_up_power_if_applicable(struct acpi_device *adev, void *not_used)
+{
+ if (adev->status.present && adev->status.enabled)
+ acpi_device_fix_up_power(adev);
+
+ return 0;
+}
+
+/**
+ * acpi_device_fix_up_power_extended - Force device and its children into D0.
+ * @adev: Parent device object whose power state is to be fixed up.
+ *
+ * Call acpi_device_fix_up_power() for @adev and its children so long as they
+ * are reported as present and enabled.
+ */
+void acpi_device_fix_up_power_extended(struct acpi_device *adev)
+{
+ acpi_device_fix_up_power(adev);
+ acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL);
+}
+EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended);
+
int acpi_device_update_power(struct acpi_device *device, int *state_p)
{
int state;
diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c
index d5d6403ba07b..120873dad2cc 100644
--- a/drivers/acpi/device_sysfs.c
+++ b/drivers/acpi/device_sysfs.c
@@ -376,7 +376,7 @@ eject_store(struct device *d, struct device_attribute *attr,
return -EINVAL;
if ((!acpi_device->handler || !acpi_device->handler->hotplug.enabled)
- && !acpi_device->driver)
+ && !d->driver)
return -ENODEV;
status = acpi_get_type(acpi_device->handle, &not_used);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 8d769114a048..204fe94c7e45 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -77,12 +77,22 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
#define FIND_CHILD_MIN_SCORE 1
#define FIND_CHILD_MAX_SCORE 2
+static int match_any(struct acpi_device *adev, void *not_used)
+{
+ return 1;
+}
+
+static bool acpi_dev_has_children(struct acpi_device *adev)
+{
+ return acpi_dev_for_each_child(adev, match_any, NULL) > 0;
+}
+
static int find_child_checks(struct acpi_device *adev, bool check_children)
{
unsigned long long sta;
acpi_status status;
- if (check_children && list_empty(&adev->children))
+ if (check_children && !acpi_dev_has_children(adev))
return -ENODEV;
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
@@ -105,54 +115,97 @@ static int find_child_checks(struct acpi_device *adev, bool check_children)
return FIND_CHILD_MAX_SCORE;
}
-struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
- u64 address, bool check_children)
-{
- struct acpi_device *adev, *ret = NULL;
- int ret_score = 0;
-
- if (!parent)
- return NULL;
+struct find_child_walk_data {
+ struct acpi_device *adev;
+ u64 address;
+ int score;
+ bool check_sta;
+ bool check_children;
+};
- list_for_each_entry(adev, &parent->children, node) {
- acpi_bus_address addr = acpi_device_adr(adev);
- int score;
+static int check_one_child(struct acpi_device *adev, void *data)
+{
+ struct find_child_walk_data *wd = data;
+ int score;
- if (!adev->pnp.type.bus_address || addr != address)
- continue;
+ if (!adev->pnp.type.bus_address || acpi_device_adr(adev) != wd->address)
+ return 0;
- if (!ret) {
- /* This is the first matching object. Save it. */
- ret = adev;
- continue;
- }
+ if (!wd->adev) {
/*
- * There is more than one matching device object with the same
- * _ADR value. That really is unexpected, so we are kind of
- * beyond the scope of the spec here. We have to choose which
- * one to return, though.
- *
- * First, check if the previously found object is good enough
- * and return it if so. Second, do the same for the object that
- * we've just found.
+ * This is the first matching object, so save it. If it is not
+ * necessary to look for any other matching objects, stop the
+ * search.
*/
- if (!ret_score) {
- ret_score = find_child_checks(ret, check_children);
- if (ret_score == FIND_CHILD_MAX_SCORE)
- return ret;
- }
- score = find_child_checks(adev, check_children);
- if (score == FIND_CHILD_MAX_SCORE) {
- return adev;
- } else if (score > ret_score) {
- ret = adev;
- ret_score = score;
- }
+ wd->adev = adev;
+ return !(wd->check_sta || wd->check_children);
}
- return ret;
+
+ /*
+ * There is more than one matching device object with the same _ADR
+ * value. That really is unexpected, so we are kind of beyond the scope
+ * of the spec here. We have to choose which one to return, though.
+ *
+ * First, get the score for the previously found object and terminate
+ * the walk if it is maximum.
+ */
+ if (!wd->score) {
+ score = find_child_checks(wd->adev, wd->check_children);
+ if (score == FIND_CHILD_MAX_SCORE)
+ return 1;
+
+ wd->score = score;
+ }
+ /*
+ * Second, if the object that has just been found has a better score,
+ * replace the previously found one with it and terminate the walk if
+ * the new score is maximum.
+ */
+ score = find_child_checks(adev, wd->check_children);
+ if (score > wd->score) {
+ wd->adev = adev;
+ if (score == FIND_CHILD_MAX_SCORE)
+ return 1;
+
+ wd->score = score;
+ }
+
+ /* Continue, because there may be better matches. */
+ return 0;
+}
+
+static struct acpi_device *acpi_find_child(struct acpi_device *parent,
+ u64 address, bool check_children,
+ bool check_sta)
+{
+ struct find_child_walk_data wd = {
+ .address = address,
+ .check_children = check_children,
+ .check_sta = check_sta,
+ .adev = NULL,
+ .score = 0,
+ };
+
+ if (parent)
+ acpi_dev_for_each_child(parent, check_one_child, &wd);
+
+ return wd.adev;
+}
+
+struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
+ u64 address, bool check_children)
+{
+ return acpi_find_child(parent, address, check_children, true);
}
EXPORT_SYMBOL_GPL(acpi_find_child_device);
+struct acpi_device *acpi_find_child_by_adr(struct acpi_device *adev,
+ acpi_bus_address adr)
+{
+ return acpi_find_child(adev, adr, false, false);
+}
+EXPORT_SYMBOL_GPL(acpi_find_child_by_adr);
+
static void acpi_physnode_link_name(char *buf, unsigned int node_id)
{
if (node_id > 0)
diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
index d3173811614e..e764f9ac9cf8 100644
--- a/drivers/acpi/property.c
+++ b/drivers/acpi/property.c
@@ -1012,6 +1012,22 @@ static int acpi_node_prop_read(const struct fwnode_handle *fwnode,
propname, proptype, val, nval);
}
+static int stop_on_next(struct acpi_device *adev, void *data)
+{
+ struct acpi_device **ret_p = data;
+
+ if (!*ret_p) {
+ *ret_p = adev;
+ return 1;
+ }
+
+ /* Skip until the "previous" object is found. */
+ if (*ret_p == adev)
+ *ret_p = NULL;
+
+ return 0;
+}
+
/**
* acpi_get_next_subnode - Return the next child node handle for a fwnode
* @fwnode: Firmware node to find the next child node for.
@@ -1020,35 +1036,22 @@ static int acpi_node_prop_read(const struct fwnode_handle *fwnode,
struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
- const struct acpi_device *adev = to_acpi_device_node(fwnode);
- const struct list_head *head;
- struct list_head *next;
+ struct acpi_device *adev = to_acpi_device_node(fwnode);
if ((!child || is_acpi_device_node(child)) && adev) {
- struct acpi_device *child_adev;
+ struct acpi_device *child_adev = to_acpi_device_node(child);
- head = &adev->children;
- if (list_empty(head))
- goto nondev;
+ acpi_dev_for_each_child(adev, stop_on_next, &child_adev);
+ if (child_adev)
+ return acpi_fwnode_handle(child_adev);
- if (child) {
- adev = to_acpi_device_node(child);
- next = adev->node.next;
- if (next == head) {
- child = NULL;
- goto nondev;
- }
- child_adev = list_entry(next, struct acpi_device, node);
- } else {
- child_adev = list_first_entry(head, struct acpi_device,
- node);
- }
- return acpi_fwnode_handle(child_adev);
+ child = NULL;
}
- nondev:
if (!child || is_acpi_data_node(child)) {
const struct acpi_data_node *data = to_acpi_data_node(fwnode);
+ const struct list_head *head;
+ struct list_head *next;
struct acpi_data_node *dn;
/*
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 762b61f67e6c..b100e6ca9bb4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -334,10 +334,9 @@ static int acpi_scan_device_check(struct acpi_device *adev)
return error;
}
-static int acpi_scan_bus_check(struct acpi_device *adev)
+static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
{
struct acpi_scan_handler *handler = adev->handler;
- struct acpi_device *child;
int error;
acpi_bus_get_status(adev);
@@ -353,19 +352,14 @@ static int acpi_scan_bus_check(struct acpi_device *adev)
dev_warn(&adev->dev, "Namespace scan failure\n");
return error;
}
- list_for_each_entry(child, &adev->children, node) {
- error = acpi_scan_bus_check(child);
- if (error)
- return error;
- }
- return 0;
+ return acpi_dev_for_each_child(adev, acpi_scan_bus_check, NULL);
}
static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
{
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
- return acpi_scan_bus_check(adev);
+ return acpi_scan_bus_check(adev, NULL);
case ACPI_NOTIFY_DEVICE_CHECK:
return acpi_scan_device_check(adev);
case ACPI_NOTIFY_EJECT_REQUEST:
@@ -471,8 +465,6 @@ static void acpi_device_del(struct acpi_device *device)
struct acpi_device_bus_id *acpi_device_bus_id;
mutex_lock(&acpi_device_lock);
- if (device->parent)
- list_del(&device->node);
list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)
if (!strcmp(acpi_device_bus_id->bus_id,
@@ -488,6 +480,7 @@ static void acpi_device_del(struct acpi_device *device)
}
list_del(&device->wakeup_list);
+
mutex_unlock(&acpi_device_lock);
acpi_power_add_remove_device(device, false);
@@ -680,8 +673,6 @@ static int __acpi_device_add(struct acpi_device *device,
* -------
* Link this device to its parent and siblings.
*/
- INIT_LIST_HEAD(&device->children);
- INIT_LIST_HEAD(&device->node);
INIT_LIST_HEAD(&device->wakeup_list);
INIT_LIST_HEAD(&device->physical_node_list);
INIT_LIST_HEAD(&device->del_list);
@@ -721,9 +712,6 @@ static int __acpi_device_add(struct acpi_device *device,
list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
}
- if (device->parent)
- list_add_tail(&device->node, &device->parent->children);
-
if (device->wakeup.flags.valid)
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
@@ -752,9 +740,6 @@ static int __acpi_device_add(struct acpi_device *device,
err:
mutex_lock(&acpi_device_lock);
- if (device->parent)
- list_del(&device->node);
-
list_del(&device->wakeup_list);
err_unlock:
@@ -2187,9 +2172,8 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
return ret;
}
-static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
+static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
{
- struct acpi_device *child;
bool skip = !first_pass && device->flags.visited;
acpi_handle ejd;
int ret;
@@ -2206,7 +2190,7 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
device->flags.initialized = false;
acpi_device_clear_enumerated(device);
device->flags.power_manageable = 0;
- return;
+ return 0;
}
if (device->handler)
goto ok;
@@ -2224,7 +2208,7 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
ret = acpi_scan_attach_handler(device);
if (ret < 0)
- return;
+ return 0;
device->flags.match_driver = true;
if (ret > 0 && !device->flags.enumeration_by_parent) {
@@ -2234,19 +2218,20 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
ret = device_attach(&device->dev);
if (ret < 0)
- return;
+ return 0;
if (device->pnp.type.platform_id || device->flags.enumeration_by_parent)
acpi_default_enumeration(device);
else
acpi_device_set_enumerated(device);
- ok:
- list_for_each_entry(child, &device->children, node)
- acpi_bus_attach(child, first_pass);
+ok:
+ acpi_dev_for_each_child(device, acpi_bus_attach, first_pass);
if (!skip && device->handler && device->handler->hotplug.notify_online)
device->handler->hotplug.notify_online(device);
+
+ return 0;
}
static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
@@ -2274,7 +2259,7 @@ static void acpi_scan_clear_dep_fn(struct work_struct *work)
cdw = container_of(work, struct acpi_scan_clear_dep_work, work);
acpi_scan_lock_acquire();
- acpi_bus_attach(cdw->adev, true);
+ acpi_bus_attach(cdw->adev, (void *)true);
acpi_scan_lock_release();
acpi_dev_put(cdw->adev);
@@ -2432,7 +2417,7 @@ int acpi_bus_scan(acpi_handle handle)
if (!device)
return -ENODEV;
- acpi_bus_attach(device, true);
+ acpi_bus_attach(device, (void *)true);
if (!acpi_bus_scan_second_pass)
return 0;
@@ -2446,25 +2431,17 @@ int acpi_bus_scan(acpi_handle handle)
acpi_bus_check_add_2, NULL, NULL,
(void **)&device);
- acpi_bus_attach(device, false);
+ acpi_bus_attach(device, NULL);
return 0;
}
EXPORT_SYMBOL(acpi_bus_scan);
-/**
- * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects.
- * @adev: Root of the ACPI namespace scope to walk.
- *
- * Must be called under acpi_scan_lock.
- */
-void acpi_bus_trim(struct acpi_device *adev)
+static int acpi_bus_trim_one(struct acpi_device *adev, void *not_used)
{
struct acpi_scan_handler *handler = adev->handler;
- struct acpi_device *child;
- list_for_each_entry_reverse(child, &adev->children, node)
- acpi_bus_trim(child);
+ acpi_dev_for_each_child_reverse(adev, acpi_bus_trim_one, NULL);
adev->flags.match_driver = false;
if (handler) {
@@ -2482,6 +2459,19 @@ void acpi_bus_trim(struct acpi_device *adev)
acpi_device_set_power(adev, ACPI_STATE_D3_COLD);
adev->flags.initialized = false;
acpi_device_clear_enumerated(adev);
+
+ return 0;
+}
+
+/**
+ * acpi_bus_trim - Detach scan handlers and drivers from ACPI device objects.
+ * @adev: Root of the ACPI namespace scope to walk.
+ *
+ * Must be called under acpi_scan_lock.
+ */
+void acpi_bus_trim(struct acpi_device *adev)
+{
+ acpi_bus_trim_one(adev, NULL);
}
EXPORT_SYMBOL_GPL(acpi_bus_trim);