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.c86
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,
875static int 922static int
876acpi_video_bus_match(struct acpi_device *device) 923acpi_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