aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/scan.c11
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c51
-rw-r--r--include/acpi/acpi_bus.h2
3 files changed, 38 insertions, 26 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 59eba29a6066..d64a5826ef35 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -41,6 +41,7 @@ static DEFINE_MUTEX(acpi_scan_lock);
41static LIST_HEAD(acpi_scan_handlers_list); 41static LIST_HEAD(acpi_scan_handlers_list);
42DEFINE_MUTEX(acpi_device_lock); 42DEFINE_MUTEX(acpi_device_lock);
43LIST_HEAD(acpi_wakeup_device_list); 43LIST_HEAD(acpi_wakeup_device_list);
44static DEFINE_MUTEX(acpi_hp_context_lock);
44 45
45struct acpi_device_bus_id{ 46struct acpi_device_bus_id{
46 char bus_id[15]; 47 char bus_id[15];
@@ -60,6 +61,16 @@ void acpi_scan_lock_release(void)
60} 61}
61EXPORT_SYMBOL_GPL(acpi_scan_lock_release); 62EXPORT_SYMBOL_GPL(acpi_scan_lock_release);
62 63
64void acpi_lock_hp_context(void)
65{
66 mutex_lock(&acpi_hp_context_lock);
67}
68
69void acpi_unlock_hp_context(void)
70{
71 mutex_unlock(&acpi_hp_context_lock);
72}
73
63int acpi_scan_add_handler(struct acpi_scan_handler *handler) 74int acpi_scan_add_handler(struct acpi_scan_handler *handler)
64{ 75{
65 if (!handler || !handler->attach) 76 if (!handler || !handler->attach)
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 5da32eff3bc3..8139a4b0d389 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -58,7 +58,6 @@
58 58
59static LIST_HEAD(bridge_list); 59static LIST_HEAD(bridge_list);
60static DEFINE_MUTEX(bridge_mutex); 60static DEFINE_MUTEX(bridge_mutex);
61static DEFINE_MUTEX(acpiphp_context_lock);
62 61
63static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); 62static void handle_hotplug_event(acpi_handle handle, u32 type, void *data);
64static void acpiphp_sanitize_bus(struct pci_bus *bus); 63static void acpiphp_sanitize_bus(struct pci_bus *bus);
@@ -75,7 +74,7 @@ static void acpiphp_context_handler(acpi_handle handle, void *context)
75 * acpiphp_init_context - Create hotplug context and grab a reference to it. 74 * acpiphp_init_context - Create hotplug context and grab a reference to it.
76 * @adev: ACPI device object to create the context for. 75 * @adev: ACPI device object to create the context for.
77 * 76 *
78 * Call under acpiphp_context_lock. 77 * Call under acpi_hp_context_lock.
79 */ 78 */
80static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) 79static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
81{ 80{
@@ -100,7 +99,7 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
100 * acpiphp_get_context - Get hotplug context and grab a reference to it. 99 * acpiphp_get_context - Get hotplug context and grab a reference to it.
101 * @handle: ACPI object handle to get the context for. 100 * @handle: ACPI object handle to get the context for.
102 * 101 *
103 * Call under acpiphp_context_lock. 102 * Call under acpi_hp_context_lock.
104 */ 103 */
105static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) 104static struct acpiphp_context *acpiphp_get_context(acpi_handle handle)
106{ 105{
@@ -122,7 +121,7 @@ static struct acpiphp_context *acpiphp_get_context(acpi_handle handle)
122 * 121 *
123 * The context object is removed if there are no more references to it. 122 * The context object is removed if there are no more references to it.
124 * 123 *
125 * Call under acpiphp_context_lock. 124 * Call under acpi_hp_context_lock.
126 */ 125 */
127static void acpiphp_put_context(struct acpiphp_context *context) 126static void acpiphp_put_context(struct acpiphp_context *context)
128{ 127{
@@ -151,7 +150,7 @@ static void free_bridge(struct kref *kref)
151 struct acpiphp_slot *slot, *next; 150 struct acpiphp_slot *slot, *next;
152 struct acpiphp_func *func, *tmp; 151 struct acpiphp_func *func, *tmp;
153 152
154 mutex_lock(&acpiphp_context_lock); 153 acpi_lock_hp_context();
155 154
156 bridge = container_of(kref, struct acpiphp_bridge, ref); 155 bridge = container_of(kref, struct acpiphp_bridge, ref);
157 156
@@ -175,7 +174,7 @@ static void free_bridge(struct kref *kref)
175 pci_dev_put(bridge->pci_dev); 174 pci_dev_put(bridge->pci_dev);
176 kfree(bridge); 175 kfree(bridge);
177 176
178 mutex_unlock(&acpiphp_context_lock); 177 acpi_unlock_hp_context();
179} 178}
180 179
181/* 180/*
@@ -214,16 +213,16 @@ static void dock_event(acpi_handle handle, u32 type, void *data)
214{ 213{
215 struct acpiphp_context *context; 214 struct acpiphp_context *context;
216 215
217 mutex_lock(&acpiphp_context_lock); 216 acpi_lock_hp_context();
218 context = acpiphp_get_context(handle); 217 context = acpiphp_get_context(handle);
219 if (!context || WARN_ON(context->adev->handle != handle) 218 if (!context || WARN_ON(context->adev->handle != handle)
220 || context->func.parent->is_going_away) { 219 || context->func.parent->is_going_away) {
221 mutex_unlock(&acpiphp_context_lock); 220 acpi_unlock_hp_context();
222 return; 221 return;
223 } 222 }
224 get_bridge(context->func.parent); 223 get_bridge(context->func.parent);
225 acpiphp_put_context(context); 224 acpiphp_put_context(context);
226 mutex_unlock(&acpiphp_context_lock); 225 acpi_unlock_hp_context();
227 226
228 hotplug_event(type, context); 227 hotplug_event(type, context);
229 228
@@ -310,17 +309,17 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
310 device = (adr >> 16) & 0xffff; 309 device = (adr >> 16) & 0xffff;
311 function = adr & 0xffff; 310 function = adr & 0xffff;
312 311
313 mutex_lock(&acpiphp_context_lock); 312 acpi_lock_hp_context();
314 context = acpiphp_init_context(adev); 313 context = acpiphp_init_context(adev);
315 if (!context) { 314 if (!context) {
316 mutex_unlock(&acpiphp_context_lock); 315 acpi_unlock_hp_context();
317 acpi_handle_err(handle, "No hotplug context\n"); 316 acpi_handle_err(handle, "No hotplug context\n");
318 return AE_NOT_EXIST; 317 return AE_NOT_EXIST;
319 } 318 }
320 newfunc = &context->func; 319 newfunc = &context->func;
321 newfunc->function = function; 320 newfunc->function = function;
322 newfunc->parent = bridge; 321 newfunc->parent = bridge;
323 mutex_unlock(&acpiphp_context_lock); 322 acpi_unlock_hp_context();
324 323
325 if (acpi_has_method(handle, "_EJ0")) 324 if (acpi_has_method(handle, "_EJ0"))
326 newfunc->flags = FUNC_HAS_EJ0; 325 newfunc->flags = FUNC_HAS_EJ0;
@@ -338,9 +337,9 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
338 337
339 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); 338 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
340 if (!slot) { 339 if (!slot) {
341 mutex_lock(&acpiphp_context_lock); 340 acpi_lock_hp_context();
342 acpiphp_put_context(context); 341 acpiphp_put_context(context);
343 mutex_unlock(&acpiphp_context_lock); 342 acpi_unlock_hp_context();
344 return AE_NO_MEMORY; 343 return AE_NO_MEMORY;
345 } 344 }
346 345
@@ -415,7 +414,7 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
415 struct acpiphp_context *context; 414 struct acpiphp_context *context;
416 struct acpiphp_bridge *bridge = NULL; 415 struct acpiphp_bridge *bridge = NULL;
417 416
418 mutex_lock(&acpiphp_context_lock); 417 acpi_lock_hp_context();
419 context = acpiphp_get_context(handle); 418 context = acpiphp_get_context(handle);
420 if (context) { 419 if (context) {
421 bridge = context->bridge; 420 bridge = context->bridge;
@@ -424,7 +423,7 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
424 423
425 acpiphp_put_context(context); 424 acpiphp_put_context(context);
426 } 425 }
427 mutex_unlock(&acpiphp_context_lock); 426 acpi_unlock_hp_context();
428 return bridge; 427 return bridge;
429} 428}
430 429
@@ -458,9 +457,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
458 list_del(&bridge->list); 457 list_del(&bridge->list);
459 mutex_unlock(&bridge_mutex); 458 mutex_unlock(&bridge_mutex);
460 459
461 mutex_lock(&acpiphp_context_lock); 460 acpi_lock_hp_context();
462 bridge->is_going_away = true; 461 bridge->is_going_away = true;
463 mutex_unlock(&acpiphp_context_lock); 462 acpi_unlock_hp_context();
464} 463}
465 464
466/** 465/**
@@ -820,12 +819,12 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
820 struct acpiphp_slot *slot = func->slot; 819 struct acpiphp_slot *slot = func->slot;
821 struct acpiphp_bridge *bridge; 820 struct acpiphp_bridge *bridge;
822 821
823 mutex_lock(&acpiphp_context_lock); 822 acpi_lock_hp_context();
824 bridge = context->bridge; 823 bridge = context->bridge;
825 if (bridge) 824 if (bridge)
826 get_bridge(bridge); 825 get_bridge(bridge);
827 826
828 mutex_unlock(&acpiphp_context_lock); 827 acpi_unlock_hp_context();
829 828
830 pci_lock_rescan_remove(); 829 pci_lock_rescan_remove();
831 830
@@ -927,7 +926,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
927 goto out; 926 goto out;
928 } 927 }
929 928
930 mutex_lock(&acpiphp_context_lock); 929 acpi_lock_hp_context();
931 context = acpiphp_get_context(handle); 930 context = acpiphp_get_context(handle);
932 if (!context || WARN_ON(context->adev->handle != handle) 931 if (!context || WARN_ON(context->adev->handle != handle)
933 || context->func.parent->is_going_away) 932 || context->func.parent->is_going_away)
@@ -937,13 +936,13 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
937 acpiphp_put_context(context); 936 acpiphp_put_context(context);
938 status = acpi_hotplug_execute(hotplug_event_work, context, type); 937 status = acpi_hotplug_execute(hotplug_event_work, context, type);
939 if (ACPI_SUCCESS(status)) { 938 if (ACPI_SUCCESS(status)) {
940 mutex_unlock(&acpiphp_context_lock); 939 acpi_unlock_hp_context();
941 return; 940 return;
942 } 941 }
943 put_bridge(context->func.parent); 942 put_bridge(context->func.parent);
944 943
945 err_out: 944 err_out:
946 mutex_unlock(&acpiphp_context_lock); 945 acpi_unlock_hp_context();
947 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 946 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
948 947
949 out: 948 out:
@@ -999,10 +998,10 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
999 * parent is going to be handled by pciehp, in which case this 998 * parent is going to be handled by pciehp, in which case this
1000 * bridge is not interesting to us either. 999 * bridge is not interesting to us either.
1001 */ 1000 */
1002 mutex_lock(&acpiphp_context_lock); 1001 acpi_lock_hp_context();
1003 context = acpiphp_get_context(handle); 1002 context = acpiphp_get_context(handle);
1004 if (!context) { 1003 if (!context) {
1005 mutex_unlock(&acpiphp_context_lock); 1004 acpi_unlock_hp_context();
1006 put_device(&bus->dev); 1005 put_device(&bus->dev);
1007 pci_dev_put(bridge->pci_dev); 1006 pci_dev_put(bridge->pci_dev);
1008 kfree(bridge); 1007 kfree(bridge);
@@ -1012,7 +1011,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1012 context->bridge = bridge; 1011 context->bridge = bridge;
1013 /* Get a reference to the parent bridge. */ 1012 /* Get a reference to the parent bridge. */
1014 get_bridge(context->func.parent); 1013 get_bridge(context->func.parent);
1015 mutex_unlock(&acpiphp_context_lock); 1014 acpi_unlock_hp_context();
1016 } 1015 }
1017 1016
1018 /* must be added to the list prior to calling register_slot */ 1017 /* must be added to the list prior to calling register_slot */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 94fd61a0456d..0c82708ff08a 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -404,6 +404,8 @@ static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; }
404 404
405void acpi_scan_lock_acquire(void); 405void acpi_scan_lock_acquire(void);
406void acpi_scan_lock_release(void); 406void acpi_scan_lock_release(void);
407void acpi_lock_hp_context(void);
408void acpi_unlock_hp_context(void);
407int acpi_scan_add_handler(struct acpi_scan_handler *handler); 409int acpi_scan_add_handler(struct acpi_scan_handler *handler);
408int acpi_bus_register_driver(struct acpi_driver *driver); 410int acpi_bus_register_driver(struct acpi_driver *driver);
409void acpi_bus_unregister_driver(struct acpi_driver *driver); 411void acpi_bus_unregister_driver(struct acpi_driver *driver);