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.c130
1 files changed, 86 insertions, 44 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2b6c21d86b98..64d4da0d6d52 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
705} 705}
706 706
707static acpi_status 707static acpi_status
708acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 708acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
709 union acpi_object *package) 709 struct acpi_device_wakeup *wakeup)
710{ 710{
711 int i = 0; 711 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
712 union acpi_object *package = NULL;
712 union acpi_object *element = NULL; 713 union acpi_object *element = NULL;
714 acpi_status status;
715 int i = 0;
713 716
714 if (!device || !package || (package->package.count < 2)) 717 if (!wakeup)
715 return AE_BAD_PARAMETER; 718 return AE_BAD_PARAMETER;
716 719
720 /* _PRW */
721 status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
722 if (ACPI_FAILURE(status)) {
723 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
724 return status;
725 }
726
727 package = (union acpi_object *)buffer.pointer;
728
729 if (!package || (package->package.count < 2)) {
730 status = AE_BAD_DATA;
731 goto out;
732 }
733
717 element = &(package->package.elements[0]); 734 element = &(package->package.elements[0]);
718 if (!element) 735 if (!element) {
719 return AE_BAD_PARAMETER; 736 status = AE_BAD_DATA;
737 goto out;
738 }
720 if (element->type == ACPI_TYPE_PACKAGE) { 739 if (element->type == ACPI_TYPE_PACKAGE) {
721 if ((element->package.count < 2) || 740 if ((element->package.count < 2) ||
722 (element->package.elements[0].type != 741 (element->package.elements[0].type !=
723 ACPI_TYPE_LOCAL_REFERENCE) 742 ACPI_TYPE_LOCAL_REFERENCE)
724 || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) 743 || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
725 return AE_BAD_DATA; 744 status = AE_BAD_DATA;
726 device->wakeup.gpe_device = 745 goto out;
746 }
747 wakeup->gpe_device =
727 element->package.elements[0].reference.handle; 748 element->package.elements[0].reference.handle;
728 device->wakeup.gpe_number = 749 wakeup->gpe_number =
729 (u32) element->package.elements[1].integer.value; 750 (u32) element->package.elements[1].integer.value;
730 } else if (element->type == ACPI_TYPE_INTEGER) { 751 } else if (element->type == ACPI_TYPE_INTEGER) {
731 device->wakeup.gpe_number = element->integer.value; 752 wakeup->gpe_device = NULL;
732 } else 753 wakeup->gpe_number = element->integer.value;
733 return AE_BAD_DATA; 754 } else {
755 status = AE_BAD_DATA;
756 goto out;
757 }
734 758
735 element = &(package->package.elements[1]); 759 element = &(package->package.elements[1]);
736 if (element->type != ACPI_TYPE_INTEGER) { 760 if (element->type != ACPI_TYPE_INTEGER) {
737 return AE_BAD_DATA; 761 status = AE_BAD_DATA;
762 goto out;
738 } 763 }
739 device->wakeup.sleep_state = element->integer.value; 764 wakeup->sleep_state = element->integer.value;
740 765
741 if ((package->package.count - 2) > ACPI_MAX_HANDLES) { 766 if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
742 return AE_NO_MEMORY; 767 status = AE_NO_MEMORY;
768 goto out;
743 } 769 }
744 device->wakeup.resources.count = package->package.count - 2; 770 wakeup->resources.count = package->package.count - 2;
745 for (i = 0; i < device->wakeup.resources.count; i++) { 771 for (i = 0; i < wakeup->resources.count; i++) {
746 element = &(package->package.elements[i + 2]); 772 element = &(package->package.elements[i + 2]);
747 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 773 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
748 return AE_BAD_DATA; 774 status = AE_BAD_DATA;
775 goto out;
776 }
749 777
750 device->wakeup.resources.handles[i] = element->reference.handle; 778 wakeup->resources.handles[i] = element->reference.handle;
751 } 779 }
752 780
753 acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); 781 acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
754 782
755 return AE_OK; 783 out:
784 kfree(buffer.pointer);
785
786 return status;
756} 787}
757 788
758static void acpi_bus_set_run_wake_flags(struct acpi_device *device) 789static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
@@ -772,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
772 /* Power button, Lid switch always enable wakeup */ 803 /* Power button, Lid switch always enable wakeup */
773 if (!acpi_match_device_ids(device, button_device_ids)) { 804 if (!acpi_match_device_ids(device, button_device_ids)) {
774 device->wakeup.flags.run_wake = 1; 805 device->wakeup.flags.run_wake = 1;
775 device->wakeup.flags.always_enabled = 1; 806 device_set_wakeup_capable(&device->dev, true);
776 return; 807 return;
777 } 808 }
778 809
@@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
787static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) 818static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
788{ 819{
789 acpi_status status = 0; 820 acpi_status status = 0;
790 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
791 union acpi_object *package = NULL;
792 int psw_error; 821 int psw_error;
793 822
794 /* _PRW */ 823 status = acpi_bus_extract_wakeup_device_power_package(device->handle,
795 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); 824 &device->wakeup);
796 if (ACPI_FAILURE(status)) {
797 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
798 goto end;
799 }
800
801 package = (union acpi_object *)buffer.pointer;
802 status = acpi_bus_extract_wakeup_device_power_package(device, package);
803 if (ACPI_FAILURE(status)) { 825 if (ACPI_FAILURE(status)) {
804 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); 826 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
805 goto end; 827 goto end;
806 } 828 }
807 829
808 kfree(buffer.pointer);
809
810 device->wakeup.flags.valid = 1; 830 device->wakeup.flags.valid = 1;
811 device->wakeup.prepare_count = 0; 831 device->wakeup.prepare_count = 0;
812 acpi_bus_set_run_wake_flags(device); 832 acpi_bus_set_run_wake_flags(device);
@@ -827,6 +847,8 @@ end:
827 return 0; 847 return 0;
828} 848}
829 849
850static void acpi_bus_add_power_resource(acpi_handle handle);
851
830static int acpi_bus_get_power_flags(struct acpi_device *device) 852static int acpi_bus_get_power_flags(struct acpi_device *device)
831{ 853{
832 acpi_status status = 0; 854 acpi_status status = 0;
@@ -855,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
855 acpi_evaluate_reference(device->handle, object_name, NULL, 877 acpi_evaluate_reference(device->handle, object_name, NULL,
856 &ps->resources); 878 &ps->resources);
857 if (ps->resources.count) { 879 if (ps->resources.count) {
880 int j;
881
858 device->power.flags.power_resources = 1; 882 device->power.flags.power_resources = 1;
859 ps->flags.valid = 1; 883 ps->flags.valid = 1;
884 for (j = 0; j < ps->resources.count; j++)
885 acpi_bus_add_power_resource(ps->resources.handles[j]);
860 } 886 }
861 887
862 /* Evaluate "_PSx" to see if we can do explicit sets */ 888 /* Evaluate "_PSx" to see if we can do explicit sets */
@@ -881,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
881 device->power.states[ACPI_STATE_D3].flags.valid = 1; 907 device->power.states[ACPI_STATE_D3].flags.valid = 1;
882 device->power.states[ACPI_STATE_D3].power = 0; 908 device->power.states[ACPI_STATE_D3].power = 0;
883 909
884 /* TBD: System wake support and resource requirements. */ 910 acpi_bus_init_power(device);
885
886 device->power.state = ACPI_STATE_UNKNOWN;
887 acpi_bus_get_power(device->handle, &(device->power.state));
888 911
889 return 0; 912 return 0;
890} 913}
@@ -1306,6 +1329,20 @@ end:
1306#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ 1329#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
1307 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) 1330 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
1308 1331
1332static void acpi_bus_add_power_resource(acpi_handle handle)
1333{
1334 struct acpi_bus_ops ops = {
1335 .acpi_op_add = 1,
1336 .acpi_op_start = 1,
1337 };
1338 struct acpi_device *device = NULL;
1339
1340 acpi_bus_get_device(handle, &device);
1341 if (!device)
1342 acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
1343 ACPI_STA_DEFAULT, &ops);
1344}
1345
1309static int acpi_bus_type_and_status(acpi_handle handle, int *type, 1346static int acpi_bus_type_and_status(acpi_handle handle, int *type,
1310 unsigned long long *sta) 1347 unsigned long long *sta)
1311{ 1348{
@@ -1351,6 +1388,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
1351 struct acpi_bus_ops *ops = context; 1388 struct acpi_bus_ops *ops = context;
1352 int type; 1389 int type;
1353 unsigned long long sta; 1390 unsigned long long sta;
1391 struct acpi_device_wakeup wakeup;
1354 struct acpi_device *device; 1392 struct acpi_device *device;
1355 acpi_status status; 1393 acpi_status status;
1356 int result; 1394 int result;
@@ -1360,8 +1398,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
1360 return AE_OK; 1398 return AE_OK;
1361 1399
1362 if (!(sta & ACPI_STA_DEVICE_PRESENT) && 1400 if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
1363 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) 1401 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
1402 acpi_bus_extract_wakeup_device_power_package(handle, &wakeup);
1364 return AE_CTRL_DEPTH; 1403 return AE_CTRL_DEPTH;
1404 }
1365 1405
1366 /* 1406 /*
1367 * We may already have an acpi_device from a previous enumeration. If 1407 * We may already have an acpi_device from a previous enumeration. If
@@ -1444,7 +1484,7 @@ int acpi_bus_start(struct acpi_device *device)
1444 1484
1445 result = acpi_bus_scan(device->handle, &ops, NULL); 1485 result = acpi_bus_scan(device->handle, &ops, NULL);
1446 1486
1447 acpi_update_gpes(); 1487 acpi_update_all_gpes();
1448 1488
1449 return result; 1489 return result;
1450} 1490}
@@ -1550,6 +1590,8 @@ int __init acpi_scan_init(void)
1550 printk(KERN_ERR PREFIX "Could not register bus type\n"); 1590 printk(KERN_ERR PREFIX "Could not register bus type\n");
1551 } 1591 }
1552 1592
1593 acpi_power_init();
1594
1553 /* 1595 /*
1554 * Enumerate devices in the ACPI namespace. 1596 * Enumerate devices in the ACPI namespace.
1555 */ 1597 */
@@ -1561,7 +1603,7 @@ int __init acpi_scan_init(void)
1561 if (result) 1603 if (result)
1562 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1604 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
1563 else 1605 else
1564 acpi_update_gpes(); 1606 acpi_update_all_gpes();
1565 1607
1566 return result; 1608 return result;
1567} 1609}