aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-26 19:29:14 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-08-26 19:29:14 -0400
commit8462d9df9d5033da4d25e59016b1e7a9d94a1f22 (patch)
tree2317c60e9510664d74966b489a75287fd0ecc918 /drivers/acpi
parent0c581415b522267138d807814e526aa7534b9a61 (diff)
parent464c114717ae221202ebdbd9aa216035b4626f18 (diff)
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
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/glue.c91
1 files changed, 47 insertions, 44 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 408f6b2a5fa8..94672297e1b1 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)
173} 173}
174EXPORT_SYMBOL_GPL(acpi_find_child); 174EXPORT_SYMBOL_GPL(acpi_find_child);
175 175
176static void acpi_physnode_link_name(char *buf, unsigned int node_id)
177{
178 if (node_id > 0)
179 snprintf(buf, PHYSICAL_NODE_NAME_SIZE,
180 PHYSICAL_NODE_STRING "%u", node_id);
181 else
182 strcpy(buf, PHYSICAL_NODE_STRING);
183}
184
176int acpi_bind_one(struct device *dev, acpi_handle handle) 185int acpi_bind_one(struct device *dev, acpi_handle handle)
177{ 186{
178 struct acpi_device *acpi_dev; 187 struct acpi_device *acpi_dev;
@@ -216,8 +225,15 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
216 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) { 225 list_for_each_entry(pn, &acpi_dev->physical_node_list, node) {
217 /* Sanity check. */ 226 /* Sanity check. */
218 if (pn->dev == dev) { 227 if (pn->dev == dev) {
228 mutex_unlock(&acpi_dev->physical_node_lock);
229
219 dev_warn(dev, "Already associated with ACPI node\n"); 230 dev_warn(dev, "Already associated with ACPI node\n");
220 goto err_free; 231 kfree(physical_node);
232 if (ACPI_HANDLE(dev) != handle)
233 goto err;
234
235 put_device(dev);
236 return 0;
221 } 237 }
222 if (pn->node_id == node_id) { 238 if (pn->node_id == node_id) {
223 physnode_list = &pn->node; 239 physnode_list = &pn->node;
@@ -230,20 +246,23 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
230 list_add(&physical_node->node, physnode_list); 246 list_add(&physical_node->node, physnode_list);
231 acpi_dev->physical_node_count++; 247 acpi_dev->physical_node_count++;
232 248
233 mutex_unlock(&acpi_dev->physical_node_lock);
234
235 if (!ACPI_HANDLE(dev)) 249 if (!ACPI_HANDLE(dev))
236 ACPI_HANDLE_SET(dev, acpi_dev->handle); 250 ACPI_HANDLE_SET(dev, acpi_dev->handle);
237 251
238 if (!physical_node->node_id) 252 acpi_physnode_link_name(physical_node_name, node_id);
239 strcpy(physical_node_name, PHYSICAL_NODE_STRING);
240 else
241 sprintf(physical_node_name,
242 "physical_node%d", physical_node->node_id);
243 retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 253 retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
244 physical_node_name); 254 physical_node_name);
255 if (retval)
256 dev_err(&acpi_dev->dev, "Failed to create link %s (%d)\n",
257 physical_node_name, retval);
258
245 retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, 259 retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
246 "firmware_node"); 260 "firmware_node");
261 if (retval)
262 dev_err(dev, "Failed to create link firmware_node (%d)\n",
263 retval);
264
265 mutex_unlock(&acpi_dev->physical_node_lock);
247 266
248 if (acpi_dev->wakeup.flags.valid) 267 if (acpi_dev->wakeup.flags.valid)
249 device_set_wakeup_capable(dev, true); 268 device_set_wakeup_capable(dev, true);
@@ -254,11 +273,6 @@ int acpi_bind_one(struct device *dev, acpi_handle handle)
254 ACPI_HANDLE_SET(dev, NULL); 273 ACPI_HANDLE_SET(dev, NULL);
255 put_device(dev); 274 put_device(dev);
256 return retval; 275 return retval;
257
258 err_free:
259 mutex_unlock(&acpi_dev->physical_node_lock);
260 kfree(physical_node);
261 goto err;
262} 276}
263EXPORT_SYMBOL_GPL(acpi_bind_one); 277EXPORT_SYMBOL_GPL(acpi_bind_one);
264 278
@@ -267,48 +281,37 @@ int acpi_unbind_one(struct device *dev)
267 struct acpi_device_physical_node *entry; 281 struct acpi_device_physical_node *entry;
268 struct acpi_device *acpi_dev; 282 struct acpi_device *acpi_dev;
269 acpi_status status; 283 acpi_status status;
270 struct list_head *node, *next;
271 284
272 if (!ACPI_HANDLE(dev)) 285 if (!ACPI_HANDLE(dev))
273 return 0; 286 return 0;
274 287
275 status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); 288 status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev);
276 if (ACPI_FAILURE(status)) 289 if (ACPI_FAILURE(status)) {
277 goto err; 290 dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__);
291 return -EINVAL;
292 }
278 293
279 mutex_lock(&acpi_dev->physical_node_lock); 294 mutex_lock(&acpi_dev->physical_node_lock);
280 list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
281 char physical_node_name[PHYSICAL_NODE_NAME_SIZE];
282 295
283 entry = list_entry(node, struct acpi_device_physical_node, 296 list_for_each_entry(entry, &acpi_dev->physical_node_list, node)
284 node); 297 if (entry->dev == dev) {
285 if (entry->dev != dev) 298 char physnode_name[PHYSICAL_NODE_NAME_SIZE];
286 continue;
287 299
288 list_del(node); 300 list_del(&entry->node);
301 acpi_dev->physical_node_count--;
289 302
290 acpi_dev->physical_node_count--; 303 acpi_physnode_link_name(physnode_name, entry->node_id);
304 sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name);
305 sysfs_remove_link(&dev->kobj, "firmware_node");
306 ACPI_HANDLE_SET(dev, NULL);
307 /* acpi_bind_one() increase refcnt by one. */
308 put_device(dev);
309 kfree(entry);
310 break;
311 }
291 312
292 if (!entry->node_id)
293 strcpy(physical_node_name, PHYSICAL_NODE_STRING);
294 else
295 sprintf(physical_node_name,
296 "physical_node%d", entry->node_id);
297
298 sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
299 sysfs_remove_link(&dev->kobj, "firmware_node");
300 ACPI_HANDLE_SET(dev, NULL);
301 /* acpi_bind_one increase refcnt by one */
302 put_device(dev);
303 kfree(entry);
304 }
305 mutex_unlock(&acpi_dev->physical_node_lock); 313 mutex_unlock(&acpi_dev->physical_node_lock);
306
307 return 0; 314 return 0;
308
309err:
310 dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
311 return -EINVAL;
312} 315}
313EXPORT_SYMBOL_GPL(acpi_unbind_one); 316EXPORT_SYMBOL_GPL(acpi_unbind_one);
314 317