diff options
| author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2016-05-23 18:39:51 -0400 |
|---|---|---|
| committer | Darren Hart <dvhart@linux.intel.com> | 2016-05-27 14:47:55 -0400 |
| commit | afcedebc6a094224973534f43b396bbbf33fe44e (patch) | |
| tree | f8f3741b8e432615db8d3628717a7121c3289428 /drivers/platform | |
| parent | a29ccf6ff3e07061253b9209a65edb8c0126f78d (diff) | |
thinkpad_acpi: save kbdlight state on suspend and restore it on resume
Override default LED class suspend/resume handles, by keeping track of
the brightness level before suspending so that it can be automatically
restored on resume by calling default resume handler.
Signed-off-by: Marco Trevisan (Treviño) <mail@3v1n0.net>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Diffstat (limited to 'drivers/platform')
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e305ab541a22..5f09f161765f 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -5001,6 +5001,8 @@ static int kbdlight_set_level(int level) | |||
| 5001 | return 0; | 5001 | return 0; |
| 5002 | } | 5002 | } |
| 5003 | 5003 | ||
| 5004 | static int kbdlight_set_level_and_update(int level); | ||
| 5005 | |||
| 5004 | static int kbdlight_get_level(void) | 5006 | static int kbdlight_get_level(void) |
| 5005 | { | 5007 | { |
| 5006 | int status = 0; | 5008 | int status = 0; |
| @@ -5068,7 +5070,7 @@ static void kbdlight_set_worker(struct work_struct *work) | |||
| 5068 | container_of(work, struct tpacpi_led_classdev, work); | 5070 | container_of(work, struct tpacpi_led_classdev, work); |
| 5069 | 5071 | ||
| 5070 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) | 5072 | if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) |
| 5071 | kbdlight_set_level(data->new_state); | 5073 | kbdlight_set_level_and_update(data->new_state); |
| 5072 | } | 5074 | } |
| 5073 | 5075 | ||
| 5074 | static void kbdlight_sysfs_set(struct led_classdev *led_cdev, | 5076 | static void kbdlight_sysfs_set(struct led_classdev *led_cdev, |
| @@ -5099,7 +5101,6 @@ static struct tpacpi_led_classdev tpacpi_led_kbdlight = { | |||
| 5099 | .max_brightness = 2, | 5101 | .max_brightness = 2, |
| 5100 | .brightness_set = &kbdlight_sysfs_set, | 5102 | .brightness_set = &kbdlight_sysfs_set, |
| 5101 | .brightness_get = &kbdlight_sysfs_get, | 5103 | .brightness_get = &kbdlight_sysfs_get, |
| 5102 | .flags = LED_CORE_SUSPENDRESUME, | ||
| 5103 | } | 5104 | } |
| 5104 | }; | 5105 | }; |
| 5105 | 5106 | ||
| @@ -5137,6 +5138,20 @@ static void kbdlight_exit(void) | |||
| 5137 | flush_workqueue(tpacpi_wq); | 5138 | flush_workqueue(tpacpi_wq); |
| 5138 | } | 5139 | } |
| 5139 | 5140 | ||
| 5141 | static int kbdlight_set_level_and_update(int level) | ||
| 5142 | { | ||
| 5143 | int ret; | ||
| 5144 | struct led_classdev *led_cdev; | ||
| 5145 | |||
| 5146 | ret = kbdlight_set_level(level); | ||
| 5147 | led_cdev = &tpacpi_led_kbdlight.led_classdev; | ||
| 5148 | |||
| 5149 | if (ret == 0 && !(led_cdev->flags & LED_SUSPENDED)) | ||
| 5150 | led_cdev->brightness = level; | ||
| 5151 | |||
| 5152 | return ret; | ||
| 5153 | } | ||
| 5154 | |||
| 5140 | static int kbdlight_read(struct seq_file *m) | 5155 | static int kbdlight_read(struct seq_file *m) |
| 5141 | { | 5156 | { |
| 5142 | int level; | 5157 | int level; |
| @@ -5177,13 +5192,35 @@ static int kbdlight_write(char *buf) | |||
| 5177 | if (level == -1) | 5192 | if (level == -1) |
| 5178 | return -EINVAL; | 5193 | return -EINVAL; |
| 5179 | 5194 | ||
| 5180 | return kbdlight_set_level(level); | 5195 | return kbdlight_set_level_and_update(level); |
| 5196 | } | ||
| 5197 | |||
| 5198 | static void kbdlight_suspend(void) | ||
| 5199 | { | ||
| 5200 | struct led_classdev *led_cdev; | ||
| 5201 | |||
| 5202 | if (!tp_features.kbdlight) | ||
| 5203 | return; | ||
| 5204 | |||
| 5205 | led_cdev = &tpacpi_led_kbdlight.led_classdev; | ||
| 5206 | led_update_brightness(led_cdev); | ||
| 5207 | led_classdev_suspend(led_cdev); | ||
| 5208 | } | ||
| 5209 | |||
| 5210 | static void kbdlight_resume(void) | ||
| 5211 | { | ||
| 5212 | if (!tp_features.kbdlight) | ||
| 5213 | return; | ||
| 5214 | |||
| 5215 | led_classdev_resume(&tpacpi_led_kbdlight.led_classdev); | ||
| 5181 | } | 5216 | } |
| 5182 | 5217 | ||
| 5183 | static struct ibm_struct kbdlight_driver_data = { | 5218 | static struct ibm_struct kbdlight_driver_data = { |
| 5184 | .name = "kbdlight", | 5219 | .name = "kbdlight", |
| 5185 | .read = kbdlight_read, | 5220 | .read = kbdlight_read, |
| 5186 | .write = kbdlight_write, | 5221 | .write = kbdlight_write, |
| 5222 | .suspend = kbdlight_suspend, | ||
| 5223 | .resume = kbdlight_resume, | ||
| 5187 | .exit = kbdlight_exit, | 5224 | .exit = kbdlight_exit, |
| 5188 | }; | 5225 | }; |
| 5189 | 5226 | ||
