aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/scan.c137
-rw-r--r--drivers/pci/hotplug/acpiphp.h9
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c168
-rw-r--r--include/acpi/acpi_bus.h25
4 files changed, 158 insertions, 181 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d64a5826ef35..984eaff235df 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -450,43 +450,61 @@ static int acpi_scan_bus_check(struct acpi_device *adev)
450 return 0; 450 return 0;
451} 451}
452 452
453static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
454{
455 switch (type) {
456 case ACPI_NOTIFY_BUS_CHECK:
457 return acpi_scan_bus_check(adev);
458 case ACPI_NOTIFY_DEVICE_CHECK:
459 return acpi_scan_device_check(adev);
460 case ACPI_NOTIFY_EJECT_REQUEST:
461 case ACPI_OST_EC_OSPM_EJECT:
462 return acpi_scan_hot_remove(adev);
463 }
464 return -EINVAL;
465}
466
453static void acpi_device_hotplug(void *data, u32 src) 467static void acpi_device_hotplug(void *data, u32 src)
454{ 468{
455 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 469 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
456 struct acpi_device *adev = data; 470 struct acpi_device *adev = data;
457 int error; 471 int error = -ENODEV;
458 472
459 lock_device_hotplug(); 473 lock_device_hotplug();
460 mutex_lock(&acpi_scan_lock); 474 mutex_lock(&acpi_scan_lock);
461 475
462 /* 476 /*
463 * The device object's ACPI handle cannot become invalid as long as we 477 * The device object's ACPI handle cannot become invalid as long as we
464 * are holding acpi_scan_lock, but it may have become invalid before 478 * are holding acpi_scan_lock, but it might have become invalid before
465 * that lock was acquired. 479 * that lock was acquired.
466 */ 480 */
467 if (adev->handle == INVALID_ACPI_HANDLE) 481 if (adev->handle == INVALID_ACPI_HANDLE)
468 goto out; 482 goto err_out;
469 483
470 switch (src) { 484 if (adev->flags.hotplug_notify) {
471 case ACPI_NOTIFY_BUS_CHECK: 485 error = acpi_generic_hotplug_event(adev, src);
472 error = acpi_scan_bus_check(adev); 486 } else {
473 break; 487 int (*event)(struct acpi_device *, u32);
474 case ACPI_NOTIFY_DEVICE_CHECK: 488
475 error = acpi_scan_device_check(adev); 489 acpi_lock_hp_context();
476 break; 490 event = adev->hp ? adev->hp->event : NULL;
477 case ACPI_NOTIFY_EJECT_REQUEST: 491 acpi_unlock_hp_context();
478 case ACPI_OST_EC_OSPM_EJECT: 492 /*
479 error = acpi_scan_hot_remove(adev); 493 * There may be additional notify handlers for device objects
480 break; 494 * without the .event() callback, so ignore them here.
481 default: 495 */
482 error = -EINVAL; 496 if (event)
483 break; 497 error = event(adev, src);
498 else
499 goto out;
484 } 500 }
485 if (!error) 501 if (!error)
486 ost_code = ACPI_OST_SC_SUCCESS; 502 ost_code = ACPI_OST_SC_SUCCESS;
487 503
488 out: 504 err_out:
489 acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); 505 acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL);
506
507 out:
490 acpi_bus_put_acpi_device(adev); 508 acpi_bus_put_acpi_device(adev);
491 mutex_unlock(&acpi_scan_lock); 509 mutex_unlock(&acpi_scan_lock);
492 unlock_device_hotplug(); 510 unlock_device_hotplug();
@@ -494,8 +512,8 @@ static void acpi_device_hotplug(void *data, u32 src)
494 512
495static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) 513static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
496{ 514{
497 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
498 struct acpi_scan_handler *handler = data; 515 struct acpi_scan_handler *handler = data;
516 u32 ost_code = ACPI_OST_SC_SUCCESS;
499 struct acpi_device *adev; 517 struct acpi_device *adev;
500 acpi_status status; 518 acpi_status status;
501 519
@@ -503,26 +521,49 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
503 case ACPI_NOTIFY_BUS_CHECK: 521 case ACPI_NOTIFY_BUS_CHECK:
504 acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); 522 acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n");
505 break; 523 break;
524
506 case ACPI_NOTIFY_DEVICE_CHECK: 525 case ACPI_NOTIFY_DEVICE_CHECK:
507 acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); 526 acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n");
508 break; 527 break;
528
509 case ACPI_NOTIFY_EJECT_REQUEST: 529 case ACPI_NOTIFY_EJECT_REQUEST:
510 acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); 530 acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
511 if (!handler->hotplug.enabled) { 531 if (handler && !handler->hotplug.enabled) {
512 acpi_handle_err(handle, "Eject disabled\n"); 532 acpi_handle_err(handle, "Eject disabled\n");
513 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; 533 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
514 goto err_out; 534 goto out;
515 } 535 }
516 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, 536 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
517 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 537 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
518 break; 538 break;
519 default: 539
520 /* non-hotplug event; possibly handled by other handler */ 540 case ACPI_NOTIFY_DEVICE_WAKE:
521 return; 541 return;
542
543 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
544 acpi_handle_err(handle, "Device cannot be configured due "
545 "to a frequency mismatch\n");
546 goto out;
547
548 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
549 acpi_handle_err(handle, "Device cannot be configured due "
550 "to a bus mode mismatch\n");
551 goto out;
552
553 case ACPI_NOTIFY_POWER_FAULT:
554 acpi_handle_err(handle, "Device has suffered a power fault\n");
555 goto out;
556
557 default:
558 acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
559 ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
560 goto out;
522 } 561 }
562
563 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
523 adev = acpi_bus_get_acpi_device(handle); 564 adev = acpi_bus_get_acpi_device(handle);
524 if (!adev) 565 if (!adev)
525 goto err_out; 566 goto out;
526 567
527 status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); 568 status = acpi_hotplug_execute(acpi_device_hotplug, adev, type);
528 if (ACPI_SUCCESS(status)) 569 if (ACPI_SUCCESS(status))
@@ -530,10 +571,22 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
530 571
531 acpi_bus_put_acpi_device(adev); 572 acpi_bus_put_acpi_device(adev);
532 573
533 err_out: 574 out:
534 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); 575 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
535} 576}
536 577
578void acpi_install_hotplug_notify_handler(acpi_handle handle, void *data)
579{
580 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
581 acpi_hotplug_notify_cb, data);
582}
583
584void acpi_remove_hotplug_notify_handler(acpi_handle handle)
585{
586 acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
587 acpi_hotplug_notify_cb);
588}
589
537static ssize_t real_power_state_show(struct device *dev, 590static ssize_t real_power_state_show(struct device *dev,
538 struct device_attribute *attr, char *buf) 591 struct device_attribute *attr, char *buf)
539{ 592{
@@ -1976,33 +2029,21 @@ void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val)
1976 mutex_unlock(&acpi_scan_lock); 2029 mutex_unlock(&acpi_scan_lock);
1977} 2030}
1978 2031
1979static void acpi_scan_init_hotplug(acpi_handle handle, int type) 2032static void acpi_scan_init_hotplug(struct acpi_device *adev)
1980{ 2033{
1981 struct acpi_device_pnp pnp = {};
1982 struct acpi_hardware_id *hwid; 2034 struct acpi_hardware_id *hwid;
1983 struct acpi_scan_handler *handler;
1984 2035
1985 INIT_LIST_HEAD(&pnp.ids); 2036 list_for_each_entry(hwid, &adev->pnp.ids, list) {
1986 acpi_set_pnp_ids(handle, &pnp, type); 2037 struct acpi_scan_handler *handler;
1987
1988 if (!pnp.type.hardware_id)
1989 goto out;
1990 2038
1991 /*
1992 * This relies on the fact that acpi_install_notify_handler() will not
1993 * install the same notify handler routine twice for the same handle.
1994 */
1995 list_for_each_entry(hwid, &pnp.ids, list) {
1996 handler = acpi_scan_match_handler(hwid->id, NULL); 2039 handler = acpi_scan_match_handler(hwid->id, NULL);
1997 if (handler) { 2040 if (!handler)
1998 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 2041 continue;
1999 acpi_hotplug_notify_cb, handler);
2000 break;
2001 }
2002 }
2003 2042
2004out: 2043 acpi_install_hotplug_notify_handler(adev->handle, handler);
2005 acpi_free_pnp_ids(&pnp); 2044 adev->flags.hotplug_notify = true;
2045 break;
2046 }
2006} 2047}
2007 2048
2008static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, 2049static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
@@ -2026,12 +2067,12 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
2026 return AE_OK; 2067 return AE_OK;
2027 } 2068 }
2028 2069
2029 acpi_scan_init_hotplug(handle, type);
2030
2031 acpi_add_single_object(&device, handle, type, sta); 2070 acpi_add_single_object(&device, handle, type, sta);
2032 if (!device) 2071 if (!device)
2033 return AE_CTRL_DEPTH; 2072 return AE_CTRL_DEPTH;
2034 2073
2074 acpi_scan_init_hotplug(device);
2075
2035 out: 2076 out:
2036 if (!*return_value) 2077 if (!*return_value)
2037 *return_value = device; 2078 *return_value = device;
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 373c7aa3b4a6..d7c1fc9712ad 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -116,12 +116,17 @@ struct acpiphp_func {
116}; 116};
117 117
118struct acpiphp_context { 118struct acpiphp_context {
119 struct acpi_hotplug_context hp;
119 struct acpiphp_func func; 120 struct acpiphp_func func;
120 struct acpi_device *adev;
121 struct acpiphp_bridge *bridge; 121 struct acpiphp_bridge *bridge;
122 unsigned int refcount; 122 unsigned int refcount;
123}; 123};
124 124
125static inline struct acpiphp_context *to_acpiphp_context(struct acpi_hotplug_context *hp)
126{
127 return container_of(hp, struct acpiphp_context, hp);
128}
129
125static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func) 130static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func)
126{ 131{
127 return container_of(func, struct acpiphp_context, func); 132 return container_of(func, struct acpiphp_context, func);
@@ -129,7 +134,7 @@ static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func)
129 134
130static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func) 135static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func)
131{ 136{
132 return func_to_context(func)->adev; 137 return func_to_context(func)->hp.self;
133} 138}
134 139
135static inline acpi_handle func_to_handle(struct acpiphp_func *func) 140static inline acpi_handle func_to_handle(struct acpiphp_func *func)
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 8139a4b0d389..7c498d663eb3 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -59,17 +59,12 @@
59static LIST_HEAD(bridge_list); 59static LIST_HEAD(bridge_list);
60static DEFINE_MUTEX(bridge_mutex); 60static DEFINE_MUTEX(bridge_mutex);
61 61
62static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); 62static int acpiphp_hotplug_event(struct acpi_device *adev, u32 type);
63static void acpiphp_sanitize_bus(struct pci_bus *bus); 63static void acpiphp_sanitize_bus(struct pci_bus *bus);
64static void acpiphp_set_hpp_values(struct pci_bus *bus); 64static void acpiphp_set_hpp_values(struct pci_bus *bus);
65static void hotplug_event(u32 type, struct acpiphp_context *context); 65static void hotplug_event(u32 type, struct acpiphp_context *context);
66static void free_bridge(struct kref *kref); 66static void free_bridge(struct kref *kref);
67 67
68static void acpiphp_context_handler(acpi_handle handle, void *context)
69{
70 /* Intentionally empty. */
71}
72
73/** 68/**
74 * acpiphp_init_context - Create hotplug context and grab a reference to it. 69 * acpiphp_init_context - Create hotplug context and grab a reference to it.
75 * @adev: ACPI device object to create the context for. 70 * @adev: ACPI device object to create the context for.
@@ -79,39 +74,31 @@ static void acpiphp_context_handler(acpi_handle handle, void *context)
79static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) 74static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
80{ 75{
81 struct acpiphp_context *context; 76 struct acpiphp_context *context;
82 acpi_status status;
83 77
84 context = kzalloc(sizeof(*context), GFP_KERNEL); 78 context = kzalloc(sizeof(*context), GFP_KERNEL);
85 if (!context) 79 if (!context)
86 return NULL; 80 return NULL;
87 81
88 context->adev = adev;
89 context->refcount = 1; 82 context->refcount = 1;
90 status = acpi_attach_data(adev->handle, acpiphp_context_handler, context); 83 acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_event);
91 if (ACPI_FAILURE(status)) {
92 kfree(context);
93 return NULL;
94 }
95 return context; 84 return context;
96} 85}
97 86
98/** 87/**
99 * acpiphp_get_context - Get hotplug context and grab a reference to it. 88 * acpiphp_get_context - Get hotplug context and grab a reference to it.
100 * @handle: ACPI object handle to get the context for. 89 * @adev: ACPI device object to get the context for.
101 * 90 *
102 * Call under acpi_hp_context_lock. 91 * Call under acpi_hp_context_lock.
103 */ 92 */
104static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) 93static struct acpiphp_context *acpiphp_get_context(struct acpi_device *adev)
105{ 94{
106 struct acpiphp_context *context = NULL; 95 struct acpiphp_context *context;
107 acpi_status status;
108 void *data;
109 96
110 status = acpi_get_data(handle, acpiphp_context_handler, &data); 97 if (!adev->hp)
111 if (ACPI_SUCCESS(status)) { 98 return NULL;
112 context = data; 99
113 context->refcount++; 100 context = to_acpiphp_context(adev->hp);
114 } 101 context->refcount++;
115 return context; 102 return context;
116} 103}
117 104
@@ -129,7 +116,7 @@ static void acpiphp_put_context(struct acpiphp_context *context)
129 return; 116 return;
130 117
131 WARN_ON(context->bridge); 118 WARN_ON(context->bridge);
132 acpi_detach_data(context->adev->handle, acpiphp_context_handler); 119 context->hp.self->hp = NULL;
133 kfree(context); 120 kfree(context);
134} 121}
135 122
@@ -211,22 +198,13 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data)
211 198
212static void dock_event(acpi_handle handle, u32 type, void *data) 199static void dock_event(acpi_handle handle, u32 type, void *data)
213{ 200{
214 struct acpiphp_context *context; 201 struct acpi_device *adev;
215 202
216 acpi_lock_hp_context(); 203 adev = acpi_bus_get_acpi_device(handle);
217 context = acpiphp_get_context(handle); 204 if (adev) {
218 if (!context || WARN_ON(context->adev->handle != handle) 205 acpiphp_hotplug_event(adev, type);
219 || context->func.parent->is_going_away) { 206 acpi_bus_put_acpi_device(adev);
220 acpi_unlock_hp_context();
221 return;
222 } 207 }
223 get_bridge(context->func.parent);
224 acpiphp_put_context(context);
225 acpi_unlock_hp_context();
226
227 hotplug_event(type, context);
228
229 put_bridge(context->func.parent);
230} 208}
231 209
232static const struct acpi_dock_ops acpiphp_dock_ops = { 210static const struct acpi_dock_ops acpiphp_dock_ops = {
@@ -397,25 +375,23 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
397 } 375 }
398 376
399 /* install notify handler */ 377 /* install notify handler */
400 if (!(newfunc->flags & FUNC_HAS_DCK)) { 378 if (!(newfunc->flags & FUNC_HAS_DCK))
401 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 379 acpi_install_hotplug_notify_handler(handle, NULL);
402 handle_hotplug_event,
403 context);
404 if (ACPI_FAILURE(status))
405 acpi_handle_err(handle,
406 "failed to install notify handler\n");
407 }
408 380
409 return AE_OK; 381 return AE_OK;
410} 382}
411 383
412static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) 384static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
413{ 385{
386 struct acpi_device *adev = acpi_bus_get_acpi_device(handle);
414 struct acpiphp_context *context; 387 struct acpiphp_context *context;
415 struct acpiphp_bridge *bridge = NULL; 388 struct acpiphp_bridge *bridge = NULL;
416 389
390 if (!adev)
391 return NULL;
392
417 acpi_lock_hp_context(); 393 acpi_lock_hp_context();
418 context = acpiphp_get_context(handle); 394 context = acpiphp_get_context(adev);
419 if (context) { 395 if (context) {
420 bridge = context->bridge; 396 bridge = context->bridge;
421 if (bridge) 397 if (bridge)
@@ -424,6 +400,7 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
424 acpiphp_put_context(context); 400 acpiphp_put_context(context);
425 } 401 }
426 acpi_unlock_hp_context(); 402 acpi_unlock_hp_context();
403 acpi_bus_put_acpi_device(adev);
427 return bridge; 404 return bridge;
428} 405}
429 406
@@ -431,7 +408,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
431{ 408{
432 struct acpiphp_slot *slot; 409 struct acpiphp_slot *slot;
433 struct acpiphp_func *func; 410 struct acpiphp_func *func;
434 acpi_status status;
435 411
436 list_for_each_entry(slot, &bridge->slots, node) { 412 list_for_each_entry(slot, &bridge->slots, node) {
437 list_for_each_entry(func, &slot->funcs, sibling) { 413 list_for_each_entry(func, &slot->funcs, sibling) {
@@ -440,13 +416,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
440 if (is_dock_device(handle)) 416 if (is_dock_device(handle))
441 unregister_hotplug_dock_device(handle); 417 unregister_hotplug_dock_device(handle);
442 418
443 if (!(func->flags & FUNC_HAS_DCK)) { 419 if (!(func->flags & FUNC_HAS_DCK))
444 status = acpi_remove_notify_handler(handle, 420 acpi_remove_hotplug_notify_handler(handle);
445 ACPI_SYSTEM_NOTIFY,
446 handle_hotplug_event);
447 if (ACPI_FAILURE(status))
448 pr_err("failed to remove notify handler\n");
449 }
450 } 421 }
451 slot->flags |= SLOT_IS_GOING_AWAY; 422 slot->flags |= SLOT_IS_GOING_AWAY;
452 if (slot->slot) 423 if (slot->slot)
@@ -814,7 +785,7 @@ static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
814 785
815static void hotplug_event(u32 type, struct acpiphp_context *context) 786static void hotplug_event(u32 type, struct acpiphp_context *context)
816{ 787{
817 acpi_handle handle = context->adev->handle; 788 acpi_handle handle = context->hp.self->handle;
818 struct acpiphp_func *func = &context->func; 789 struct acpiphp_func *func = &context->func;
819 struct acpiphp_slot *slot = func->slot; 790 struct acpiphp_slot *slot = func->slot;
820 struct acpiphp_bridge *bridge; 791 struct acpiphp_bridge *bridge;
@@ -866,87 +837,24 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
866 put_bridge(bridge); 837 put_bridge(bridge);
867} 838}
868 839
869static void hotplug_event_work(void *data, u32 type) 840static int acpiphp_hotplug_event(struct acpi_device *adev, u32 type)
870{
871 struct acpiphp_context *context = data;
872
873 acpi_scan_lock_acquire();
874
875 hotplug_event(type, context);
876
877 acpi_scan_lock_release();
878 acpi_evaluate_hotplug_ost(context->adev->handle, type,
879 ACPI_OST_SC_SUCCESS, NULL);
880 put_bridge(context->func.parent);
881}
882
883/**
884 * handle_hotplug_event - handle ACPI hotplug event
885 * @handle: Notify()'ed acpi_handle
886 * @type: Notify code
887 * @data: pointer to acpiphp_context structure
888 *
889 * Handles ACPI event notification on slots.
890 */
891static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
892{ 841{
893 struct acpiphp_context *context; 842 struct acpiphp_context *context;
894 u32 ost_code = ACPI_OST_SC_SUCCESS;
895 acpi_status status;
896
897 switch (type) {
898 case ACPI_NOTIFY_BUS_CHECK:
899 case ACPI_NOTIFY_DEVICE_CHECK:
900 break;
901 case ACPI_NOTIFY_EJECT_REQUEST:
902 ost_code = ACPI_OST_SC_EJECT_IN_PROGRESS;
903 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
904 break;
905
906 case ACPI_NOTIFY_DEVICE_WAKE:
907 return;
908
909 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
910 acpi_handle_err(handle, "Device cannot be configured due "
911 "to a frequency mismatch\n");
912 goto out;
913
914 case ACPI_NOTIFY_BUS_MODE_MISMATCH:
915 acpi_handle_err(handle, "Device cannot be configured due "
916 "to a bus mode mismatch\n");
917 goto out;
918
919 case ACPI_NOTIFY_POWER_FAULT:
920 acpi_handle_err(handle, "Device has suffered a power fault\n");
921 goto out;
922
923 default:
924 acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
925 ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
926 goto out;
927 }
928 843
929 acpi_lock_hp_context(); 844 acpi_lock_hp_context();
930 context = acpiphp_get_context(handle); 845 context = acpiphp_get_context(adev);
931 if (!context || WARN_ON(context->adev->handle != handle) 846 if (!context || context->func.parent->is_going_away) {
932 || context->func.parent->is_going_away)
933 goto err_out;
934
935 get_bridge(context->func.parent);
936 acpiphp_put_context(context);
937 status = acpi_hotplug_execute(hotplug_event_work, context, type);
938 if (ACPI_SUCCESS(status)) {
939 acpi_unlock_hp_context(); 847 acpi_unlock_hp_context();
940 return; 848 return -ENODATA;
941 } 849 }
942 put_bridge(context->func.parent); 850 get_bridge(context->func.parent);
943 851 acpiphp_put_context(context);
944 err_out:
945 acpi_unlock_hp_context(); 852 acpi_unlock_hp_context();
946 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
947 853
948 out: 854 hotplug_event(type, context);
949 acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); 855
856 put_bridge(context->func.parent);
857 return 0;
950} 858}
951 859
952/** 860/**
@@ -999,7 +907,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
999 * bridge is not interesting to us either. 907 * bridge is not interesting to us either.
1000 */ 908 */
1001 acpi_lock_hp_context(); 909 acpi_lock_hp_context();
1002 context = acpiphp_get_context(handle); 910 context = acpiphp_get_context(adev);
1003 if (!context) { 911 if (!context) {
1004 acpi_unlock_hp_context(); 912 acpi_unlock_hp_context();
1005 put_device(&bus->dev); 913 put_device(&bus->dev);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 0c82708ff08a..53ce357f6335 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -137,6 +137,16 @@ struct acpi_scan_handler {
137}; 137};
138 138
139/* 139/*
140 * ACPI Hotplug Context
141 * --------------------
142 */
143
144struct acpi_hotplug_context {
145 struct acpi_device *self;
146 int (*event)(struct acpi_device *, u32);
147};
148
149/*
140 * ACPI Driver 150 * ACPI Driver
141 * ----------- 151 * -----------
142 */ 152 */
@@ -190,7 +200,8 @@ struct acpi_device_flags {
190 u32 initialized:1; 200 u32 initialized:1;
191 u32 visited:1; 201 u32 visited:1;
192 u32 no_hotplug:1; 202 u32 no_hotplug:1;
193 u32 reserved:24; 203 u32 hotplug_notify:1;
204 u32 reserved:23;
194}; 205};
195 206
196/* File System */ 207/* File System */
@@ -329,6 +340,7 @@ struct acpi_device {
329 struct acpi_device_perf performance; 340 struct acpi_device_perf performance;
330 struct acpi_device_dir dir; 341 struct acpi_device_dir dir;
331 struct acpi_scan_handler *handler; 342 struct acpi_scan_handler *handler;
343 struct acpi_hotplug_context *hp;
332 struct acpi_driver *driver; 344 struct acpi_driver *driver;
333 void *driver_data; 345 void *driver_data;
334 struct device dev; 346 struct device dev;
@@ -351,6 +363,15 @@ static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta)
351 *((u32 *)&adev->status) = sta; 363 *((u32 *)&adev->status) = sta;
352} 364}
353 365
366static inline void acpi_set_hp_context(struct acpi_device *adev,
367 struct acpi_hotplug_context *hp,
368 int (*event)(struct acpi_device *, u32))
369{
370 hp->self = adev;
371 hp->event = event;
372 adev->hp = hp;
373}
374
354/* acpi_device.dev.bus == &acpi_bus_type */ 375/* acpi_device.dev.bus == &acpi_bus_type */
355extern struct bus_type acpi_bus_type; 376extern struct bus_type acpi_bus_type;
356 377
@@ -425,6 +446,8 @@ static inline bool acpi_device_enumerated(struct acpi_device *adev)
425typedef void (*acpi_hp_callback)(void *data, u32 src); 446typedef void (*acpi_hp_callback)(void *data, u32 src);
426 447
427acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src); 448acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src);
449void acpi_install_hotplug_notify_handler(acpi_handle handle, void *data);
450void acpi_remove_hotplug_notify_handler(acpi_handle handle);
428 451
429/** 452/**
430 * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver 453 * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver