diff options
author | Herbert Poetzl <herbert@13thfloor.at> | 2007-02-08 12:32:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:35:20 -0500 |
commit | 8eec14295e03f9dfe2be7bb75c8004a5fa867cdb (patch) | |
tree | fe5533f0d6957e456bbba4c420e9abb9a3fae358 /drivers/media | |
parent | 2a9f8b5d25beacd034369fca416b548cbf931561 (diff) |
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>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 69 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 29 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.h | 1 |
3 files changed, 37 insertions, 62 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 7c42d53a1cc7..470ae167beb9 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/list.h> | 36 | #include <linux/list.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <linux/jiffies.h> | 38 | #include <linux/jiffies.h> |
39 | #include <linux/kthread.h> | ||
39 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
40 | 41 | ||
41 | #include "dvb_frontend.h" | 42 | #include "dvb_frontend.h" |
@@ -100,7 +101,7 @@ struct dvb_frontend_private { | |||
100 | struct semaphore sem; | 101 | struct semaphore sem; |
101 | struct list_head list_head; | 102 | struct list_head list_head; |
102 | wait_queue_head_t wait_queue; | 103 | wait_queue_head_t wait_queue; |
103 | pid_t thread_pid; | 104 | struct task_struct *thread; |
104 | unsigned long release_jiffies; | 105 | unsigned long release_jiffies; |
105 | unsigned int exit; | 106 | unsigned int exit; |
106 | unsigned int wakeup; | 107 | unsigned int wakeup; |
@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data) | |||
508 | struct dvb_frontend *fe = data; | 509 | struct dvb_frontend *fe = data; |
509 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 510 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
510 | unsigned long timeout; | 511 | unsigned long timeout; |
511 | char name [15]; | ||
512 | fe_status_t s; | 512 | fe_status_t s; |
513 | struct dvb_frontend_parameters *params; | 513 | struct dvb_frontend_parameters *params; |
514 | 514 | ||
515 | dprintk("%s\n", __FUNCTION__); | 515 | dprintk("%s\n", __FUNCTION__); |
516 | 516 | ||
517 | snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num); | ||
518 | |||
519 | lock_kernel(); | ||
520 | daemonize(name); | ||
521 | sigfillset(¤t->blocked); | ||
522 | unlock_kernel(); | ||
523 | |||
524 | fepriv->check_wrapped = 0; | 517 | fepriv->check_wrapped = 0; |
525 | fepriv->quality = 0; | 518 | fepriv->quality = 0; |
526 | fepriv->delay = 3*HZ; | 519 | fepriv->delay = 3*HZ; |
@@ -534,14 +527,16 @@ static int dvb_frontend_thread(void *data) | |||
534 | up(&fepriv->sem); /* is locked when we enter the thread... */ | 527 | up(&fepriv->sem); /* is locked when we enter the thread... */ |
535 | 528 | ||
536 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, | 529 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, |
537 | dvb_frontend_should_wakeup(fe), | 530 | dvb_frontend_should_wakeup(fe) || kthread_should_stop(), |
538 | fepriv->delay); | 531 | fepriv->delay); |
539 | if (0 != dvb_frontend_is_exiting(fe)) { | 532 | |
533 | if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { | ||
540 | /* got signal or quitting */ | 534 | /* got signal or quitting */ |
541 | break; | 535 | break; |
542 | } | 536 | } |
543 | 537 | ||
544 | try_to_freeze(); | 538 | if (try_to_freeze()) |
539 | continue; | ||
545 | 540 | ||
546 | if (down_interruptible(&fepriv->sem)) | 541 | if (down_interruptible(&fepriv->sem)) |
547 | break; | 542 | break; |
@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data) | |||
591 | fe->ops.sleep(fe); | 586 | fe->ops.sleep(fe); |
592 | } | 587 | } |
593 | 588 | ||
594 | fepriv->thread_pid = 0; | 589 | fepriv->thread = NULL; |
595 | mb(); | 590 | mb(); |
596 | 591 | ||
597 | dvb_frontend_wakeup(fe); | 592 | dvb_frontend_wakeup(fe); |
@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data) | |||
600 | 595 | ||
601 | static void dvb_frontend_stop(struct dvb_frontend *fe) | 596 | static void dvb_frontend_stop(struct dvb_frontend *fe) |
602 | { | 597 | { |
603 | unsigned long ret; | ||
604 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 598 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
605 | 599 | ||
606 | dprintk ("%s\n", __FUNCTION__); | 600 | dprintk ("%s\n", __FUNCTION__); |
@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
608 | fepriv->exit = 1; | 602 | fepriv->exit = 1; |
609 | mb(); | 603 | mb(); |
610 | 604 | ||
611 | if (!fepriv->thread_pid) | 605 | if (!fepriv->thread) |
612 | return; | 606 | return; |
613 | 607 | ||
614 | /* check if the thread is really alive */ | 608 | kthread_stop(fepriv->thread); |
615 | if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { | 609 | init_MUTEX (&fepriv->sem); |
616 | printk("dvb_frontend_stop: thread PID %d already died\n", | ||
617 | fepriv->thread_pid); | ||
618 | /* make sure the mutex was not held by the thread */ | ||
619 | init_MUTEX (&fepriv->sem); | ||
620 | return; | ||
621 | } | ||
622 | |||
623 | /* wake up the frontend thread, so it notices that fe->exit == 1 */ | ||
624 | dvb_frontend_wakeup(fe); | ||
625 | |||
626 | /* wait until the frontend thread has exited */ | ||
627 | ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid); | ||
628 | if (-ERESTARTSYS != ret) { | ||
629 | fepriv->state = FESTATE_IDLE; | ||
630 | return; | ||
631 | } | ||
632 | fepriv->state = FESTATE_IDLE; | 610 | fepriv->state = FESTATE_IDLE; |
633 | 611 | ||
634 | /* paranoia check in case a signal arrived */ | 612 | /* paranoia check in case a signal arrived */ |
635 | if (fepriv->thread_pid) | 613 | if (fepriv->thread) |
636 | printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", | 614 | printk("dvb_frontend_stop: warning: thread %p won't exit\n", |
637 | fepriv->thread_pid); | 615 | fepriv->thread); |
638 | } | 616 | } |
639 | 617 | ||
640 | s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) | 618 | s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) |
@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe) | |||
684 | { | 662 | { |
685 | int ret; | 663 | int ret; |
686 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 664 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
665 | struct task_struct *fe_thread; | ||
687 | 666 | ||
688 | dprintk ("%s\n", __FUNCTION__); | 667 | dprintk ("%s\n", __FUNCTION__); |
689 | 668 | ||
690 | if (fepriv->thread_pid) { | 669 | if (fepriv->thread) { |
691 | if (!fepriv->exit) | 670 | if (!fepriv->exit) |
692 | return 0; | 671 | return 0; |
693 | else | 672 | else |
@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe) | |||
701 | 680 | ||
702 | fepriv->state = FESTATE_IDLE; | 681 | fepriv->state = FESTATE_IDLE; |
703 | fepriv->exit = 0; | 682 | fepriv->exit = 0; |
704 | fepriv->thread_pid = 0; | 683 | fepriv->thread = NULL; |
705 | mb(); | 684 | mb(); |
706 | 685 | ||
707 | ret = kernel_thread (dvb_frontend_thread, fe, 0); | 686 | fe_thread = kthread_run(dvb_frontend_thread, fe, |
708 | 687 | "kdvb-fe-%i", fe->dvb->num); | |
709 | if (ret < 0) { | 688 | if (IS_ERR(fe_thread)) { |
710 | printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); | 689 | ret = PTR_ERR(fe_thread); |
690 | printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); | ||
711 | up(&fepriv->sem); | 691 | up(&fepriv->sem); |
712 | return ret; | 692 | return ret; |
713 | } | 693 | } |
714 | fepriv->thread_pid = ret; | 694 | fepriv->thread = fe_thread; |
715 | |||
716 | return 0; | 695 | return 0; |
717 | } | 696 | } |
718 | 697 | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index bb213d836c90..29ed532ba966 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/firmware.h> | 51 | #include <linux/firmware.h> |
52 | #include <linux/crc32.h> | 52 | #include <linux/crc32.h> |
53 | #include <linux/i2c.h> | 53 | #include <linux/i2c.h> |
54 | #include <linux/kthread.h> | ||
54 | 55 | ||
55 | #include <asm/system.h> | 56 | #include <asm/system.h> |
56 | 57 | ||
@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110) | |||
223 | 224 | ||
224 | static void av7110_arm_sync(struct av7110 *av7110) | 225 | static void av7110_arm_sync(struct av7110 *av7110) |
225 | { | 226 | { |
226 | av7110->arm_rmmod = 1; | 227 | if (av7110->arm_thread) |
227 | wake_up_interruptible(&av7110->arm_wait); | 228 | kthread_stop(av7110->arm_thread); |
228 | 229 | ||
229 | while (av7110->arm_thread) | 230 | av7110->arm_thread = NULL; |
230 | msleep(1); | ||
231 | } | 231 | } |
232 | 232 | ||
233 | static int arm_thread(void *data) | 233 | static int arm_thread(void *data) |
@@ -238,17 +238,11 @@ static int arm_thread(void *data) | |||
238 | 238 | ||
239 | dprintk(4, "%p\n",av7110); | 239 | dprintk(4, "%p\n",av7110); |
240 | 240 | ||
241 | lock_kernel(); | ||
242 | daemonize("arm_mon"); | ||
243 | sigfillset(¤t->blocked); | ||
244 | unlock_kernel(); | ||
245 | |||
246 | av7110->arm_thread = current; | ||
247 | |||
248 | for (;;) { | 241 | for (;;) { |
249 | timeout = wait_event_interruptible_timeout(av7110->arm_wait, | 242 | timeout = wait_event_interruptible_timeout(av7110->arm_wait, |
250 | av7110->arm_rmmod, 5 * HZ); | 243 | kthread_should_stop(), 5 * HZ); |
251 | if (-ERESTARTSYS == timeout || av7110->arm_rmmod) { | 244 | |
245 | if (-ERESTARTSYS == timeout || kthread_should_stop()) { | ||
252 | /* got signal or told to quit*/ | 246 | /* got signal or told to quit*/ |
253 | break; | 247 | break; |
254 | } | 248 | } |
@@ -276,7 +270,6 @@ static int arm_thread(void *data) | |||
276 | av7110->arm_errors = 0; | 270 | av7110->arm_errors = 0; |
277 | } | 271 | } |
278 | 272 | ||
279 | av7110->arm_thread = NULL; | ||
280 | return 0; | 273 | return 0; |
281 | } | 274 | } |
282 | 275 | ||
@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2338 | const int length = TS_WIDTH * TS_HEIGHT; | 2331 | const int length = TS_WIDTH * TS_HEIGHT; |
2339 | struct pci_dev *pdev = dev->pci; | 2332 | struct pci_dev *pdev = dev->pci; |
2340 | struct av7110 *av7110; | 2333 | struct av7110 *av7110; |
2334 | struct task_struct *thread; | ||
2341 | int ret, count = 0; | 2335 | int ret, count = 0; |
2342 | 2336 | ||
2343 | dprintk(4, "dev: %p\n", dev); | 2337 | dprintk(4, "dev: %p\n", dev); |
@@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2622 | printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " | 2616 | printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " |
2623 | "System might be unstable!\n", FW_VERSION(av7110->arm_app)); | 2617 | "System might be unstable!\n", FW_VERSION(av7110->arm_app)); |
2624 | 2618 | ||
2625 | ret = kernel_thread(arm_thread, (void *) av7110, 0); | 2619 | thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); |
2626 | if (ret < 0) | 2620 | if (IS_ERR(thread)) { |
2621 | ret = PTR_ERR(thread); | ||
2627 | goto err_stop_arm_9; | 2622 | goto err_stop_arm_9; |
2623 | } | ||
2624 | av7110->arm_thread = thread; | ||
2628 | 2625 | ||
2629 | /* set initial volume in mixer struct */ | 2626 | /* set initial volume in mixer struct */ |
2630 | av7110->mixer.volume_left = volume; | 2627 | av7110->mixer.volume_left = volume; |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 1d05166bd853..b98bd453cade 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -204,7 +204,6 @@ struct av7110 { | |||
204 | struct task_struct *arm_thread; | 204 | struct task_struct *arm_thread; |
205 | wait_queue_head_t arm_wait; | 205 | wait_queue_head_t arm_wait; |
206 | u16 arm_loops; | 206 | u16 arm_loops; |
207 | int arm_rmmod; | ||
208 | 207 | ||
209 | void *debi_virt; | 208 | void *debi_virt; |
210 | dma_addr_t debi_bus; | 209 | dma_addr_t debi_bus; |