diff options
-rw-r--r-- | drivers/acpi/scan.c | 11 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 51 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 2 |
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); | |||
41 | static LIST_HEAD(acpi_scan_handlers_list); | 41 | static LIST_HEAD(acpi_scan_handlers_list); |
42 | DEFINE_MUTEX(acpi_device_lock); | 42 | DEFINE_MUTEX(acpi_device_lock); |
43 | LIST_HEAD(acpi_wakeup_device_list); | 43 | LIST_HEAD(acpi_wakeup_device_list); |
44 | static DEFINE_MUTEX(acpi_hp_context_lock); | ||
44 | 45 | ||
45 | struct acpi_device_bus_id{ | 46 | struct 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 | } |
61 | EXPORT_SYMBOL_GPL(acpi_scan_lock_release); | 62 | EXPORT_SYMBOL_GPL(acpi_scan_lock_release); |
62 | 63 | ||
64 | void acpi_lock_hp_context(void) | ||
65 | { | ||
66 | mutex_lock(&acpi_hp_context_lock); | ||
67 | } | ||
68 | |||
69 | void acpi_unlock_hp_context(void) | ||
70 | { | ||
71 | mutex_unlock(&acpi_hp_context_lock); | ||
72 | } | ||
73 | |||
63 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) | 74 | int 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 | ||
59 | static LIST_HEAD(bridge_list); | 59 | static LIST_HEAD(bridge_list); |
60 | static DEFINE_MUTEX(bridge_mutex); | 60 | static DEFINE_MUTEX(bridge_mutex); |
61 | static DEFINE_MUTEX(acpiphp_context_lock); | ||
62 | 61 | ||
63 | static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); | 62 | static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); |
64 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 63 | static 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 | */ |
80 | static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) | 79 | static 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 | */ |
105 | static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) | 104 | static 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 | */ |
127 | static void acpiphp_put_context(struct acpiphp_context *context) | 126 | static 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 | ||
405 | void acpi_scan_lock_acquire(void); | 405 | void acpi_scan_lock_acquire(void); |
406 | void acpi_scan_lock_release(void); | 406 | void acpi_scan_lock_release(void); |
407 | void acpi_lock_hp_context(void); | ||
408 | void acpi_unlock_hp_context(void); | ||
407 | int acpi_scan_add_handler(struct acpi_scan_handler *handler); | 409 | int acpi_scan_add_handler(struct acpi_scan_handler *handler); |
408 | int acpi_bus_register_driver(struct acpi_driver *driver); | 410 | int acpi_bus_register_driver(struct acpi_driver *driver); |
409 | void acpi_bus_unregister_driver(struct acpi_driver *driver); | 411 | void acpi_bus_unregister_driver(struct acpi_driver *driver); |