aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 14:22:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 14:22:45 -0400
commit02b9735c12892e04d3e101b06e4c6d64a814f566 (patch)
tree7907deb1cbfd1599d4f34d414873170d3266f164 /drivers/acpi
parent75acebf2423ab13ff6198daa6e17ef7a2543bfe4 (diff)
parentf1728fd1599112239ed5cebc7be9810264db6792 (diff)
Merge tag 'pm+acpi-fixes-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management fixes from Rafael Wysocki: "All of these commits are fixes that have emerged recently and some of them fix bugs introduced during this merge window. Specifics: 1) ACPI-based PCI hotplug (ACPIPHP) fixes related to spurious events After the recent ACPIPHP changes we've seen some interesting breakage on a system that triggers device check notifications during boot for non-existing devices. Although those notifications are really spurious, we should be able to deal with them nevertheless and that shouldn't introduce too much overhead. Four commits to make that work properly. 2) Memory hotplug and hibernation mutual exclusion rework This was maent to be a cleanup, but it happens to fix a classical ABBA deadlock between system suspend/hibernation and ACPI memory hotplug which is possible if they are started roughly at the same time. Three commits rework memory hotplug so that it doesn't acquire pm_mutex and make hibernation use device_hotplug_lock which prevents it from racing with memory hotplug. 3) ACPI Intel LPSS (Low-Power Subsystem) driver crash fix The ACPI LPSS driver crashes during boot on Apple Macbook Air with Haswell that has slightly unusual BIOS configuration in which one of the LPSS device's _CRS method doesn't return all of the information expected by the driver. Fix from Mika Westerberg, for stable. 4) ACPICA fix related to Store->ArgX operation AML interpreter fix for obscure breakage that causes AML to be executed incorrectly on some machines (observed in practice). From Bob Moore. 5) ACPI core fix for PCI ACPI device objects lookup There still are cases in which there is more than one ACPI device object matching a given PCI device and we don't choose the one that the BIOS expects us to choose, so this makes the lookup take more criteria into account in those cases. 6) Fix to prevent cpuidle from crashing in some rare cases If the result of cpuidle_get_driver() is NULL, which can happen on some systems, cpuidle_driver_ref() will crash trying to use that pointer and the Daniel Fu's fix prevents that from happening. 7) cpufreq fixes related to CPU hotplug Stephen Boyd reported a number of concurrency problems with cpufreq related to CPU hotplug which are addressed by a series of fixes from Srivatsa S Bhat and Viresh Kumar. 8) cpufreq fix for time conversion in time_in_state attribute Time conversion carried out by cpufreq when user space attempts to read /sys/devices/system/cpu/cpu*/cpufreq/stats/time_in_state won't work correcty if cputime_t doesn't map directly to jiffies. Fix from Andreas Schwab. 9) Revert of a troublesome cpufreq commit Commit 7c30ed5 (cpufreq: make sure frequency transitions are serialized) was intended to address some known concurrency problems in cpufreq related to the ordering of transitions, but unfortunately it introduced several problems of its own, so I decided to revert it now and address the original problems later in a more robust way. 10) Intel Haswell CPU models for intel_pstate from Nell Hardcastle. 11) cpufreq fixes related to system suspend/resume The recent cpufreq changes that made it preserve CPU sysfs attributes over suspend/resume cycles introduced a possible NULL pointer dereference that caused it to crash during the second attempt to suspend. Three commits from Srivatsa S Bhat fix that problem and a couple of related issues. 12) cpufreq locking fix cpufreq_policy_restore() should acquire the lock for reading, but it acquires it for writing. Fix from Lan Tianyu" * tag 'pm+acpi-fixes-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (25 commits) cpufreq: Acquire the lock in cpufreq_policy_restore() for reading cpufreq: Prevent problems in update_policy_cpu() if last_cpu == new_cpu cpufreq: Restructure if/else block to avoid unintended behavior cpufreq: Fix crash in cpufreq-stats during suspend/resume intel_pstate: Add Haswell CPU models Revert "cpufreq: make sure frequency transitions are serialized" cpufreq: Use signed type for 'ret' variable, to store negative error values cpufreq: Remove temporary fix for race between CPU hotplug and sysfs-writes cpufreq: Synchronize the cpufreq store_*() routines with CPU hotplug cpufreq: Invoke __cpufreq_remove_dev_finish() after releasing cpu_hotplug.lock cpufreq: Split __cpufreq_remove_dev() into two parts cpufreq: Fix wrong time unit conversion cpufreq: serialize calls to __cpufreq_governor() cpufreq: don't allow governor limits to be changed when it is disabled ACPI / bind: Prefer device objects with _STA to those without it ACPI / hotplug / PCI: Avoid parent bus rescans on spurious device checks ACPI / hotplug / PCI: Use _OST to notify firmware about notify status ACPI / hotplug / PCI: Avoid doing too much for spurious notifies ACPICA: Fix for a Store->ArgX when ArgX contains a reference to a field. ACPI / hotplug / PCI: Don't trim devices before scanning the namespace ...
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpi_lpss.c3
-rw-r--r--drivers/acpi/acpica/exstore.c166
-rw-r--r--drivers/acpi/glue.c35
-rw-r--r--drivers/acpi/scan.c15
4 files changed, 134 insertions, 85 deletions
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 6a382188fa20..fb78bb9ad8f6 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -257,12 +257,13 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
257 pdata->mmio_size = resource_size(&rentry->res); 257 pdata->mmio_size = resource_size(&rentry->res);
258 pdata->mmio_base = ioremap(rentry->res.start, 258 pdata->mmio_base = ioremap(rentry->res.start,
259 pdata->mmio_size); 259 pdata->mmio_size);
260 pdata->dev_desc = dev_desc;
261 break; 260 break;
262 } 261 }
263 262
264 acpi_dev_free_resource_list(&resource_list); 263 acpi_dev_free_resource_list(&resource_list);
265 264
265 pdata->dev_desc = dev_desc;
266
266 if (dev_desc->clk_required) { 267 if (dev_desc->clk_required) {
267 ret = register_device_clock(adev, pdata); 268 ret = register_device_clock(adev, pdata);
268 if (ret) { 269 if (ret) {
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index 2bdba6f7d762..f0b09bf9887d 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -57,6 +57,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
57 union acpi_operand_object *dest_desc, 57 union acpi_operand_object *dest_desc,
58 struct acpi_walk_state *walk_state); 58 struct acpi_walk_state *walk_state);
59 59
60static acpi_status
61acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
62 struct acpi_namespace_node *node,
63 struct acpi_walk_state *walk_state);
64
60/******************************************************************************* 65/*******************************************************************************
61 * 66 *
62 * FUNCTION: acpi_ex_store 67 * FUNCTION: acpi_ex_store
@@ -375,7 +380,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
375 * When storing into an object the data is converted to the 380 * When storing into an object the data is converted to the
376 * target object type then stored in the object. This means 381 * target object type then stored in the object. This means
377 * that the target object type (for an initialized target) will 382 * that the target object type (for an initialized target) will
378 * not be changed by a store operation. 383 * not be changed by a store operation. A copy_object can change
384 * the target type, however.
385 *
386 * The implicit_conversion flag is set to NO/FALSE only when
387 * storing to an arg_x -- as per the rules of the ACPI spec.
379 * 388 *
380 * Assumes parameters are already validated. 389 * Assumes parameters are already validated.
381 * 390 *
@@ -399,7 +408,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
399 target_type = acpi_ns_get_type(node); 408 target_type = acpi_ns_get_type(node);
400 target_desc = acpi_ns_get_attached_object(node); 409 target_desc = acpi_ns_get_attached_object(node);
401 410
402 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", 411 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n",
403 source_desc, 412 source_desc,
404 acpi_ut_get_object_type_name(source_desc), node, 413 acpi_ut_get_object_type_name(source_desc), node,
405 acpi_ut_get_type_name(target_type))); 414 acpi_ut_get_type_name(target_type)));
@@ -413,45 +422,30 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
413 return_ACPI_STATUS(status); 422 return_ACPI_STATUS(status);
414 } 423 }
415 424
416 /* If no implicit conversion, drop into the default case below */
417
418 if ((!implicit_conversion) ||
419 ((walk_state->opcode == AML_COPY_OP) &&
420 (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
421 (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
422 (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
423 /*
424 * Force execution of default (no implicit conversion). Note:
425 * copy_object does not perform an implicit conversion, as per the ACPI
426 * spec -- except in case of region/bank/index fields -- because these
427 * objects must retain their original type permanently.
428 */
429 target_type = ACPI_TYPE_ANY;
430 }
431
432 /* Do the actual store operation */ 425 /* Do the actual store operation */
433 426
434 switch (target_type) { 427 switch (target_type) {
435 case ACPI_TYPE_BUFFER_FIELD:
436 case ACPI_TYPE_LOCAL_REGION_FIELD:
437 case ACPI_TYPE_LOCAL_BANK_FIELD:
438 case ACPI_TYPE_LOCAL_INDEX_FIELD:
439
440 /* For fields, copy the source data to the target field. */
441
442 status = acpi_ex_write_data_to_field(source_desc, target_desc,
443 &walk_state->result_obj);
444 break;
445
446 case ACPI_TYPE_INTEGER: 428 case ACPI_TYPE_INTEGER:
447 case ACPI_TYPE_STRING: 429 case ACPI_TYPE_STRING:
448 case ACPI_TYPE_BUFFER: 430 case ACPI_TYPE_BUFFER:
449 /* 431 /*
450 * These target types are all of type Integer/String/Buffer, and 432 * The simple data types all support implicit source operand
451 * therefore support implicit conversion before the store. 433 * conversion before the store.
452 *
453 * Copy and/or convert the source object to a new target object
454 */ 434 */
435
436 if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) {
437 /*
438 * However, copy_object and Stores to arg_x do not perform
439 * an implicit conversion, as per the ACPI specification.
440 * A direct store is performed instead.
441 */
442 status = acpi_ex_store_direct_to_node(source_desc, node,
443 walk_state);
444 break;
445 }
446
447 /* Store with implicit source operand conversion support */
448
455 status = 449 status =
456 acpi_ex_store_object_to_object(source_desc, target_desc, 450 acpi_ex_store_object_to_object(source_desc, target_desc,
457 &new_desc, walk_state); 451 &new_desc, walk_state);
@@ -465,13 +459,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
465 * the Name's type to that of the value being stored in it. 459 * the Name's type to that of the value being stored in it.
466 * source_desc reference count is incremented by attach_object. 460 * source_desc reference count is incremented by attach_object.
467 * 461 *
468 * Note: This may change the type of the node if an explicit store 462 * Note: This may change the type of the node if an explicit
469 * has been performed such that the node/object type has been 463 * store has been performed such that the node/object type
470 * changed. 464 * has been changed.
471 */ 465 */
472 status = 466 status = acpi_ns_attach_object(node, new_desc,
473 acpi_ns_attach_object(node, new_desc, 467 new_desc->common.type);
474 new_desc->common.type);
475 468
476 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 469 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
477 "Store %s into %s via Convert/Attach\n", 470 "Store %s into %s via Convert/Attach\n",
@@ -482,38 +475,83 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
482 } 475 }
483 break; 476 break;
484 477
485 default: 478 case ACPI_TYPE_BUFFER_FIELD:
486 479 case ACPI_TYPE_LOCAL_REGION_FIELD:
487 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 480 case ACPI_TYPE_LOCAL_BANK_FIELD:
488 "Storing [%s] (%p) directly into node [%s] (%p)" 481 case ACPI_TYPE_LOCAL_INDEX_FIELD:
489 " with no implicit conversion\n", 482 /*
490 acpi_ut_get_object_type_name(source_desc), 483 * For all fields, always write the source data to the target
491 source_desc, 484 * field. Any required implicit source operand conversion is
492 acpi_ut_get_object_type_name(target_desc), 485 * performed in the function below as necessary. Note, field
493 node)); 486 * objects must retain their original type permanently.
487 */
488 status = acpi_ex_write_data_to_field(source_desc, target_desc,
489 &walk_state->result_obj);
490 break;
494 491
492 default:
495 /* 493 /*
496 * No conversions for all other types. Directly store a copy of 494 * No conversions for all other types. Directly store a copy of
497 * the source object. NOTE: This is a departure from the ACPI 495 * the source object. This is the ACPI spec-defined behavior for
498 * spec, which states "If conversion is impossible, abort the 496 * the copy_object operator.
499 * running control method".
500 * 497 *
501 * This code implements "If conversion is impossible, treat the 498 * NOTE: For the Store operator, this is a departure from the
502 * Store operation as a CopyObject". 499 * ACPI spec, which states "If conversion is impossible, abort
500 * the running control method". Instead, this code implements
501 * "If conversion is impossible, treat the Store operation as
502 * a CopyObject".
503 */ 503 */
504 status = 504 status = acpi_ex_store_direct_to_node(source_desc, node,
505 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, 505 walk_state);
506 walk_state);
507 if (ACPI_FAILURE(status)) {
508 return_ACPI_STATUS(status);
509 }
510
511 status =
512 acpi_ns_attach_object(node, new_desc,
513 new_desc->common.type);
514 acpi_ut_remove_reference(new_desc);
515 break; 506 break;
516 } 507 }
517 508
518 return_ACPI_STATUS(status); 509 return_ACPI_STATUS(status);
519} 510}
511
512/*******************************************************************************
513 *
514 * FUNCTION: acpi_ex_store_direct_to_node
515 *
516 * PARAMETERS: source_desc - Value to be stored
517 * node - Named object to receive the value
518 * walk_state - Current walk state
519 *
520 * RETURN: Status
521 *
522 * DESCRIPTION: "Store" an object directly to a node. This involves a copy
523 * and an attach.
524 *
525 ******************************************************************************/
526
527static acpi_status
528acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
529 struct acpi_namespace_node *node,
530 struct acpi_walk_state *walk_state)
531{
532 acpi_status status;
533 union acpi_operand_object *new_desc;
534
535 ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
536
537 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
538 "Storing [%s] (%p) directly into node [%s] (%p)"
539 " with no implicit conversion\n",
540 acpi_ut_get_object_type_name(source_desc),
541 source_desc, acpi_ut_get_type_name(node->type),
542 node));
543
544 /* Copy the source object to a new object */
545
546 status =
547 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
548 if (ACPI_FAILURE(status)) {
549 return_ACPI_STATUS(status);
550 }
551
552 /* Attach the new object to the node */
553
554 status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
555 acpi_ut_remove_reference(new_desc);
556 return_ACPI_STATUS(status);
557}
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 94672297e1b1..10f0f40587bb 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -79,6 +79,9 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
79 return ret; 79 return ret;
80} 80}
81 81
82#define FIND_CHILD_MIN_SCORE 1
83#define FIND_CHILD_MAX_SCORE 2
84
82static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used, 85static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
83 void *not_used, void **ret_p) 86 void *not_used, void **ret_p)
84{ 87{
@@ -92,14 +95,17 @@ static acpi_status acpi_dev_present(acpi_handle handle, u32 lvl_not_used,
92 return AE_OK; 95 return AE_OK;
93} 96}
94 97
95static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge) 98static int do_find_child_checks(acpi_handle handle, bool is_bridge)
96{ 99{
100 bool sta_present = true;
97 unsigned long long sta; 101 unsigned long long sta;
98 acpi_status status; 102 acpi_status status;
99 103
100 status = acpi_bus_get_status_handle(handle, &sta); 104 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
101 if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED)) 105 if (status == AE_NOT_FOUND)
102 return false; 106 sta_present = false;
107 else if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_ENABLED))
108 return -ENODEV;
103 109
104 if (is_bridge) { 110 if (is_bridge) {
105 void *test = NULL; 111 void *test = NULL;
@@ -107,16 +113,17 @@ static bool acpi_extra_checks_passed(acpi_handle handle, bool is_bridge)
107 /* Check if this object has at least one child device. */ 113 /* Check if this object has at least one child device. */
108 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 114 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
109 acpi_dev_present, NULL, NULL, &test); 115 acpi_dev_present, NULL, NULL, &test);
110 return !!test; 116 if (!test)
117 return -ENODEV;
111 } 118 }
112 return true; 119 return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
113} 120}
114 121
115struct find_child_context { 122struct find_child_context {
116 u64 addr; 123 u64 addr;
117 bool is_bridge; 124 bool is_bridge;
118 acpi_handle ret; 125 acpi_handle ret;
119 bool ret_checked; 126 int ret_score;
120}; 127};
121 128
122static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used, 129static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
@@ -125,6 +132,7 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
125 struct find_child_context *context = data; 132 struct find_child_context *context = data;
126 unsigned long long addr; 133 unsigned long long addr;
127 acpi_status status; 134 acpi_status status;
135 int score;
128 136
129 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr); 137 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
130 if (ACPI_FAILURE(status) || addr != context->addr) 138 if (ACPI_FAILURE(status) || addr != context->addr)
@@ -144,15 +152,20 @@ static acpi_status do_find_child(acpi_handle handle, u32 lvl_not_used,
144 * its handle if so. Second, check the same for the object that we've 152 * its handle if so. Second, check the same for the object that we've
145 * just found. 153 * just found.
146 */ 154 */
147 if (!context->ret_checked) { 155 if (!context->ret_score) {
148 if (acpi_extra_checks_passed(context->ret, context->is_bridge)) 156 score = do_find_child_checks(context->ret, context->is_bridge);
157 if (score == FIND_CHILD_MAX_SCORE)
149 return AE_CTRL_TERMINATE; 158 return AE_CTRL_TERMINATE;
150 else 159 else
151 context->ret_checked = true; 160 context->ret_score = score;
152 } 161 }
153 if (acpi_extra_checks_passed(handle, context->is_bridge)) { 162 score = do_find_child_checks(handle, context->is_bridge);
163 if (score == FIND_CHILD_MAX_SCORE) {
154 context->ret = handle; 164 context->ret = handle;
155 return AE_CTRL_TERMINATE; 165 return AE_CTRL_TERMINATE;
166 } else if (score > context->ret_score) {
167 context->ret = handle;
168 context->ret_score = score;
156 } 169 }
157 return AE_OK; 170 return AE_OK;
158} 171}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 61d090b6ce25..fbdb82e70d10 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -204,8 +204,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
204 return -EINVAL; 204 return -EINVAL;
205 } 205 }
206 206
207 lock_device_hotplug();
208
209 /* 207 /*
210 * Carry out two passes here and ignore errors in the first pass, 208 * Carry out two passes here and ignore errors in the first pass,
211 * because if the devices in question are memory blocks and 209 * because if the devices in question are memory blocks and
@@ -236,9 +234,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
236 ACPI_UINT32_MAX, 234 ACPI_UINT32_MAX,
237 acpi_bus_online_companions, NULL, 235 acpi_bus_online_companions, NULL,
238 NULL, NULL); 236 NULL, NULL);
239
240 unlock_device_hotplug();
241
242 put_device(&device->dev); 237 put_device(&device->dev);
243 return -EBUSY; 238 return -EBUSY;
244 } 239 }
@@ -249,8 +244,6 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
249 244
250 acpi_bus_trim(device); 245 acpi_bus_trim(device);
251 246
252 unlock_device_hotplug();
253
254 /* Device node has been unregistered. */ 247 /* Device node has been unregistered. */
255 put_device(&device->dev); 248 put_device(&device->dev);
256 device = NULL; 249 device = NULL;
@@ -289,6 +282,7 @@ static void acpi_bus_device_eject(void *context)
289 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 282 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
290 int error; 283 int error;
291 284
285 lock_device_hotplug();
292 mutex_lock(&acpi_scan_lock); 286 mutex_lock(&acpi_scan_lock);
293 287
294 acpi_bus_get_device(handle, &device); 288 acpi_bus_get_device(handle, &device);
@@ -312,6 +306,7 @@ static void acpi_bus_device_eject(void *context)
312 306
313 out: 307 out:
314 mutex_unlock(&acpi_scan_lock); 308 mutex_unlock(&acpi_scan_lock);
309 unlock_device_hotplug();
315 return; 310 return;
316 311
317 err_out: 312 err_out:
@@ -326,8 +321,8 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
326 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 321 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
327 int error; 322 int error;
328 323
329 mutex_lock(&acpi_scan_lock);
330 lock_device_hotplug(); 324 lock_device_hotplug();
325 mutex_lock(&acpi_scan_lock);
331 326
332 if (ost_source != ACPI_NOTIFY_BUS_CHECK) { 327 if (ost_source != ACPI_NOTIFY_BUS_CHECK) {
333 acpi_bus_get_device(handle, &device); 328 acpi_bus_get_device(handle, &device);
@@ -353,9 +348,9 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
353 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); 348 kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
354 349
355 out: 350 out:
356 unlock_device_hotplug();
357 acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL); 351 acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
358 mutex_unlock(&acpi_scan_lock); 352 mutex_unlock(&acpi_scan_lock);
353 unlock_device_hotplug();
359} 354}
360 355
361static void acpi_scan_bus_check(void *context) 356static void acpi_scan_bus_check(void *context)
@@ -446,6 +441,7 @@ void acpi_bus_hot_remove_device(void *context)
446 acpi_handle handle = device->handle; 441 acpi_handle handle = device->handle;
447 int error; 442 int error;
448 443
444 lock_device_hotplug();
449 mutex_lock(&acpi_scan_lock); 445 mutex_lock(&acpi_scan_lock);
450 446
451 error = acpi_scan_hot_remove(device); 447 error = acpi_scan_hot_remove(device);
@@ -455,6 +451,7 @@ void acpi_bus_hot_remove_device(void *context)
455 NULL); 451 NULL);
456 452
457 mutex_unlock(&acpi_scan_lock); 453 mutex_unlock(&acpi_scan_lock);
454 unlock_device_hotplug();
458 kfree(context); 455 kfree(context);
459} 456}
460EXPORT_SYMBOL(acpi_bus_hot_remove_device); 457EXPORT_SYMBOL(acpi_bus_hot_remove_device);