aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2007-10-03 10:23:01 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 23:03:08 -0400
commit9320874a3e6aea7044a4a7eedeab13db990424ab (patch)
treeed60c3726ca646a3b486bb29bde02f4adec8f310 /drivers/media
parentd00cd2985e0e796621adf0f782af1563d990b0b5 (diff)
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: Andrew Morton <akpm@linux-foundation.org> CC: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c84
1 files changed, 16 insertions, 68 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 5c7bcb8393d2..084a508a03da 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -36,6 +36,7 @@
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/spinlock.h> 37#include <linux/spinlock.h>
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/kthread.h>
39 40
40#include "dvb_ca_en50221.h" 41#include "dvb_ca_en50221.h"
41#include "dvb_ringbuffer.h" 42#include "dvb_ringbuffer.h"
@@ -139,13 +140,7 @@ struct dvb_ca_private {
139 wait_queue_head_t wait_queue; 140 wait_queue_head_t wait_queue;
140 141
141 /* PID of the monitoring thread */ 142 /* PID of the monitoring thread */
142 pid_t thread_pid; 143 struct task_struct *thread;
143
144 /* Wait queue used when shutting thread down */
145 wait_queue_head_t thread_queue;
146
147 /* Flag indicating when thread should exit */
148 unsigned int exit:1;
149 144
150 /* Flag indicating if the CA device is open */ 145 /* Flag indicating if the CA device is open */
151 unsigned int open:1; 146 unsigned int open:1;
@@ -901,28 +896,10 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
901 896
902 ca->wakeup = 1; 897 ca->wakeup = 1;
903 mb(); 898 mb();
904 wake_up_interruptible(&ca->thread_queue); 899 wake_up_process(ca->thread);
905} 900}
906 901
907/** 902/**
908 * Used by the CA thread to determine if an early wakeup is necessary
909 *
910 * @param ca CA instance.
911 */
912static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
913{
914 if (ca->wakeup) {
915 ca->wakeup = 0;
916 return 1;
917 }
918 if (ca->exit)
919 return 1;
920
921 return 0;
922}
923
924
925/**
926 * Update the delay used by the thread. 903 * Update the delay used by the thread.
927 * 904 *
928 * @param ca CA instance. 905 * @param ca CA instance.
@@ -981,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
981static int dvb_ca_en50221_thread(void *data) 958static int dvb_ca_en50221_thread(void *data)
982{ 959{
983 struct dvb_ca_private *ca = data; 960 struct dvb_ca_private *ca = data;
984 char name[15];
985 int slot; 961 int slot;
986 int flags; 962 int flags;
987 int status; 963 int status;
@@ -990,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data)
990 966
991 dprintk("%s\n", __FUNCTION__); 967 dprintk("%s\n", __FUNCTION__);
992 968
993 /* setup kernel thread */
994 snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
995
996 lock_kernel();
997 daemonize(name);
998 sigfillset(&current->blocked);
999 unlock_kernel();
1000
1001 /* choose the correct initial delay */ 969 /* choose the correct initial delay */
1002 dvb_ca_en50221_thread_update_delay(ca); 970 dvb_ca_en50221_thread_update_delay(ca);
1003 971
1004 /* main loop */ 972 /* main loop */
1005 while (!ca->exit) { 973 while (!kthread_should_stop()) {
1006 /* sleep for a bit */ 974 /* sleep for a bit */
1007 if (!ca->wakeup) { 975 while (!ca->wakeup) {
1008 flags = wait_event_interruptible_timeout(ca->thread_queue, 976 set_current_state(TASK_INTERRUPTIBLE);
1009 dvb_ca_en50221_thread_should_wakeup(ca), 977 schedule_timeout(ca->delay);
1010 ca->delay); 978 if (kthread_should_stop())
1011 if ((flags == -ERESTARTSYS) || ca->exit) { 979 return 0;
1012 /* got signal or quitting */
1013 break;
1014 }
1015 } 980 }
1016 ca->wakeup = 0; 981 ca->wakeup = 0;
1017 982
@@ -1180,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data)
1180 } 1145 }
1181 } 1146 }
1182 1147
1183 /* completed */
1184 ca->thread_pid = 0;
1185 mb();
1186 wake_up_interruptible(&ca->thread_queue);
1187 return 0; 1148 return 0;
1188} 1149}
1189 1150
@@ -1683,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1683 goto error; 1644 goto error;
1684 } 1645 }
1685 init_waitqueue_head(&ca->wait_queue); 1646 init_waitqueue_head(&ca->wait_queue);
1686 ca->thread_pid = 0;
1687 init_waitqueue_head(&ca->thread_queue);
1688 ca->exit = 0;
1689 ca->open = 0; 1647 ca->open = 0;
1690 ca->wakeup = 0; 1648 ca->wakeup = 0;
1691 ca->next_read_slot = 0; 1649 ca->next_read_slot = 0;
@@ -1711,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
1711 mb(); 1669 mb();
1712 1670
1713 /* create a kthread for monitoring this CA device */ 1671 /* create a kthread for monitoring this CA device */
1714 1672 ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
1715 ret = kernel_thread(dvb_ca_en50221_thread, ca, 0); 1673 ca->dvbdev->adapter->num, ca->dvbdev->id);
1716 1674 if (IS_ERR(ca->thread)) {
1717 if (ret < 0) { 1675 ret = PTR_ERR(ca->thread);
1718 printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret); 1676 printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
1677 ret);
1719 goto error; 1678 goto error;
1720 } 1679 }
1721 ca->thread_pid = ret;
1722 return 0; 1680 return 0;
1723 1681
1724error: 1682error:
@@ -1749,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
1749 dprintk("%s\n", __FUNCTION__); 1707 dprintk("%s\n", __FUNCTION__);
1750 1708
1751 /* shutdown the thread if there was one */ 1709 /* shutdown the thread if there was one */
1752 if (ca->thread_pid) { 1710 kthread_stop(ca->thread);
1753 if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
1754 printk("dvb_ca_release adapter %d: thread PID %d already died\n",
1755 ca->dvbdev->adapter->num, ca->thread_pid);
1756 } else {
1757 ca->exit = 1;
1758 mb();
1759 dvb_ca_en50221_thread_wakeup(ca);
1760 wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
1761 }
1762 }
1763 1711
1764 for (i = 0; i < ca->slot_count; i++) { 1712 for (i = 0; i < ca->slot_count; i++) {
1765 dvb_ca_en50221_slot_shutdown(ca, i); 1713 dvb_ca_en50221_slot_shutdown(ca, i);