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

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
...@@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
node); if (entry->dev == dev) {
if (entry->dev != dev) char physnode_name[PHYSICAL_NODE_NAME_SIZE];
continue;
list_del(node);
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment