Commit 935e5f29 authored by Zhang Rui's avatar Zhang Rui Committed by Len Brown

ACPI: video: Fix reversed brightness behavior on ThinkPad SL series

Section B.6.2 of ACPI 3.0b specification that defines _BCL method
doesn't require the brightness levels returned to be sorted.
At least ThinkPad SL300 (and probably all IdeaPads) returns the
array reversed (i.e. bightest levels have lowest indexes), which
causes the brightness management behave in completely reversed
manner on these machines (brightness increases when the laptop is
idle, while the display dims when used).

Sorting the array by brightness level values after reading the list
fixes the issue.

http://bugzilla.kernel.org/show_bug.cgi?id=12037Signed-off-by: default avatarZhang Rui <rui.zhang@intel.com>
Tested-by: default avatarLubomir Rintel <lkundrak@v3.sk>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 6c34bc29
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/video_output.h> #include <linux/video_output.h>
#include <linux/sort.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
...@@ -625,6 +626,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) ...@@ -625,6 +626,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
return status; return status;
} }
/*
* Simple comparison function used to sort backlight levels.
*/
static int
acpi_video_cmp_level(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
/* /*
* Arg: * Arg:
* device : video output device (LCD, CRT, ..) * device : video output device (LCD, CRT, ..)
...@@ -676,6 +687,10 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -676,6 +687,10 @@ acpi_video_init_brightness(struct acpi_video_device *device)
count++; count++;
} }
/* don't sort the first two brightness levels */
sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
acpi_video_cmp_level, NULL);
if (count < 2) if (count < 2)
goto out_free_levels; goto out_free_levels;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment