diff options
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 86 |
1 files changed, 65 insertions, 21 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3fac011f9cf9..6d85289f1c12 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -39,20 +39,26 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
39 | int size) | 39 | int size) |
40 | { | 40 | { |
41 | int len; | 41 | int len; |
42 | int count; | ||
42 | 43 | ||
43 | if (!acpi_dev->flags.hardware_id) | 44 | if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids) |
44 | return -ENODEV; | 45 | return -ENODEV; |
45 | 46 | ||
46 | len = snprintf(modalias, size, "acpi:%s:", | 47 | len = snprintf(modalias, size, "acpi:"); |
47 | acpi_dev->pnp.hardware_id); | ||
48 | if (len < 0 || len >= size) | ||
49 | return -EINVAL; | ||
50 | size -= len; | 48 | size -= len; |
51 | 49 | ||
50 | if (acpi_dev->flags.hardware_id) { | ||
51 | count = snprintf(&modalias[len], size, "%s:", | ||
52 | acpi_dev->pnp.hardware_id); | ||
53 | if (count < 0 || count >= size) | ||
54 | return -EINVAL; | ||
55 | len += count; | ||
56 | size -= count; | ||
57 | } | ||
58 | |||
52 | if (acpi_dev->flags.compatible_ids) { | 59 | if (acpi_dev->flags.compatible_ids) { |
53 | struct acpi_compatible_id_list *cid_list; | 60 | struct acpi_compatible_id_list *cid_list; |
54 | int i; | 61 | int i; |
55 | int count; | ||
56 | 62 | ||
57 | cid_list = acpi_dev->pnp.cid_list; | 63 | cid_list = acpi_dev->pnp.cid_list; |
58 | for (i = 0; i < cid_list->count; i++) { | 64 | for (i = 0; i < cid_list->count; i++) { |
@@ -609,7 +615,8 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | |||
609 | status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); | 615 | status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); |
610 | if (ACPI_SUCCESS(status)) { | 616 | if (ACPI_SUCCESS(status)) { |
611 | obj = buffer.pointer; | 617 | obj = buffer.pointer; |
612 | status = acpi_get_handle(NULL, obj->string.pointer, ejd); | 618 | status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, |
619 | ejd); | ||
613 | kfree(buffer.pointer); | 620 | kfree(buffer.pointer); |
614 | } | 621 | } |
615 | return status; | 622 | return status; |
@@ -670,9 +677,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | |||
670 | device->wakeup.resources.count = package->package.count - 2; | 677 | device->wakeup.resources.count = package->package.count - 2; |
671 | for (i = 0; i < device->wakeup.resources.count; i++) { | 678 | for (i = 0; i < device->wakeup.resources.count; i++) { |
672 | element = &(package->package.elements[i + 2]); | 679 | element = &(package->package.elements[i + 2]); |
673 | if (element->type != ACPI_TYPE_ANY) { | 680 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) |
674 | return AE_BAD_DATA; | 681 | return AE_BAD_DATA; |
675 | } | ||
676 | 682 | ||
677 | device->wakeup.resources.handles[i] = element->reference.handle; | 683 | device->wakeup.resources.handles[i] = element->reference.handle; |
678 | } | 684 | } |
@@ -685,6 +691,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
685 | acpi_status status = 0; | 691 | acpi_status status = 0; |
686 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 692 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
687 | union acpi_object *package = NULL; | 693 | union acpi_object *package = NULL; |
694 | union acpi_object in_arg[3]; | ||
695 | struct acpi_object_list arg_list = { 3, in_arg }; | ||
696 | acpi_status psw_status = AE_OK; | ||
688 | 697 | ||
689 | struct acpi_device_id button_device_ids[] = { | 698 | struct acpi_device_id button_device_ids[] = { |
690 | {"PNP0C0D", 0}, | 699 | {"PNP0C0D", 0}, |
@@ -693,7 +702,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
693 | {"", 0}, | 702 | {"", 0}, |
694 | }; | 703 | }; |
695 | 704 | ||
696 | |||
697 | /* _PRW */ | 705 | /* _PRW */ |
698 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 706 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); |
699 | if (ACPI_FAILURE(status)) { | 707 | if (ACPI_FAILURE(status)) { |
@@ -711,6 +719,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
711 | kfree(buffer.pointer); | 719 | kfree(buffer.pointer); |
712 | 720 | ||
713 | device->wakeup.flags.valid = 1; | 721 | device->wakeup.flags.valid = 1; |
722 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | ||
723 | * system for the ACPI device with the _PRW object. | ||
724 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | ||
725 | * So it is necessary to call _DSW object first. Only when it is not | ||
726 | * present will the _PSW object used. | ||
727 | */ | ||
728 | /* | ||
729 | * Three agruments are needed for the _DSW object. | ||
730 | * Argument 0: enable/disable the wake capabilities | ||
731 | * When _DSW object is called to disable the wake capabilities, maybe | ||
732 | * the first argument is filled. The value of the other two agruments | ||
733 | * is meaningless. | ||
734 | */ | ||
735 | in_arg[0].type = ACPI_TYPE_INTEGER; | ||
736 | in_arg[0].integer.value = 0; | ||
737 | in_arg[1].type = ACPI_TYPE_INTEGER; | ||
738 | in_arg[1].integer.value = 0; | ||
739 | in_arg[2].type = ACPI_TYPE_INTEGER; | ||
740 | in_arg[2].integer.value = 0; | ||
741 | psw_status = acpi_evaluate_object(device->handle, "_DSW", | ||
742 | &arg_list, NULL); | ||
743 | if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) | ||
744 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n")); | ||
745 | /* | ||
746 | * When the _DSW object is not present, OSPM will call _PSW object. | ||
747 | */ | ||
748 | if (psw_status == AE_NOT_FOUND) { | ||
749 | /* | ||
750 | * Only one agruments is required for the _PSW object. | ||
751 | * agrument 0: enable/disable the wake capabilities | ||
752 | */ | ||
753 | arg_list.count = 1; | ||
754 | in_arg[0].integer.value = 0; | ||
755 | psw_status = acpi_evaluate_object(device->handle, "_PSW", | ||
756 | &arg_list, NULL); | ||
757 | if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND)) | ||
758 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in " | ||
759 | "evaluate _PSW\n")); | ||
760 | } | ||
714 | /* Power button, Lid switch always enable wakeup */ | 761 | /* Power button, Lid switch always enable wakeup */ |
715 | if (!acpi_match_device_ids(device, button_device_ids)) | 762 | if (!acpi_match_device_ids(device, button_device_ids)) |
716 | device->wakeup.flags.run_wake = 1; | 763 | device->wakeup.flags.run_wake = 1; |
@@ -875,10 +922,7 @@ static void acpi_device_get_busid(struct acpi_device *device, | |||
875 | static int | 922 | static int |
876 | acpi_video_bus_match(struct acpi_device *device) | 923 | acpi_video_bus_match(struct acpi_device *device) |
877 | { | 924 | { |
878 | acpi_handle h_dummy1; | 925 | acpi_handle h_dummy; |
879 | acpi_handle h_dummy2; | ||
880 | acpi_handle h_dummy3; | ||
881 | |||
882 | 926 | ||
883 | if (!device) | 927 | if (!device) |
884 | return -EINVAL; | 928 | return -EINVAL; |
@@ -888,18 +932,18 @@ acpi_video_bus_match(struct acpi_device *device) | |||
888 | */ | 932 | */ |
889 | 933 | ||
890 | /* Does this device able to support video switching ? */ | 934 | /* Does this device able to support video switching ? */ |
891 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && | 935 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && |
892 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) | 936 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) |
893 | return 0; | 937 | return 0; |
894 | 938 | ||
895 | /* Does this device able to retrieve a video ROM ? */ | 939 | /* Does this device able to retrieve a video ROM ? */ |
896 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) | 940 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) |
897 | return 0; | 941 | return 0; |
898 | 942 | ||
899 | /* Does this device able to configure which video head to be POSTed ? */ | 943 | /* Does this device able to configure which video head to be POSTed ? */ |
900 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && | 944 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && |
901 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && | 945 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && |
902 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) | 946 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) |
903 | return 0; | 947 | return 0; |
904 | 948 | ||
905 | return -ENODEV; | 949 | return -ENODEV; |
@@ -966,7 +1010,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
966 | case ACPI_BUS_TYPE_DEVICE: | 1010 | case ACPI_BUS_TYPE_DEVICE: |
967 | status = acpi_get_object_info(handle, &buffer); | 1011 | status = acpi_get_object_info(handle, &buffer); |
968 | if (ACPI_FAILURE(status)) { | 1012 | if (ACPI_FAILURE(status)) { |
969 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __FUNCTION__); | 1013 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); |
970 | return; | 1014 | return; |
971 | } | 1015 | } |
972 | 1016 | ||