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: 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>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
2a9f8b5d25
commit
8eec14295e
@@ -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 {
|
|||||||
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)
|
|||||||
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(¤t->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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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) {
|
|
||||||
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);
|
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
dprintk(4, "%p\n",av7110);
|
dprintk(4, "%p\n",av7110);
|
||||||
|
|
||||||
lock_kernel();
|
|
||||||
daemonize("arm_mon");
|
|
||||||
sigfillset(¤t->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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user