]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/misc/thinkpad_acpi.c
serial: fix enable_irq_wake/disable_irq_wake imbalance in serial_core.c
[karo-tx-linux.git] / drivers / misc / thinkpad_acpi.c
index f471b46dcf5c7672f1cc1b032c1d041907e2bfb6..3f28f6eabdbffcca3868b0b688b4a0516da91347 100644 (file)
@@ -21,7 +21,7 @@
  *  02110-1301, USA.
  */
 
-#define TPACPI_VERSION "0.19"
+#define TPACPI_VERSION "0.20"
 #define TPACPI_SYSFS_VERSION 0x020200
 
 /*
@@ -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)
@@ -6188,7 +6191,7 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
 
        tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
                                        GFP_KERNEL);
-       if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
+       if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
                kfree(tp->model_str);
                tp->model_str = NULL;
        }
@@ -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