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 | ||