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:24 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-22 22:00:22 -0400
commitbbd34fcdd1b201e996235731a7c98fd5197d9e51 (patch)
tree3f8d3f7ebf4e42dbc52890753a8b400f7066aa93 /drivers/pci/hotplug/acpiphp_glue.c
parentac372338b750648355bcc64bb0bca13fc6f0a3d5 (diff)
ACPI / hotplug / PCI: Register all devices under the given bridge
Rework register_slot() to create a struct acpiphp_func object for every function it is called for and to create acpiphp slots for all of them. Although acpiphp_register_hotplug_slot() is only called for the slots whose functions are identified as "ejectable", so that user space can manipulate them, the ACPIPHP notify handler, handle_hotplug_event(), is now installed for all of the registered functions (that aren't dock stations) and hotplug events may be handled for all of them. As a result, essentially, all PCI bridges represented by objects in the ACPI namespace are now going to be "hotplug" bridges and that may affect resources allocation in general, although it shouldn't lead to problems. This allows the code to be simplified substantially and addresses the problem where bus check or device check notifications for some PCI bridges or devices are not handled, because those devices are not recognized as "ejectable" or there appear to be no "ejectable" devices under those bridges. 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.c232
1 files changed, 76 insertions, 156 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 95af39c9a396..b306e993ad08 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -65,20 +65,6 @@ static void acpiphp_set_hpp_values(struct pci_bus *bus);
65static void hotplug_event(acpi_handle handle, u32 type, void *data); 65static void hotplug_event(acpi_handle handle, u32 type, void *data);
66static void free_bridge(struct kref *kref); 66static void free_bridge(struct kref *kref);
67 67
68/* callback routine to check for the existence of a pci dock device */
69static acpi_status
70is_pci_dock_device(acpi_handle handle, u32 lvl, void *context, void **rv)
71{
72 int *count = (int *)context;
73
74 if (is_dock_device(handle)) {
75 (*count)++;
76 return AE_CTRL_TERMINATE;
77 } else {
78 return AE_OK;
79 }
80}
81
82static void acpiphp_context_handler(acpi_handle handle, void *context) 68static void acpiphp_context_handler(acpi_handle handle, void *context)
83{ 69{
84 /* Intentionally empty. */ 70 /* Intentionally empty. */
@@ -179,14 +165,16 @@ static void free_bridge(struct kref *kref)
179 } 165 }
180 166
181 context = bridge->context; 167 context = bridge->context;
182 /* Release the reference acquired by acpiphp_enumerate_slots(). */ 168 /* Root bridges will not have hotplug context. */
183 if (context->handler_for_func) 169 if (context) {
170 /* Release the reference taken by acpiphp_enumerate_slots(). */
184 put_bridge(context->func->slot->bridge); 171 put_bridge(context->func->slot->bridge);
172 context->bridge = NULL;
173 acpiphp_put_context(context);
174 }
185 175
186 put_device(&bridge->pci_bus->dev); 176 put_device(&bridge->pci_bus->dev);
187 pci_dev_put(bridge->pci_dev); 177 pci_dev_put(bridge->pci_dev);
188 context->bridge = NULL;
189 acpiphp_put_context(context);
190 kfree(bridge); 178 kfree(bridge);
191 179
192 mutex_unlock(&acpiphp_context_lock); 180 mutex_unlock(&acpiphp_context_lock);
@@ -282,28 +270,24 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
282 struct acpiphp_slot *slot; 270 struct acpiphp_slot *slot;
283 struct acpiphp_func *newfunc; 271 struct acpiphp_func *newfunc;
284 acpi_status status = AE_OK; 272 acpi_status status = AE_OK;
285 unsigned long long adr, sun; 273 unsigned long long adr;
286 int device, function, retval; 274 int device, function;
287 struct pci_bus *pbus = bridge->pci_bus; 275 struct pci_bus *pbus = bridge->pci_bus;
288 struct pci_dev *pdev; 276 struct pci_dev *pdev = bridge->pci_dev;
289 u32 val; 277 u32 val;
290 278
291 if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) 279 if (pdev && device_is_managed_by_native_pciehp(pdev))
292 return AE_OK; 280 return AE_OK;
293 281
294 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); 282 status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
295 if (ACPI_FAILURE(status)) { 283 if (ACPI_FAILURE(status)) {
296 warn("can't evaluate _ADR (%#x)\n", status); 284 acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status);
297 return AE_OK; 285 return AE_OK;
298 } 286 }
299 287
300 device = (adr >> 16) & 0xffff; 288 device = (adr >> 16) & 0xffff;
301 function = adr & 0xffff; 289 function = adr & 0xffff;
302 290
303 pdev = bridge->pci_dev;
304 if (pdev && device_is_managed_by_native_pciehp(pdev))
305 return AE_OK;
306
307 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL); 291 newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
308 if (!newfunc) 292 if (!newfunc)
309 return AE_NO_MEMORY; 293 return AE_NO_MEMORY;
@@ -338,23 +322,10 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
338 if (acpi_has_method(handle, "_DCK")) 322 if (acpi_has_method(handle, "_DCK"))
339 newfunc->flags |= FUNC_HAS_DCK; 323 newfunc->flags |= FUNC_HAS_DCK;
340 324
341 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
342 if (ACPI_FAILURE(status)) {
343 /*
344 * use the count of the number of slots we've found
345 * for the number of the slot
346 */
347 sun = bridge->nr_slots+1;
348 }
349
350 /* search for objects that share the same slot */ 325 /* search for objects that share the same slot */
351 list_for_each_entry(slot, &bridge->slots, node) 326 list_for_each_entry(slot, &bridge->slots, node)
352 if (slot->device == device) { 327 if (slot->device == device)
353 if (slot->sun != sun)
354 warn("sibling found, but _SUN doesn't match!\n");
355
356 goto slot_found; 328 goto slot_found;
357 }
358 329
359 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); 330 slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL);
360 if (!slot) { 331 if (!slot) {
@@ -364,34 +335,38 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
364 335
365 slot->bridge = bridge; 336 slot->bridge = bridge;
366 slot->device = device; 337 slot->device = device;
367 slot->sun = sun;
368 INIT_LIST_HEAD(&slot->funcs); 338 INIT_LIST_HEAD(&slot->funcs);
369 mutex_init(&slot->crit_sect); 339 mutex_init(&slot->crit_sect);
370 340
371 mutex_lock(&bridge_mutex); 341 mutex_lock(&bridge_mutex);
372 list_add_tail(&slot->node, &bridge->slots); 342 list_add_tail(&slot->node, &bridge->slots);
373 mutex_unlock(&bridge_mutex); 343 mutex_unlock(&bridge_mutex);
374 bridge->nr_slots++;
375
376 dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
377 slot->sun, pci_domain_nr(pbus), pbus->number, device);
378 344
379 retval = acpiphp_register_hotplug_slot(slot); 345 /* Register slots for ejectable funtions only. */
380 if (retval) { 346 if (acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) {
381 if (retval == -EBUSY) 347 unsigned long long sun;
382 warn("Slot %llu already registered by another " 348 int retval;
383 "hotplug driver\n", slot->sun);
384 else
385 warn("acpiphp_register_hotplug_slot failed "
386 "(err code = 0x%x)\n", retval);
387 349
388 bridge->nr_slots--; 350 bridge->nr_slots++;
389 mutex_lock(&bridge_mutex); 351 status = acpi_evaluate_integer(handle, "_SUN", NULL, &sun);
390 list_del(&slot->node); 352 if (ACPI_FAILURE(status))
391 mutex_unlock(&bridge_mutex); 353 sun = bridge->nr_slots;
392 kfree(slot); 354
393 status = AE_OK; 355 slot->sun = sun;
394 goto err; 356 dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n",
357 slot->sun, pci_domain_nr(pbus), pbus->number, device);
358
359 retval = acpiphp_register_hotplug_slot(slot);
360 if (retval) {
361 bridge->nr_slots--;
362 if (retval == -EBUSY)
363 warn("Slot %llu already registered by another "
364 "hotplug driver\n", slot->sun);
365 else
366 warn("acpiphp_register_hotplug_slot failed "
367 "(err code = 0x%x)\n", retval);
368 }
369 /* Even if the slot registration fails, we can still use it. */
395 } 370 }
396 371
397 slot_found: 372 slot_found:
@@ -421,10 +396,9 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
421 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 396 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
422 handle_hotplug_event, 397 handle_hotplug_event,
423 context); 398 context);
424 if (ACPI_SUCCESS(status)) 399 if (ACPI_FAILURE(status))
425 context->handler_for_func = true; 400 acpi_handle_err(handle,
426 else 401 "failed to install notify handler\n");
427 err("failed to register interrupt notify handler\n");
428 } 402 }
429 403
430 return AE_OK; 404 return AE_OK;
@@ -438,18 +412,6 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data,
438 return status; 412 return status;
439} 413}
440 414
441
442/* see if it's worth looking at this bridge */
443static int detect_ejectable_slots(acpi_handle handle)
444{
445 int found = acpi_pci_detect_ejectable(handle);
446 if (!found) {
447 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
448 is_pci_dock_device, NULL, (void *)&found, NULL);
449 }
450 return found;
451}
452
453static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) 415static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
454{ 416{
455 struct acpiphp_context *context; 417 struct acpiphp_context *context;
@@ -473,14 +435,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
473 struct acpiphp_slot *slot; 435 struct acpiphp_slot *slot;
474 struct acpiphp_func *func; 436 struct acpiphp_func *func;
475 acpi_status status; 437 acpi_status status;
476 acpi_handle handle = bridge->handle;
477
478 if (!bridge->context->handler_for_func) {
479 status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
480 handle_hotplug_event);
481 if (ACPI_FAILURE(status))
482 err("failed to remove notify handler\n");
483 }
484 438
485 list_for_each_entry(slot, &bridge->slots, node) { 439 list_for_each_entry(slot, &bridge->slots, node) {
486 list_for_each_entry(func, &slot->funcs, sibling) { 440 list_for_each_entry(func, &slot->funcs, sibling) {
@@ -488,7 +442,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
488 unregister_hotplug_dock_device(func->handle); 442 unregister_hotplug_dock_device(func->handle);
489 } 443 }
490 if (!(func->flags & FUNC_HAS_DCK)) { 444 if (!(func->flags & FUNC_HAS_DCK)) {
491 func->context->handler_for_func = false;
492 status = acpi_remove_notify_handler(func->handle, 445 status = acpi_remove_notify_handler(func->handle,
493 ACPI_SYSTEM_NOTIFY, 446 ACPI_SYSTEM_NOTIFY,
494 handle_hotplug_event); 447 handle_hotplug_event);
@@ -678,9 +631,7 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
678 631
679 list_for_each_entry(func, &slot->funcs, sibling) { 632 list_for_each_entry(func, &slot->funcs, sibling) {
680 if (PCI_FUNC(dev->devfn) == func->function) { 633 if (PCI_FUNC(dev->devfn) == func->function) {
681 /* check if this bridge has ejectable slots */ 634 dev->is_hotplug_bridge = 1;
682 if ((detect_ejectable_slots(func->handle) > 0))
683 dev->is_hotplug_bridge = 1;
684 break; 635 break;
685 } 636 }
686 } 637 }
@@ -988,8 +939,8 @@ void acpiphp_check_host_bridge(acpi_handle handle)
988static void hotplug_event(acpi_handle handle, u32 type, void *data) 939static void hotplug_event(acpi_handle handle, u32 type, void *data)
989{ 940{
990 struct acpiphp_context *context = data; 941 struct acpiphp_context *context = data;
942 struct acpiphp_func *func = context->func;
991 struct acpiphp_bridge *bridge; 943 struct acpiphp_bridge *bridge;
992 struct acpiphp_func *func;
993 char objname[64]; 944 char objname[64];
994 struct acpi_buffer buffer = { .length = sizeof(objname), 945 struct acpi_buffer buffer = { .length = sizeof(objname),
995 .pointer = objname }; 946 .pointer = objname };
@@ -999,11 +950,6 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
999 if (bridge) 950 if (bridge)
1000 get_bridge(bridge); 951 get_bridge(bridge);
1001 952
1002 /*
1003 * If context->func is not NULL, we are holding a reference to its
1004 * parent bridge, so it won't go away until we drop that reference.
1005 */
1006 func = context->func;
1007 mutex_unlock(&acpiphp_context_lock); 953 mutex_unlock(&acpiphp_context_lock);
1008 954
1009 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 955 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
@@ -1041,9 +987,6 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
1041 case ACPI_NOTIFY_EJECT_REQUEST: 987 case ACPI_NOTIFY_EJECT_REQUEST:
1042 /* request device eject */ 988 /* request device eject */
1043 dbg("%s: Device eject notify on %s\n", __func__, objname); 989 dbg("%s: Device eject notify on %s\n", __func__, objname);
1044 if (!func)
1045 break;
1046
1047 if (bridge && !(bridge->flags & BRIDGE_HAS_EJ0)) 990 if (bridge && !(bridge->flags & BRIDGE_HAS_EJ0))
1048 break; 991 break;
1049 992
@@ -1090,14 +1033,7 @@ static void hotplug_event_work(struct work_struct *work)
1090 1033
1091 acpi_scan_lock_release(); 1034 acpi_scan_lock_release();
1092 kfree(hp_work); /* allocated in handle_hotplug_event() */ 1035 kfree(hp_work); /* allocated in handle_hotplug_event() */
1093 1036 put_bridge(context->func->slot->bridge);
1094 mutex_lock(&acpiphp_context_lock);
1095 if (context->func)
1096 put_bridge(context->func->slot->bridge);
1097 else
1098 acpiphp_put_context(context);
1099
1100 mutex_unlock(&acpiphp_context_lock);
1101} 1037}
1102 1038
1103/** 1039/**
@@ -1115,13 +1051,8 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
1115 mutex_lock(&acpiphp_context_lock); 1051 mutex_lock(&acpiphp_context_lock);
1116 context = acpiphp_get_context(handle); 1052 context = acpiphp_get_context(handle);
1117 if (context) { 1053 if (context) {
1118 if (context->func) { 1054 get_bridge(context->func->slot->bridge);
1119 get_bridge(context->func->slot->bridge); 1055 acpiphp_put_context(context);
1120 acpiphp_put_context(context);
1121 } else if (!context->bridge) {
1122 acpiphp_put_context(context);
1123 context = NULL;
1124 }
1125 } 1056 }
1126 mutex_unlock(&acpiphp_context_lock); 1057 mutex_unlock(&acpiphp_context_lock);
1127 /* 1058 /*
@@ -1142,7 +1073,6 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data)
1142 */ 1073 */
1143void acpiphp_enumerate_slots(struct pci_bus *bus) 1074void acpiphp_enumerate_slots(struct pci_bus *bus)
1144{ 1075{
1145 struct acpiphp_context *context;
1146 struct acpiphp_bridge *bridge; 1076 struct acpiphp_bridge *bridge;
1147 acpi_handle handle; 1077 acpi_handle handle;
1148 acpi_status status; 1078 acpi_status status;
@@ -1151,7 +1081,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1151 return; 1081 return;
1152 1082
1153 handle = ACPI_HANDLE(bus->bridge); 1083 handle = ACPI_HANDLE(bus->bridge);
1154 if (!handle || detect_ejectable_slots(handle) <= 0) 1084 if (!handle)
1155 return; 1085 return;
1156 1086
1157 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); 1087 bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -1166,21 +1096,6 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1166 bridge->pci_dev = pci_dev_get(bus->self); 1096 bridge->pci_dev = pci_dev_get(bus->self);
1167 bridge->pci_bus = bus; 1097 bridge->pci_bus = bus;
1168 1098
1169 mutex_lock(&acpiphp_context_lock);
1170 context = acpiphp_get_context(handle);
1171 if (!context) {
1172 context = acpiphp_init_context(handle);
1173 if (!context) {
1174 mutex_unlock(&acpiphp_context_lock);
1175 acpi_handle_err(handle, "No hotplug context\n");
1176 kfree(bridge);
1177 return;
1178 }
1179 }
1180 bridge->context = context;
1181 context->bridge = bridge;
1182 mutex_unlock(&acpiphp_context_lock);
1183
1184 /* 1099 /*
1185 * Grab a ref to the subordinate PCI bus in case the bus is 1100 * Grab a ref to the subordinate PCI bus in case the bus is
1186 * removed via PCI core logical hotplug. The ref pins the bus 1101 * removed via PCI core logical hotplug. The ref pins the bus
@@ -1188,6 +1103,35 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1188 */ 1103 */
1189 get_device(&bus->dev); 1104 get_device(&bus->dev);
1190 1105
1106 if (!pci_is_root_bus(bridge->pci_bus)) {
1107 struct acpiphp_context *context;
1108
1109 /*
1110 * This bridge should have been registered as a hotplug function
1111 * under its parent, so the context has to be there. If not, we
1112 * are in deep goo.
1113 */
1114 mutex_lock(&acpiphp_context_lock);
1115 context = acpiphp_get_context(handle);
1116 if (WARN_ON(!context || !context->func)) {
1117 mutex_unlock(&acpiphp_context_lock);
1118 put_device(&bus->dev);
1119 kfree(bridge);
1120 return;
1121 }
1122 bridge->context = context;
1123 context->bridge = bridge;
1124 /* Get a reference to the parent bridge. */
1125 get_bridge(context->func->slot->bridge);
1126 mutex_unlock(&acpiphp_context_lock);
1127 }
1128
1129 status = acpi_get_handle(bridge->handle, "_EJ0", &handle);
1130 if (ACPI_SUCCESS(status)) {
1131 dbg("found ejectable p2p bridge\n");
1132 bridge->flags |= BRIDGE_HAS_EJ0;
1133 }
1134
1191 /* must be added to the list prior to calling register_slot */ 1135 /* must be added to the list prior to calling register_slot */
1192 mutex_lock(&bridge_mutex); 1136 mutex_lock(&bridge_mutex);
1193 list_add(&bridge->list, &bridge_list); 1137 list_add(&bridge->list, &bridge_list);
@@ -1198,33 +1142,9 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
1198 register_slot, NULL, bridge, NULL); 1142 register_slot, NULL, bridge, NULL);
1199 if (ACPI_FAILURE(status)) { 1143 if (ACPI_FAILURE(status)) {
1200 acpi_handle_err(bridge->handle, "failed to register slots\n"); 1144 acpi_handle_err(bridge->handle, "failed to register slots\n");
1201 goto err; 1145 cleanup_bridge(bridge);
1202 } 1146 put_bridge(bridge);
1203
1204 if (pci_is_root_bus(bridge->pci_bus))
1205 return;
1206
1207 if (acpi_has_method(bridge->handle, "_EJ0")) {
1208 dbg("found ejectable p2p bridge\n");
1209 bridge->flags |= BRIDGE_HAS_EJ0;
1210 }
1211 if (context->handler_for_func) {
1212 /* Notify handler already installed. */
1213 get_bridge(context->func->slot->bridge);
1214 return;
1215 } 1147 }
1216
1217 /* install notify handler for P2P bridges */
1218 status = acpi_install_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
1219 handle_hotplug_event, NULL);
1220 if (ACPI_SUCCESS(status))
1221 return;
1222
1223 acpi_handle_err(bridge->handle, "failed to register notify handler\n");
1224
1225 err:
1226 cleanup_bridge(bridge);
1227 put_bridge(bridge);
1228} 1148}
1229 1149
1230/* Destroy hotplug slots associated with the PCI bus */ 1150/* Destroy hotplug slots associated with the PCI bus */