diff options
48 files changed, 38 insertions, 1495 deletions
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 0759c98f8e1c..86991f657900 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig | |||
@@ -13,13 +13,6 @@ config COMEDI_DEBUG | |||
13 | This is an option for use by developers; most people should | 13 | This is an option for use by developers; most people should |
14 | say N here. This enables comedi core and driver debugging. | 14 | say N here. This enables comedi core and driver debugging. |
15 | 15 | ||
16 | config COMEDI_RT | ||
17 | tristate "Comedi Real-time support" | ||
18 | depends on COMEDI && RT | ||
19 | default N | ||
20 | ---help--- | ||
21 | Enable Real time support for the Comedi core. | ||
22 | |||
23 | config COMEDI_PCI_DRIVERS | 16 | config COMEDI_PCI_DRIVERS |
24 | tristate "Comedi PCI drivers" | 17 | tristate "Comedi PCI drivers" |
25 | depends on COMEDI && PCI | 18 | depends on COMEDI && PCI |
diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index afd1a19c1b87..05811f79d85b 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile | |||
@@ -1,5 +1,4 @@ | |||
1 | obj-$(CONFIG_COMEDI) += comedi.o | 1 | obj-$(CONFIG_COMEDI) += comedi.o |
2 | obj-$(CONFIG_COMEDI_RT) += comedi_rt.o | ||
3 | 2 | ||
4 | obj-$(CONFIG_COMEDI) += kcomedilib/ | 3 | obj-$(CONFIG_COMEDI) += kcomedilib/ |
5 | obj-$(CONFIG_COMEDI) += drivers/ | 4 | obj-$(CONFIG_COMEDI) += drivers/ |
@@ -11,7 +10,3 @@ comedi-objs := \ | |||
11 | drivers.o \ | 10 | drivers.o \ |
12 | comedi_compat32.o \ | 11 | comedi_compat32.o \ |
13 | comedi_ksyms.o \ | 12 | comedi_ksyms.o \ |
14 | |||
15 | comedi_rt-objs := \ | ||
16 | rt_pend_tq.o \ | ||
17 | rt.o | ||
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9713fc746561..61b586477c10 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
@@ -1079,13 +1079,6 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) | |||
1079 | 1079 | ||
1080 | comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING); | 1080 | comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING); |
1081 | 1081 | ||
1082 | #ifdef CONFIG_COMEDI_RT | ||
1083 | if (async->cmd.flags & TRIG_RT) { | ||
1084 | if (comedi_switch_to_rt(dev) == 0) | ||
1085 | comedi_set_subdevice_runflags(s, SRF_RT, SRF_RT); | ||
1086 | } | ||
1087 | #endif | ||
1088 | |||
1089 | ret = s->do_cmd(dev, s); | 1082 | ret = s->do_cmd(dev, s); |
1090 | if (ret == 0) | 1083 | if (ret == 0) |
1091 | return 0; | 1084 | return 0; |
@@ -1720,12 +1713,6 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) | |||
1720 | struct comedi_async *async = s->async; | 1713 | struct comedi_async *async = s->async; |
1721 | 1714 | ||
1722 | comedi_set_subdevice_runflags(s, SRF_RUNNING, 0); | 1715 | comedi_set_subdevice_runflags(s, SRF_RUNNING, 0); |
1723 | #ifdef CONFIG_COMEDI_RT | ||
1724 | if (comedi_get_subdevice_runflags(s) & SRF_RT) { | ||
1725 | comedi_switch_to_non_rt(dev); | ||
1726 | comedi_set_subdevice_runflags(s, SRF_RT, 0); | ||
1727 | } | ||
1728 | #endif | ||
1729 | if (async) { | 1716 | if (async) { |
1730 | comedi_reset_async_buf(async); | 1717 | comedi_reset_async_buf(async); |
1731 | async->inttrig = NULL; | 1718 | async->inttrig = NULL; |
@@ -1952,8 +1939,6 @@ static int __init comedi_init(void) | |||
1952 | } | 1939 | } |
1953 | } | 1940 | } |
1954 | 1941 | ||
1955 | comedi_rt_init(); | ||
1956 | |||
1957 | comedi_register_ioctl32(); | 1942 | comedi_register_ioctl32(); |
1958 | 1943 | ||
1959 | return 0; | 1944 | return 0; |
@@ -1974,8 +1959,6 @@ static void __exit comedi_cleanup(void) | |||
1974 | 1959 | ||
1975 | comedi_proc_cleanup(); | 1960 | comedi_proc_cleanup(); |
1976 | 1961 | ||
1977 | comedi_rt_cleanup(); | ||
1978 | |||
1979 | comedi_unregister_ioctl32(); | 1962 | comedi_unregister_ioctl32(); |
1980 | } | 1963 | } |
1981 | 1964 | ||
@@ -2015,15 +1998,8 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) | |||
2015 | 1998 | ||
2016 | if (async->cb_mask & s->async->events) { | 1999 | if (async->cb_mask & s->async->events) { |
2017 | if (comedi_get_subdevice_runflags(s) & SRF_USER) { | 2000 | if (comedi_get_subdevice_runflags(s) & SRF_USER) { |
2018 | |||
2019 | if (dev->rt) { | 2001 | if (dev->rt) { |
2020 | #ifdef CONFIG_COMEDI_RT | 2002 | printk("BUG: comedi_event() code unreachable\n"); |
2021 | /* pend wake up */ | ||
2022 | comedi_rt_pend_wakeup(&async->wait_head); | ||
2023 | #else | ||
2024 | printk | ||
2025 | ("BUG: comedi_event() code unreachable\n"); | ||
2026 | #endif | ||
2027 | } else { | 2003 | } else { |
2028 | wake_up_interruptible(&async->wait_head); | 2004 | wake_up_interruptible(&async->wait_head); |
2029 | if (s->subdev_flags & SDF_CMD_READ) { | 2005 | if (s->subdev_flags & SDF_CMD_READ) { |
diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c index 6e6fb979ef54..a732e342dcd2 100644 --- a/drivers/staging/comedi/comedi_ksyms.c +++ b/drivers/staging/comedi/comedi_ksyms.c | |||
@@ -46,13 +46,6 @@ EXPORT_SYMBOL(range_bipolar2_5); | |||
46 | EXPORT_SYMBOL(range_unipolar10); | 46 | EXPORT_SYMBOL(range_unipolar10); |
47 | EXPORT_SYMBOL(range_unipolar5); | 47 | EXPORT_SYMBOL(range_unipolar5); |
48 | EXPORT_SYMBOL(range_unknown); | 48 | EXPORT_SYMBOL(range_unknown); |
49 | #ifdef CONFIG_COMEDI_RT | ||
50 | EXPORT_SYMBOL(comedi_free_irq); | ||
51 | EXPORT_SYMBOL(comedi_request_irq); | ||
52 | EXPORT_SYMBOL(comedi_switch_to_rt); | ||
53 | EXPORT_SYMBOL(comedi_switch_to_non_rt); | ||
54 | EXPORT_SYMBOL(rt_pend_call); | ||
55 | #endif | ||
56 | #ifdef CONFIG_COMEDI_DEBUG | 49 | #ifdef CONFIG_COMEDI_DEBUG |
57 | EXPORT_SYMBOL(comedi_debug); | 50 | EXPORT_SYMBOL(comedi_debug); |
58 | #endif | 51 | #endif |
diff --git a/drivers/staging/comedi/comedi_rt.h b/drivers/staging/comedi/comedi_rt.h deleted file mode 100644 index cddd5406abfc..000000000000 --- a/drivers/staging/comedi/comedi_rt.h +++ /dev/null | |||
@@ -1,150 +0,0 @@ | |||
1 | /* | ||
2 | module/comedi_rt.h | ||
3 | header file for real-time structures, variables, and constants | ||
4 | |||
5 | COMEDI - Linux Control and Measurement Device Interface | ||
6 | Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | |||
22 | */ | ||
23 | |||
24 | #ifndef _COMEDI_RT_H | ||
25 | #define _COMEDI_RT_H | ||
26 | |||
27 | #ifndef _COMEDIDEV_H | ||
28 | #error comedi_rt.h should only be included by comedidev.h | ||
29 | #endif | ||
30 | |||
31 | #include <linux/kdev_t.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/spinlock.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | |||
38 | #ifdef CONFIG_COMEDI_RT | ||
39 | |||
40 | #ifdef CONFIG_COMEDI_RTAI | ||
41 | #include <rtai.h> | ||
42 | #include <rtai_sched.h> | ||
43 | #include <rtai_version.h> | ||
44 | #endif | ||
45 | #ifdef CONFIG_COMEDI_RTL | ||
46 | #include <rtl_core.h> | ||
47 | #include <rtl_time.h> | ||
48 | /* #ifdef RTLINUX_VERSION_CODE */ | ||
49 | #include <rtl_sync.h> | ||
50 | /* #endif */ | ||
51 | #define rt_printk rtl_printf | ||
52 | #endif | ||
53 | #ifdef CONFIG_COMEDI_FUSION | ||
54 | #define rt_printk(format, args...) printk(format , ## args) | ||
55 | #endif /* CONFIG_COMEDI_FUSION */ | ||
56 | #ifdef CONFIG_PRIORITY_IRQ | ||
57 | #define rt_printk printk | ||
58 | #endif | ||
59 | |||
60 | int comedi_request_irq(unsigned int irq, irq_handler_t handler, | ||
61 | unsigned long flags, const char *device, | ||
62 | struct comedi_device *dev_id); | ||
63 | void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id); | ||
64 | void comedi_rt_init(void); | ||
65 | void comedi_rt_cleanup(void); | ||
66 | int comedi_switch_to_rt(struct comedi_device *dev); | ||
67 | void comedi_switch_to_non_rt(struct comedi_device *dev); | ||
68 | void comedi_rt_pend_wakeup(wait_queue_head_t *q); | ||
69 | extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, | ||
70 | void *arg2); | ||
71 | |||
72 | #else | ||
73 | |||
74 | #define comedi_request_irq(a, b, c, d, e) request_irq(a, b, c, d, e) | ||
75 | #define comedi_free_irq(a, b) free_irq(a, b) | ||
76 | #define comedi_rt_init() do {} while (0) | ||
77 | #define comedi_rt_cleanup() do {} while (0) | ||
78 | #define comedi_switch_to_rt(a) (-1) | ||
79 | #define comedi_switch_to_non_rt(a) do {} while (0) | ||
80 | #define comedi_rt_pend_wakeup(a) do {} while (0) | ||
81 | |||
82 | #define rt_printk(format, args...) printk(format, ##args) | ||
83 | |||
84 | #endif | ||
85 | |||
86 | /* Define a spin_lock_irqsave function that will work with rt or without. | ||
87 | * Use inline functions instead of just macros to enforce some type checking. | ||
88 | */ | ||
89 | #define comedi_spin_lock_irqsave(lock_ptr, flags) \ | ||
90 | (flags = __comedi_spin_lock_irqsave(lock_ptr)) | ||
91 | |||
92 | static inline unsigned long __comedi_spin_lock_irqsave(spinlock_t *lock_ptr) | ||
93 | { | ||
94 | unsigned long flags; | ||
95 | |||
96 | #if defined(CONFIG_COMEDI_RTAI) | ||
97 | flags = rt_spin_lock_irqsave(lock_ptr); | ||
98 | |||
99 | #elif defined(CONFIG_COMEDI_RTL) | ||
100 | rtl_spin_lock_irqsave(lock_ptr, flags); | ||
101 | |||
102 | #elif defined(CONFIG_COMEDI_RTL_V1) | ||
103 | rtl_spin_lock_irqsave(lock_ptr, flags); | ||
104 | |||
105 | #elif defined(CONFIG_COMEDI_FUSION) | ||
106 | rthal_spin_lock_irqsave(lock_ptr, flags); | ||
107 | #else | ||
108 | spin_lock_irqsave(lock_ptr, flags); | ||
109 | |||
110 | #endif | ||
111 | |||
112 | return flags; | ||
113 | } | ||
114 | |||
115 | static inline void comedi_spin_unlock_irqrestore(spinlock_t *lock_ptr, | ||
116 | unsigned long flags) | ||
117 | { | ||
118 | |||
119 | #if defined(CONFIG_COMEDI_RTAI) | ||
120 | rt_spin_unlock_irqrestore(flags, lock_ptr); | ||
121 | |||
122 | #elif defined(CONFIG_COMEDI_RTL) | ||
123 | rtl_spin_unlock_irqrestore(lock_ptr, flags); | ||
124 | |||
125 | #elif defined(CONFIG_COMEDI_RTL_V1) | ||
126 | rtl_spin_unlock_irqrestore(lock_ptr, flags); | ||
127 | #elif defined(CONFIG_COMEDI_FUSION) | ||
128 | rthal_spin_unlock_irqrestore(lock_ptr, flags); | ||
129 | #else | ||
130 | spin_unlock_irqrestore(lock_ptr, flags); | ||
131 | |||
132 | #endif | ||
133 | |||
134 | } | ||
135 | |||
136 | /* define a RT safe udelay */ | ||
137 | static inline void comedi_udelay(unsigned int usec) | ||
138 | { | ||
139 | #if defined(CONFIG_COMEDI_RTAI) | ||
140 | static const int nanosec_per_usec = 1000; | ||
141 | rt_busy_sleep(usec * nanosec_per_usec); | ||
142 | #elif defined(CONFIG_COMEDI_RTL) | ||
143 | static const int nanosec_per_usec = 1000; | ||
144 | rtl_delay(usec * nanosec_per_usec); | ||
145 | #else | ||
146 | udelay(usec); | ||
147 | #endif | ||
148 | } | ||
149 | |||
150 | #endif | ||
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 753d3ab312c0..0bfb58cb2936 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h | |||
@@ -523,8 +523,6 @@ struct usb_device; /* forward declaration */ | |||
523 | int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); | 523 | int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); |
524 | void comedi_usb_auto_unconfig(struct usb_device *usbdev); | 524 | void comedi_usb_auto_unconfig(struct usb_device *usbdev); |
525 | 525 | ||
526 | #include "comedi_rt.h" | ||
527 | |||
528 | #ifdef CONFIG_COMEDI_PCI_DRIVERS | 526 | #ifdef CONFIG_COMEDI_PCI_DRIVERS |
529 | #define CONFIG_COMEDI_PCI | 527 | #define CONFIG_COMEDI_PCI |
530 | #endif | 528 | #endif |
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 7b064d5df6ff..7af245b42e51 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c | |||
@@ -31,6 +31,7 @@ Status: experimental | |||
31 | 31 | ||
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/interrupt.h> | ||
34 | #include "../comedidev.h" | 35 | #include "../comedidev.h" |
35 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
36 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index c69ec5d51e76..57d250c73abc 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c | |||
@@ -43,6 +43,7 @@ See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more | |||
43 | #include "../comedidev.h" | 43 | #include "../comedidev.h" |
44 | 44 | ||
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/interrupt.h> | ||
46 | 47 | ||
47 | #include "comedi_pci.h" | 48 | #include "comedi_pci.h" |
48 | #include "plx9052.h" | 49 | #include "plx9052.h" |
diff --git a/drivers/staging/comedi/drivers/comedi_rt_timer.c b/drivers/staging/comedi/drivers/comedi_rt_timer.c deleted file mode 100644 index 0453a983571c..000000000000 --- a/drivers/staging/comedi/drivers/comedi_rt_timer.c +++ /dev/null | |||
@@ -1,756 +0,0 @@ | |||
1 | /* | ||
2 | comedi/drivers/comedi_rt_timer.c | ||
3 | virtual driver for using RTL timing sources | ||
4 | |||
5 | Authors: David A. Schleef, Frank M. Hess | ||
6 | |||
7 | COMEDI - Linux Control and Measurement Device Interface | ||
8 | Copyright (C) 1999,2001 David A. Schleef <ds@schleef.org> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | |||
24 | ************************************************************************** | ||
25 | */ | ||
26 | /* | ||
27 | Driver: comedi_rt_timer | ||
28 | Description: Command emulator using real-time tasks | ||
29 | Author: ds, fmhess | ||
30 | Devices: | ||
31 | Status: works | ||
32 | |||
33 | This driver requires RTAI or RTLinux to work correctly. It doesn't | ||
34 | actually drive hardware directly, but calls other drivers and uses | ||
35 | a real-time task to emulate commands for drivers and devices that | ||
36 | are incapable of native commands. Thus, you can get accurately | ||
37 | timed I/O on any device. | ||
38 | |||
39 | Since the timing is all done in software, sampling jitter is much | ||
40 | higher than with a device that has an on-board timer, and maximum | ||
41 | sample rate is much lower. | ||
42 | |||
43 | Configuration options: | ||
44 | [0] - minor number of device you wish to emulate commands for | ||
45 | [1] - subdevice number you wish to emulate commands for | ||
46 | */ | ||
47 | /* | ||
48 | TODO: | ||
49 | Support for digital io commands could be added, except I can't see why | ||
50 | anyone would want to use them | ||
51 | What happens if device we are emulating for is de-configured? | ||
52 | */ | ||
53 | |||
54 | #include "../comedidev.h" | ||
55 | #include "../comedilib.h" | ||
56 | |||
57 | #include "comedi_fc.h" | ||
58 | |||
59 | #ifdef CONFIG_COMEDI_RTL_V1 | ||
60 | #include <rtl_sched.h> | ||
61 | #include <asm/rt_irq.h> | ||
62 | #endif | ||
63 | #ifdef CONFIG_COMEDI_RTL | ||
64 | #include <rtl.h> | ||
65 | #include <rtl_sched.h> | ||
66 | #include <rtl_compat.h> | ||
67 | #include <asm/div64.h> | ||
68 | |||
69 | #ifndef RTLINUX_VERSION_CODE | ||
70 | #define RTLINUX_VERSION_CODE 0 | ||
71 | #endif | ||
72 | #ifndef RTLINUX_VERSION | ||
73 | #define RTLINUX_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) | ||
74 | #endif | ||
75 | |||
76 | /* begin hack to workaround broken HRT_TO_8254() function on rtlinux */ | ||
77 | #if RTLINUX_VERSION_CODE <= RTLINUX_VERSION(3, 0, 100) | ||
78 | /* this function sole purpose is to divide a long long by 838 */ | ||
79 | static inline RTIME nano2count(long long ns) | ||
80 | { | ||
81 | do_div(ns, 838); | ||
82 | return ns; | ||
83 | } | ||
84 | |||
85 | #ifdef rt_get_time() | ||
86 | #undef rt_get_time() | ||
87 | #endif | ||
88 | #define rt_get_time() nano2count(gethrtime()) | ||
89 | |||
90 | #else | ||
91 | |||
92 | #define nano2count(x) HRT_TO_8254(x) | ||
93 | #endif | ||
94 | /* end hack */ | ||
95 | |||
96 | /* rtl-rtai compatibility */ | ||
97 | #define rt_task_wait_period() rt_task_wait() | ||
98 | #define rt_pend_linux_srq(irq) rtl_global_pend_irq(irq) | ||
99 | #define rt_free_srq(irq) rtl_free_soft_irq(irq) | ||
100 | #define rt_request_srq(x, y, z) rtl_get_soft_irq(y, "timer") | ||
101 | #define rt_task_init(a, b, c, d, e, f, g) rt_task_init(a, b, c, d, (e)+1) | ||
102 | #define rt_task_resume(x) rt_task_wakeup(x) | ||
103 | #define rt_set_oneshot_mode() | ||
104 | #define start_rt_timer(x) | ||
105 | #define stop_rt_timer() | ||
106 | |||
107 | #define comedi_rt_task_context_t int | ||
108 | |||
109 | #endif | ||
110 | #ifdef CONFIG_COMEDI_RTAI | ||
111 | #include <rtai.h> | ||
112 | #include <rtai_sched.h> | ||
113 | #include <rtai_version.h> | ||
114 | |||
115 | /* RTAI_VERSION_CODE doesn't work for rtai-3.6-cv and other strange versions. | ||
116 | * These are characterized by CONFIG_RTAI_REVISION_LEVEL being defined as an | ||
117 | * empty macro and CONFIG_RTAI_VERSION_MINOR being defined as something like | ||
118 | * '6-cv' or '7-test1'. The problem has been noted by the RTAI folks and they | ||
119 | * promise not to do it again. :-) Try and work around it here. */ | ||
120 | #if !(CONFIG_RTAI_REVISION_LEVEL + 0) | ||
121 | #undef CONFIG_RTAI_REVISION_LEVEL | ||
122 | #define CONFIG_RTAI_REVISION_LEVEL 0 | ||
123 | #define cv 0 | ||
124 | #define test1 0 | ||
125 | #define test2 0 | ||
126 | #define test3 0 | ||
127 | #endif | ||
128 | |||
129 | #if RTAI_VERSION_CODE < RTAI_MANGLE_VERSION(3, 3, 0) | ||
130 | #define comedi_rt_task_context_t int | ||
131 | #else | ||
132 | #define comedi_rt_task_context_t long | ||
133 | #endif | ||
134 | |||
135 | /* Finished checking RTAI_VERSION_CODE. */ | ||
136 | #undef cv | ||
137 | #undef test1 | ||
138 | #undef test2 | ||
139 | #undef test3 | ||
140 | |||
141 | #endif | ||
142 | |||
143 | /* This defines the fastest speed we will emulate. Note that | ||
144 | * without a watchdog (like in RTAI), we could easily overrun our | ||
145 | * task period because analog input tends to be slow. */ | ||
146 | #define SPEED_LIMIT 100000 /* in nanoseconds */ | ||
147 | |||
148 | static int timer_attach(struct comedi_device *dev, struct comedi_devconfig *it); | ||
149 | static int timer_detach(struct comedi_device *dev); | ||
150 | static int timer_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, | ||
151 | unsigned int trig_num); | ||
152 | static int timer_start_cmd(struct comedi_device *dev, struct comedi_subdevice *s); | ||
153 | |||
154 | static struct comedi_driver driver_timer = { | ||
155 | .module = THIS_MODULE, | ||
156 | .driver_name = "comedi_rt_timer", | ||
157 | .attach = timer_attach, | ||
158 | .detach = timer_detach, | ||
159 | /* .open = timer_open, */ | ||
160 | }; | ||
161 | |||
162 | COMEDI_INITCLEANUP(driver_timer); | ||
163 | |||
164 | struct timer_private { | ||
165 | comedi_t *device; /* device we are emulating commands for */ | ||
166 | int subd; /* subdevice we are emulating commands for */ | ||
167 | RT_TASK *rt_task; /* rt task that starts scans */ | ||
168 | RT_TASK *scan_task; /* rt task that controls conversion timing in a scan */ | ||
169 | /* io_function can point to either an input or output function | ||
170 | * depending on what kind of subdevice we are emulating for */ | ||
171 | int (*io_function) (struct comedi_device *dev, struct comedi_cmd *cmd, | ||
172 | unsigned int index); | ||
173 | /* | ||
174 | * RTIME has units of 1 = 838 nanoseconds time at which first scan | ||
175 | * started, used to check scan timing | ||
176 | */ | ||
177 | RTIME start; | ||
178 | /* time between scans */ | ||
179 | RTIME scan_period; | ||
180 | /* time between conversions in a scan */ | ||
181 | RTIME convert_period; | ||
182 | /* flags */ | ||
183 | volatile int stop; /* indicates we should stop */ | ||
184 | volatile int rt_task_active; /* indicates rt_task is servicing a struct comedi_cmd */ | ||
185 | volatile int scan_task_active; /* indicates scan_task is servicing a struct comedi_cmd */ | ||
186 | unsigned timer_running:1; | ||
187 | }; | ||
188 | #define devpriv ((struct timer_private *)dev->private) | ||
189 | |||
190 | static int timer_cancel(struct comedi_device *dev, struct comedi_subdevice *s) | ||
191 | { | ||
192 | devpriv->stop = 1; | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | /* checks for scan timing error */ | ||
198 | inline static int check_scan_timing(struct comedi_device *dev, | ||
199 | unsigned long long scan) | ||
200 | { | ||
201 | RTIME now, timing_error; | ||
202 | |||
203 | now = rt_get_time(); | ||
204 | timing_error = now - (devpriv->start + scan * devpriv->scan_period); | ||
205 | if (timing_error > devpriv->scan_period) { | ||
206 | comedi_error(dev, "timing error"); | ||
207 | printk("scan started %i ns late\n", timing_error * 838); | ||
208 | return -1; | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /* checks for conversion timing error */ | ||
215 | inline static int check_conversion_timing(struct comedi_device *dev, | ||
216 | RTIME scan_start, unsigned int conversion) | ||
217 | { | ||
218 | RTIME now, timing_error; | ||
219 | |||
220 | now = rt_get_time(); | ||
221 | timing_error = | ||
222 | now - (scan_start + conversion * devpriv->convert_period); | ||
223 | if (timing_error > devpriv->convert_period) { | ||
224 | comedi_error(dev, "timing error"); | ||
225 | printk("conversion started %i ns late\n", | ||
226 | timing_error * 838); | ||
227 | return -1; | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | /* devpriv->io_function for an input subdevice */ | ||
234 | static int timer_data_read(struct comedi_device *dev, struct comedi_cmd *cmd, | ||
235 | unsigned int index) | ||
236 | { | ||
237 | struct comedi_subdevice *s = dev->read_subdev; | ||
238 | int ret; | ||
239 | unsigned int data; | ||
240 | |||
241 | ret = comedi_data_read(devpriv->device, devpriv->subd, | ||
242 | CR_CHAN(cmd->chanlist[index]), | ||
243 | CR_RANGE(cmd->chanlist[index]), | ||
244 | CR_AREF(cmd->chanlist[index]), &data); | ||
245 | if (ret < 0) { | ||
246 | comedi_error(dev, "read error"); | ||
247 | return -EIO; | ||
248 | } | ||
249 | if (s->flags & SDF_LSAMPL) { | ||
250 | cfc_write_long_to_buffer(s, data); | ||
251 | } else { | ||
252 | comedi_buf_put(s->async, data); | ||
253 | } | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | /* devpriv->io_function for an output subdevice */ | ||
259 | static int timer_data_write(struct comedi_device *dev, struct comedi_cmd *cmd, | ||
260 | unsigned int index) | ||
261 | { | ||
262 | struct comedi_subdevice *s = dev->write_subdev; | ||
263 | unsigned int num_bytes; | ||
264 | short data; | ||
265 | unsigned int long_data; | ||
266 | int ret; | ||
267 | |||
268 | if (s->flags & SDF_LSAMPL) { | ||
269 | num_bytes = | ||
270 | cfc_read_array_from_buffer(s, &long_data, | ||
271 | sizeof(long_data)); | ||
272 | } else { | ||
273 | num_bytes = cfc_read_array_from_buffer(s, &data, sizeof(data)); | ||
274 | long_data = data; | ||
275 | } | ||
276 | |||
277 | if (num_bytes == 0) { | ||
278 | comedi_error(dev, "buffer underrun"); | ||
279 | return -EAGAIN; | ||
280 | } | ||
281 | ret = comedi_data_write(devpriv->device, devpriv->subd, | ||
282 | CR_CHAN(cmd->chanlist[index]), | ||
283 | CR_RANGE(cmd->chanlist[index]), | ||
284 | CR_AREF(cmd->chanlist[index]), long_data); | ||
285 | if (ret < 0) { | ||
286 | comedi_error(dev, "write error"); | ||
287 | return -EIO; | ||
288 | } | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* devpriv->io_function for DIO subdevices */ | ||
294 | static int timer_dio_read(struct comedi_device *dev, struct comedi_cmd *cmd, | ||
295 | unsigned int index) | ||
296 | { | ||
297 | struct comedi_subdevice *s = dev->read_subdev; | ||
298 | int ret; | ||
299 | unsigned int data; | ||
300 | |||
301 | ret = comedi_dio_bitfield(devpriv->device, devpriv->subd, 0, &data); | ||
302 | if (ret < 0) { | ||
303 | comedi_error(dev, "read error"); | ||
304 | return -EIO; | ||
305 | } | ||
306 | |||
307 | if (s->flags & SDF_LSAMPL) | ||
308 | cfc_write_long_to_buffer(s, data); | ||
309 | else | ||
310 | cfc_write_to_buffer(s, data); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | /* performs scans */ | ||
316 | static void scan_task_func(comedi_rt_task_context_t d) | ||
317 | { | ||
318 | struct comedi_device *dev = (struct comedi_device *) d; | ||
319 | struct comedi_subdevice *s = dev->subdevices + 0; | ||
320 | struct comedi_async *async = s->async; | ||
321 | struct comedi_cmd *cmd = &async->cmd; | ||
322 | int i, ret; | ||
323 | unsigned long long n; | ||
324 | RTIME scan_start; | ||
325 | |||
326 | /* every struct comedi_cmd causes one execution of while loop */ | ||
327 | while (1) { | ||
328 | devpriv->scan_task_active = 1; | ||
329 | /* each for loop completes one scan */ | ||
330 | for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE; | ||
331 | n++) { | ||
332 | if (n) { | ||
333 | /* suspend task until next scan */ | ||
334 | ret = rt_task_suspend(devpriv->scan_task); | ||
335 | if (ret < 0) { | ||
336 | comedi_error(dev, | ||
337 | "error suspending scan task"); | ||
338 | async->events |= COMEDI_CB_ERROR; | ||
339 | goto cleanup; | ||
340 | } | ||
341 | } | ||
342 | /* check if stop flag was set (by timer_cancel()) */ | ||
343 | if (devpriv->stop) | ||
344 | goto cleanup; | ||
345 | ret = check_scan_timing(dev, n); | ||
346 | if (ret < 0) { | ||
347 | async->events |= COMEDI_CB_ERROR; | ||
348 | goto cleanup; | ||
349 | } | ||
350 | scan_start = rt_get_time(); | ||
351 | for (i = 0; i < cmd->scan_end_arg; i++) { | ||
352 | /* conversion timing */ | ||
353 | if (cmd->convert_src == TRIG_TIMER && i) { | ||
354 | rt_task_wait_period(); | ||
355 | ret = check_conversion_timing(dev, | ||
356 | scan_start, i); | ||
357 | if (ret < 0) { | ||
358 | async->events |= | ||
359 | COMEDI_CB_ERROR; | ||
360 | goto cleanup; | ||
361 | } | ||
362 | } | ||
363 | ret = devpriv->io_function(dev, cmd, i); | ||
364 | if (ret < 0) { | ||
365 | async->events |= COMEDI_CB_ERROR; | ||
366 | goto cleanup; | ||
367 | } | ||
368 | } | ||
369 | s->async->events |= COMEDI_CB_BLOCK; | ||
370 | comedi_event(dev, s); | ||
371 | s->async->events = 0; | ||
372 | } | ||
373 | |||
374 | cleanup: | ||
375 | |||
376 | comedi_unlock(devpriv->device, devpriv->subd); | ||
377 | async->events |= COMEDI_CB_EOA; | ||
378 | comedi_event(dev, s); | ||
379 | async->events = 0; | ||
380 | devpriv->scan_task_active = 0; | ||
381 | /* suspend task until next struct comedi_cmd */ | ||
382 | rt_task_suspend(devpriv->scan_task); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | static void timer_task_func(comedi_rt_task_context_t d) | ||
387 | { | ||
388 | struct comedi_device *dev = (struct comedi_device *) d; | ||
389 | struct comedi_subdevice *s = dev->subdevices + 0; | ||
390 | struct comedi_cmd *cmd = &s->async->cmd; | ||
391 | int ret; | ||
392 | unsigned long long n; | ||
393 | |||
394 | /* every struct comedi_cmd causes one execution of while loop */ | ||
395 | while (1) { | ||
396 | devpriv->rt_task_active = 1; | ||
397 | devpriv->scan_task_active = 1; | ||
398 | devpriv->start = rt_get_time(); | ||
399 | |||
400 | for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE; | ||
401 | n++) { | ||
402 | /* scan timing */ | ||
403 | if (n) | ||
404 | rt_task_wait_period(); | ||
405 | if (devpriv->scan_task_active == 0) { | ||
406 | goto cleanup; | ||
407 | } | ||
408 | ret = rt_task_make_periodic(devpriv->scan_task, | ||
409 | devpriv->start + devpriv->scan_period * n, | ||
410 | devpriv->convert_period); | ||
411 | if (ret < 0) { | ||
412 | comedi_error(dev, "bug!"); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | cleanup: | ||
417 | |||
418 | devpriv->rt_task_active = 0; | ||
419 | /* suspend until next struct comedi_cmd */ | ||
420 | rt_task_suspend(devpriv->rt_task); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | static int timer_insn(struct comedi_device *dev, struct comedi_subdevice *s, | ||
425 | struct comedi_insn *insn, unsigned int *data) | ||
426 | { | ||
427 | struct comedi_insn xinsn = *insn; | ||
428 | |||
429 | xinsn.data = data; | ||
430 | xinsn.subdev = devpriv->subd; | ||
431 | |||
432 | return comedi_do_insn(devpriv->device, &xinsn); | ||
433 | } | ||
434 | |||
435 | static int cmdtest_helper(struct comedi_cmd *cmd, | ||
436 | unsigned int start_src, | ||
437 | unsigned int scan_begin_src, | ||
438 | unsigned int convert_src, | ||
439 | unsigned int scan_end_src, unsigned int stop_src) | ||
440 | { | ||
441 | int err = 0; | ||
442 | int tmp; | ||
443 | |||
444 | tmp = cmd->start_src; | ||
445 | cmd->start_src &= start_src; | ||
446 | if (!cmd->start_src || tmp != cmd->start_src) | ||
447 | err++; | ||
448 | |||
449 | tmp = cmd->scan_begin_src; | ||
450 | cmd->scan_begin_src &= scan_begin_src; | ||
451 | if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) | ||
452 | err++; | ||
453 | |||
454 | tmp = cmd->convert_src; | ||
455 | cmd->convert_src &= convert_src; | ||
456 | if (!cmd->convert_src || tmp != cmd->convert_src) | ||
457 | err++; | ||
458 | |||
459 | tmp = cmd->scan_end_src; | ||
460 | cmd->scan_end_src &= scan_end_src; | ||
461 | if (!cmd->scan_end_src || tmp != cmd->scan_end_src) | ||
462 | err++; | ||
463 | |||
464 | tmp = cmd->stop_src; | ||
465 | cmd->stop_src &= stop_src; | ||
466 | if (!cmd->stop_src || tmp != cmd->stop_src) | ||
467 | err++; | ||
468 | |||
469 | return err; | ||
470 | } | ||
471 | |||
472 | static int timer_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, | ||
473 | struct comedi_cmd *cmd) | ||
474 | { | ||
475 | int err = 0; | ||
476 | unsigned int start_src = 0; | ||
477 | |||
478 | if (s->type == COMEDI_SUBD_AO) | ||
479 | start_src = TRIG_INT; | ||
480 | else | ||
481 | start_src = TRIG_NOW; | ||
482 | |||
483 | err = cmdtest_helper(cmd, start_src, /* start_src */ | ||
484 | TRIG_TIMER | TRIG_FOLLOW, /* scan_begin_src */ | ||
485 | TRIG_NOW | TRIG_TIMER, /* convert_src */ | ||
486 | TRIG_COUNT, /* scan_end_src */ | ||
487 | TRIG_COUNT | TRIG_NONE); /* stop_src */ | ||
488 | if (err) | ||
489 | return 1; | ||
490 | |||
491 | /* step 2: make sure trigger sources are unique and mutually | ||
492 | * compatible */ | ||
493 | |||
494 | if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT) | ||
495 | err++; | ||
496 | if (cmd->scan_begin_src != TRIG_TIMER && | ||
497 | cmd->scan_begin_src != TRIG_FOLLOW) | ||
498 | err++; | ||
499 | if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_NOW) | ||
500 | err++; | ||
501 | if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) | ||
502 | err++; | ||
503 | if (cmd->scan_begin_src == TRIG_FOLLOW | ||
504 | && cmd->convert_src != TRIG_TIMER) | ||
505 | err++; | ||
506 | if (cmd->convert_src == TRIG_NOW && cmd->scan_begin_src != TRIG_TIMER) | ||
507 | err++; | ||
508 | |||
509 | if (err) | ||
510 | return 2; | ||
511 | |||
512 | /* step 3: make sure arguments are trivially compatible */ | ||
513 | /* limit frequency, this is fairly arbitrary */ | ||
514 | if (cmd->scan_begin_src == TRIG_TIMER) { | ||
515 | if (cmd->scan_begin_arg < SPEED_LIMIT) { | ||
516 | cmd->scan_begin_arg = SPEED_LIMIT; | ||
517 | err++; | ||
518 | } | ||
519 | } | ||
520 | if (cmd->convert_src == TRIG_TIMER) { | ||
521 | if (cmd->convert_arg < SPEED_LIMIT) { | ||
522 | cmd->convert_arg = SPEED_LIMIT; | ||
523 | err++; | ||
524 | } | ||
525 | } | ||
526 | /* make sure conversion and scan frequencies are compatible */ | ||
527 | if (cmd->convert_src == TRIG_TIMER && cmd->scan_begin_src == TRIG_TIMER) { | ||
528 | if (cmd->convert_arg * cmd->scan_end_arg > cmd->scan_begin_arg) { | ||
529 | cmd->scan_begin_arg = | ||
530 | cmd->convert_arg * cmd->scan_end_arg; | ||
531 | err++; | ||
532 | } | ||
533 | } | ||
534 | if (err) | ||
535 | return 3; | ||
536 | |||
537 | /* step 4: fix up and arguments */ | ||
538 | if (err) | ||
539 | return 4; | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static int timer_cmd(struct comedi_device *dev, struct comedi_subdevice *s) | ||
545 | { | ||
546 | int ret; | ||
547 | struct comedi_cmd *cmd = &s->async->cmd; | ||
548 | |||
549 | /* hack attack: drivers are not supposed to do this: */ | ||
550 | dev->rt = 1; | ||
551 | |||
552 | /* make sure tasks have finished cleanup of last struct comedi_cmd */ | ||
553 | if (devpriv->rt_task_active || devpriv->scan_task_active) | ||
554 | return -EBUSY; | ||
555 | |||
556 | ret = comedi_lock(devpriv->device, devpriv->subd); | ||
557 | if (ret < 0) { | ||
558 | comedi_error(dev, "failed to obtain lock"); | ||
559 | return ret; | ||
560 | } | ||
561 | switch (cmd->scan_begin_src) { | ||
562 | case TRIG_TIMER: | ||
563 | devpriv->scan_period = nano2count(cmd->scan_begin_arg); | ||
564 | break; | ||
565 | case TRIG_FOLLOW: | ||
566 | devpriv->scan_period = | ||
567 | nano2count(cmd->convert_arg * cmd->scan_end_arg); | ||
568 | break; | ||
569 | default: | ||
570 | comedi_error(dev, "bug setting scan period!"); | ||
571 | return -1; | ||
572 | break; | ||
573 | } | ||
574 | switch (cmd->convert_src) { | ||
575 | case TRIG_TIMER: | ||
576 | devpriv->convert_period = nano2count(cmd->convert_arg); | ||
577 | break; | ||
578 | case TRIG_NOW: | ||
579 | devpriv->convert_period = 1; | ||
580 | break; | ||
581 | default: | ||
582 | comedi_error(dev, "bug setting conversion period!"); | ||
583 | return -1; | ||
584 | break; | ||
585 | } | ||
586 | |||
587 | if (cmd->start_src == TRIG_NOW) | ||
588 | return timer_start_cmd(dev, s); | ||
589 | |||
590 | s->async->inttrig = timer_inttrig; | ||
591 | |||
592 | return 0; | ||
593 | } | ||
594 | |||
595 | static int timer_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, | ||
596 | unsigned int trig_num) | ||
597 | { | ||
598 | if (trig_num != 0) | ||
599 | return -EINVAL; | ||
600 | |||
601 | s->async->inttrig = NULL; | ||
602 | |||
603 | return timer_start_cmd(dev, s); | ||
604 | } | ||
605 | |||
606 | static int timer_start_cmd(struct comedi_device *dev, struct comedi_subdevice *s) | ||
607 | { | ||
608 | struct comedi_async *async = s->async; | ||
609 | struct comedi_cmd *cmd = &async->cmd; | ||
610 | RTIME now, delay, period; | ||
611 | int ret; | ||
612 | |||
613 | devpriv->stop = 0; | ||
614 | s->async->events = 0; | ||
615 | |||
616 | if (cmd->start_src == TRIG_NOW) | ||
617 | delay = nano2count(cmd->start_arg); | ||
618 | else | ||
619 | delay = 0; | ||
620 | |||
621 | now = rt_get_time(); | ||
622 | /* Using 'period' this way gets around some weird bug in gcc-2.95.2 | ||
623 | * that generates the compile error 'internal error--unrecognizable insn' | ||
624 | * when rt_task_make_period() is called (observed with rtlinux-3.1, linux-2.2.19). | ||
625 | * - fmhess */ | ||
626 | period = devpriv->scan_period; | ||
627 | ret = rt_task_make_periodic(devpriv->rt_task, now + delay, period); | ||
628 | if (ret < 0) { | ||
629 | comedi_error(dev, "error starting rt_task"); | ||
630 | return ret; | ||
631 | } | ||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int timer_attach(struct comedi_device *dev, struct comedi_devconfig *it) | ||
636 | { | ||
637 | int ret; | ||
638 | struct comedi_subdevice *s, *emul_s; | ||
639 | struct comedi_device *emul_dev; | ||
640 | /* These should probably be devconfig options[] */ | ||
641 | const int timer_priority = 4; | ||
642 | const int scan_priority = timer_priority + 1; | ||
643 | char path[20]; | ||
644 | |||
645 | printk("comedi%d: timer: ", dev->minor); | ||
646 | |||
647 | dev->board_name = "timer"; | ||
648 | |||
649 | ret = alloc_subdevices(dev, 1); | ||
650 | if (ret < 0) | ||
651 | return ret; | ||
652 | |||
653 | ret = alloc_private(dev, sizeof(struct timer_private)); | ||
654 | if (ret < 0) | ||
655 | return ret; | ||
656 | |||
657 | sprintf(path, "/dev/comedi%d", it->options[0]); | ||
658 | devpriv->device = comedi_open(path); | ||
659 | devpriv->subd = it->options[1]; | ||
660 | |||
661 | printk("emulating commands for minor %i, subdevice %d\n", | ||
662 | it->options[0], devpriv->subd); | ||
663 | |||
664 | emul_dev = devpriv->device; | ||
665 | emul_s = emul_dev->subdevices + devpriv->subd; | ||
666 | |||
667 | /* input or output subdevice */ | ||
668 | s = dev->subdevices + 0; | ||
669 | s->type = emul_s->type; | ||
670 | s->subdev_flags = emul_s->subdev_flags; /* SDF_GROUND (to fool check_driver) */ | ||
671 | s->n_chan = emul_s->n_chan; | ||
672 | s->len_chanlist = 1024; | ||
673 | s->do_cmd = timer_cmd; | ||
674 | s->do_cmdtest = timer_cmdtest; | ||
675 | s->cancel = timer_cancel; | ||
676 | s->maxdata = emul_s->maxdata; | ||
677 | s->range_table = emul_s->range_table; | ||
678 | s->range_table_list = emul_s->range_table_list; | ||
679 | switch (emul_s->type) { | ||
680 | case COMEDI_SUBD_AI: | ||
681 | s->insn_read = timer_insn; | ||
682 | dev->read_subdev = s; | ||
683 | s->subdev_flags |= SDF_CMD_READ; | ||
684 | devpriv->io_function = timer_data_read; | ||
685 | break; | ||
686 | case COMEDI_SUBD_AO: | ||
687 | s->insn_write = timer_insn; | ||
688 | s->insn_read = timer_insn; | ||
689 | dev->write_subdev = s; | ||
690 | s->subdev_flags |= SDF_CMD_WRITE; | ||
691 | devpriv->io_function = timer_data_write; | ||
692 | break; | ||
693 | case COMEDI_SUBD_DIO: | ||
694 | s->insn_write = timer_insn; | ||
695 | s->insn_read = timer_insn; | ||
696 | s->insn_bits = timer_insn; | ||
697 | dev->read_subdev = s; | ||
698 | s->subdev_flags |= SDF_CMD_READ; | ||
699 | devpriv->io_function = timer_dio_read; | ||
700 | break; | ||
701 | default: | ||
702 | comedi_error(dev, "failed to determine subdevice type!"); | ||
703 | return -EINVAL; | ||
704 | } | ||
705 | |||
706 | rt_set_oneshot_mode(); | ||
707 | start_rt_timer(1); | ||
708 | devpriv->timer_running = 1; | ||
709 | |||
710 | devpriv->rt_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL); | ||
711 | |||
712 | /* initialize real-time tasks */ | ||
713 | ret = rt_task_init(devpriv->rt_task, timer_task_func, | ||
714 | (comedi_rt_task_context_t) dev, 3000, timer_priority, 0, 0); | ||
715 | if (ret < 0) { | ||
716 | comedi_error(dev, "error initalizing rt_task"); | ||
717 | kfree(devpriv->rt_task); | ||
718 | devpriv->rt_task = 0; | ||
719 | return ret; | ||
720 | } | ||
721 | |||
722 | devpriv->scan_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL); | ||
723 | |||
724 | ret = rt_task_init(devpriv->scan_task, scan_task_func, | ||
725 | (comedi_rt_task_context_t) dev, 3000, scan_priority, 0, 0); | ||
726 | if (ret < 0) { | ||
727 | comedi_error(dev, "error initalizing scan_task"); | ||
728 | kfree(devpriv->scan_task); | ||
729 | devpriv->scan_task = 0; | ||
730 | return ret; | ||
731 | } | ||
732 | |||
733 | return 1; | ||
734 | } | ||
735 | |||
736 | /* free allocated resources */ | ||
737 | static int timer_detach(struct comedi_device *dev) | ||
738 | { | ||
739 | printk("comedi%d: timer: remove\n", dev->minor); | ||
740 | |||
741 | if (devpriv) { | ||
742 | if (devpriv->rt_task) { | ||
743 | rt_task_delete(devpriv->rt_task); | ||
744 | kfree(devpriv->rt_task); | ||
745 | } | ||
746 | if (devpriv->scan_task) { | ||
747 | rt_task_delete(devpriv->scan_task); | ||
748 | kfree(devpriv->scan_task); | ||
749 | } | ||
750 | if (devpriv->timer_running) | ||
751 | stop_rt_timer(); | ||
752 | if (devpriv->device) | ||
753 | comedi_close(devpriv->device); | ||
754 | } | ||
755 | return 0; | ||
756 | } | ||
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index ff0ca2c51ce6..d4526c616a99 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c | |||
@@ -119,6 +119,7 @@ Configuration options: | |||
119 | #include "../comedidev.h" | 119 | #include "../comedidev.h" |
120 | 120 | ||
121 | #include <linux/delay.h> | 121 | #include <linux/delay.h> |
122 | #include <linux/interrupt.h> | ||
122 | 123 | ||
123 | #include "comedi_pci.h" | 124 | #include "comedi_pci.h" |
124 | #include "8255.h" | 125 | #include "8255.h" |
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index c0fbb8516730..59af86a8bbfb 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c | |||
@@ -79,6 +79,7 @@ Computer boards manuals also available from their website www.measurementcomputi | |||
79 | */ | 79 | */ |
80 | 80 | ||
81 | #include <linux/pci.h> | 81 | #include <linux/pci.h> |
82 | #include <linux/interrupt.h> | ||
82 | #include <asm/dma.h> | 83 | #include <asm/dma.h> |
83 | #include "../comedidev.h" | 84 | #include "../comedidev.h" |
84 | 85 | ||
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index a0e405fc4c67..3da8bf47cbf6 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c | |||
@@ -59,6 +59,7 @@ irq can be omitted, although the cmd interface will not work without it. | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include <linux/ioport.h> | 61 | #include <linux/ioport.h> |
62 | #include <linux/interrupt.h> | ||
62 | #include "../comedidev.h" | 63 | #include "../comedidev.h" |
63 | 64 | ||
64 | #include "8255.h" | 65 | #include "8255.h" |
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 5d67d2359add..a3434088c9e6 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c | |||
@@ -100,6 +100,7 @@ TODO: | |||
100 | read insn for analog out | 100 | read insn for analog out |
101 | */ | 101 | */ |
102 | 102 | ||
103 | #include <linux/interrupt.h> | ||
103 | #include "../comedidev.h" | 104 | #include "../comedidev.h" |
104 | 105 | ||
105 | #include <linux/ioport.h> | 106 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 37611ef80f5f..0114eb935305 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c | |||
@@ -38,6 +38,7 @@ Devices: [Keithley Metrabyte] DAS6402 (das6402) | |||
38 | This driver has suffered bitrot. | 38 | This driver has suffered bitrot. |
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include <linux/interrupt.h> | ||
41 | #include "../comedidev.h" | 42 | #include "../comedidev.h" |
42 | 43 | ||
43 | #include <linux/ioport.h> | 44 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index ef64a20d836b..70e9d699c7a3 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c | |||
@@ -62,6 +62,7 @@ cmd triggers supported: | |||
62 | 62 | ||
63 | */ | 63 | */ |
64 | 64 | ||
65 | #include <linux/interrupt.h> | ||
65 | #include "../comedidev.h" | 66 | #include "../comedidev.h" |
66 | 67 | ||
67 | #include <linux/ioport.h> | 68 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 5a53c61ddbdf..573cbe72b20b 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c | |||
@@ -74,6 +74,7 @@ Configuration Options: | |||
74 | * options that are used with comedi_config. | 74 | * options that are used with comedi_config. |
75 | */ | 75 | */ |
76 | 76 | ||
77 | #include <linux/interrupt.h> | ||
77 | #include "../comedidev.h" | 78 | #include "../comedidev.h" |
78 | #include <linux/ioport.h> | 79 | #include <linux/ioport.h> |
79 | 80 | ||
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index a112324fc45d..7853902be621 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c | |||
@@ -45,6 +45,7 @@ Configuration options: | |||
45 | [4] - D/A 1 range (same choices) | 45 | [4] - D/A 1 range (same choices) |
46 | */ | 46 | */ |
47 | 47 | ||
48 | #include <linux/interrupt.h> | ||
48 | #include "../comedidev.h" | 49 | #include "../comedidev.h" |
49 | 50 | ||
50 | #include <linux/ioport.h> | 51 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index c639d7415ce7..5906ddddf65c 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c | |||
@@ -39,6 +39,7 @@ a power of 10, from 1 to 10^7, of which only 3 or 4 are useful. In | |||
39 | addition, the clock does not seem to be very accurate. | 39 | addition, the clock does not seem to be very accurate. |
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include <linux/interrupt.h> | ||
42 | #include "../comedidev.h" | 43 | #include "../comedidev.h" |
43 | 44 | ||
44 | #include <linux/ioport.h> | 45 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 6ece082583c9..2af8b59f9061 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c | |||
@@ -59,6 +59,7 @@ AO commands are not supported. | |||
59 | 59 | ||
60 | #define DEBUG 1 | 60 | #define DEBUG 1 |
61 | 61 | ||
62 | #include <linux/interrupt.h> | ||
62 | #include "../comedidev.h" | 63 | #include "../comedidev.h" |
63 | #include <linux/delay.h> | 64 | #include <linux/delay.h> |
64 | 65 | ||
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index dedd0df37549..b156ae717ae4 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c | |||
@@ -45,6 +45,7 @@ support could be added to this driver. | |||
45 | 45 | ||
46 | */ | 46 | */ |
47 | 47 | ||
48 | #include <linux/interrupt.h> | ||
48 | #include "../comedidev.h" | 49 | #include "../comedidev.h" |
49 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
50 | 51 | ||
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 4cfdfc55b6ed..984f995149b6 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c | |||
@@ -50,6 +50,7 @@ Options: | |||
50 | [1] - PCI slot number | 50 | [1] - PCI slot number |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #include <linux/interrupt.h> | ||
53 | #include "../comedidev.h" | 54 | #include "../comedidev.h" |
54 | 55 | ||
55 | #include <linux/delay.h> | 56 | #include <linux/delay.h> |
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index bf7833011a4c..236845871735 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c | |||
@@ -51,6 +51,7 @@ broken. | |||
51 | 51 | ||
52 | */ | 52 | */ |
53 | 53 | ||
54 | #include <linux/interrupt.h> | ||
54 | #include "../comedidev.h" | 55 | #include "../comedidev.h" |
55 | 56 | ||
56 | #include <linux/delay.h> | 57 | #include <linux/delay.h> |
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 0f023d009e61..f21cecaa2e09 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c | |||
@@ -50,6 +50,7 @@ from http://www.comedi.org | |||
50 | 50 | ||
51 | */ | 51 | */ |
52 | 52 | ||
53 | #include <linux/interrupt.h> | ||
53 | #include "../comedidev.h" | 54 | #include "../comedidev.h" |
54 | 55 | ||
55 | #include "comedi_pci.h" | 56 | #include "comedi_pci.h" |
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index b3412241633a..f7cce6cc7766 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c | |||
@@ -29,6 +29,7 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3) | |||
29 | 29 | ||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include <linux/interrupt.h> | ||
32 | #include "../comedidev.h" | 33 | #include "../comedidev.h" |
33 | 34 | ||
34 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 491bdf22cd3e..67adc97265bd 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c | |||
@@ -41,6 +41,7 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800 | |||
41 | #define DEBUG 1 | 41 | #define DEBUG 1 |
42 | #define DEBUG_FLAGS | 42 | #define DEBUG_FLAGS |
43 | 43 | ||
44 | #include <linux/interrupt.h> | ||
44 | #include "../comedidev.h" | 45 | #include "../comedidev.h" |
45 | 46 | ||
46 | #include "mite.h" | 47 | #include "mite.h" |
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 8c3cbf9f0e11..35708503dec3 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c | |||
@@ -50,6 +50,7 @@ except maybe the 6514. | |||
50 | #define _GNU_SOURCE | 50 | #define _GNU_SOURCE |
51 | #define DEBUG 1 | 51 | #define DEBUG 1 |
52 | #define DEBUG_FLAGS | 52 | #define DEBUG_FLAGS |
53 | #include <linux/interrupt.h> | ||
53 | #include "../comedidev.h" | 54 | #include "../comedidev.h" |
54 | 55 | ||
55 | #include "mite.h" | 56 | #include "mite.h" |
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 68a6ec8fd1a0..11e9b0411805 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c | |||
@@ -40,6 +40,7 @@ DAQ 6601/6602 User Manual (NI 322137B-01) | |||
40 | 40 | ||
41 | */ | 41 | */ |
42 | 42 | ||
43 | #include <linux/interrupt.h> | ||
43 | #include "../comedidev.h" | 44 | #include "../comedidev.h" |
44 | #include "mite.h" | 45 | #include "mite.h" |
45 | #include "ni_tio.h" | 46 | #include "ni_tio.h" |
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 7bb22919eb8f..71f7d3ab3aa1 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c | |||
@@ -41,6 +41,7 @@ Commands are not supported. | |||
41 | 41 | ||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/interrupt.h> | ||
44 | #include "../comedidev.h" | 45 | #include "../comedidev.h" |
45 | 46 | ||
46 | #include "mite.h" | 47 | #include "mite.h" |
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 4f348b77bb4a..45c6809031db 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c | |||
@@ -64,6 +64,7 @@ TRIG_WAKE_EOS | |||
64 | 64 | ||
65 | */ | 65 | */ |
66 | 66 | ||
67 | #include <linux/interrupt.h> | ||
67 | #include "../comedidev.h" | 68 | #include "../comedidev.h" |
68 | 69 | ||
69 | #include <linux/ioport.h> | 70 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index c39d388c90f2..8839447538f2 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c | |||
@@ -93,6 +93,7 @@ are not supported. | |||
93 | 93 | ||
94 | */ | 94 | */ |
95 | 95 | ||
96 | #include <linux/interrupt.h> | ||
96 | #include "../comedidev.h" | 97 | #include "../comedidev.h" |
97 | 98 | ||
98 | #include <linux/delay.h> | 99 | #include <linux/delay.h> |
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 67034380af3a..1a8c2ab20d3d 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c | |||
@@ -35,6 +35,7 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d) | |||
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include <linux/interrupt.h> | ||
38 | #include "../comedidev.h" | 39 | #include "../comedidev.h" |
39 | 40 | ||
40 | #include <linux/ioport.h> | 41 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 6a69d36018e0..e34948205320 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c | |||
@@ -41,6 +41,7 @@ emu as port A output, port B input, port C N/A). | |||
41 | IRQ is assigned but not used. | 41 | IRQ is assigned but not used. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/interrupt.h> | ||
44 | #include "../comedidev.h" | 45 | #include "../comedidev.h" |
45 | 46 | ||
46 | #include <linux/ioport.h> | 47 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 7f378e529d0f..a8ac02febc66 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c | |||
@@ -40,6 +40,7 @@ the PCMCIA interface. | |||
40 | /* #define LABPC_DEBUG */ /* enable debugging messages */ | 40 | /* #define LABPC_DEBUG */ /* enable debugging messages */ |
41 | #undef LABPC_DEBUG | 41 | #undef LABPC_DEBUG |
42 | 42 | ||
43 | #include <linux/interrupt.h> | ||
43 | #include "../comedidev.h" | 44 | #include "../comedidev.h" |
44 | 45 | ||
45 | #include <linux/ioport.h> | 46 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 435e34a838aa..30e11f46a640 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c | |||
@@ -76,6 +76,7 @@ NI manuals: | |||
76 | #undef LABPC_DEBUG | 76 | #undef LABPC_DEBUG |
77 | /* #define LABPC_DEBUG enable debugging messages */ | 77 | /* #define LABPC_DEBUG enable debugging messages */ |
78 | 78 | ||
79 | #include <linux/interrupt.h> | ||
79 | #include "../comedidev.h" | 80 | #include "../comedidev.h" |
80 | 81 | ||
81 | #include <linux/delay.h> | 82 | #include <linux/delay.h> |
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 476f30a13d16..d727d7533fc8 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c | |||
@@ -61,6 +61,7 @@ | |||
61 | /* #define DEBUG_STATUS_A */ | 61 | /* #define DEBUG_STATUS_A */ |
62 | /* #define DEBUG_STATUS_B */ | 62 | /* #define DEBUG_STATUS_B */ |
63 | 63 | ||
64 | #include <linux/interrupt.h> | ||
64 | #include "8255.h" | 65 | #include "8255.h" |
65 | #include "mite.h" | 66 | #include "mite.h" |
66 | #include "comedi_fc.h" | 67 | #include "comedi_fc.h" |
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index cbc203fd066f..6b86a39aac5e 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c | |||
@@ -69,6 +69,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org | |||
69 | /* #define DEBUG 1 */ | 69 | /* #define DEBUG 1 */ |
70 | /* #define DEBUG_FLAGS */ | 70 | /* #define DEBUG_FLAGS */ |
71 | 71 | ||
72 | #include <linux/interrupt.h> | ||
72 | #include "../comedidev.h" | 73 | #include "../comedidev.h" |
73 | 74 | ||
74 | #include "mite.h" | 75 | #include "mite.h" |
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 01faaf95d199..7b72b7af75c8 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c | |||
@@ -58,6 +58,7 @@ supported. | |||
58 | 58 | ||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include <linux/interrupt.h> | ||
61 | #include "../comedidev.h" | 62 | #include "../comedidev.h" |
62 | 63 | ||
63 | #include <linux/ioport.h> | 64 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 46fad0393e31..dd91fe9f5f51 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c | |||
@@ -107,6 +107,7 @@ Options for ACL-8113, ISO-813: | |||
107 | 3= 20V unipolar inputs | 107 | 3= 20V unipolar inputs |
108 | */ | 108 | */ |
109 | 109 | ||
110 | #include <linux/interrupt.h> | ||
110 | #include "../comedidev.h" | 111 | #include "../comedidev.h" |
111 | 112 | ||
112 | #include <linux/delay.h> | 113 | #include <linux/delay.h> |
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 14f40df298eb..9bb26699f47e 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c | |||
@@ -41,6 +41,7 @@ Configuration options: | |||
41 | 1 = two's complement | 41 | 1 = two's complement |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/interrupt.h> | ||
44 | #include "../comedidev.h" | 45 | #include "../comedidev.h" |
45 | 46 | ||
46 | #include <linux/ioport.h> | 47 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 55a2d1d0408d..6931f1075089 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c | |||
@@ -73,6 +73,7 @@ Configuration Options: | |||
73 | [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature) | 73 | [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature) |
74 | */ | 74 | */ |
75 | 75 | ||
76 | #include <linux/interrupt.h> | ||
76 | #include "../comedidev.h" | 77 | #include "../comedidev.h" |
77 | #include <linux/pci.h> /* for PCI devices */ | 78 | #include <linux/pci.h> /* for PCI devices */ |
78 | 79 | ||
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 291b6d963fd9..8df67c37795b 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c | |||
@@ -75,6 +75,7 @@ Configuration Options: | |||
75 | [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!) | 75 | [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!) |
76 | */ | 76 | */ |
77 | 77 | ||
78 | #include <linux/interrupt.h> | ||
78 | #include "../comedidev.h" | 79 | #include "../comedidev.h" |
79 | 80 | ||
80 | #include <linux/pci.h> /* for PCI devices */ | 81 | #include <linux/pci.h> /* for PCI devices */ |
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 3536ec5fbfce..243ee76c836d 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c | |||
@@ -101,6 +101,7 @@ Configuration options: | |||
101 | 101 | ||
102 | */ | 102 | */ |
103 | 103 | ||
104 | #include <linux/interrupt.h> | ||
104 | #include <linux/delay.h> | 105 | #include <linux/delay.h> |
105 | 106 | ||
106 | #include "../comedidev.h" | 107 | #include "../comedidev.h" |
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 46b5e3fb6742..f1b7e0252f13 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c | |||
@@ -52,6 +52,7 @@ Configuration options: | |||
52 | [8] - DAC 1 encoding (same as DAC 0) | 52 | [8] - DAC 1 encoding (same as DAC 0) |
53 | */ | 53 | */ |
54 | 54 | ||
55 | #include <linux/interrupt.h> | ||
55 | #include "../comedidev.h" | 56 | #include "../comedidev.h" |
56 | 57 | ||
57 | #include <linux/ioport.h> | 58 | #include <linux/ioport.h> |
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index bebc12bf3891..92121cf8c45c 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c | |||
@@ -68,6 +68,7 @@ INSN_CONFIG instructions: | |||
68 | comedi_do_insn(cf,&insn); //executing configuration | 68 | comedi_do_insn(cf,&insn); //executing configuration |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #include <linux/interrupt.h> | ||
71 | #include <linux/kernel.h> | 72 | #include <linux/kernel.h> |
72 | #include <linux/types.h> | 73 | #include <linux/types.h> |
73 | 74 | ||
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 95f0dde8d3e6..b39ea7c50b87 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c | |||
@@ -150,10 +150,6 @@ int comedi_command(void *d, struct comedi_cmd *cmd) | |||
150 | 150 | ||
151 | runflags = SRF_RUNNING; | 151 | runflags = SRF_RUNNING; |
152 | 152 | ||
153 | #ifdef CONFIG_COMEDI_RT | ||
154 | if (comedi_switch_to_rt(dev) == 0) | ||
155 | runflags |= SRF_RT; | ||
156 | #endif | ||
157 | comedi_set_subdevice_runflags(s, ~0, runflags); | 153 | comedi_set_subdevice_runflags(s, ~0, runflags); |
158 | 154 | ||
159 | comedi_reset_async_buf(async); | 155 | comedi_reset_async_buf(async); |
@@ -449,11 +445,6 @@ int comedi_cancel(void *d, unsigned int subdevice) | |||
449 | if (ret) | 445 | if (ret) |
450 | return ret; | 446 | return ret; |
451 | 447 | ||
452 | #ifdef CONFIG_COMEDI_RT | ||
453 | if (comedi_get_subdevice_runflags(s) & SRF_RT) | ||
454 | comedi_switch_to_non_rt(dev); | ||
455 | |||
456 | #endif | ||
457 | comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0); | 448 | comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0); |
458 | s->async->inttrig = NULL; | 449 | s->async->inttrig = NULL; |
459 | s->busy = NULL; | 450 | s->busy = NULL; |
diff --git a/drivers/staging/comedi/rt.c b/drivers/staging/comedi/rt.c deleted file mode 100644 index ace360d4a492..000000000000 --- a/drivers/staging/comedi/rt.c +++ /dev/null | |||
@@ -1,411 +0,0 @@ | |||
1 | /* | ||
2 | comedi/rt.c | ||
3 | comedi kernel module | ||
4 | |||
5 | COMEDI - Linux Control and Measurement Device Interface | ||
6 | Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | |||
22 | */ | ||
23 | |||
24 | #undef DEBUG | ||
25 | |||
26 | #define __NO_VERSION__ | ||
27 | #include <linux/comedidev.h> | ||
28 | |||
29 | #include <linux/errno.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/fcntl.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/ioport.h> | ||
36 | #include <linux/mm.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #include "rt_pend_tq.h" | ||
41 | |||
42 | #ifdef CONFIG_COMEDI_RTAI | ||
43 | #include <rtai.h> | ||
44 | #endif | ||
45 | |||
46 | #ifdef CONFIG_COMEDI_FUSION | ||
47 | #include <nucleus/asm/hal.h> | ||
48 | #endif | ||
49 | |||
50 | #ifdef CONFIG_COMEDI_RTL | ||
51 | #include <rtl_core.h> | ||
52 | #include <rtl_sync.h> | ||
53 | #endif | ||
54 | |||
55 | struct comedi_irq_struct { | ||
56 | int rt; | ||
57 | int irq; | ||
58 | irq_handler_t handler; | ||
59 | unsigned long flags; | ||
60 | const char *device; | ||
61 | struct comedi_device *dev_id; | ||
62 | }; | ||
63 | |||
64 | static int comedi_rt_get_irq(struct comedi_irq_struct *it); | ||
65 | static int comedi_rt_release_irq(struct comedi_irq_struct *it); | ||
66 | |||
67 | static struct comedi_irq_struct *comedi_irqs[NR_IRQS]; | ||
68 | |||
69 | int comedi_request_irq(unsigned irq, irq_handler_t handler, unsigned long flags, | ||
70 | const char *device, struct comedi_device *dev_id) | ||
71 | { | ||
72 | struct comedi_irq_struct *it; | ||
73 | int ret; | ||
74 | /* null shared interrupt flag, since rt interrupt handlers do not | ||
75 | * support it, and this version of comedi_request_irq() is only | ||
76 | * called for kernels with rt support */ | ||
77 | unsigned long unshared_flags = flags & ~IRQF_SHARED; | ||
78 | |||
79 | ret = request_irq(irq, handler, unshared_flags, device, dev_id); | ||
80 | if (ret < 0) { | ||
81 | /* we failed, so fall back on allowing shared interrupt (which we won't ever make RT) */ | ||
82 | if (flags & IRQF_SHARED) { | ||
83 | rt_printk | ||
84 | ("comedi: cannot get unshared interrupt, will not use RT interrupts.\n"); | ||
85 | ret = request_irq(irq, handler, flags, device, dev_id); | ||
86 | } | ||
87 | if (ret < 0) | ||
88 | return ret; | ||
89 | |||
90 | } else { | ||
91 | it = kzalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL); | ||
92 | if (!it) | ||
93 | return -ENOMEM; | ||
94 | |||
95 | it->handler = handler; | ||
96 | it->irq = irq; | ||
97 | it->dev_id = dev_id; | ||
98 | it->device = device; | ||
99 | it->flags = unshared_flags; | ||
100 | comedi_irqs[irq] = it; | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id) | ||
106 | { | ||
107 | struct comedi_irq_struct *it; | ||
108 | |||
109 | free_irq(irq, dev_id); | ||
110 | |||
111 | it = comedi_irqs[irq]; | ||
112 | if (it == NULL) | ||
113 | return; | ||
114 | |||
115 | if (it->rt) { | ||
116 | printk("real-time IRQ allocated at board removal (ignore)\n"); | ||
117 | comedi_rt_release_irq(it); | ||
118 | } | ||
119 | |||
120 | kfree(it); | ||
121 | comedi_irqs[irq] = NULL; | ||
122 | } | ||
123 | |||
124 | int comedi_switch_to_rt(struct comedi_device *dev) | ||
125 | { | ||
126 | struct comedi_irq_struct *it; | ||
127 | unsigned long flags; | ||
128 | |||
129 | it = comedi_irqs[dev->irq]; | ||
130 | /* drivers might not be using an interrupt for commands, | ||
131 | or we might not have been able to get an unshared irq */ | ||
132 | if (it == NULL) | ||
133 | return -1; | ||
134 | |||
135 | comedi_spin_lock_irqsave(&dev->spinlock, flags); | ||
136 | |||
137 | if (!dev->rt) | ||
138 | comedi_rt_get_irq(it); | ||
139 | |||
140 | dev->rt++; | ||
141 | it->rt = 1; | ||
142 | |||
143 | comedi_spin_unlock_irqrestore(&dev->spinlock, flags); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | void comedi_switch_to_non_rt(struct comedi_device *dev) | ||
149 | { | ||
150 | struct comedi_irq_struct *it; | ||
151 | unsigned long flags; | ||
152 | |||
153 | it = comedi_irqs[dev->irq]; | ||
154 | if (it == NULL) | ||
155 | return; | ||
156 | |||
157 | comedi_spin_lock_irqsave(&dev->spinlock, flags); | ||
158 | |||
159 | dev->rt--; | ||
160 | if (!dev->rt) | ||
161 | comedi_rt_release_irq(it); | ||
162 | |||
163 | it->rt = 0; | ||
164 | |||
165 | comedi_spin_unlock_irqrestore(&dev->spinlock, flags); | ||
166 | } | ||
167 | |||
168 | void wake_up_int_handler(int arg1, void *arg2) | ||
169 | { | ||
170 | wake_up_interruptible((wait_queue_head_t *) arg2); | ||
171 | } | ||
172 | |||
173 | void comedi_rt_pend_wakeup(wait_queue_head_t *q) | ||
174 | { | ||
175 | rt_pend_call(wake_up_int_handler, 0, q); | ||
176 | } | ||
177 | |||
178 | /* RTAI section */ | ||
179 | #ifdef CONFIG_COMEDI_RTAI | ||
180 | |||
181 | #ifndef HAVE_RT_REQUEST_IRQ_WITH_ARG | ||
182 | #define DECLARE_VOID_IRQ(irq) \ | ||
183 | static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); } | ||
184 | |||
185 | static void handle_void_irq(int irq) | ||
186 | { | ||
187 | struct comedi_irq_struct *it; | ||
188 | |||
189 | it = comedi_irqs[irq]; | ||
190 | if (it == NULL) { | ||
191 | rt_printk("comedi: null irq struct?\n"); | ||
192 | return; | ||
193 | } | ||
194 | it->handler(irq, it->dev_id); | ||
195 | rt_enable_irq(irq); /* needed by rtai-adeos, seems like it shouldn't hurt earlier versions */ | ||
196 | } | ||
197 | |||
198 | DECLARE_VOID_IRQ(0); | ||
199 | DECLARE_VOID_IRQ(1); | ||
200 | DECLARE_VOID_IRQ(2); | ||
201 | DECLARE_VOID_IRQ(3); | ||
202 | DECLARE_VOID_IRQ(4); | ||
203 | DECLARE_VOID_IRQ(5); | ||
204 | DECLARE_VOID_IRQ(6); | ||
205 | DECLARE_VOID_IRQ(7); | ||
206 | DECLARE_VOID_IRQ(8); | ||
207 | DECLARE_VOID_IRQ(9); | ||
208 | DECLARE_VOID_IRQ(10); | ||
209 | DECLARE_VOID_IRQ(11); | ||
210 | DECLARE_VOID_IRQ(12); | ||
211 | DECLARE_VOID_IRQ(13); | ||
212 | DECLARE_VOID_IRQ(14); | ||
213 | DECLARE_VOID_IRQ(15); | ||
214 | DECLARE_VOID_IRQ(16); | ||
215 | DECLARE_VOID_IRQ(17); | ||
216 | DECLARE_VOID_IRQ(18); | ||
217 | DECLARE_VOID_IRQ(19); | ||
218 | DECLARE_VOID_IRQ(20); | ||
219 | DECLARE_VOID_IRQ(21); | ||
220 | DECLARE_VOID_IRQ(22); | ||
221 | DECLARE_VOID_IRQ(23); | ||
222 | |||
223 | static void handle_void_irq_ptrs[] = { | ||
224 | handle_void_irq_0, | ||
225 | handle_void_irq_1, | ||
226 | handle_void_irq_2, | ||
227 | handle_void_irq_3, | ||
228 | handle_void_irq_4, | ||
229 | handle_void_irq_5, | ||
230 | handle_void_irq_6, | ||
231 | handle_void_irq_7, | ||
232 | handle_void_irq_8, | ||
233 | handle_void_irq_9, | ||
234 | handle_void_irq_10, | ||
235 | handle_void_irq_11, | ||
236 | handle_void_irq_12, | ||
237 | handle_void_irq_13, | ||
238 | handle_void_irq_14, | ||
239 | handle_void_irq_15, | ||
240 | handle_void_irq_16, | ||
241 | handle_void_irq_17, | ||
242 | handle_void_irq_18, | ||
243 | handle_void_irq_19, | ||
244 | handle_void_irq_20, | ||
245 | handle_void_irq_21, | ||
246 | handle_void_irq_22, | ||
247 | handle_void_irq_23, | ||
248 | }; | ||
249 | |||
250 | static int comedi_rt_get_irq(struct comedi_irq_struct *it) | ||
251 | { | ||
252 | rt_request_global_irq(it->irq, handle_void_irq_ptrs[it->irq]); | ||
253 | rt_startup_irq(it->irq); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int comedi_rt_release_irq(struct comedi_irq_struct *it) | ||
259 | { | ||
260 | rt_shutdown_irq(it->irq); | ||
261 | rt_free_global_irq(it->irq); | ||
262 | return 0; | ||
263 | } | ||
264 | #else | ||
265 | |||
266 | static int comedi_rt_get_irq(struct comedi_irq_struct *it) | ||
267 | { | ||
268 | int ret; | ||
269 | |||
270 | ret = rt_request_global_irq_arg(it->irq, it->handler, it->flags, | ||
271 | it->device, it->dev_id); | ||
272 | if (ret < 0) { | ||
273 | rt_printk("rt_request_global_irq_arg() returned %d\n", ret); | ||
274 | return ret; | ||
275 | } | ||
276 | rt_startup_irq(it->irq); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int comedi_rt_release_irq(struct comedi_irq_struct *it) | ||
282 | { | ||
283 | rt_shutdown_irq(it->irq); | ||
284 | rt_free_global_irq(it->irq); | ||
285 | return 0; | ||
286 | } | ||
287 | #endif | ||
288 | |||
289 | void comedi_rt_init(void) | ||
290 | { | ||
291 | rt_mount_rtai(); | ||
292 | rt_pend_tq_init(); | ||
293 | } | ||
294 | |||
295 | void comedi_rt_cleanup(void) | ||
296 | { | ||
297 | rt_umount_rtai(); | ||
298 | rt_pend_tq_cleanup(); | ||
299 | } | ||
300 | |||
301 | #endif | ||
302 | |||
303 | /* Fusion section */ | ||
304 | #ifdef CONFIG_COMEDI_FUSION | ||
305 | |||
306 | static void fusion_handle_irq(unsigned int irq, void *cookie) | ||
307 | { | ||
308 | struct comedi_irq_struct *it = cookie; | ||
309 | |||
310 | it->handler(irq, it->dev_id); | ||
311 | rthal_irq_enable(irq); | ||
312 | } | ||
313 | |||
314 | static int comedi_rt_get_irq(struct comedi_irq_struct *it) | ||
315 | { | ||
316 | rthal_irq_request(it->irq, fusion_handle_irq, it); | ||
317 | rthal_irq_enable(it->irq); | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int comedi_rt_release_irq(struct comedi_irq_struct *it) | ||
322 | { | ||
323 | rthal_irq_disable(it->irq); | ||
324 | rthal_irq_release(it->irq); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | void comedi_rt_init(void) | ||
329 | { | ||
330 | rt_pend_tq_init(); | ||
331 | } | ||
332 | |||
333 | void comedi_rt_cleanup(void) | ||
334 | { | ||
335 | rt_pend_tq_cleanup(); | ||
336 | } | ||
337 | |||
338 | #endif /*CONFIG_COMEDI_FUSION */ | ||
339 | |||
340 | /* RTLinux section */ | ||
341 | #ifdef CONFIG_COMEDI_RTL | ||
342 | |||
343 | static unsigned int handle_rtl_irq(unsigned int irq) | ||
344 | { | ||
345 | struct comedi_irq_struct *it; | ||
346 | |||
347 | it = comedi_irqs[irq]; | ||
348 | if (it == NULL) | ||
349 | return 0; | ||
350 | it->handler(irq, it->dev_id); | ||
351 | rtl_hard_enable_irq(irq); | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static int comedi_rt_get_irq(struct comedi_irq_struct *it) | ||
356 | { | ||
357 | rtl_request_global_irq(it->irq, handle_rtl_irq); | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | static int comedi_rt_release_irq(struct comedi_irq_struct *it) | ||
362 | { | ||
363 | rtl_free_global_irq(it->irq); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | void comedi_rt_init(void) | ||
368 | { | ||
369 | rt_pend_tq_init(); | ||
370 | } | ||
371 | |||
372 | void comedi_rt_cleanup(void) | ||
373 | { | ||
374 | rt_pend_tq_cleanup(); | ||
375 | } | ||
376 | |||
377 | #endif | ||
378 | |||
379 | #ifdef CONFIG_COMEDI_PIRQ | ||
380 | static int comedi_rt_get_irq(struct comedi_irq_struct *it) | ||
381 | { | ||
382 | int ret; | ||
383 | |||
384 | free_irq(it->irq, it->dev_id); | ||
385 | ret = request_irq(it->irq, it->handler, it->flags | SA_PRIORITY, | ||
386 | it->device, it->dev_id); | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | static int comedi_rt_release_irq(struct comedi_irq_struct *it) | ||
392 | { | ||
393 | int ret; | ||
394 | |||
395 | free_irq(it->irq, it->dev_id); | ||
396 | ret = request_irq(it->irq, it->handler, it->flags, | ||
397 | it->device, it->dev_id); | ||
398 | |||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | void comedi_rt_init(void) | ||
403 | { | ||
404 | /* rt_pend_tq_init(); */ | ||
405 | } | ||
406 | |||
407 | void comedi_rt_cleanup(void) | ||
408 | { | ||
409 | /* rt_pend_tq_cleanup(); */ | ||
410 | } | ||
411 | #endif | ||
diff --git a/drivers/staging/comedi/rt_pend_tq.c b/drivers/staging/comedi/rt_pend_tq.c deleted file mode 100644 index f6e083d553d9..000000000000 --- a/drivers/staging/comedi/rt_pend_tq.c +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | #define __NO_VERSION__ | ||
2 | /* rt_pend_tq.c */ | ||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/errno.h> | ||
5 | #include <linux/sched.h> | ||
6 | #include "comedidev.h" /* for rt spinlocks */ | ||
7 | #include "rt_pend_tq.h" | ||
8 | #ifdef CONFIG_COMEDI_RTAI | ||
9 | #include <rtai.h> | ||
10 | #endif | ||
11 | #ifdef CONFIG_COMEDI_FUSION | ||
12 | #include <nucleus/asm/hal.h> | ||
13 | #endif | ||
14 | #ifdef CONFIG_COMEDI_RTL | ||
15 | #include <rtl_core.h> | ||
16 | #endif | ||
17 | |||
18 | #ifdef standalone | ||
19 | #include <linux/module.h> | ||
20 | #define rt_pend_tq_init init_module | ||
21 | #define rt_pend_tq_cleanup cleanup_module | ||
22 | #endif | ||
23 | |||
24 | volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE]; | ||
25 | volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq, | ||
26 | *volatile rt_pend_tail = rt_pend_tq; | ||
27 | int rt_pend_tq_irq = 0; | ||
28 | DEFINE_SPINLOCK(rt_pend_tq_lock); | ||
29 | |||
30 | /* WARNING: following code not checked against race conditions yet. */ | ||
31 | #define INC_CIRCULAR_PTR (ptr, begin, size) do {if (++ (ptr)>= (begin)+ (size)) (ptr)= (begin); } while (0) | ||
32 | #define DEC_CIRCULAR_PTR (ptr, begin, size) do {if (-- (ptr)< (begin)) (ptr)= (begin)+ (size)-1; } while (0) | ||
33 | |||
34 | int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, void *arg2) | ||
35 | { | ||
36 | unsigned long flags; | ||
37 | |||
38 | if (func == NULL) | ||
39 | return -EINVAL; | ||
40 | if (rt_pend_tq_irq <= 0) | ||
41 | return -ENODEV; | ||
42 | comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags); | ||
43 | INC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE); | ||
44 | if (rt_pend_head == rt_pend_tail) { | ||
45 | /* overflow, we just refuse to take this request */ | ||
46 | DEC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE); | ||
47 | comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags); | ||
48 | return -EAGAIN; | ||
49 | } | ||
50 | rt_pend_head->func = func; | ||
51 | rt_pend_head->arg1 = arg1; | ||
52 | rt_pend_head->arg2 = arg2; | ||
53 | comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags); | ||
54 | #ifdef CONFIG_COMEDI_RTAI | ||
55 | rt_pend_linux_srq(rt_pend_tq_irq); | ||
56 | #endif | ||
57 | #ifdef CONFIG_COMEDI_FUSION | ||
58 | rthal_apc_schedule(rt_pend_tq_irq); | ||
59 | #endif | ||
60 | #ifdef CONFIG_COMEDI_RTL | ||
61 | rtl_global_pend_irq(rt_pend_tq_irq); | ||
62 | |||
63 | #endif | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | #ifdef CONFIG_COMEDI_RTAI | ||
68 | void rt_pend_irq_handler(void) | ||
69 | #elif defined(CONFIG_COMEDI_FUSION) | ||
70 | void rt_pend_irq_handler(void *cookie) | ||
71 | #elif defined(CONFIG_COMEDI_RTL) | ||
72 | void rt_pend_irq_handler(int irq, void *dev) | ||
73 | #endif | ||
74 | { | ||
75 | while (rt_pend_head != rt_pend_tail) { | ||
76 | INC_CIRCULAR_PTR(rt_pend_tail, rt_pend_tq, RT_PEND_TQ_SIZE); | ||
77 | rt_pend_tail->func(rt_pend_tail->arg1, rt_pend_tail->arg2); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | int rt_pend_tq_init(void) | ||
82 | { | ||
83 | rt_pend_head = rt_pend_tail = rt_pend_tq; | ||
84 | #ifdef CONFIG_COMEDI_RTAI | ||
85 | rt_pend_tq_irq = rt_request_srq(0, rt_pend_irq_handler, NULL); | ||
86 | #endif | ||
87 | #ifdef CONFIG_COMEDI_FUSION | ||
88 | rt_pend_tq_irq = | ||
89 | rthal_apc_alloc("comedi APC", rt_pend_irq_handler, NULL); | ||
90 | #endif | ||
91 | #ifdef CONFIG_COMEDI_RTL | ||
92 | rt_pend_tq_irq = rtl_get_soft_irq(rt_pend_irq_handler, "rt_pend_irq"); | ||
93 | #endif | ||
94 | if (rt_pend_tq_irq > 0) | ||
95 | printk("rt_pend_tq: RT bottom half scheduler initialized OK\n"); | ||
96 | else | ||
97 | printk("rt_pend_tq: rtl_get_soft_irq failed\n"); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | void rt_pend_tq_cleanup(void) | ||
102 | { | ||
103 | printk("rt_pend_tq: unloading\n"); | ||
104 | #ifdef CONFIG_COMEDI_RTAI | ||
105 | rt_free_srq(rt_pend_tq_irq); | ||
106 | #endif | ||
107 | #ifdef CONFIG_COMEDI_FUSION | ||
108 | rthal_apc_free(rt_pend_tq_irq); | ||
109 | #endif | ||
110 | #ifdef CONFIG_COMEDI_RTL | ||
111 | free_irq(rt_pend_tq_irq, NULL); | ||
112 | #endif | ||
113 | } | ||
diff --git a/drivers/staging/comedi/rt_pend_tq.h b/drivers/staging/comedi/rt_pend_tq.h deleted file mode 100644 index 01ed71bf409d..000000000000 --- a/drivers/staging/comedi/rt_pend_tq.h +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #define RT_PEND_TQ_SIZE 16 | ||
2 | struct rt_pend_tq { | ||
3 | void (*func) (int arg1, void *arg2); | ||
4 | int arg1; | ||
5 | void *arg2; | ||
6 | }; | ||
7 | extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, | ||
8 | void *arg2); | ||
9 | extern int rt_pend_tq_init(void); | ||
10 | extern void rt_pend_tq_cleanup(void); | ||