diff options
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 46 |
2 files changed, 29 insertions, 26 deletions
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index b6162be4df40..098ff425f850 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -117,8 +117,8 @@ struct acpiphp_func { | |||
117 | }; | 117 | }; |
118 | 118 | ||
119 | struct acpiphp_context { | 119 | struct acpiphp_context { |
120 | acpi_handle handle; | ||
121 | struct acpiphp_func func; | 120 | struct acpiphp_func func; |
121 | struct acpi_device *adev; | ||
122 | struct acpiphp_bridge *bridge; | 122 | struct acpiphp_bridge *bridge; |
123 | unsigned int refcount; | 123 | unsigned int refcount; |
124 | }; | 124 | }; |
@@ -128,9 +128,14 @@ static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func) | |||
128 | return container_of(func, struct acpiphp_context, func); | 128 | return container_of(func, struct acpiphp_context, func); |
129 | } | 129 | } |
130 | 130 | ||
131 | static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func) | ||
132 | { | ||
133 | return func_to_context(func)->adev; | ||
134 | } | ||
135 | |||
131 | static inline acpi_handle func_to_handle(struct acpiphp_func *func) | 136 | static inline acpi_handle func_to_handle(struct acpiphp_func *func) |
132 | { | 137 | { |
133 | return func_to_context(func)->handle; | 138 | return func_to_acpi_device(func)->handle; |
134 | } | 139 | } |
135 | 140 | ||
136 | /* | 141 | /* |
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 | */ |
80 | static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) | 80 | static 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) | |||
908 | static void hotplug_event_work(void *data, u32 type) | 904 | static 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) | |||
998 | void acpiphp_enumerate_slots(struct pci_bus *bus) | 994 | void 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"); |