Commit a9e10e58 authored by Daniel Scally's avatar Daniel Scally Committed by Rafael J. Wysocki
Browse files

ACPI: scan: Extend acpi_walk_dep_device_list()



The acpi_walk_dep_device_list() function is not as generic as its
name implies, serving only to decrement the dependency count for each
dependent device of the input.

Extend it to accept a callback which can be applied to all the
dependencies in acpi_dep_list.

Replace all existing calls to the function with calls to a wrapper,
passing a callback that applies the same dependency reduction.

Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Maximilian Luz <luzmaximilian@gmail.com>  # for platform/surface parts
Signed-off-by: default avatarDaniel Scally <djrscally@gmail.com>
[ rjw: Changelog edits ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 6d279758
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1627,7 +1627,7 @@ static int acpi_ec_add(struct acpi_device *device)
	WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);

	/* Reprobe devices depending on the EC */
	acpi_walk_dep_device_list(ec->handle);
	acpi_dev_clear_dependencies(device);

	acpi_handle_debug(ec->handle, "enumerated.\n");
	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev)
		return err;

	/* Re-enumerate devices depending on PMIC */
	acpi_walk_dep_device_list(ACPI_HANDLE(pdev->dev.parent));
	acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent));
	return 0;
}

+51 −18
Original line number Diff line number Diff line
@@ -47,12 +47,6 @@ static DEFINE_MUTEX(acpi_hp_context_lock);
 */
static u64 spcr_uart_addr;

struct acpi_dep_data {
	struct list_head node;
	acpi_handle supplier;
	acpi_handle consumer;
};

void acpi_scan_lock_acquire(void)
{
	mutex_lock(&acpi_scan_lock);
@@ -2107,14 +2101,10 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
		device->handler->hotplug.notify_online(device);
}

void acpi_walk_dep_device_list(acpi_handle handle)
static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
{
	struct acpi_dep_data *dep, *tmp;
	struct acpi_device *adev;

	mutex_lock(&acpi_dep_list_lock);
	list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
		if (dep->supplier == handle) {
	acpi_bus_get_device(dep->consumer, &adev);

	if (adev) {
@@ -2125,12 +2115,55 @@ void acpi_walk_dep_device_list(acpi_handle handle)

	list_del(&dep->node);
	kfree(dep);

	return 0;
}

/**
 * acpi_walk_dep_device_list - Apply a callback to every entry in acpi_dep_list
 * @handle:	The ACPI handle of the supplier device
 * @callback:	Pointer to the callback function to apply
 * @data:	Pointer to some data to pass to the callback
 *
 * The return value of the callback determines this function's behaviour. If 0
 * is returned we continue to iterate over acpi_dep_list. If a positive value
 * is returned then the loop is broken but this function returns 0. If a
 * negative value is returned by the callback then the loop is broken and that
 * value is returned as the final error.
 */
int acpi_walk_dep_device_list(acpi_handle handle,
			      int (*callback)(struct acpi_dep_data *, void *),
			      void *data)
{
	struct acpi_dep_data *dep, *tmp;
	int ret;

	mutex_lock(&acpi_dep_list_lock);
	list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
		if (dep->supplier == handle) {
			ret = callback(dep, data);
			if (ret)
				break;
		}
	}
	mutex_unlock(&acpi_dep_list_lock);

	return ret > 0 ? 0 : ret;
}
EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);

/**
 * acpi_dev_clear_dependencies - Inform consumers that the device is now active
 * @supplier: Pointer to the supplier &struct acpi_device
 *
 * Clear dependencies on the given device.
 */
void acpi_dev_clear_dependencies(struct acpi_device *supplier)
{
	acpi_walk_dep_device_list(supplier->handle, acpi_scan_clear_dep, NULL);
}
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);

/**
 * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
 * @handle: Root of the namespace scope to scan.
+5 −5
Original line number Diff line number Diff line
@@ -1233,14 +1233,14 @@ static void acpi_gpiochip_scan_gpios(struct acpi_gpio_chip *achip)
void acpi_gpiochip_add(struct gpio_chip *chip)
{
	struct acpi_gpio_chip *acpi_gpio;
	acpi_handle handle;
	struct acpi_device *adev;
	acpi_status status;

	if (!chip || !chip->parent)
		return;

	handle = ACPI_HANDLE(chip->parent);
	if (!handle)
	adev = ACPI_COMPANION(chip->parent);
	if (!adev)
		return;

	acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL);
@@ -1254,7 +1254,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
	INIT_LIST_HEAD(&acpi_gpio->events);
	INIT_LIST_HEAD(&acpi_gpio->deferred_req_irqs_list_entry);

	status = acpi_attach_data(handle, acpi_gpio_chip_dh, acpi_gpio);
	status = acpi_attach_data(adev->handle, acpi_gpio_chip_dh, acpi_gpio);
	if (ACPI_FAILURE(status)) {
		dev_err(chip->parent, "Failed to attach ACPI GPIO chip\n");
		kfree(acpi_gpio);
@@ -1263,7 +1263,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip)

	acpi_gpiochip_request_regions(acpi_gpio);
	acpi_gpiochip_scan_gpios(acpi_gpio);
	acpi_walk_dep_device_list(handle);
	acpi_dev_clear_dependencies(adev);
}

void acpi_gpiochip_remove(struct gpio_chip *chip)
+4 −4
Original line number Diff line number Diff line
@@ -259,8 +259,8 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
 */
void i2c_acpi_register_devices(struct i2c_adapter *adap)
{
	struct acpi_device *adev;
	acpi_status status;
	acpi_handle handle;

	if (!has_acpi_companion(&adap->dev))
		return;
@@ -275,11 +275,11 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)
	if (!adap->dev.parent)
		return;

	handle = ACPI_HANDLE(adap->dev.parent);
	if (!handle)
	adev = ACPI_COMPANION(adap->dev.parent);
	if (!adev)
		return;

	acpi_walk_dep_device_list(handle);
	acpi_dev_clear_dependencies(adev);
}

static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
Loading