Add patches accepted for 2.6.30-rc4
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.30-rc4 / 0002-thinkpad-acpi-fix-LED-blinking-through-timer-trigge.patch
blob8f3474aa52b56b8fb0726c6a6c7886b03a58b888
1 From 75bd3bf2ade9d548be0d2bde60b5ee0fdce0b127 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Tue, 14 Apr 2009 02:44:11 +0000
4 Subject: thinkpad-acpi: fix LED blinking through timer trigger
6 The set_blink hook code in the LED subdriver would never manage to get
7 a LED to blink, and instead it would just turn it on. The consequence
8 of this is that the "timer" trigger would not cause the LED to blink
9 if given default parameters.
11 This problem exists since 2.6.26-rc1.
13 To fix it, switch the deferred LED work handling to use the
14 thinkpad-acpi-specific LED status (off/on/blink) directly.
16 This also makes the code easier to read, and to extend later.
18 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
19 Cc: stable@kernel.org
20 Signed-off-by: Len Brown <len.brown@intel.com>
21 ---
22 drivers/platform/x86/thinkpad_acpi.c | 41 +++++++++++++++------------------
23 1 files changed, 19 insertions(+), 22 deletions(-)
25 diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
26 index a186c5b..a1d2abc 100644
27 --- a/drivers/platform/x86/thinkpad_acpi.c
28 +++ b/drivers/platform/x86/thinkpad_acpi.c
29 @@ -303,11 +303,17 @@ static u32 dbg_level;
31 static struct workqueue_struct *tpacpi_wq;
33 +enum led_status_t {
34 + TPACPI_LED_OFF = 0,
35 + TPACPI_LED_ON,
36 + TPACPI_LED_BLINK,
37 +};
39 /* Special LED class that can defer work */
40 struct tpacpi_led_classdev {
41 struct led_classdev led_classdev;
42 struct work_struct work;
43 - enum led_brightness new_brightness;
44 + enum led_status_t new_state;
45 unsigned int led;
48 @@ -4213,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work)
49 container_of(work, struct tpacpi_led_classdev, work);
51 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
52 - light_set_status((data->new_brightness != LED_OFF));
53 + light_set_status((data->new_state != TPACPI_LED_OFF));
56 static void light_sysfs_set(struct led_classdev *led_cdev,
57 @@ -4223,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
58 container_of(led_cdev,
59 struct tpacpi_led_classdev,
60 led_classdev);
61 - data->new_brightness = brightness;
62 + data->new_state = (brightness != LED_OFF) ?
63 + TPACPI_LED_ON : TPACPI_LED_OFF;
64 queue_work(tpacpi_wq, &data->work);
67 @@ -4730,12 +4737,6 @@ enum { /* For TPACPI_LED_OLD */
68 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
71 -enum led_status_t {
72 - TPACPI_LED_OFF = 0,
73 - TPACPI_LED_ON,
74 - TPACPI_LED_BLINK,
75 -};
77 static enum led_access_mode led_supported;
79 TPACPI_HANDLE(led, ec, "SLED", /* 570 */
80 @@ -4847,23 +4848,13 @@ static int led_set_status(const unsigned int led,
81 return rc;
84 -static void led_sysfs_set_status(unsigned int led,
85 - enum led_brightness brightness)
87 - led_set_status(led,
88 - (brightness == LED_OFF) ?
89 - TPACPI_LED_OFF :
90 - (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
91 - TPACPI_LED_BLINK : TPACPI_LED_ON);
94 static void led_set_status_worker(struct work_struct *work)
96 struct tpacpi_led_classdev *data =
97 container_of(work, struct tpacpi_led_classdev, work);
99 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
100 - led_sysfs_set_status(data->led, data->new_brightness);
101 + led_set_status(data->led, data->new_state);
104 static void led_sysfs_set(struct led_classdev *led_cdev,
105 @@ -4872,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
106 struct tpacpi_led_classdev *data = container_of(led_cdev,
107 struct tpacpi_led_classdev, led_classdev);
109 - data->new_brightness = brightness;
110 + if (brightness == LED_OFF)
111 + data->new_state = TPACPI_LED_OFF;
112 + else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK)
113 + data->new_state = TPACPI_LED_ON;
114 + else
115 + data->new_state = TPACPI_LED_BLINK;
117 queue_work(tpacpi_wq, &data->work);
120 @@ -4890,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
121 } else if ((*delay_on != 500) || (*delay_off != 500))
122 return -EINVAL;
124 - data->new_brightness = TPACPI_LED_BLINK;
125 + data->new_state = TPACPI_LED_BLINK;
126 queue_work(tpacpi_wq, &data->work);
128 return 0;
130 1.6.2.3