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

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
Loading
Loading
Loading
Loading
+24 −45
Original line number Diff line number Diff line
@@ -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),
			dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
			fepriv->delay);
		if (0 != dvb_frontend_is_exiting(fe)) {

		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 */
	kthread_stop(fepriv->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;

	/* 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;
}

+13 −16
Original line number Diff line number Diff line
@@ -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;
+0 −1
Original line number Diff line number Diff line
@@ -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;