V4L/DVB (5208): Kthread API conversion for dvb_frontend and av7110
authorHerbert Poetzl <herbert@13thfloor.at>
Thu, 8 Feb 2007 17:32:43 +0000 (14:32 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Wed, 21 Feb 2007 15:35:20 +0000 (13:35 -0200)
dvb kernel_thread to kthread API port.
It is running fine here, including module load/unload and software suspend
(which doesn't work as expected with or without this patch :).
I didn't convert the dvb_ca_en50221 as I do not have such an interface, but
if the conversion process is fine with the v4l-dvb maintainers, it should not
be a problem to send a patch for that too ...
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Herbert Poetzl <herbert@13thfloor.at>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h

index 7c42d53a1cc7df9ecc55ba8859f50d75ccc14a82..470ae167beb9b1c3d4c77eccefa5273c416abb7a 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/list.h>
 #include <linux/freezer.h>
 #include <linux/jiffies.h>
+#include <linux/kthread.h>
 #include <asm/processor.h>
 
 #include "dvb_frontend.h"
@@ -100,7 +101,7 @@ struct dvb_frontend_private {
        struct semaphore sem;
        struct list_head list_head;
        wait_queue_head_t wait_queue;
-       pid_t thread_pid;
+       struct task_struct *thread;
        unsigned long release_jiffies;
        unsigned int exit;
        unsigned int wakeup;
@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data)
        struct dvb_frontend *fe = data;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        unsigned long timeout;
-       char name [15];
        fe_status_t s;
        struct dvb_frontend_parameters *params;
 
        dprintk("%s\n", __FUNCTION__);
 
-       snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);
-
-       lock_kernel();
-       daemonize(name);
-       sigfillset(&current->blocked);
-       unlock_kernel();
-
        fepriv->check_wrapped = 0;
        fepriv->quality = 0;
        fepriv->delay = 3*HZ;
@@ -534,14 +527,16 @@ static int dvb_frontend_thread(void *data)
                up(&fepriv->sem);           /* is locked when we enter the thread... */
 
                timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
-                                                          dvb_frontend_should_wakeup(fe),
-                                                          fepriv->delay);
-               if (0 != dvb_frontend_is_exiting(fe)) {
+                       dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
+                       fepriv->delay);
+
+               if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
                        /* got signal or quitting */
                        break;
                }
 
-               try_to_freeze();
+               if (try_to_freeze())
+                       continue;
 
                if (down_interruptible(&fepriv->sem))
                        break;
@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data)
                        fe->ops.sleep(fe);
        }
 
-       fepriv->thread_pid = 0;
+       fepriv->thread = NULL;
        mb();
 
        dvb_frontend_wakeup(fe);
@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data)
 
 static void dvb_frontend_stop(struct dvb_frontend *fe)
 {
-       unsigned long ret;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
        dprintk ("%s\n", __FUNCTION__);
@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
        fepriv->exit = 1;
        mb();
 
-       if (!fepriv->thread_pid)
+       if (!fepriv->thread)
                return;
 
-       /* check if the thread is really alive */
-       if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) {
-               printk("dvb_frontend_stop: thread PID %d already died\n",
-                               fepriv->thread_pid);
-               /* make sure the mutex was not held by the thread */
-               init_MUTEX (&fepriv->sem);
-               return;
-       }
-
-       /* wake up the frontend thread, so it notices that fe->exit == 1 */
-       dvb_frontend_wakeup(fe);
-
-       /* wait until the frontend thread has exited */
-       ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid);
-       if (-ERESTARTSYS != ret) {
-               fepriv->state = FESTATE_IDLE;
-               return;
-       }
+       kthread_stop(fepriv->thread);
+       init_MUTEX (&fepriv->sem);
        fepriv->state = FESTATE_IDLE;
 
        /* paranoia check in case a signal arrived */
-       if (fepriv->thread_pid)
-               printk("dvb_frontend_stop: warning: thread PID %d won't exit\n",
-                               fepriv->thread_pid);
+       if (fepriv->thread)
+               printk("dvb_frontend_stop: warning: thread %p won't exit\n",
+                               fepriv->thread);
 }
 
 s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 {
        int ret;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
+       struct task_struct *fe_thread;
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if (fepriv->thread_pid) {
+       if (fepriv->thread) {
                if (!fepriv->exit)
                        return 0;
                else
@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
 
        fepriv->state = FESTATE_IDLE;
        fepriv->exit = 0;
-       fepriv->thread_pid = 0;
+       fepriv->thread = NULL;
        mb();
 
-       ret = kernel_thread (dvb_frontend_thread, fe, 0);
-
-       if (ret < 0) {
-               printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret);
+       fe_thread = kthread_run(dvb_frontend_thread, fe,
+               "kdvb-fe-%i", fe->dvb->num);
+       if (IS_ERR(fe_thread)) {
+               ret = PTR_ERR(fe_thread);
+               printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
                up(&fepriv->sem);
                return ret;
        }
-       fepriv->thread_pid = ret;
-
+       fepriv->thread = fe_thread;
        return 0;
 }
 
index bb213d836c909fc20ab01dd6fc64231930fbc161..29ed532ba966932e9d1c687e13057cfef63c393c 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/firmware.h>
 #include <linux/crc32.h>
 #include <linux/i2c.h>
+#include <linux/kthread.h>
 
 #include <asm/system.h>
 
@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110)
 
 static void av7110_arm_sync(struct av7110 *av7110)
 {
-       av7110->arm_rmmod = 1;
-       wake_up_interruptible(&av7110->arm_wait);
+       if (av7110->arm_thread)
+               kthread_stop(av7110->arm_thread);
 
-       while (av7110->arm_thread)
-               msleep(1);
+       av7110->arm_thread = NULL;
 }
 
 static int arm_thread(void *data)
@@ -238,17 +238,11 @@ static int arm_thread(void *data)
 
        dprintk(4, "%p\n",av7110);
 
-       lock_kernel();
-       daemonize("arm_mon");
-       sigfillset(&current->blocked);
-       unlock_kernel();
-
-       av7110->arm_thread = current;
-
        for (;;) {
                timeout = wait_event_interruptible_timeout(av7110->arm_wait,
-                                                          av7110->arm_rmmod, 5 * HZ);
-               if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
+                       kthread_should_stop(), 5 * HZ);
+
+               if (-ERESTARTSYS == timeout || kthread_should_stop()) {
                        /* got signal or told to quit*/
                        break;
                }
@@ -276,7 +270,6 @@ static int arm_thread(void *data)
                av7110->arm_errors = 0;
        }
 
-       av7110->arm_thread = NULL;
        return 0;
 }
 
@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
        const int length = TS_WIDTH * TS_HEIGHT;
        struct pci_dev *pdev = dev->pci;
        struct av7110 *av7110;
+       struct task_struct *thread;
        int ret, count = 0;
 
        dprintk(4, "dev: %p\n", dev);
@@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
                printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
                        "System might be unstable!\n", FW_VERSION(av7110->arm_app));
 
-       ret = kernel_thread(arm_thread, (void *) av7110, 0);
-       if (ret < 0)
+       thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
+       if (IS_ERR(thread)) {
+               ret = PTR_ERR(thread);
                goto err_stop_arm_9;
+       }
+       av7110->arm_thread = thread;
 
        /* set initial volume in mixer struct */
        av7110->mixer.volume_left  = volume;
index 1d05166bd853d80c3e062061833d94e7ea5f810e..b98bd453cade62f7755d7d443ce7641d8bdb007c 100644 (file)
@@ -204,7 +204,6 @@ struct av7110 {
        struct task_struct *arm_thread;
        wait_queue_head_t   arm_wait;
        u16                 arm_loops;
-       int                 arm_rmmod;
 
        void               *debi_virt;
        dma_addr_t          debi_bus;