Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9320874a authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (6279): en_50221: convert to kthread API



Here's an attempted update to the full kthread API + wake_up_process:

Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
CC: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent d00cd298
Loading
Loading
Loading
Loading
+16 −68
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kthread.h>

#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
@@ -139,13 +140,7 @@ struct dvb_ca_private {
	wait_queue_head_t wait_queue;

	/* PID of the monitoring thread */
	pid_t thread_pid;

	/* Wait queue used when shutting thread down */
	wait_queue_head_t thread_queue;

	/* Flag indicating when thread should exit */
	unsigned int exit:1;
	struct task_struct *thread;

	/* Flag indicating if the CA device is open */
	unsigned int open:1;
@@ -901,26 +896,8 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)

	ca->wakeup = 1;
	mb();
	wake_up_interruptible(&ca->thread_queue);
}

/**
 * Used by the CA thread to determine if an early wakeup is necessary
 *
 * @param ca CA instance.
 */
static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
{
	if (ca->wakeup) {
		ca->wakeup = 0;
		return 1;
	wake_up_process(ca->thread);
}
	if (ca->exit)
		return 1;

	return 0;
}


/**
 * Update the delay used by the thread.
@@ -981,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
static int dvb_ca_en50221_thread(void *data)
{
	struct dvb_ca_private *ca = data;
	char name[15];
	int slot;
	int flags;
	int status;
@@ -990,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data)

	dprintk("%s\n", __FUNCTION__);

	/* setup kernel thread */
	snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);

	lock_kernel();
	daemonize(name);
	sigfillset(&current->blocked);
	unlock_kernel();

	/* choose the correct initial delay */
	dvb_ca_en50221_thread_update_delay(ca);

	/* main loop */
	while (!ca->exit) {
	while (!kthread_should_stop()) {
		/* sleep for a bit */
		if (!ca->wakeup) {
			flags = wait_event_interruptible_timeout(ca->thread_queue,
								 dvb_ca_en50221_thread_should_wakeup(ca),
								 ca->delay);
			if ((flags == -ERESTARTSYS) || ca->exit) {
				/* got signal or quitting */
				break;
			}
		while (!ca->wakeup) {
			set_current_state(TASK_INTERRUPTIBLE);
			schedule_timeout(ca->delay);
			if (kthread_should_stop())
				return 0;
		}
		ca->wakeup = 0;

@@ -1180,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data)
		}
	}

	/* completed */
	ca->thread_pid = 0;
	mb();
	wake_up_interruptible(&ca->thread_queue);
	return 0;
}

@@ -1683,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
		goto error;
	}
	init_waitqueue_head(&ca->wait_queue);
	ca->thread_pid = 0;
	init_waitqueue_head(&ca->thread_queue);
	ca->exit = 0;
	ca->open = 0;
	ca->wakeup = 0;
	ca->next_read_slot = 0;
@@ -1711,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
	mb();

	/* create a kthread for monitoring this CA device */

	ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);

	if (ret < 0) {
		printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
	ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
				 ca->dvbdev->adapter->num, ca->dvbdev->id);
	if (IS_ERR(ca->thread)) {
		ret = PTR_ERR(ca->thread);
		printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
			ret);
		goto error;
	}
	ca->thread_pid = ret;
	return 0;

error:
@@ -1749,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
	dprintk("%s\n", __FUNCTION__);

	/* shutdown the thread if there was one */
	if (ca->thread_pid) {
		if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
			printk("dvb_ca_release adapter %d: thread PID %d already died\n",
			       ca->dvbdev->adapter->num, ca->thread_pid);
		} else {
			ca->exit = 1;
			mb();
			dvb_ca_en50221_thread_wakeup(ca);
			wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
		}
	}
	kthread_stop(ca->thread);

	for (i = 0; i < ca->slot_count; i++) {
		dvb_ca_en50221_slot_shutdown(ca, i);