aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpiphp_glue.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-03 18:39:33 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-05 11:40:39 -0500
commitbbcbfc0eed6220591ccc5752edd079099bb1920c (patch)
tree1fdcf26676d7ebcc1af5d34712c4e83a6edee95c /drivers/pci/hotplug/acpiphp_glue.c
parentb2118d6a4073e394312072b6666cb576e18653b2 (diff)
ACPI / hotplug / PCI: Store acpi_device pointer in acpiphp_context
After recent modifications of the ACPI core making it create a struct acpi_device object for every namespace node representing a device regardless of the current status of that device the ACPIPHP code can store a struct acpi_device pointer instead of an ACPI handle in struct acpiphp_context. This immediately makes it possible to avoid making potentially costly calls to acpi_bus_get_device() in two places and allows some more simplifications to be made going forward. The reason why that is correct is because ACPIPHP only installs hotify handlers for namespace nodes that exist when acpiphp_enumerate_slots() is called for their parent bridge. That only happens if the parent bridge has an ACPI companion associated with it, which means that the ACPI namespace scope in question has been scanned already at that point. That, in turn, means that struct acpi_device objects have been created for all namespace nodes in that scope and pointers to those objects can be stored directly instead of their ACPI handles. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_glue.c')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c46
1 files changed, 22 insertions, 24 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a0d6c83ac27b..896a13bf2e02 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -73,11 +73,11 @@ static void acpiphp_context_handler(acpi_handle handle, void *context)
73 73
74/** 74/**
75 * acpiphp_init_context - Create hotplug context and grab a reference to it. 75 * acpiphp_init_context - Create hotplug context and grab a reference to it.
76 * @handle: ACPI object handle to create the context for. 76 * @adev: ACPI device object to create the context for.
77 * 77 *
78 * Call under acpiphp_context_lock. 78 * Call under acpiphp_context_lock.
79 */ 79 */
80static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) 80static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
81{ 81{
82 struct acpiphp_context *context; 82 struct acpiphp_context *context;
83 acpi_status status; 83 acpi_status status;
@@ -86,9 +86,9 @@ static struct acpiphp_context *acpiphp_init_context(acpi_handle handle)
86 if (!context) 86 if (!context)
87 return NULL; 87 return NULL;
88 88
89 context->handle = handle; 89 context->adev = adev;
90 context->refcount = 1; 90 context->refcount = 1;
91 status = acpi_attach_data(handle, acpiphp_context_handler, context); 91 status = acpi_attach_data(adev->handle, acpiphp_context_handler, context);
92 if (ACPI_FAILURE(status)) { 92 if (ACPI_FAILURE(status)) {
93 kfree(context); 93 kfree(context);
94 return NULL; 94 return NULL;
@@ -118,7 +118,7 @@ static struct acpiphp_context *acpiphp_get_context(acpi_handle handle)
118 118
119/** 119/**
120 * acpiphp_put_context - Drop a reference to ACPI hotplug context. 120 * acpiphp_put_context - Drop a reference to ACPI hotplug context.
121 * @handle: ACPI object handle to put the context for. 121 * @context: ACPI hotplug context to drop a reference to.
122 * 122 *
123 * The context object is removed if there are no more references to it. 123 * The context object is removed if there are no more references to it.
124 * 124 *
@@ -130,7 +130,7 @@ static void acpiphp_put_context(struct acpiphp_context *context)
130 return; 130 return;
131 131
132 WARN_ON(context->bridge); 132 WARN_ON(context->bridge);
133 acpi_detach_data(context->handle, acpiphp_context_handler); 133 acpi_detach_data(context->adev->handle, acpiphp_context_handler);
134 kfree(context); 134 kfree(context);
135} 135}
136 136
@@ -216,7 +216,7 @@ static void dock_event(acpi_handle handle, u32 type, void *data)
216 216
217 mutex_lock(&acpiphp_context_lock); 217 mutex_lock(&acpiphp_context_lock);
218 context = acpiphp_get_context(handle); 218 context = acpiphp_get_context(handle);
219 if (!context || WARN_ON(context->handle != handle) 219 if (!context || WARN_ON(context->adev->handle != handle)
220 || context->func.parent->is_going_away) { 220 || context->func.parent->is_going_away) {
221 mutex_unlock(&acpiphp_context_lock); 221 mutex_unlock(&acpiphp_context_lock);
222 return; 222 return;
@@ -284,6 +284,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
284{ 284{
285 struct acpiphp_bridge *bridge = data; 285 struct acpiphp_bridge *bridge = data;
286 struct acpiphp_context *context; 286 struct acpiphp_context *context;
287 struct acpi_device *adev;
287 struct acpiphp_slot *slot; 288 struct acpiphp_slot *slot;
288 struct acpiphp_func *newfunc; 289 struct acpiphp_func *newfunc;
289 acpi_status status = AE_OK; 290 acpi_status status = AE_OK;
@@ -303,12 +304,14 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
303 "can't evaluate _ADR (%#x)\n", status); 304 "can't evaluate _ADR (%#x)\n", status);
304 return AE_OK; 305 return AE_OK;
305 } 306 }
307 if (acpi_bus_get_device(handle, &adev))
308 return AE_OK;
306 309
307 device = (adr >> 16) & 0xffff; 310 device = (adr >> 16) & 0xffff;
308 function = adr & 0xffff; 311 function = adr & 0xffff;
309 312
310 mutex_lock(&acpiphp_context_lock); 313 mutex_lock(&acpiphp_context_lock);
311 context = acpiphp_init_context(handle); 314 context = acpiphp_init_context(adev);
312 if (!context) { 315 if (!context) {
313 mutex_unlock(&acpiphp_context_lock); 316 mutex_unlock(&acpiphp_context_lock);
314 acpi_handle_err(handle, "No hotplug context\n"); 317 acpi_handle_err(handle, "No hotplug context\n");
@@ -628,12 +631,8 @@ static void disable_slot(struct acpiphp_slot *slot)
628 if (PCI_SLOT(dev->devfn) == slot->device) 631 if (PCI_SLOT(dev->devfn) == slot->device)
629 pci_stop_and_remove_bus_device(dev); 632 pci_stop_and_remove_bus_device(dev);
630 633
631 list_for_each_entry(func, &slot->funcs, sibling) { 634 list_for_each_entry(func, &slot->funcs, sibling)
632 struct acpi_device *adev; 635 acpi_bus_trim(func_to_acpi_device(func));
633
634 if (!acpi_bus_get_device(func_to_handle(func), &adev))
635 acpi_bus_trim(adev);
636 }
637 636
638 slot->flags &= (~SLOT_ENABLED); 637 slot->flags &= (~SLOT_ENABLED);
639} 638}
@@ -647,13 +646,10 @@ static bool slot_no_hotplug(struct acpiphp_slot *slot)
647{ 646{
648 struct acpiphp_func *func; 647 struct acpiphp_func *func;
649 648
650 list_for_each_entry(func, &slot->funcs, sibling) { 649 list_for_each_entry(func, &slot->funcs, sibling)
651 struct acpi_device *adev = NULL; 650 if (acpiphp_no_hotplug(func_to_acpi_device(func)))
652
653 acpi_bus_get_device(func_to_handle(func), &adev);
654 if (acpiphp_no_hotplug(adev))
655 return true; 651 return true;
656 } 652
657 return false; 653 return false;
658} 654}
659 655
@@ -908,7 +904,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
908static void hotplug_event_work(void *data, u32 type) 904static void hotplug_event_work(void *data, u32 type)
909{ 905{
910 struct acpiphp_context *context = data; 906 struct acpiphp_context *context = data;
911 acpi_handle handle = context->handle; 907 acpi_handle handle = context->adev->handle;
912 908
913 acpi_scan_lock_acquire(); 909 acpi_scan_lock_acquire();
914 910
@@ -967,7 +963,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
967 963
968 mutex_lock(&acpiphp_context_lock); 964 mutex_lock(&acpiphp_context_lock);
969 context = acpiphp_get_context(handle); 965 context = acpiphp_get_context(handle);
970 if (!context || WARN_ON(context->handle != handle) 966 if (!context || WARN_ON(context->adev->handle != handle)
971 || context->func.parent->is_going_away) 967 || context->func.parent->is_going_away)
972 goto err_out; 968 goto err_out;
973 969
@@ -998,16 +994,18 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
998void acpiphp_enumerate_slots(struct pci_bus *bus) 994void acpiphp_enumerate_slots(struct pci_bus *bus)
999{ 995{
1000 struct acpiphp_bridge *bridge; 996 struct acpiphp_bridge *bridge;
997 struct acpi_device *adev;
1001 acpi_handle handle; 998 acpi_handle handle;
1002 acpi_status status; 999 acpi_status status;
1003 1000
1004 if (acpiphp_disabled) 1001 if (acpiphp_disabled)
1005 return; 1002 return;
1006 1003
1007 handle = ACPI_HANDLE(bus->bridge); 1004 adev = ACPI_COMPANION(bus->bridge);
1008 if (!handle) 1005 if (!adev)
1009 return; 1006 return;
1010 1007
1008 handle = adev->handle;
1011 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 1009 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
1012 if (!bridge) { 1010 if (!bridge) {
1013 acpi_handle_err(handle, "No memory for bridge object\n"); 1011 acpi_handle_err(handle, "No memory for bridge object\n");