Commit d60b6b0b authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

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()
parents 4f4179fc e6bdbcc7
Loading
Loading
Loading
Loading
+16 −25
Original line number Diff line number Diff line
@@ -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 */
+29 −17
Original line number Diff line number Diff line
@@ -464,7 +464,6 @@ static void acpi_bus_osc_negotiate_usb_control(void)
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 (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) {
	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
   -------------------------------------------------------------------------- */
+9 −8
Original line number Diff line number Diff line
@@ -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 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)
+22 −0
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
Loading