aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/thinkpad_acpi.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index f471b46dcf5c..d5c08c01fd11 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -140,6 +140,7 @@ enum {
140#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" 140#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
141 141
142#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd" 142#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
143#define TPACPI_WORKQUEUE_NAME "ktpacpid"
143 144
144#define TPACPI_MAX_ACPI_ARGS 3 145#define TPACPI_MAX_ACPI_ARGS 3
145 146
@@ -272,6 +273,8 @@ static enum {
272static int experimental; 273static int experimental;
273static u32 dbg_level; 274static u32 dbg_level;
274 275
276static struct workqueue_struct *tpacpi_wq;
277
275/* Special LED class that can defer work */ 278/* Special LED class that can defer work */
276struct tpacpi_led_classdev { 279struct tpacpi_led_classdev {
277 struct led_classdev led_classdev; 280 struct led_classdev led_classdev;
@@ -3298,7 +3301,7 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
3298 struct tpacpi_led_classdev, 3301 struct tpacpi_led_classdev,
3299 led_classdev); 3302 led_classdev);
3300 data->new_brightness = brightness; 3303 data->new_brightness = brightness;
3301 schedule_work(&data->work); 3304 queue_work(tpacpi_wq, &data->work);
3302} 3305}
3303 3306
3304static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) 3307static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
@@ -3355,7 +3358,7 @@ static void light_exit(void)
3355{ 3358{
3356 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); 3359 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
3357 if (work_pending(&tpacpi_led_thinklight.work)) 3360 if (work_pending(&tpacpi_led_thinklight.work))
3358 flush_scheduled_work(); 3361 flush_workqueue(tpacpi_wq);
3359} 3362}
3360 3363
3361static int light_read(char *p) 3364static int light_read(char *p)
@@ -3925,7 +3928,7 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
3925 struct tpacpi_led_classdev, led_classdev); 3928 struct tpacpi_led_classdev, led_classdev);
3926 3929
3927 data->new_brightness = brightness; 3930 data->new_brightness = brightness;
3928 schedule_work(&data->work); 3931 queue_work(tpacpi_wq, &data->work);
3929} 3932}
3930 3933
3931static int led_sysfs_blink_set(struct led_classdev *led_cdev, 3934static int led_sysfs_blink_set(struct led_classdev *led_cdev,
@@ -3943,7 +3946,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
3943 return -EINVAL; 3946 return -EINVAL;
3944 3947
3945 data->new_brightness = TPACPI_LED_BLINK; 3948 data->new_brightness = TPACPI_LED_BLINK;
3946 schedule_work(&data->work); 3949 queue_work(tpacpi_wq, &data->work);
3947 3950
3948 return 0; 3951 return 0;
3949} 3952}
@@ -5408,11 +5411,11 @@ static void fan_watchdog_reset(void)
5408 if (fan_watchdog_maxinterval > 0 && 5411 if (fan_watchdog_maxinterval > 0 &&
5409 tpacpi_lifecycle != TPACPI_LIFE_EXITING) { 5412 tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
5410 fan_watchdog_active = 1; 5413 fan_watchdog_active = 1;
5411 if (!schedule_delayed_work(&fan_watchdog_task, 5414 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
5412 msecs_to_jiffies(fan_watchdog_maxinterval 5415 msecs_to_jiffies(fan_watchdog_maxinterval
5413 * 1000))) { 5416 * 1000))) {
5414 printk(TPACPI_ERR 5417 printk(TPACPI_ERR
5415 "failed to schedule the fan watchdog, " 5418 "failed to queue the fan watchdog, "
5416 "watchdog will not trigger\n"); 5419 "watchdog will not trigger\n");
5417 } 5420 }
5418 } else 5421 } else
@@ -5782,7 +5785,7 @@ static void fan_exit(void)
5782 &driver_attr_fan_watchdog); 5785 &driver_attr_fan_watchdog);
5783 5786
5784 cancel_delayed_work(&fan_watchdog_task); 5787 cancel_delayed_work(&fan_watchdog_task);
5785 flush_scheduled_work(); 5788 flush_workqueue(tpacpi_wq);
5786} 5789}
5787 5790
5788static int fan_read(char *p) 5791static int fan_read(char *p)
@@ -6436,6 +6439,9 @@ static void thinkpad_acpi_module_exit(void)
6436 if (proc_dir) 6439 if (proc_dir)
6437 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); 6440 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
6438 6441
6442 if (tpacpi_wq)
6443 destroy_workqueue(tpacpi_wq);
6444
6439 kfree(thinkpad_id.bios_version_str); 6445 kfree(thinkpad_id.bios_version_str);
6440 kfree(thinkpad_id.ec_version_str); 6446 kfree(thinkpad_id.ec_version_str);
6441 kfree(thinkpad_id.model_str); 6447 kfree(thinkpad_id.model_str);
@@ -6466,6 +6472,12 @@ static int __init thinkpad_acpi_module_init(void)
6466 TPACPI_ACPIHANDLE_INIT(ecrd); 6472 TPACPI_ACPIHANDLE_INIT(ecrd);
6467 TPACPI_ACPIHANDLE_INIT(ecwr); 6473 TPACPI_ACPIHANDLE_INIT(ecwr);
6468 6474
6475 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
6476 if (!tpacpi_wq) {
6477 thinkpad_acpi_module_exit();
6478 return -ENOMEM;
6479 }
6480
6469 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); 6481 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
6470 if (!proc_dir) { 6482 if (!proc_dir) {
6471 printk(TPACPI_ERR 6483 printk(TPACPI_ERR