From 3fe444ad7e3a6951fa0c9b552c5afe6f6df0d571 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:15:25 +0200 Subject: ACPI: Do not fail acpi_bind_one() if device is already bound correctly Modify acpi_bind_one() so that it doesn't fail if the device represented by its first argument has already been bound to the given ACPI handle (second argument), because that is not a good enough reason for returning an error code. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Lan Tianyu <tianyu.lan@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> --- drivers/acpi/glue.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 408f6b2a5fa8..48cc4c98e18b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -217,7 +217,10 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) /* Sanity check. */ if (pn->dev == dev) { dev_warn(dev, "Already associated with ACPI node\n"); - goto err_free; + if (ACPI_HANDLE(dev) == handle) + retval = 0; + + goto out_free; } if (pn->node_id == node_id) { physnode_list = &pn->node; @@ -255,10 +258,14 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) put_device(dev); return retval; - err_free: + out_free: mutex_unlock(&acpi_dev->physical_node_lock); kfree(physical_node); - goto err; + if (retval) + goto err; + + put_device(dev); + return 0; } EXPORT_SYMBOL_GPL(acpi_bind_one); -- cgit v1.2.3 From bdbdbf91081250657d018fc66d7cd0c07f337070 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:19:23 +0200 Subject: ACPI: Reduce acpi_bind_one()/acpi_unbind_one() code duplication Move some duplicated code from acpi_bind_one() and acpi_unbind_one() into a separate function and make that function use snprintf() instead of sprintf() for extra safety. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> --- drivers/acpi/glue.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 48cc4c98e18b..92cacb12ef5c 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -173,6 +173,15 @@ acpi_handle acpi_find_child(acpi_handle parent, u64 addr, bool is_bridge) } 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) { struct acpi_device *acpi_dev; @@ -238,11 +247,7 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) if (!ACPI_HANDLE(dev)) ACPI_HANDLE_SET(dev, acpi_dev->handle); - if (!physical_node->node_id) - strcpy(physical_node_name, PHYSICAL_NODE_STRING); - else - sprintf(physical_node_name, - "physical_node%d", physical_node->node_id); + acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, physical_node_name); retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, @@ -296,12 +301,7 @@ int acpi_unbind_one(struct device *dev) acpi_dev->physical_node_count--; - if (!entry->node_id) - strcpy(physical_node_name, PHYSICAL_NODE_STRING); - else - sprintf(physical_node_name, - "physical_node%d", entry->node_id); - + acpi_physnode_link_name(physical_node_name, entry->node_id); sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); sysfs_remove_link(&dev->kobj, "firmware_node"); ACPI_HANDLE_SET(dev, NULL); -- cgit v1.2.3 From 4005520648c7d6cf28e74addb52bc4a793eea3eb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:19:37 +0200 Subject: ACPI: Create symlinks in acpi_bind_one() under physical_node_lock Put the creation of symlinks in acpi_bind_one() under the physical_node_lock mutex of the given ACPI device object, because that is part of the binding operation logically (those links are already removed under that mutex too). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> --- drivers/acpi/glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 92cacb12ef5c..914a34601231 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -242,8 +242,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) list_add(&physical_node->node, physnode_list); acpi_dev->physical_node_count++; - mutex_unlock(&acpi_dev->physical_node_lock); - if (!ACPI_HANDLE(dev)) ACPI_HANDLE_SET(dev, acpi_dev->handle); @@ -253,6 +251,8 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, "firmware_node"); + mutex_unlock(&acpi_dev->physical_node_lock); + if (acpi_dev->wakeup.flags.valid) device_set_wakeup_capable(dev, true); -- cgit v1.2.3 From f501b6ec290f59b9c444bc061acf0e422347fb55 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:19:52 +0200 Subject: ACPI: acpi_bind_one()/acpi_unbind_one() whitespace cleanups Clean up some inconsistent use of whitespace in acpi_bind_one() and acpi_unbind_one(). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> --- drivers/acpi/glue.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 914a34601231..69641c061619 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -247,9 +247,9 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, - physical_node_name); + physical_node_name); retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, - "firmware_node"); + "firmware_node"); mutex_unlock(&acpi_dev->physical_node_lock); @@ -293,12 +293,11 @@ int acpi_unbind_one(struct device *dev) char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; entry = list_entry(node, struct acpi_device_physical_node, - node); + node); if (entry->dev != dev) continue; list_del(node); - acpi_dev->physical_node_count--; acpi_physnode_link_name(physical_node_name, entry->node_id); -- cgit v1.2.3 From 3e3327837c180781960188563b4e4d5c004c2b29 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:22:08 +0200 Subject: ACPI: Use list_for_each_entry() in acpi_unbind_one() Since acpi_unbind_one() walks physical_node_list under the ACPI device object's physical_node_lock mutex and the walk may be terminated as soon as the matching entry has been found, it is not necessary to use list_for_each_safe() for that walk, so use list_for_each_entry() instead and make the code slightly more straightforward. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> --- drivers/acpi/glue.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 69641c061619..570628e1def3 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -279,7 +279,6 @@ int acpi_unbind_one(struct device *dev) struct acpi_device_physical_node *entry; struct acpi_device *acpi_dev; acpi_status status; - struct list_head *node, *next; if (!ACPI_HANDLE(dev)) return 0; @@ -289,25 +288,24 @@ int acpi_unbind_one(struct device *dev) goto err; 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); - acpi_dev->physical_node_count--; - - acpi_physnode_link_name(physical_node_name, entry->node_id); - sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); - sysfs_remove_link(&dev->kobj, "firmware_node"); - ACPI_HANDLE_SET(dev, NULL); - /* acpi_bind_one increase refcnt by one */ - put_device(dev); - kfree(entry); - } + + 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_physnode_link_name(physnode_name, entry->node_id); + sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); + sysfs_remove_link(&dev->kobj, "firmware_node"); + ACPI_HANDLE_SET(dev, NULL); + /* acpi_bind_one() increase refcnt by one. */ + put_device(dev); + kfree(entry); + break; + } + mutex_unlock(&acpi_dev->physical_node_lock); return 0; -- cgit v1.2.3 From 38e88839eff8a3d2e8d3bcc2ad833fe51cca0496 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Wed, 7 Aug 2013 01:22:51 +0200 Subject: ACPI: Clean up error code path in acpi_unbind_one() The error code path in acpi_unbind_one() is unnecessarily complicated (in particular, the err label is not really necessary) and the error message printed by it is inaccurate (there's nothing called 'acpi_handle' in that function), so clean up those things. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> --- drivers/acpi/glue.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 570628e1def3..dcba319ac3f1 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -284,8 +284,10 @@ int acpi_unbind_one(struct device *dev) return 0; status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); - if (ACPI_FAILURE(status)) - goto err; + if (ACPI_FAILURE(status)) { + dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__); + return -EINVAL; + } mutex_lock(&acpi_dev->physical_node_lock); @@ -307,12 +309,7 @@ int acpi_unbind_one(struct device *dev) } mutex_unlock(&acpi_dev->physical_node_lock); - return 0; - -err: - dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); - return -EINVAL; } EXPORT_SYMBOL_GPL(acpi_unbind_one); -- cgit v1.2.3 From 3342c753bdeb29ec29d721c7ce38d283cc969174 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Thu, 8 Aug 2013 16:19:10 +0200 Subject: ACPI: Drop unnecessary label from acpi_bind_one() The out_free label in acpi_bind_one() is only jumped to from one place, so in fact it is not necessary, because the code below it can be moved to that place directly. Move that code and drop the label. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> --- drivers/acpi/glue.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index dcba319ac3f1..f3ead0ce37ab 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -225,11 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { /* Sanity check. */ if (pn->dev == dev) { + mutex_unlock(&acpi_dev->physical_node_lock); + dev_warn(dev, "Already associated with ACPI node\n"); - if (ACPI_HANDLE(dev) == handle) - retval = 0; + kfree(physical_node); + if (ACPI_HANDLE(dev) != handle) + goto err; - goto out_free; + put_device(dev); + return 0; } if (pn->node_id == node_id) { physnode_list = &pn->node; @@ -262,15 +266,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) ACPI_HANDLE_SET(dev, NULL); put_device(dev); return retval; - - out_free: - mutex_unlock(&acpi_dev->physical_node_lock); - kfree(physical_node); - if (retval) - goto err; - - put_device(dev); - return 0; } EXPORT_SYMBOL_GPL(acpi_bind_one); -- cgit v1.2.3 From 464c114717ae221202ebdbd9aa216035b4626f18 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Date: Thu, 8 Aug 2013 16:19:19 +0200 Subject: ACPI: Print diagnostic messages if device links cannot be created Although the device links created by acpi_bind_one() are not essential from the kernel functionality point of view, user space may be confused when they are missing, so print diagnostic messages to the kernel log if they can't be created. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> --- drivers/acpi/glue.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index f3ead0ce37ab..94672297e1b1 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -252,8 +252,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) acpi_physnode_link_name(physical_node_name, node_id); retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 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, "firmware_node"); + if (retval) + dev_err(dev, "Failed to create link firmware_node (%d)\n", + retval); mutex_unlock(&acpi_dev->physical_node_lock); -- cgit v1.2.3