diff options
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 29ef505c487b..b99e62494607 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -778,7 +778,7 @@ acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, | |||
778 | wakeup->resources.handles[i] = element->reference.handle; | 778 | wakeup->resources.handles[i] = element->reference.handle; |
779 | } | 779 | } |
780 | 780 | ||
781 | acpi_gpe_can_wake(wakeup->gpe_device, wakeup->gpe_number); | 781 | acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number); |
782 | 782 | ||
783 | out: | 783 | out: |
784 | kfree(buffer.pointer); | 784 | kfree(buffer.pointer); |
@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
803 | /* Power button, Lid switch always enable wakeup */ | 803 | /* Power button, Lid switch always enable wakeup */ |
804 | if (!acpi_match_device_ids(device, button_device_ids)) { | 804 | if (!acpi_match_device_ids(device, button_device_ids)) { |
805 | device->wakeup.flags.run_wake = 1; | 805 | device->wakeup.flags.run_wake = 1; |
806 | device->wakeup.flags.always_enabled = 1; | 806 | device_set_wakeup_capable(&device->dev, true); |
807 | return; | 807 | return; |
808 | } | 808 | } |
809 | 809 | ||
@@ -815,16 +815,22 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
815 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); | 815 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); |
816 | } | 816 | } |
817 | 817 | ||
818 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 818 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
819 | { | 819 | { |
820 | acpi_handle temp; | ||
820 | acpi_status status = 0; | 821 | acpi_status status = 0; |
821 | int psw_error; | 822 | int psw_error; |
822 | 823 | ||
824 | /* Presence of _PRW indicates wake capable */ | ||
825 | status = acpi_get_handle(device->handle, "_PRW", &temp); | ||
826 | if (ACPI_FAILURE(status)) | ||
827 | return; | ||
828 | |||
823 | status = acpi_bus_extract_wakeup_device_power_package(device->handle, | 829 | status = acpi_bus_extract_wakeup_device_power_package(device->handle, |
824 | &device->wakeup); | 830 | &device->wakeup); |
825 | if (ACPI_FAILURE(status)) { | 831 | if (ACPI_FAILURE(status)) { |
826 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); | 832 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); |
827 | goto end; | 833 | return; |
828 | } | 834 | } |
829 | 835 | ||
830 | device->wakeup.flags.valid = 1; | 836 | device->wakeup.flags.valid = 1; |
@@ -840,13 +846,10 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
840 | if (psw_error) | 846 | if (psw_error) |
841 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 847 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
842 | "error in _DSW or _PSW evaluation\n")); | 848 | "error in _DSW or _PSW evaluation\n")); |
843 | |||
844 | end: | ||
845 | if (ACPI_FAILURE(status)) | ||
846 | device->flags.wake_capable = 0; | ||
847 | return 0; | ||
848 | } | 849 | } |
849 | 850 | ||
851 | static void acpi_bus_add_power_resource(acpi_handle handle); | ||
852 | |||
850 | static int acpi_bus_get_power_flags(struct acpi_device *device) | 853 | static int acpi_bus_get_power_flags(struct acpi_device *device) |
851 | { | 854 | { |
852 | acpi_status status = 0; | 855 | acpi_status status = 0; |
@@ -875,8 +878,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
875 | acpi_evaluate_reference(device->handle, object_name, NULL, | 878 | acpi_evaluate_reference(device->handle, object_name, NULL, |
876 | &ps->resources); | 879 | &ps->resources); |
877 | if (ps->resources.count) { | 880 | if (ps->resources.count) { |
881 | int j; | ||
882 | |||
878 | device->power.flags.power_resources = 1; | 883 | device->power.flags.power_resources = 1; |
879 | ps->flags.valid = 1; | 884 | ps->flags.valid = 1; |
885 | for (j = 0; j < ps->resources.count; j++) | ||
886 | acpi_bus_add_power_resource(ps->resources.handles[j]); | ||
880 | } | 887 | } |
881 | 888 | ||
882 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 889 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
@@ -901,10 +908,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
901 | device->power.states[ACPI_STATE_D3].flags.valid = 1; | 908 | device->power.states[ACPI_STATE_D3].flags.valid = 1; |
902 | device->power.states[ACPI_STATE_D3].power = 0; | 909 | device->power.states[ACPI_STATE_D3].power = 0; |
903 | 910 | ||
904 | /* TBD: System wake support and resource requirements. */ | 911 | acpi_bus_init_power(device); |
905 | |||
906 | device->power.state = ACPI_STATE_UNKNOWN; | ||
907 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
908 | 912 | ||
909 | return 0; | 913 | return 0; |
910 | } | 914 | } |
@@ -947,11 +951,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) | |||
947 | if (ACPI_SUCCESS(status)) | 951 | if (ACPI_SUCCESS(status)) |
948 | device->flags.power_manageable = 1; | 952 | device->flags.power_manageable = 1; |
949 | 953 | ||
950 | /* Presence of _PRW indicates wake capable */ | ||
951 | status = acpi_get_handle(device->handle, "_PRW", &temp); | ||
952 | if (ACPI_SUCCESS(status)) | ||
953 | device->flags.wake_capable = 1; | ||
954 | |||
955 | /* TBD: Performance management */ | 954 | /* TBD: Performance management */ |
956 | 955 | ||
957 | return 0; | 956 | return 0; |
@@ -1278,11 +1277,7 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1278 | * Wakeup device management | 1277 | * Wakeup device management |
1279 | *----------------------- | 1278 | *----------------------- |
1280 | */ | 1279 | */ |
1281 | if (device->flags.wake_capable) { | 1280 | acpi_bus_get_wakeup_device_flags(device); |
1282 | result = acpi_bus_get_wakeup_device_flags(device); | ||
1283 | if (result) | ||
1284 | goto end; | ||
1285 | } | ||
1286 | 1281 | ||
1287 | /* | 1282 | /* |
1288 | * Performance Management | 1283 | * Performance Management |
@@ -1326,6 +1321,20 @@ end: | |||
1326 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ | 1321 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ |
1327 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) | 1322 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) |
1328 | 1323 | ||
1324 | static void acpi_bus_add_power_resource(acpi_handle handle) | ||
1325 | { | ||
1326 | struct acpi_bus_ops ops = { | ||
1327 | .acpi_op_add = 1, | ||
1328 | .acpi_op_start = 1, | ||
1329 | }; | ||
1330 | struct acpi_device *device = NULL; | ||
1331 | |||
1332 | acpi_bus_get_device(handle, &device); | ||
1333 | if (!device) | ||
1334 | acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, | ||
1335 | ACPI_STA_DEFAULT, &ops); | ||
1336 | } | ||
1337 | |||
1329 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | 1338 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, |
1330 | unsigned long long *sta) | 1339 | unsigned long long *sta) |
1331 | { | 1340 | { |
@@ -1371,7 +1380,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1371 | struct acpi_bus_ops *ops = context; | 1380 | struct acpi_bus_ops *ops = context; |
1372 | int type; | 1381 | int type; |
1373 | unsigned long long sta; | 1382 | unsigned long long sta; |
1374 | struct acpi_device_wakeup wakeup; | ||
1375 | struct acpi_device *device; | 1383 | struct acpi_device *device; |
1376 | acpi_status status; | 1384 | acpi_status status; |
1377 | int result; | 1385 | int result; |
@@ -1382,7 +1390,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1382 | 1390 | ||
1383 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | 1391 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
1384 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { | 1392 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { |
1385 | acpi_bus_extract_wakeup_device_power_package(handle, &wakeup); | 1393 | struct acpi_device_wakeup wakeup; |
1394 | acpi_handle temp; | ||
1395 | |||
1396 | status = acpi_get_handle(handle, "_PRW", &temp); | ||
1397 | if (ACPI_SUCCESS(status)) | ||
1398 | acpi_bus_extract_wakeup_device_power_package(handle, | ||
1399 | &wakeup); | ||
1386 | return AE_CTRL_DEPTH; | 1400 | return AE_CTRL_DEPTH; |
1387 | } | 1401 | } |
1388 | 1402 | ||
@@ -1467,7 +1481,7 @@ int acpi_bus_start(struct acpi_device *device) | |||
1467 | 1481 | ||
1468 | result = acpi_bus_scan(device->handle, &ops, NULL); | 1482 | result = acpi_bus_scan(device->handle, &ops, NULL); |
1469 | 1483 | ||
1470 | acpi_update_gpes(); | 1484 | acpi_update_all_gpes(); |
1471 | 1485 | ||
1472 | return result; | 1486 | return result; |
1473 | } | 1487 | } |
@@ -1573,6 +1587,8 @@ int __init acpi_scan_init(void) | |||
1573 | printk(KERN_ERR PREFIX "Could not register bus type\n"); | 1587 | printk(KERN_ERR PREFIX "Could not register bus type\n"); |
1574 | } | 1588 | } |
1575 | 1589 | ||
1590 | acpi_power_init(); | ||
1591 | |||
1576 | /* | 1592 | /* |
1577 | * Enumerate devices in the ACPI namespace. | 1593 | * Enumerate devices in the ACPI namespace. |
1578 | */ | 1594 | */ |
@@ -1584,7 +1600,7 @@ int __init acpi_scan_init(void) | |||
1584 | if (result) | 1600 | if (result) |
1585 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1601 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1586 | else | 1602 | else |
1587 | acpi_update_gpes(); | 1603 | acpi_update_all_gpes(); |
1588 | 1604 | ||
1589 | return result; | 1605 | return result; |
1590 | } | 1606 | } |