V4L/DVB (4624): Tvaudio: Replaced kernel_thread() with kthread_run()
authorCedric Le Goater <clg@fr.ibm.com>
Mon, 11 Sep 2006 19:31:45 +0000 (16:31 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Tue, 26 Sep 2006 15:30:36 +0000 (12:30 -0300)
Replaced kernel_thread() with kthread_run() since kernel_thread() is
deprecated in drivers/modules.
Removed the completion and the wait queue which are now useless with
kthread. Also removed the allow_signal() call as signals don't apply
to kernel threads.
Fixed a small race condition when thread is stopped.
Please check if the timer vs. thread still works fine without the wait
queue.

Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/tvaudio.c

index 936e3f7..fcaef4b 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/i2c-algo-bit.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/kthread.h>
 
 #include <media/tvaudio.h>
 #include <media/v4l2-common.h>
@@ -124,11 +125,8 @@ struct CHIPSTATE {
        int input;
 
        /* thread */
-       pid_t                tpid;
-       struct completion    texit;
-       wait_queue_head_t    wq;
+       struct task_struct   *thread;
        struct timer_list    wt;
-       int                  done;
        int                  watch_stereo;
        int                  audmode;
 };
@@ -264,28 +262,23 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
 static void chip_thread_wake(unsigned long data)
 {
        struct CHIPSTATE *chip = (struct CHIPSTATE*)data;
-       wake_up_interruptible(&chip->wq);
+       wake_up_process(chip->thread);
 }
 
 static int chip_thread(void *data)
 {
-       DECLARE_WAITQUEUE(wait, current);
        struct CHIPSTATE *chip = data;
        struct CHIPDESC  *desc = chiplist + chip->type;
 
-       daemonize("%s", chip->c.name);
-       allow_signal(SIGTERM);
        v4l_dbg(1, debug, &chip->c, "%s: thread started\n", chip->c.name);
 
        for (;;) {
-               add_wait_queue(&chip->wq, &wait);
-               if (!chip->done) {
-                       set_current_state(TASK_INTERRUPTIBLE);
+               set_current_state(TASK_INTERRUPTIBLE);
+               if (!kthread_should_stop())
                        schedule();
-               }
-               remove_wait_queue(&chip->wq, &wait);
+               set_current_state(TASK_RUNNING);
                try_to_freeze();
-               if (chip->done || signal_pending(current))
+               if (kthread_should_stop())
                        break;
                v4l_dbg(1, debug, &chip->c, "%s: thread wakeup\n", chip->c.name);
 
@@ -301,7 +294,6 @@ static int chip_thread(void *data)
        }
 
        v4l_dbg(1, debug, &chip->c, "%s: thread exiting\n", chip->c.name);
-       complete_and_exit(&chip->texit, 0);
        return 0;
 }
 
@@ -1536,19 +1528,18 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
                chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
        }
 
-       chip->tpid = -1;
+       chip->thread = NULL;
        if (desc->checkmode) {
                /* start async thread */
                init_timer(&chip->wt);
                chip->wt.function = chip_thread_wake;
                chip->wt.data     = (unsigned long)chip;
-               init_waitqueue_head(&chip->wq);
-               init_completion(&chip->texit);
-               chip->tpid = kernel_thread(chip_thread,(void *)chip,0);
-               if (chip->tpid < 0)
-                       v4l_warn(&chip->c, "%s: kernel_thread() failed\n",
+               chip->thread = kthread_run(chip_thread, chip, chip->c.name);
+               if (IS_ERR(chip->thread)) {
+                       v4l_warn(&chip->c, "%s: failed to create kthread\n",
                               chip->c.name);
-               wake_up_interruptible(&chip->wq);
+                       chip->thread = NULL;
+               }
        }
        return 0;
 }
@@ -1569,11 +1560,10 @@ static int chip_detach(struct i2c_client *client)
        struct CHIPSTATE *chip = i2c_get_clientdata(client);
 
        del_timer_sync(&chip->wt);
-       if (chip->tpid >= 0) {
+       if (chip->thread) {
                /* shutdown async thread */
-               chip->done = 1;
-               wake_up_interruptible(&chip->wq);
-               wait_for_completion(&chip->texit);
+               kthread_stop(chip->thread);
+               chip->thread = NULL;
        }
 
        i2c_detach_client(&chip->c);