Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'acpi-bind'

* acpi-bind:
  ACPI: Print diagnostic messages if device links cannot be created
  ACPI: Drop unnecessary label from acpi_bind_one()
  ACPI: Clean up error code path in acpi_unbind_one()
  ACPI: Use list_for_each_entry() in acpi_unbind_one()
  ACPI: acpi_bind_one()/acpi_unbind_one() whitespace cleanups
  ACPI: Create symlinks in acpi_bind_one() under physical_node_lock
  ACPI: Reduce acpi_bind_one()/acpi_unbind_one() code duplication
  ACPI: Do not fail acpi_bind_one() if device is already bound correctly
parents 0c581415 464c1147
Loading
Loading
Loading
Loading
+47 −44
Original line number Original line Diff line number Diff line
@@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge)
}
}
EXPORT_SYMBOL_GPL(acpi_find_child);
EXPORT_SYMBOL_GPL(acpi_find_child);


static void acpi_physnode_link_name(char *buf, unsigned int node_id)
{
	if (node_id > 0)
		snprintf(buf, PHYSICAL_NODE_NAME_SIZE,
			 PHYSICAL_NODE_STRING "%u", node_id);
	else
		strcpy(buf, PHYSICAL_NODE_STRING);
}

int acpi_bind_one(struct device *dev, acpi_handle handle)
int acpi_bind_one(struct device *dev, acpi_handle handle)
{
{
	struct acpi_device *acpi_dev;
	struct acpi_device *acpi_dev;
@@ -216,8 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
	list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
		/* Sanity check. */
		/* Sanity check. */
		if (pn->dev == dev) {
		if (pn->dev == dev) {
			mutex_unlock(&acpi_dev->physical_node_lock);

			dev_warn(dev, "Already associated with ACPI node\n");
			dev_warn(dev, "Already associated with ACPI node\n");
			goto err_free;
			kfree(physical_node);
			if (ACPI_HANDLE(dev) != handle)
				goto err;

			put_device(dev);
			return 0;
		}
		}
		if (pn->node_id == node_id) {
		if (pn->node_id == node_id) {
			physnode_list = &pn->node;
			physnode_list = &pn->node;
@@ -230,20 +246,23 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
	list_add(&physical_node->node, physnode_list);
	list_add(&physical_node->node, physnode_list);
	acpi_dev->physical_node_count++;
	acpi_dev->physical_node_count++;


	mutex_unlock(&acpi_dev->physical_node_lock);

	if (!ACPI_HANDLE(dev))
	if (!ACPI_HANDLE(dev))
		ACPI_HANDLE_SET(dev, acpi_dev->handle);
		ACPI_HANDLE_SET(dev, acpi_dev->handle);


	if (!physical_node->node_id)
	acpi_physnode_link_name(physical_node_name, node_id);
		strcpy(physical_node_name, PHYSICAL_NODE_STRING);
	else
		sprintf(physical_node_name,
			"physical_node%d", physical_node->node_id);
	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
				   physical_node_name);
				   physical_node_name);
	if (retval)
		dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",
			physical_node_name, retval);

	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
				   "firmware_node");
				   "firmware_node");
	if (retval)
		dev_err(dev, "Failed to create link firmware_node (%d)\n",
			retval);

	mutex_unlock(&acpi_dev->physical_node_lock);


	if (acpi_dev->wakeup.flags.valid)
	if (acpi_dev->wakeup.flags.valid)
		device_set_wakeup_capable(dev, true);
		device_set_wakeup_capable(dev, true);
@@ -254,11 +273,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
	ACPI_HANDLE_SET(dev, NULL);
	ACPI_HANDLE_SET(dev, NULL);
	put_device(dev);
	put_device(dev);
	return retval;
	return retval;

 err_free:
	mutex_unlock(&acpi_dev->physical_node_lock);
	kfree(physical_node);
	goto err;
}
}
EXPORT_SYMBOL_GPL(acpi_bind_one);
EXPORT_SYMBOL_GPL(acpi_bind_one);


@@ -267,48 +281,37 @@ int acpi_unbind_one(struct device *dev)
	struct acpi_device_physical_node *entry;
	struct acpi_device_physical_node *entry;
	struct acpi_device *acpi_dev;
	struct acpi_device *acpi_dev;
	acpi_status status;
	acpi_status status;
	struct list_head *node, *next;


	if (!ACPI_HANDLE(dev))
	if (!ACPI_HANDLE(dev))
		return 0;
		return 0;


	status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev);
	status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev);
	if (ACPI_FAILURE(status))
	if (ACPI_FAILURE(status)) {
		goto err;
		dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__);
		return -EINVAL;
	}


	mutex_lock(&acpi_dev->physical_node_lock);
	mutex_lock(&acpi_dev->physical_node_lock);
	list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
		char physical_node_name[PHYSICAL_NODE_NAME_SIZE];

		entry = list_entry(node, struct acpi_device_physical_node,
			node);
		if (entry->dev != dev)
			continue;


		list_del(node);
	list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
		if (entry->dev == dev) {
			char physnode_name[PHYSICAL_NODE_NAME_SIZE];


			list_del(&entry->node);
			acpi_dev->physical_node_count--;
			acpi_dev->physical_node_count--;


		if (!entry->node_id)
			acpi_physnode_link_name(physnode_name, entry->node_id);
			strcpy(physical_node_name, PHYSICAL_NODE_STRING);
			sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
		else
			sprintf(physical_node_name,
				"physical_node%d", entry->node_id);

		sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
			sysfs_remove_link(&dev->kobj, "firmware_node");
			sysfs_remove_link(&dev->kobj, "firmware_node");
			ACPI_HANDLE_SET(dev, NULL);
			ACPI_HANDLE_SET(dev, NULL);
		/* acpi_bind_one increase refcnt by one */
			/* acpi_bind_one() increase refcnt by one. */
			put_device(dev);
			put_device(dev);
			kfree(entry);
			kfree(entry);
			break;
		}
		}
	mutex_unlock(&acpi_dev->physical_node_lock);


	mutex_unlock(&acpi_dev->physical_node_lock);
	return 0;
	return 0;

err:
	dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
	return -EINVAL;
}
}
EXPORT_SYMBOL_GPL(acpi_unbind_one);
EXPORT_SYMBOL_GPL(acpi_unbind_one);