diff options
author | Christoph Hellwig <hch@infradead.org> | 2007-10-03 10:23:01 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 23:03:08 -0400 |
commit | 9320874a3e6aea7044a4a7eedeab13db990424ab (patch) | |
tree | ed60c3726ca646a3b486bb29bde02f4adec8f310 | |
parent | d00cd2985e0e796621adf0f782af1563d990b0b5 (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>
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 84 |
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 | */ | ||
912 | static 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) | |||
981 | static int dvb_ca_en50221_thread(void *data) | 958 | static 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(¤t->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 | ||
1724 | error: | 1682 | error: |
@@ -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); |