diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a186c5bbdcd9..a1d2abce3090 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -303,11 +303,17 @@ static u32 dbg_level; | |||
303 | 303 | ||
304 | static struct workqueue_struct *tpacpi_wq; | 304 | static struct workqueue_struct *tpacpi_wq; |
305 | 305 | ||
306 | enum led_status_t { | ||
307 | TPACPI_LED_OFF = 0, | ||
308 | TPACPI_LED_ON, | ||
309 | TPACPI_LED_BLINK, | ||
310 | }; | ||
311 | |||
306 | /* Special LED class that can defer work */ | 312 | /* Special LED class that can defer work */ |
307 | struct tpacpi_led_classdev { | 313 | struct tpacpi_led_classdev { |
308 | struct led_classdev led_classdev; | 314 | struct led_classdev led_classdev; |
309 | struct work_struct work; | 315 | struct work_struct work; |
310 | enum led_brightness new_brightness; | 316 | enum led_status_t new_state; |
311 | unsigned int led; | 317 | unsigned int led; |
312 | }; | 318 | }; |
313 | 319 | ||
@@ -4213,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work) | |||
4213 | container_of(work, struct tpacpi_led_classdev, work); | 4219 | container_of(work, struct tpacpi_led_classdev, work); |
4214 | 4220 | ||
4215 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) | 4221 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) |
4216 | light_set_status((data->new_brightness != LED_OFF)); | 4222 | light_set_status((data->new_state != TPACPI_LED_OFF)); |
4217 | } | 4223 | } |
4218 | 4224 | ||
4219 | static void light_sysfs_set(struct led_classdev *led_cdev, | 4225 | static void light_sysfs_set(struct led_classdev *led_cdev, |
@@ -4223,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev, | |||
4223 | container_of(led_cdev, | 4229 | container_of(led_cdev, |
4224 | struct tpacpi_led_classdev, | 4230 | struct tpacpi_led_classdev, |
4225 | led_classdev); | 4231 | led_classdev); |
4226 | data->new_brightness = brightness; | 4232 | data->new_state = (brightness != LED_OFF) ? |
4233 | TPACPI_LED_ON : TPACPI_LED_OFF; | ||
4227 | queue_work(tpacpi_wq, &data->work); | 4234 | queue_work(tpacpi_wq, &data->work); |
4228 | } | 4235 | } |
4229 | 4236 | ||
@@ -4730,12 +4737,6 @@ enum { /* For TPACPI_LED_OLD */ | |||
4730 | TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ | 4737 | TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ |
4731 | }; | 4738 | }; |
4732 | 4739 | ||
4733 | enum led_status_t { | ||
4734 | TPACPI_LED_OFF = 0, | ||
4735 | TPACPI_LED_ON, | ||
4736 | TPACPI_LED_BLINK, | ||
4737 | }; | ||
4738 | |||
4739 | static enum led_access_mode led_supported; | 4740 | static enum led_access_mode led_supported; |
4740 | 4741 | ||
4741 | TPACPI_HANDLE(led, ec, "SLED", /* 570 */ | 4742 | TPACPI_HANDLE(led, ec, "SLED", /* 570 */ |
@@ -4847,23 +4848,13 @@ static int led_set_status(const unsigned int led, | |||
4847 | return rc; | 4848 | return rc; |
4848 | } | 4849 | } |
4849 | 4850 | ||
4850 | static void led_sysfs_set_status(unsigned int led, | ||
4851 | enum led_brightness brightness) | ||
4852 | { | ||
4853 | led_set_status(led, | ||
4854 | (brightness == LED_OFF) ? | ||
4855 | TPACPI_LED_OFF : | ||
4856 | (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? | ||
4857 | TPACPI_LED_BLINK : TPACPI_LED_ON); | ||
4858 | } | ||
4859 | |||
4860 | static void led_set_status_worker(struct work_struct *work) | 4851 | static void led_set_status_worker(struct work_struct *work) |
4861 | { | 4852 | { |
4862 | struct tpacpi_led_classdev *data = | 4853 | struct tpacpi_led_classdev *data = |
4863 | container_of(work, struct tpacpi_led_classdev, work); | 4854 | container_of(work, struct tpacpi_led_classdev, work); |
4864 | 4855 | ||
4865 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) | 4856 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) |
4866 | led_sysfs_set_status(data->led, data->new_brightness); | 4857 | led_set_status(data->led, data->new_state); |
4867 | } | 4858 | } |
4868 | 4859 | ||
4869 | static void led_sysfs_set(struct led_classdev *led_cdev, | 4860 | static void led_sysfs_set(struct led_classdev *led_cdev, |
@@ -4872,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev, | |||
4872 | struct tpacpi_led_classdev *data = container_of(led_cdev, | 4863 | struct tpacpi_led_classdev *data = container_of(led_cdev, |
4873 | struct tpacpi_led_classdev, led_classdev); | 4864 | struct tpacpi_led_classdev, led_classdev); |
4874 | 4865 | ||
4875 | data->new_brightness = brightness; | 4866 | if (brightness == LED_OFF) |
4867 | data->new_state = TPACPI_LED_OFF; | ||
4868 | else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK) | ||
4869 | data->new_state = TPACPI_LED_ON; | ||
4870 | else | ||
4871 | data->new_state = TPACPI_LED_BLINK; | ||
4872 | |||
4876 | queue_work(tpacpi_wq, &data->work); | 4873 | queue_work(tpacpi_wq, &data->work); |
4877 | } | 4874 | } |
4878 | 4875 | ||
@@ -4890,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev, | |||
4890 | } else if ((*delay_on != 500) || (*delay_off != 500)) | 4887 | } else if ((*delay_on != 500) || (*delay_off != 500)) |
4891 | return -EINVAL; | 4888 | return -EINVAL; |
4892 | 4889 | ||
4893 | data->new_brightness = TPACPI_LED_BLINK; | 4890 | data->new_state = TPACPI_LED_BLINK; |
4894 | queue_work(tpacpi_wq, &data->work); | 4891 | queue_work(tpacpi_wq, &data->work); |
4895 | 4892 | ||
4896 | return 0; | 4893 | return 0; |