aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/ec.c43
-rw-r--r--drivers/acpi/video.c15
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
983int __init acpi_ec_ecdt_probe(void) 983int __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;
1032install:
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: 1037error:
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
633static int
634acpi_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