Commit 8eec1429 authored by Herbert Poetzl's avatar Herbert Poetzl Committed by Mauro Carvalho Chehab

V4L/DVB (5208): Kthread API conversion for dvb_frontend and av7110

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: default avatarOliver Endriss <o.endriss@gmx.de>
Signed-off-by: default avatarHerbert Poetzl <herbert@13thfloor.at>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Acked-by: default avatarOliver Endriss <o.endriss@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 2a9f8b5d
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kthread.h>
#include <asm/processor.h> #include <asm/processor.h>
#include "dvb_frontend.h" #include "dvb_frontend.h"
...@@ -100,7 +101,7 @@ struct dvb_frontend_private { ...@@ -100,7 +101,7 @@ struct dvb_frontend_private {
struct semaphore sem; struct semaphore sem;
struct list_head list_head; struct list_head list_head;
wait_queue_head_t wait_queue; wait_queue_head_t wait_queue;
pid_t thread_pid; struct task_struct *thread;
unsigned long release_jiffies; unsigned long release_jiffies;
unsigned int exit; unsigned int exit;
unsigned int wakeup; unsigned int wakeup;
...@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data) ...@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data)
struct dvb_frontend *fe = data; struct dvb_frontend *fe = data;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
unsigned long timeout; unsigned long timeout;
char name [15];
fe_status_t s; fe_status_t s;
struct dvb_frontend_parameters *params; struct dvb_frontend_parameters *params;
dprintk("%s\n", __FUNCTION__); 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->check_wrapped = 0;
fepriv->quality = 0; fepriv->quality = 0;
fepriv->delay = 3*HZ; fepriv->delay = 3*HZ;
...@@ -534,14 +527,16 @@ static int dvb_frontend_thread(void *data) ...@@ -534,14 +527,16 @@ static int dvb_frontend_thread(void *data)
up(&fepriv->sem); /* is locked when we enter the thread... */ up(&fepriv->sem); /* is locked when we enter the thread... */
timeout = wait_event_interruptible_timeout(fepriv->wait_queue, timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
dvb_frontend_should_wakeup(fe), dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
fepriv->delay); fepriv->delay);
if (0 != dvb_frontend_is_exiting(fe)) {
if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
/* got signal or quitting */ /* got signal or quitting */
break; break;
} }
try_to_freeze(); if (try_to_freeze())
continue;
if (down_interruptible(&fepriv->sem)) if (down_interruptible(&fepriv->sem))
break; break;
...@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data) ...@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data)
fe->ops.sleep(fe); fe->ops.sleep(fe);
} }
fepriv->thread_pid = 0; fepriv->thread = NULL;
mb(); mb();
dvb_frontend_wakeup(fe); dvb_frontend_wakeup(fe);
...@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data) ...@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data)
static void dvb_frontend_stop(struct dvb_frontend *fe) static void dvb_frontend_stop(struct dvb_frontend *fe)
{ {
unsigned long ret;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
...@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) ...@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->exit = 1; fepriv->exit = 1;
mb(); mb();
if (!fepriv->thread_pid) if (!fepriv->thread)
return; return;
/* check if the thread is really alive */ kthread_stop(fepriv->thread);
if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { init_MUTEX (&fepriv->sem);
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;
}
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
/* paranoia check in case a signal arrived */ /* paranoia check in case a signal arrived */
if (fepriv->thread_pid) if (fepriv->thread)
printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", printk("dvb_frontend_stop: warning: thread %p won't exit\n",
fepriv->thread_pid); fepriv->thread);
} }
s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
...@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
{ {
int ret; int ret;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct task_struct *fe_thread;
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
if (fepriv->thread_pid) { if (fepriv->thread) {
if (!fepriv->exit) if (!fepriv->exit)
return 0; return 0;
else else
...@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
fepriv->exit = 0; fepriv->exit = 0;
fepriv->thread_pid = 0; fepriv->thread = NULL;
mb(); mb();
ret = kernel_thread (dvb_frontend_thread, fe, 0); fe_thread = kthread_run(dvb_frontend_thread, fe,
"kdvb-fe-%i", fe->dvb->num);
if (ret < 0) { if (IS_ERR(fe_thread)) {
printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); ret = PTR_ERR(fe_thread);
printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
up(&fepriv->sem); up(&fepriv->sem);
return ret; return ret;
} }
fepriv->thread_pid = ret; fepriv->thread = fe_thread;
return 0; return 0;
} }
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/kthread.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110) ...@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110)
static void av7110_arm_sync(struct av7110 *av7110) static void av7110_arm_sync(struct av7110 *av7110)
{ {
av7110->arm_rmmod = 1; if (av7110->arm_thread)
wake_up_interruptible(&av7110->arm_wait); kthread_stop(av7110->arm_thread);
while (av7110->arm_thread) av7110->arm_thread = NULL;
msleep(1);
} }
static int arm_thread(void *data) static int arm_thread(void *data)
...@@ -238,17 +238,11 @@ static int arm_thread(void *data) ...@@ -238,17 +238,11 @@ static int arm_thread(void *data)
dprintk(4, "%p\n",av7110); dprintk(4, "%p\n",av7110);
lock_kernel();
daemonize("arm_mon");
sigfillset(&current->blocked);
unlock_kernel();
av7110->arm_thread = current;
for (;;) { for (;;) {
timeout = wait_event_interruptible_timeout(av7110->arm_wait, timeout = wait_event_interruptible_timeout(av7110->arm_wait,
av7110->arm_rmmod, 5 * HZ); kthread_should_stop(), 5 * HZ);
if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
if (-ERESTARTSYS == timeout || kthread_should_stop()) {
/* got signal or told to quit*/ /* got signal or told to quit*/
break; break;
} }
...@@ -276,7 +270,6 @@ static int arm_thread(void *data) ...@@ -276,7 +270,6 @@ static int arm_thread(void *data)
av7110->arm_errors = 0; av7110->arm_errors = 0;
} }
av7110->arm_thread = NULL;
return 0; return 0;
} }
...@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, ...@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
const int length = TS_WIDTH * TS_HEIGHT; const int length = TS_WIDTH * TS_HEIGHT;
struct pci_dev *pdev = dev->pci; struct pci_dev *pdev = dev->pci;
struct av7110 *av7110; struct av7110 *av7110;
struct task_struct *thread;
int ret, count = 0; int ret, count = 0;
dprintk(4, "dev: %p\n", dev); dprintk(4, "dev: %p\n", dev);
...@@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* 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. " printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
"System might be unstable!\n", FW_VERSION(av7110->arm_app)); "System might be unstable!\n", FW_VERSION(av7110->arm_app));
ret = kernel_thread(arm_thread, (void *) av7110, 0); thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
if (ret < 0) if (IS_ERR(thread)) {
ret = PTR_ERR(thread);
goto err_stop_arm_9; goto err_stop_arm_9;
}
av7110->arm_thread = thread;
/* set initial volume in mixer struct */ /* set initial volume in mixer struct */
av7110->mixer.volume_left = volume; av7110->mixer.volume_left = volume;
......
...@@ -204,7 +204,6 @@ struct av7110 { ...@@ -204,7 +204,6 @@ struct av7110 {
struct task_struct *arm_thread; struct task_struct *arm_thread;
wait_queue_head_t arm_wait; wait_queue_head_t arm_wait;
u16 arm_loops; u16 arm_loops;
int arm_rmmod;
void *debi_virt; void *debi_virt;
dma_addr_t debi_bus; dma_addr_t debi_bus;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment