diff options
Diffstat (limited to 'drivers/acpi/scan.c')
| -rw-r--r-- | drivers/acpi/scan.c | 65 |
1 files changed, 50 insertions, 15 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ff9f6226085d..fb7fc24fe727 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -741,19 +741,40 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | |||
| 741 | return AE_OK; | 741 | return AE_OK; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 744 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) |
| 745 | { | 745 | { |
| 746 | acpi_status status = 0; | ||
| 747 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 748 | union acpi_object *package = NULL; | ||
| 749 | int psw_error; | ||
| 750 | |||
| 751 | struct acpi_device_id button_device_ids[] = { | 746 | struct acpi_device_id button_device_ids[] = { |
| 752 | {"PNP0C0D", 0}, | 747 | {"PNP0C0D", 0}, |
| 753 | {"PNP0C0C", 0}, | 748 | {"PNP0C0C", 0}, |
| 754 | {"PNP0C0E", 0}, | 749 | {"PNP0C0E", 0}, |
| 755 | {"", 0}, | 750 | {"", 0}, |
| 756 | }; | 751 | }; |
| 752 | acpi_status status; | ||
| 753 | acpi_event_status event_status; | ||
| 754 | |||
| 755 | device->wakeup.run_wake_count = 0; | ||
| 756 | device->wakeup.flags.notifier_present = 0; | ||
| 757 | |||
| 758 | /* Power button, Lid switch always enable wakeup */ | ||
| 759 | if (!acpi_match_device_ids(device, button_device_ids)) { | ||
| 760 | device->wakeup.flags.run_wake = 1; | ||
| 761 | device->wakeup.flags.always_enabled = 1; | ||
| 762 | return; | ||
| 763 | } | ||
| 764 | |||
| 765 | status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, | ||
| 766 | ACPI_NOT_ISR, &event_status); | ||
| 767 | if (status == AE_OK) | ||
| 768 | device->wakeup.flags.run_wake = | ||
| 769 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); | ||
| 770 | } | ||
| 771 | |||
| 772 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | ||
| 773 | { | ||
| 774 | acpi_status status = 0; | ||
| 775 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 776 | union acpi_object *package = NULL; | ||
| 777 | int psw_error; | ||
| 757 | 778 | ||
| 758 | /* _PRW */ | 779 | /* _PRW */ |
| 759 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 780 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); |
| @@ -773,6 +794,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
| 773 | 794 | ||
| 774 | device->wakeup.flags.valid = 1; | 795 | device->wakeup.flags.valid = 1; |
| 775 | device->wakeup.prepare_count = 0; | 796 | device->wakeup.prepare_count = 0; |
| 797 | acpi_bus_set_run_wake_flags(device); | ||
| 776 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 798 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping |
| 777 | * system for the ACPI device with the _PRW object. | 799 | * system for the ACPI device with the _PRW object. |
| 778 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 800 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
| @@ -784,10 +806,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
| 784 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 806 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 785 | "error in _DSW or _PSW evaluation\n")); | 807 | "error in _DSW or _PSW evaluation\n")); |
| 786 | 808 | ||
| 787 | /* Power button, Lid switch always enable wakeup */ | ||
| 788 | if (!acpi_match_device_ids(device, button_device_ids)) | ||
| 789 | device->wakeup.flags.run_wake = 1; | ||
| 790 | |||
| 791 | end: | 809 | end: |
| 792 | if (ACPI_FAILURE(status)) | 810 | if (ACPI_FAILURE(status)) |
| 793 | device->flags.wake_capable = 0; | 811 | device->flags.wake_capable = 0; |
| @@ -1336,9 +1354,25 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, | |||
| 1336 | 1354 | ||
| 1337 | if (child) | 1355 | if (child) |
| 1338 | *child = device; | 1356 | *child = device; |
| 1339 | return 0; | 1357 | |
| 1358 | if (device) | ||
| 1359 | return 0; | ||
| 1360 | else | ||
| 1361 | return -ENODEV; | ||
| 1340 | } | 1362 | } |
| 1341 | 1363 | ||
| 1364 | /* | ||
| 1365 | * acpi_bus_add and acpi_bus_start | ||
| 1366 | * | ||
| 1367 | * scan a given ACPI tree and (probably recently hot-plugged) | ||
| 1368 | * create and add or starts found devices. | ||
| 1369 | * | ||
| 1370 | * If no devices were found -ENODEV is returned which does not | ||
| 1371 | * mean that this is a real error, there just have been no suitable | ||
| 1372 | * ACPI objects in the table trunk from which the kernel could create | ||
| 1373 | * a device and add/start an appropriate driver. | ||
| 1374 | */ | ||
| 1375 | |||
| 1342 | int | 1376 | int |
| 1343 | acpi_bus_add(struct acpi_device **child, | 1377 | acpi_bus_add(struct acpi_device **child, |
| 1344 | struct acpi_device *parent, acpi_handle handle, int type) | 1378 | struct acpi_device *parent, acpi_handle handle, int type) |
| @@ -1348,8 +1382,7 @@ acpi_bus_add(struct acpi_device **child, | |||
| 1348 | memset(&ops, 0, sizeof(ops)); | 1382 | memset(&ops, 0, sizeof(ops)); |
| 1349 | ops.acpi_op_add = 1; | 1383 | ops.acpi_op_add = 1; |
| 1350 | 1384 | ||
| 1351 | acpi_bus_scan(handle, &ops, child); | 1385 | return acpi_bus_scan(handle, &ops, child); |
| 1352 | return 0; | ||
| 1353 | } | 1386 | } |
| 1354 | EXPORT_SYMBOL(acpi_bus_add); | 1387 | EXPORT_SYMBOL(acpi_bus_add); |
| 1355 | 1388 | ||
| @@ -1357,11 +1390,13 @@ int acpi_bus_start(struct acpi_device *device) | |||
| 1357 | { | 1390 | { |
| 1358 | struct acpi_bus_ops ops; | 1391 | struct acpi_bus_ops ops; |
| 1359 | 1392 | ||
| 1393 | if (!device) | ||
| 1394 | return -EINVAL; | ||
| 1395 | |||
| 1360 | memset(&ops, 0, sizeof(ops)); | 1396 | memset(&ops, 0, sizeof(ops)); |
| 1361 | ops.acpi_op_start = 1; | 1397 | ops.acpi_op_start = 1; |
| 1362 | 1398 | ||
| 1363 | acpi_bus_scan(device->handle, &ops, NULL); | 1399 | return acpi_bus_scan(device->handle, &ops, NULL); |
| 1364 | return 0; | ||
| 1365 | } | 1400 | } |
| 1366 | EXPORT_SYMBOL(acpi_bus_start); | 1401 | EXPORT_SYMBOL(acpi_bus_start); |
| 1367 | 1402 | ||
