aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpiphp_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_glue.c')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 72ec4a29a402..1e125b56c9a9 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1505,6 +1505,37 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type)
1505 * ACPI event handlers 1505 * ACPI event handlers
1506 */ 1506 */
1507 1507
1508static acpi_status
1509count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
1510{
1511 int *count = (int *)context;
1512 struct acpiphp_bridge *bridge;
1513
1514 bridge = acpiphp_handle_to_bridge(handle);
1515 if (bridge)
1516 (*count)++;
1517 return AE_OK ;
1518}
1519
1520static acpi_status
1521check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
1522{
1523 struct acpiphp_bridge *bridge;
1524 char objname[64];
1525 struct acpi_buffer buffer = { .length = sizeof(objname),
1526 .pointer = objname };
1527
1528 bridge = acpiphp_handle_to_bridge(handle);
1529 if (bridge) {
1530 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1531 dbg("%s: re-enumerating slots under %s\n",
1532 __FUNCTION__, objname);
1533 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1534 acpiphp_check_bridge(bridge);
1535 }
1536 return AE_OK ;
1537}
1538
1508/** 1539/**
1509 * handle_hotplug_event_bridge - handle ACPI event on bridges 1540 * handle_hotplug_event_bridge - handle ACPI event on bridges
1510 * 1541 *
@@ -1522,6 +1553,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1522 struct acpi_buffer buffer = { .length = sizeof(objname), 1553 struct acpi_buffer buffer = { .length = sizeof(objname),
1523 .pointer = objname }; 1554 .pointer = objname };
1524 struct acpi_device *device; 1555 struct acpi_device *device;
1556 int num_sub_bridges = 0;
1525 1557
1526 if (acpi_bus_get_device(handle, &device)) { 1558 if (acpi_bus_get_device(handle, &device)) {
1527 /* This bridge must have just been physically inserted */ 1559 /* This bridge must have just been physically inserted */
@@ -1530,7 +1562,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1530 } 1562 }
1531 1563
1532 bridge = acpiphp_handle_to_bridge(handle); 1564 bridge = acpiphp_handle_to_bridge(handle);
1533 if (!bridge) { 1565 if (type == ACPI_NOTIFY_BUS_CHECK) {
1566 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX,
1567 count_sub_bridges, &num_sub_bridges, NULL);
1568 }
1569
1570 if (!bridge && !num_sub_bridges) {
1534 err("cannot get bridge info\n"); 1571 err("cannot get bridge info\n");
1535 return; 1572 return;
1536 } 1573 }
@@ -1541,7 +1578,14 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1541 case ACPI_NOTIFY_BUS_CHECK: 1578 case ACPI_NOTIFY_BUS_CHECK:
1542 /* bus re-enumerate */ 1579 /* bus re-enumerate */
1543 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname); 1580 dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname);
1544 acpiphp_check_bridge(bridge); 1581 if (bridge) {
1582 dbg("%s: re-enumerating slots under %s\n",
1583 __FUNCTION__, objname);
1584 acpiphp_check_bridge(bridge);
1585 }
1586 if (num_sub_bridges)
1587 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
1588 ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL);
1545 break; 1589 break;
1546 1590
1547 case ACPI_NOTIFY_DEVICE_CHECK: 1591 case ACPI_NOTIFY_DEVICE_CHECK: