diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-26 19:29:14 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-08-26 19:29:14 -0400 |
commit | 8462d9df9d5033da4d25e59016b1e7a9d94a1f22 (patch) | |
tree | 2317c60e9510664d74966b489a75287fd0ecc918 /drivers/acpi | |
parent | 0c581415b522267138d807814e526aa7534b9a61 (diff) | |
parent | 464c114717ae221202ebdbd9aa216035b4626f18 (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.c | 91 |
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 | } |
174 | EXPORT_SYMBOL_GPL(acpi_find_child); | 174 | EXPORT_SYMBOL_GPL(acpi_find_child); |
175 | 175 | ||
176 | static 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 | |||
176 | int acpi_bind_one(struct device *dev, acpi_handle handle) | 185 | int 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 | } |
263 | EXPORT_SYMBOL_GPL(acpi_bind_one); | 277 | EXPORT_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 | |||
309 | err: | ||
310 | dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); | ||
311 | return -EINVAL; | ||
312 | } | 315 | } |
313 | EXPORT_SYMBOL_GPL(acpi_unbind_one); | 316 | EXPORT_SYMBOL_GPL(acpi_unbind_one); |
314 | 317 | ||