diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-18 07:48:30 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-18 07:48:30 -0500 |
commit | 0b3571274b8ff53c0e08bc667ecd3d8a43bd8714 (patch) | |
tree | 57fa58c4c5abe63cccf3fd842548d16fc8d792ba /drivers/acpi/scan.c | |
parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) | |
parent | 5993c4670ea2453ef5abb45b312f150e994e6eb9 (diff) |
Merge branch 'acpi-scan' into acpi-lpss
The following commits depend on the 'acpi-scan' material.
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 320 |
1 files changed, 116 insertions, 204 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c88be6c37c30..7d164a966b0d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -116,24 +116,18 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | |||
116 | void acpi_bus_hot_remove_device(void *context) | 116 | void acpi_bus_hot_remove_device(void *context) |
117 | { | 117 | { |
118 | struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; | 118 | struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; |
119 | struct acpi_device *device; | 119 | struct acpi_device *device = ej_event->device; |
120 | acpi_handle handle = ej_event->handle; | 120 | acpi_handle handle = device->handle; |
121 | acpi_handle temp; | 121 | acpi_handle temp; |
122 | struct acpi_object_list arg_list; | 122 | struct acpi_object_list arg_list; |
123 | union acpi_object arg; | 123 | union acpi_object arg; |
124 | acpi_status status = AE_OK; | 124 | acpi_status status = AE_OK; |
125 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ | 125 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ |
126 | 126 | ||
127 | if (acpi_bus_get_device(handle, &device)) | ||
128 | goto err_out; | ||
129 | |||
130 | if (!device) | ||
131 | goto err_out; | ||
132 | |||
133 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 127 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
134 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 128 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
135 | 129 | ||
136 | if (acpi_bus_trim(device, 1)) { | 130 | if (acpi_bus_trim(device)) { |
137 | printk(KERN_ERR PREFIX | 131 | printk(KERN_ERR PREFIX |
138 | "Removing device failed\n"); | 132 | "Removing device failed\n"); |
139 | goto err_out; | 133 | goto err_out; |
@@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
215 | goto err; | 209 | goto err; |
216 | } | 210 | } |
217 | 211 | ||
218 | ej_event->handle = acpi_device->handle; | 212 | ej_event->device = acpi_device; |
219 | if (acpi_device->flags.eject_pending) { | 213 | if (acpi_device->flags.eject_pending) { |
220 | /* event originated from ACPI eject notification */ | 214 | /* event originated from ACPI eject notification */ |
221 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; | 215 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; |
@@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
223 | } else { | 217 | } else { |
224 | /* event originated from user */ | 218 | /* event originated from user */ |
225 | ej_event->event = ACPI_OST_EC_OSPM_EJECT; | 219 | ej_event->event = ACPI_OST_EC_OSPM_EJECT; |
226 | (void) acpi_evaluate_hotplug_ost(ej_event->handle, | 220 | (void) acpi_evaluate_hotplug_ost(acpi_device->handle, |
227 | ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 221 | ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
228 | } | 222 | } |
229 | 223 | ||
@@ -494,7 +488,8 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) | |||
494 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 488 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
495 | struct acpi_driver *acpi_drv = to_acpi_driver(drv); | 489 | struct acpi_driver *acpi_drv = to_acpi_driver(drv); |
496 | 490 | ||
497 | return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); | 491 | return acpi_dev->flags.match_driver |
492 | && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); | ||
498 | } | 493 | } |
499 | 494 | ||
500 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) | 495 | static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) |
@@ -570,7 +565,6 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) | |||
570 | } | 565 | } |
571 | 566 | ||
572 | static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); | 567 | static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); |
573 | static int acpi_start_single_object(struct acpi_device *); | ||
574 | static int acpi_device_probe(struct device * dev) | 568 | static int acpi_device_probe(struct device * dev) |
575 | { | 569 | { |
576 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 570 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
@@ -579,9 +573,6 @@ static int acpi_device_probe(struct device * dev) | |||
579 | 573 | ||
580 | ret = acpi_bus_driver_init(acpi_dev, acpi_drv); | 574 | ret = acpi_bus_driver_init(acpi_dev, acpi_drv); |
581 | if (!ret) { | 575 | if (!ret) { |
582 | if (acpi_dev->bus_ops.acpi_op_start) | ||
583 | acpi_start_single_object(acpi_dev); | ||
584 | |||
585 | if (acpi_drv->ops.notify) { | 576 | if (acpi_drv->ops.notify) { |
586 | ret = acpi_device_install_notify_handler(acpi_dev); | 577 | ret = acpi_device_install_notify_handler(acpi_dev); |
587 | if (ret) { | 578 | if (ret) { |
@@ -704,7 +695,7 @@ end: | |||
704 | return result; | 695 | return result; |
705 | } | 696 | } |
706 | 697 | ||
707 | static void acpi_device_unregister(struct acpi_device *device, int type) | 698 | static void acpi_device_unregister(struct acpi_device *device) |
708 | { | 699 | { |
709 | mutex_lock(&acpi_device_lock); | 700 | mutex_lock(&acpi_device_lock); |
710 | if (device->parent) | 701 | if (device->parent) |
@@ -760,24 +751,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) | |||
760 | return 0; | 751 | return 0; |
761 | } | 752 | } |
762 | 753 | ||
763 | static int acpi_start_single_object(struct acpi_device *device) | ||
764 | { | ||
765 | int result = 0; | ||
766 | struct acpi_driver *driver; | ||
767 | |||
768 | |||
769 | if (!(driver = device->driver)) | ||
770 | return 0; | ||
771 | |||
772 | if (driver->ops.start) { | ||
773 | result = driver->ops.start(device); | ||
774 | if (result && driver->ops.remove) | ||
775 | driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); | ||
776 | } | ||
777 | |||
778 | return result; | ||
779 | } | ||
780 | |||
781 | /** | 754 | /** |
782 | * acpi_bus_register_driver - register a driver with the ACPI bus | 755 | * acpi_bus_register_driver - register a driver with the ACPI bus |
783 | * @driver: driver being registered | 756 | * @driver: driver being registered |
@@ -1395,33 +1368,9 @@ static int acpi_device_set_context(struct acpi_device *device) | |||
1395 | return -ENODEV; | 1368 | return -ENODEV; |
1396 | } | 1369 | } |
1397 | 1370 | ||
1398 | static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | ||
1399 | { | ||
1400 | if (!dev) | ||
1401 | return -EINVAL; | ||
1402 | |||
1403 | dev->removal_type = ACPI_BUS_REMOVAL_EJECT; | ||
1404 | device_release_driver(&dev->dev); | ||
1405 | |||
1406 | if (!rmdevice) | ||
1407 | return 0; | ||
1408 | |||
1409 | /* | ||
1410 | * unbind _ADR-Based Devices when hot removal | ||
1411 | */ | ||
1412 | if (dev->flags.bus_address) { | ||
1413 | if ((dev->parent) && (dev->parent->ops.unbind)) | ||
1414 | dev->parent->ops.unbind(dev); | ||
1415 | } | ||
1416 | acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); | ||
1417 | |||
1418 | return 0; | ||
1419 | } | ||
1420 | |||
1421 | static int acpi_add_single_object(struct acpi_device **child, | 1371 | static int acpi_add_single_object(struct acpi_device **child, |
1422 | acpi_handle handle, int type, | 1372 | acpi_handle handle, int type, |
1423 | unsigned long long sta, | 1373 | unsigned long long sta, bool match_driver) |
1424 | struct acpi_bus_ops *ops) | ||
1425 | { | 1374 | { |
1426 | int result; | 1375 | int result; |
1427 | struct acpi_device *device; | 1376 | struct acpi_device *device; |
@@ -1437,7 +1386,6 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1437 | device->device_type = type; | 1386 | device->device_type = type; |
1438 | device->handle = handle; | 1387 | device->handle = handle; |
1439 | device->parent = acpi_bus_get_parent(handle); | 1388 | device->parent = acpi_bus_get_parent(handle); |
1440 | device->bus_ops = *ops; /* workround for not call .start */ | ||
1441 | STRUCT_TO_INT(device->status) = sta; | 1389 | STRUCT_TO_INT(device->status) = sta; |
1442 | 1390 | ||
1443 | acpi_device_get_busid(device); | 1391 | acpi_device_get_busid(device); |
@@ -1488,16 +1436,9 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1488 | if ((result = acpi_device_set_context(device))) | 1436 | if ((result = acpi_device_set_context(device))) |
1489 | goto end; | 1437 | goto end; |
1490 | 1438 | ||
1439 | device->flags.match_driver = match_driver; | ||
1491 | result = acpi_device_register(device); | 1440 | result = acpi_device_register(device); |
1492 | 1441 | ||
1493 | /* | ||
1494 | * Bind _ADR-Based Devices when hot add | ||
1495 | */ | ||
1496 | if (device->flags.bus_address) { | ||
1497 | if (device->parent && device->parent->ops.bind) | ||
1498 | device->parent->ops.bind(device); | ||
1499 | } | ||
1500 | |||
1501 | end: | 1442 | end: |
1502 | if (!result) { | 1443 | if (!result) { |
1503 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1444 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
@@ -1519,16 +1460,12 @@ end: | |||
1519 | 1460 | ||
1520 | static void acpi_bus_add_power_resource(acpi_handle handle) | 1461 | static void acpi_bus_add_power_resource(acpi_handle handle) |
1521 | { | 1462 | { |
1522 | struct acpi_bus_ops ops = { | ||
1523 | .acpi_op_add = 1, | ||
1524 | .acpi_op_start = 1, | ||
1525 | }; | ||
1526 | struct acpi_device *device = NULL; | 1463 | struct acpi_device *device = NULL; |
1527 | 1464 | ||
1528 | acpi_bus_get_device(handle, &device); | 1465 | acpi_bus_get_device(handle, &device); |
1529 | if (!device) | 1466 | if (!device) |
1530 | acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, | 1467 | acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, |
1531 | ACPI_STA_DEFAULT, &ops); | 1468 | ACPI_STA_DEFAULT, true); |
1532 | } | 1469 | } |
1533 | 1470 | ||
1534 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | 1471 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, |
@@ -1570,16 +1507,19 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, | |||
1570 | return 0; | 1507 | return 0; |
1571 | } | 1508 | } |
1572 | 1509 | ||
1573 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | 1510 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, |
1574 | void *context, void **return_value) | 1511 | void *not_used, void **return_value) |
1575 | { | 1512 | { |
1576 | struct acpi_bus_ops *ops = context; | 1513 | struct acpi_device *device = NULL; |
1577 | int type; | 1514 | int type; |
1578 | unsigned long long sta; | 1515 | unsigned long long sta; |
1579 | struct acpi_device *device; | ||
1580 | acpi_status status; | 1516 | acpi_status status; |
1581 | int result; | 1517 | int result; |
1582 | 1518 | ||
1519 | acpi_bus_get_device(handle, &device); | ||
1520 | if (device) | ||
1521 | goto out; | ||
1522 | |||
1583 | result = acpi_bus_type_and_status(handle, &type, &sta); | 1523 | result = acpi_bus_type_and_status(handle, &type, &sta); |
1584 | if (result) | 1524 | if (result) |
1585 | return AE_OK; | 1525 | return AE_OK; |
@@ -1596,150 +1536,130 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1596 | return AE_CTRL_DEPTH; | 1536 | return AE_CTRL_DEPTH; |
1597 | } | 1537 | } |
1598 | 1538 | ||
1599 | /* | 1539 | acpi_add_single_object(&device, handle, type, sta, |
1600 | * We may already have an acpi_device from a previous enumeration. If | 1540 | type == ACPI_BUS_TYPE_POWER); |
1601 | * so, we needn't add it again, but we may still have to start it. | ||
1602 | */ | ||
1603 | device = NULL; | ||
1604 | acpi_bus_get_device(handle, &device); | ||
1605 | if (ops->acpi_op_add && !device) { | ||
1606 | acpi_add_single_object(&device, handle, type, sta, ops); | ||
1607 | /* Is the device a known good platform device? */ | ||
1608 | if (device | ||
1609 | && !acpi_match_device_ids(device, acpi_platform_device_ids)) | ||
1610 | acpi_create_platform_device(device); | ||
1611 | } | ||
1612 | |||
1613 | if (!device) | 1541 | if (!device) |
1614 | return AE_CTRL_DEPTH; | 1542 | return AE_CTRL_DEPTH; |
1615 | 1543 | ||
1616 | if (ops->acpi_op_start && !(ops->acpi_op_add)) { | 1544 | device->flags.match_driver = true; |
1617 | status = acpi_start_single_object(device); | ||
1618 | if (ACPI_FAILURE(status)) | ||
1619 | return AE_CTRL_DEPTH; | ||
1620 | } | ||
1621 | 1545 | ||
1546 | out: | ||
1622 | if (!*return_value) | 1547 | if (!*return_value) |
1623 | *return_value = device; | 1548 | *return_value = device; |
1549 | |||
1624 | return AE_OK; | 1550 | return AE_OK; |
1625 | } | 1551 | } |
1626 | 1552 | ||
1627 | static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, | 1553 | static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, |
1628 | struct acpi_device **child) | 1554 | void *not_used, void **ret_not_used) |
1555 | { | ||
1556 | acpi_status status = AE_OK; | ||
1557 | struct acpi_device *device; | ||
1558 | unsigned long long sta_not_used; | ||
1559 | int type_not_used; | ||
1560 | |||
1561 | /* | ||
1562 | * Ignore errors ignored by acpi_bus_check_add() to avoid terminating | ||
1563 | * namespace walks prematurely. | ||
1564 | */ | ||
1565 | if (acpi_bus_type_and_status(handle, &type_not_used, &sta_not_used)) | ||
1566 | return AE_OK; | ||
1567 | |||
1568 | if (acpi_bus_get_device(handle, &device)) | ||
1569 | return AE_CTRL_DEPTH; | ||
1570 | |||
1571 | if (!acpi_match_device_ids(device, acpi_platform_device_ids)) { | ||
1572 | /* This is a known good platform device. */ | ||
1573 | acpi_create_platform_device(device); | ||
1574 | } else if (device_attach(&device->dev) < 0) { | ||
1575 | status = AE_CTRL_DEPTH; | ||
1576 | } | ||
1577 | return status; | ||
1578 | } | ||
1579 | |||
1580 | static int acpi_bus_scan(acpi_handle handle) | ||
1629 | { | 1581 | { |
1630 | acpi_status status; | ||
1631 | void *device = NULL; | 1582 | void *device = NULL; |
1632 | 1583 | ||
1633 | status = acpi_bus_check_add(handle, 0, ops, &device); | 1584 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) |
1634 | if (ACPI_SUCCESS(status)) | ||
1635 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1585 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1636 | acpi_bus_check_add, NULL, ops, &device); | 1586 | acpi_bus_check_add, NULL, NULL, &device); |
1637 | 1587 | ||
1638 | if (child) | 1588 | if (!device) |
1639 | *child = device; | ||
1640 | |||
1641 | if (device) | ||
1642 | return 0; | ||
1643 | else | ||
1644 | return -ENODEV; | 1589 | return -ENODEV; |
1590 | |||
1591 | if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) | ||
1592 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | ||
1593 | acpi_bus_device_attach, NULL, NULL, NULL); | ||
1594 | |||
1595 | return 0; | ||
1645 | } | 1596 | } |
1646 | 1597 | ||
1647 | /* | 1598 | /** |
1648 | * acpi_bus_add and acpi_bus_start | 1599 | * acpi_bus_add - Add ACPI device node objects in a given namespace scope. |
1600 | * @handle: Root of the namespace scope to scan. | ||
1649 | * | 1601 | * |
1650 | * scan a given ACPI tree and (probably recently hot-plugged) | 1602 | * Scan a given ACPI tree (probably recently hot-plugged) and create and add |
1651 | * create and add or starts found devices. | 1603 | * found devices. |
1652 | * | 1604 | * |
1653 | * If no devices were found -ENODEV is returned which does not | 1605 | * If no devices were found, -ENODEV is returned, but it does not mean that |
1654 | * mean that this is a real error, there just have been no suitable | 1606 | * there has been a real error. There just have been no suitable ACPI objects |
1655 | * ACPI objects in the table trunk from which the kernel could create | 1607 | * in the table trunk from which the kernel could create a device and add an |
1656 | * a device and add/start an appropriate driver. | 1608 | * appropriate driver. |
1657 | */ | 1609 | */ |
1658 | 1610 | int acpi_bus_add(acpi_handle handle) | |
1659 | int | ||
1660 | acpi_bus_add(struct acpi_device **child, | ||
1661 | struct acpi_device *parent, acpi_handle handle, int type) | ||
1662 | { | 1611 | { |
1663 | struct acpi_bus_ops ops; | 1612 | int err; |
1664 | 1613 | ||
1665 | memset(&ops, 0, sizeof(ops)); | 1614 | err = acpi_bus_scan(handle); |
1666 | ops.acpi_op_add = 1; | 1615 | if (err) |
1616 | return err; | ||
1667 | 1617 | ||
1668 | return acpi_bus_scan(handle, &ops, child); | 1618 | acpi_update_all_gpes(); |
1619 | return 0; | ||
1669 | } | 1620 | } |
1670 | EXPORT_SYMBOL(acpi_bus_add); | 1621 | EXPORT_SYMBOL(acpi_bus_add); |
1671 | 1622 | ||
1672 | int acpi_bus_start(struct acpi_device *device) | 1623 | static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used, |
1624 | void *not_used, void **ret_not_used) | ||
1673 | { | 1625 | { |
1674 | struct acpi_bus_ops ops; | 1626 | struct acpi_device *device = NULL; |
1675 | int result; | ||
1676 | |||
1677 | if (!device) | ||
1678 | return -EINVAL; | ||
1679 | |||
1680 | memset(&ops, 0, sizeof(ops)); | ||
1681 | ops.acpi_op_start = 1; | ||
1682 | |||
1683 | result = acpi_bus_scan(device->handle, &ops, NULL); | ||
1684 | |||
1685 | acpi_update_all_gpes(); | ||
1686 | 1627 | ||
1687 | return result; | 1628 | if (!acpi_bus_get_device(handle, &device)) { |
1629 | device->removal_type = ACPI_BUS_REMOVAL_EJECT; | ||
1630 | device_release_driver(&device->dev); | ||
1631 | } | ||
1632 | return AE_OK; | ||
1688 | } | 1633 | } |
1689 | EXPORT_SYMBOL(acpi_bus_start); | ||
1690 | 1634 | ||
1691 | int acpi_bus_trim(struct acpi_device *start, int rmdevice) | 1635 | static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, |
1636 | void *not_used, void **ret_not_used) | ||
1692 | { | 1637 | { |
1693 | acpi_status status; | 1638 | struct acpi_device *device = NULL; |
1694 | struct acpi_device *parent, *child; | ||
1695 | acpi_handle phandle, chandle; | ||
1696 | acpi_object_type type; | ||
1697 | u32 level = 1; | ||
1698 | int err = 0; | ||
1699 | |||
1700 | parent = start; | ||
1701 | phandle = start->handle; | ||
1702 | child = chandle = NULL; | ||
1703 | |||
1704 | while ((level > 0) && parent && (!err)) { | ||
1705 | status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, | ||
1706 | chandle, &chandle); | ||
1707 | 1639 | ||
1708 | /* | 1640 | if (!acpi_bus_get_device(handle, &device)) |
1709 | * If this scope is exhausted then move our way back up. | 1641 | acpi_device_unregister(device); |
1710 | */ | ||
1711 | if (ACPI_FAILURE(status)) { | ||
1712 | level--; | ||
1713 | chandle = phandle; | ||
1714 | acpi_get_parent(phandle, &phandle); | ||
1715 | child = parent; | ||
1716 | parent = parent->parent; | ||
1717 | |||
1718 | if (level == 0) | ||
1719 | err = acpi_bus_remove(child, rmdevice); | ||
1720 | else | ||
1721 | err = acpi_bus_remove(child, 1); | ||
1722 | 1642 | ||
1723 | continue; | 1643 | return AE_OK; |
1724 | } | 1644 | } |
1725 | 1645 | ||
1726 | status = acpi_get_type(chandle, &type); | 1646 | int acpi_bus_trim(struct acpi_device *start) |
1727 | if (ACPI_FAILURE(status)) { | 1647 | { |
1728 | continue; | 1648 | /* |
1729 | } | 1649 | * Execute acpi_bus_device_detach() as a post-order callback to detach |
1730 | /* | 1650 | * all ACPI drivers from the device nodes being removed. |
1731 | * If there is a device corresponding to chandle then | 1651 | */ |
1732 | * parse it (depth-first). | 1652 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, |
1733 | */ | 1653 | acpi_bus_device_detach, NULL, NULL); |
1734 | if (acpi_bus_get_device(chandle, &child) == 0) { | 1654 | acpi_bus_device_detach(start->handle, 0, NULL, NULL); |
1735 | level++; | 1655 | /* |
1736 | phandle = chandle; | 1656 | * Execute acpi_bus_remove() as a post-order callback to remove device |
1737 | chandle = NULL; | 1657 | * nodes in the given namespace scope. |
1738 | parent = child; | 1658 | */ |
1739 | } | 1659 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, |
1740 | continue; | 1660 | acpi_bus_remove, NULL, NULL); |
1741 | } | 1661 | acpi_bus_remove(start->handle, 0, NULL, NULL); |
1742 | return err; | 1662 | return 0; |
1743 | } | 1663 | } |
1744 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 1664 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1745 | 1665 | ||
@@ -1747,11 +1667,6 @@ static int acpi_bus_scan_fixed(void) | |||
1747 | { | 1667 | { |
1748 | int result = 0; | 1668 | int result = 0; |
1749 | struct acpi_device *device = NULL; | 1669 | struct acpi_device *device = NULL; |
1750 | struct acpi_bus_ops ops; | ||
1751 | |||
1752 | memset(&ops, 0, sizeof(ops)); | ||
1753 | ops.acpi_op_add = 1; | ||
1754 | ops.acpi_op_start = 1; | ||
1755 | 1670 | ||
1756 | /* | 1671 | /* |
1757 | * Enumerate all fixed-feature devices. | 1672 | * Enumerate all fixed-feature devices. |
@@ -1759,16 +1674,14 @@ static int acpi_bus_scan_fixed(void) | |||
1759 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { | 1674 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { |
1760 | result = acpi_add_single_object(&device, NULL, | 1675 | result = acpi_add_single_object(&device, NULL, |
1761 | ACPI_BUS_TYPE_POWER_BUTTON, | 1676 | ACPI_BUS_TYPE_POWER_BUTTON, |
1762 | ACPI_STA_DEFAULT, | 1677 | ACPI_STA_DEFAULT, true); |
1763 | &ops); | ||
1764 | device_init_wakeup(&device->dev, true); | 1678 | device_init_wakeup(&device->dev, true); |
1765 | } | 1679 | } |
1766 | 1680 | ||
1767 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { | 1681 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { |
1768 | result = acpi_add_single_object(&device, NULL, | 1682 | result = acpi_add_single_object(&device, NULL, |
1769 | ACPI_BUS_TYPE_SLEEP_BUTTON, | 1683 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
1770 | ACPI_STA_DEFAULT, | 1684 | ACPI_STA_DEFAULT, true); |
1771 | &ops); | ||
1772 | } | 1685 | } |
1773 | 1686 | ||
1774 | return result; | 1687 | return result; |
@@ -1777,11 +1690,6 @@ static int acpi_bus_scan_fixed(void) | |||
1777 | int __init acpi_scan_init(void) | 1690 | int __init acpi_scan_init(void) |
1778 | { | 1691 | { |
1779 | int result; | 1692 | int result; |
1780 | struct acpi_bus_ops ops; | ||
1781 | |||
1782 | memset(&ops, 0, sizeof(ops)); | ||
1783 | ops.acpi_op_add = 1; | ||
1784 | ops.acpi_op_start = 1; | ||
1785 | 1693 | ||
1786 | result = bus_register(&acpi_bus_type); | 1694 | result = bus_register(&acpi_bus_type); |
1787 | if (result) { | 1695 | if (result) { |
@@ -1790,17 +1698,21 @@ int __init acpi_scan_init(void) | |||
1790 | } | 1698 | } |
1791 | 1699 | ||
1792 | acpi_power_init(); | 1700 | acpi_power_init(); |
1701 | acpi_pci_root_init(); | ||
1793 | 1702 | ||
1794 | /* | 1703 | /* |
1795 | * Enumerate devices in the ACPI namespace. | 1704 | * Enumerate devices in the ACPI namespace. |
1796 | */ | 1705 | */ |
1797 | result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root); | 1706 | result = acpi_bus_scan(ACPI_ROOT_OBJECT); |
1707 | if (result) | ||
1708 | return result; | ||
1798 | 1709 | ||
1710 | result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); | ||
1799 | if (!result) | 1711 | if (!result) |
1800 | result = acpi_bus_scan_fixed(); | 1712 | result = acpi_bus_scan_fixed(); |
1801 | 1713 | ||
1802 | if (result) | 1714 | if (result) |
1803 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1715 | acpi_device_unregister(acpi_root); |
1804 | else | 1716 | else |
1805 | acpi_update_all_gpes(); | 1717 | acpi_update_all_gpes(); |
1806 | 1718 | ||