diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/ec.c | 43 | ||||
-rw-r--r-- | drivers/acpi/video.c | 15 |
2 files changed, 37 insertions, 21 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 3105e0410e9b..2e8317bf723e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -982,9 +982,9 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
982 | 982 | ||
983 | int __init acpi_ec_ecdt_probe(void) | 983 | int __init acpi_ec_ecdt_probe(void) |
984 | { | 984 | { |
985 | int ret; | ||
986 | acpi_status status; | 985 | acpi_status status; |
987 | struct acpi_table_ecdt *ecdt_ptr; | 986 | struct acpi_table_ecdt *ecdt_ptr; |
987 | acpi_handle dummy; | ||
988 | 988 | ||
989 | boot_ec = make_acpi_ec(); | 989 | boot_ec = make_acpi_ec(); |
990 | if (!boot_ec) | 990 | if (!boot_ec) |
@@ -1010,30 +1010,31 @@ int __init acpi_ec_ecdt_probe(void) | |||
1010 | boot_ec->gpe = ecdt_ptr->gpe; | 1010 | boot_ec->gpe = ecdt_ptr->gpe; |
1011 | boot_ec->handle = ACPI_ROOT_OBJECT; | 1011 | boot_ec->handle = ACPI_ROOT_OBJECT; |
1012 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 1012 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
1013 | } else { | 1013 | /* Add some basic check against completely broken table */ |
1014 | /* This workaround is needed only on some broken machines, | 1014 | if (boot_ec->data_addr != boot_ec->command_addr) |
1015 | * which require early EC, but fail to provide ECDT */ | 1015 | goto install; |
1016 | acpi_handle x; | 1016 | /* fall through */ |
1017 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | ||
1018 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1019 | boot_ec, NULL); | ||
1020 | /* Check that acpi_get_devices actually find something */ | ||
1021 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1022 | goto error; | ||
1023 | /* We really need to limit this workaround, the only ASUS, | ||
1024 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1025 | * Keep boot_ec struct as it will be needed soon. | ||
1026 | */ | ||
1027 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) | ||
1028 | return -ENODEV; | ||
1029 | } | 1017 | } |
1030 | 1018 | /* This workaround is needed only on some broken machines, | |
1031 | ret = ec_install_handlers(boot_ec); | 1019 | * which require early EC, but fail to provide ECDT */ |
1032 | if (!ret) { | 1020 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |
1021 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | ||
1022 | boot_ec, NULL); | ||
1023 | /* Check that acpi_get_devices actually find something */ | ||
1024 | if (ACPI_FAILURE(status) || !boot_ec->handle) | ||
1025 | goto error; | ||
1026 | /* We really need to limit this workaround, the only ASUS, | ||
1027 | * which needs it, has fake EC._INI method, so use it as flag. | ||
1028 | * Keep boot_ec struct as it will be needed soon. | ||
1029 | */ | ||
1030 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &dummy))) | ||
1031 | return -ENODEV; | ||
1032 | install: | ||
1033 | if (!ec_install_handlers(boot_ec)) { | ||
1033 | first_ec = boot_ec; | 1034 | first_ec = boot_ec; |
1034 | return 0; | 1035 | return 0; |
1035 | } | 1036 | } |
1036 | error: | 1037 | error: |
1037 | kfree(boot_ec); | 1038 | kfree(boot_ec); |
1038 | boot_ec = NULL; | 1039 | boot_ec = NULL; |
1039 | return -ENODEV; | 1040 | return -ENODEV; |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index baa441929720..38bf8b43fd19 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/backlight.h> | 36 | #include <linux/backlight.h> |
37 | #include <linux/thermal.h> | 37 | #include <linux/thermal.h> |
38 | #include <linux/video_output.h> | 38 | #include <linux/video_output.h> |
39 | #include <linux/sort.h> | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | 41 | ||
41 | #include <acpi/acpi_bus.h> | 42 | #include <acpi/acpi_bus.h> |
@@ -626,6 +627,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | |||
626 | } | 627 | } |
627 | 628 | ||
628 | /* | 629 | /* |
630 | * Simple comparison function used to sort backlight levels. | ||
631 | */ | ||
632 | |||
633 | static int | ||
634 | acpi_video_cmp_level(const void *a, const void *b) | ||
635 | { | ||
636 | return *(int *)a - *(int *)b; | ||
637 | } | ||
638 | |||
639 | /* | ||
629 | * Arg: | 640 | * Arg: |
630 | * device : video output device (LCD, CRT, ..) | 641 | * device : video output device (LCD, CRT, ..) |
631 | * | 642 | * |
@@ -676,6 +687,10 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
676 | count++; | 687 | count++; |
677 | } | 688 | } |
678 | 689 | ||
690 | /* don't sort the first two brightness levels */ | ||
691 | sort(&br->levels[2], count - 2, sizeof(br->levels[2]), | ||
692 | acpi_video_cmp_level, NULL); | ||
693 | |||
679 | if (count < 2) | 694 | if (count < 2) |
680 | goto out_free_levels; | 695 | goto out_free_levels; |
681 | 696 | ||