aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c70
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
818static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) 818static 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
844end:
845 if (ACPI_FAILURE(status))
846 device->flags.wake_capable = 0;
847 return 0;
848} 849}
849 850
851static void acpi_bus_add_power_resource(acpi_handle handle);
852
850static int acpi_bus_get_power_flags(struct acpi_device *device) 853static 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
1324static 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
1329static int acpi_bus_type_and_status(acpi_handle handle, int *type, 1338static 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}