aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-03 18:43:17 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-05 11:41:26 -0500
commite525506fcb67a9bbd94f01eac84af802139004eb (patch)
tree505ec664227aa70fc7fa3a7f21bcfe45983ca979
parent78ea4639a7647f2fcc957c3a532bde49df9895c7 (diff)
ACPI / hotplug / PCI: Define hotplug context lock in the core
Subsequent changes will require the ACPI core to acquire the lock protecting the ACPIPHP hotplug contexts, so move the definition of the lock to the core and change its name to be more generic. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-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);