aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpiphp_glue.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-13 17:27:23 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-22 22:00:19 -0400
commit2552002a46cd6a7a262ea1718db33d1a1517008e (patch)
tree1f5ba281d3676cee578470a99351c280d47bcee6 /drivers/pci/hotplug/acpiphp_glue.c
parentbe1c9de98d8904c75a5ab8b2a0d97bea0f7c07cc (diff)
ACPI / hotplug / PCI: Consolidate acpiphp_enumerate_slots()
The acpiphp_enumerate_slots() function is now split into two parts, acpiphp_enumerate_slots() proper and init_bridge_misc() which is only called by the former. If these functions are combined, it is possible to make the code easier to follow and to clean up the error handling (to prevent memory leaks on error from happening in particular), so do that. 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.c92
1 files changed, 45 insertions, 47 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a203ba529fef..68c3809ed7ce 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -353,46 +353,6 @@ static int detect_ejectable_slots(acpi_handle handle)
353 return found; 353 return found;
354} 354}
355 355
356/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
357static void init_bridge_misc(struct acpiphp_bridge *bridge)
358{
359 acpi_status status;
360
361 /* must be added to the list prior to calling register_slot */
362 mutex_lock(&bridge_mutex);
363 list_add(&bridge->list, &bridge_list);
364 mutex_unlock(&bridge_mutex);
365
366 /* register all slot objects under this bridge */
367 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
368 register_slot, NULL, bridge, NULL);
369 if (ACPI_FAILURE(status)) {
370 mutex_lock(&bridge_mutex);
371 list_del(&bridge->list);
372 mutex_unlock(&bridge_mutex);
373 return;
374 }
375
376 /* install notify handler for P2P bridges */
377 if (!pci_is_root_bus(bridge->pci_bus)) {
378 if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) {
379 status = acpi_remove_notify_handler(bridge->func->handle,
380 ACPI_SYSTEM_NOTIFY,
381 handle_hotplug_event_func);
382 if (ACPI_FAILURE(status))
383 err("failed to remove notify handler\n");
384 }
385 status = acpi_install_notify_handler(bridge->handle,
386 ACPI_SYSTEM_NOTIFY,
387 handle_hotplug_event_bridge,
388 bridge);
389
390 if (ACPI_FAILURE(status)) {
391 err("failed to register interrupt notify handler\n");
392 }
393 }
394}
395
396 356
397/* find acpiphp_func from acpiphp_bridge */ 357/* find acpiphp_func from acpiphp_bridge */
398static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) 358static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
@@ -1149,8 +1109,9 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
1149 */ 1109 */
1150void acpiphp_enumerate_slots(struct pci_bus *bus) 1110void acpiphp_enumerate_slots(struct pci_bus *bus)
1151{ 1111{
1152 acpi_handle handle;
1153 struct acpiphp_bridge *bridge; 1112 struct acpiphp_bridge *bridge;
1113 acpi_handle handle;
1114 acpi_status status;
1154 1115
1155 if (acpiphp_disabled) 1116 if (acpiphp_disabled)
1156 return; 1117 return;
@@ -1178,14 +1139,51 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1178 */ 1139 */
1179 get_device(&bus->dev); 1140 get_device(&bus->dev);
1180 1141
1181 if (!pci_is_root_bus(bridge->pci_bus) && 1142 /* must be added to the list prior to calling register_slot */
1182 acpi_has_method(bridge->handle, "_EJ0")) { 1143 mutex_lock(&bridge_mutex);
1183 dbg("found ejectable p2p bridge\n"); 1144 list_add(&bridge->list, &bridge_list);
1184 bridge->flags |= BRIDGE_HAS_EJ0; 1145 mutex_unlock(&bridge_mutex);
1185 bridge->func = acpiphp_bridge_handle_to_function(handle); 1146
1147 /* register all slot objects under this bridge */
1148 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, 1,
1149 register_slot, NULL, bridge, NULL);
1150 if (ACPI_FAILURE(status)) {
1151 acpi_handle_err(bridge->handle, "failed to register slots\n");
1152 goto err;
1153 }
1154
1155 if (pci_is_root_bus(bridge->pci_bus))
1156 return;
1157
1158 /* install notify handler for P2P bridges */
1159 status = acpi_install_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1160 handle_hotplug_event_bridge,
1161 bridge);
1162 if (ACPI_FAILURE(status)) {
1163 acpi_handle_err(bridge->handle,
1164 "failed to register notify handler\n");
1165 goto err;
1166 }
1167
1168 if (!acpi_has_method(bridge->handle, "_EJ0"))
1169 return;
1170
1171 dbg("found ejectable p2p bridge\n");
1172 bridge->flags |= BRIDGE_HAS_EJ0;
1173 bridge->func = acpiphp_bridge_handle_to_function(bridge->handle);
1174 if (bridge->func) {
1175 status = acpi_remove_notify_handler(bridge->func->handle,
1176 ACPI_SYSTEM_NOTIFY,
1177 handle_hotplug_event_func);
1178 if (ACPI_FAILURE(status))
1179 acpi_handle_err(bridge->func->handle,
1180 "failed to remove notify handler\n");
1186 } 1181 }
1182 return;
1187 1183
1188 init_bridge_misc(bridge); 1184 err:
1185 cleanup_bridge(bridge);
1186 put_bridge(bridge);
1189} 1187}
1190 1188
1191/* Destroy hotplug slots associated with the PCI bus */ 1189/* Destroy hotplug slots associated with the PCI bus */