summaryrefslogtreecommitdiff
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
-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 {
#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