diff options
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 26 |
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 { #define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" #define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd" +#define TPACPI_WORKQUEUE_NAME "ktpacpid" #define TPACPI_MAX_ACPI_ARGS 3 @@ -272,6 +273,8 @@ static enum { static int experimental; static u32 dbg_level; +static struct workqueue_struct *tpacpi_wq; + /* Special LED class that can defer work */ struct tpacpi_led_classdev { struct led_classdev led_classdev; @@ -3298,7 +3301,7 @@ static void light_sysfs_set(struct led_classdev *led_cdev, struct tpacpi_led_classdev, led_classdev); data->new_brightness = brightness; - schedule_work(&data->work); + queue_work(tpacpi_wq, &data->work); } static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev) @@ -3355,7 +3358,7 @@ static void light_exit(void) { led_classdev_unregister(&tpacpi_led_thinklight.led_classdev); if (work_pending(&tpacpi_led_thinklight.work)) - flush_scheduled_work(); + flush_workqueue(tpacpi_wq); } static int light_read(char *p) @@ -3925,7 +3928,7 @@ static void led_sysfs_set(struct led_classdev *led_cdev, struct tpacpi_led_classdev, led_classdev); data->new_brightness = brightness; - schedule_work(&data->work); + queue_work(tpacpi_wq, &data->work); } static 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, return -EINVAL; data->new_brightness = TPACPI_LED_BLINK; - schedule_work(&data->work); + queue_work(tpacpi_wq, &data->work); return 0; } @@ -5408,11 +5411,11 @@ static void fan_watchdog_reset(void) if (fan_watchdog_maxinterval > 0 && tpacpi_lifecycle != TPACPI_LIFE_EXITING) { fan_watchdog_active = 1; - if (!schedule_delayed_work(&fan_watchdog_task, + if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task, msecs_to_jiffies(fan_watchdog_maxinterval * 1000))) { printk(TPACPI_ERR - "failed to schedule the fan watchdog, " + "failed to queue the fan watchdog, " "watchdog will not trigger\n"); } } else @@ -5782,7 +5785,7 @@ static void fan_exit(void) &driver_attr_fan_watchdog); cancel_delayed_work(&fan_watchdog_task); - flush_scheduled_work(); + flush_workqueue(tpacpi_wq); } static int fan_read(char *p) @@ -6436,6 +6439,9 @@ static void thinkpad_acpi_module_exit(void) if (proc_dir) remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); + if (tpacpi_wq) + destroy_workqueue(tpacpi_wq); + kfree(thinkpad_id.bios_version_str); kfree(thinkpad_id.ec_version_str); kfree(thinkpad_id.model_str); @@ -6466,6 +6472,12 @@ static int __init thinkpad_acpi_module_init(void) TPACPI_ACPIHANDLE_INIT(ecrd); TPACPI_ACPIHANDLE_INIT(ecwr); + tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME); + if (!tpacpi_wq) { + thinkpad_acpi_module_exit(); + return -ENOMEM; + } + proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); if (!proc_dir) { printk(TPACPI_ERR |