Add patches accepted for 2.6.26-rc1
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.24-rc4 / 0007-ACPI-thinkpad-acpi-fix-brightness_set-error-paths.patch
blob3ba083e8e61daae845b749cb387075a4c308a9d7
1 From 4273af8d08c823d5898a2b1c2d0f25b4a8b9eaee Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Tue, 30 Oct 2007 17:46:25 -0200
4 Subject: [PATCH 22/23] ACPI: thinkpad-acpi: fix brightness_set error paths
6 The code calling brightness_set() can't handle EINTR/ERESTARTSYS well, nor
7 is it checking brightness_set() return status properly.
9 Fix it.
11 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
12 Signed-off-by: Len Brown <len.brown@intel.com>
13 ---
14 drivers/misc/thinkpad_acpi.c | 34 +++++++++++++++++++++-------------
15 1 files changed, 21 insertions(+), 13 deletions(-)
17 diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
18 index 306daa5..8c94307 100644
19 --- a/drivers/misc/thinkpad_acpi.c
20 +++ b/drivers/misc/thinkpad_acpi.c
21 @@ -3278,6 +3278,8 @@ static void brightness_exit(void)
23 static int brightness_update_status(struct backlight_device *bd)
25 + /* it is the backlight class's job (caller) to handle
26 + * EINTR and other errors properly */
27 return brightness_set(
28 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
29 bd->props.power == FB_BLANK_UNBLANK) ?
30 @@ -3318,6 +3320,7 @@ static int brightness_get(struct backlight_device *bd)
31 return level;
34 +/* May return EINTR which can always be mapped to ERESTARTSYS */
35 static int brightness_set(int value)
37 int cmos_cmd, inc, i, res;
38 @@ -3381,29 +3384,34 @@ static int brightness_read(char *p)
39 static int brightness_write(char *buf)
41 int level;
42 - int new_level;
43 + int rc;
44 char *cmd;
45 int max_level = (tp_features.bright_16levels) ? 15 : 7;
47 - while ((cmd = next_cmd(&buf))) {
48 - if ((level = brightness_get(NULL)) < 0)
49 - return level;
50 + level = brightness_get(NULL);
51 + if (level < 0)
52 + return level;
54 + while ((cmd = next_cmd(&buf))) {
55 if (strlencmp(cmd, "up") == 0) {
56 - new_level = level == (max_level)?
57 - max_level : level + 1;
58 + if (level < max_level)
59 + level++;
60 } else if (strlencmp(cmd, "down") == 0) {
61 - new_level = level == 0? 0 : level - 1;
62 - } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
63 - new_level >= 0 && new_level <= max_level) {
64 - /* new_level set */
65 + if (level > 0)
66 + level--;
67 + } else if (sscanf(cmd, "level %d", &level) == 1 &&
68 + level >= 0 && level <= max_level) {
69 + /* new level set */
70 } else
71 return -EINVAL;
73 - brightness_set(new_level);
76 - return 0;
77 + /*
78 + * Now we know what the final level should be, so we try to set it.
79 + * Doing it this way makes the syscall restartable in case of EINTR
80 + */
81 + rc = brightness_set(level);
82 + return (rc == -EINTR)? ERESTARTSYS : rc;
85 static struct ibm_struct brightness_driver_data = {
86 --
87 1.5.3.4