aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/comedi/Kconfig7
-rw-r--r--drivers/staging/comedi/Makefile5
-rw-r--r--drivers/staging/comedi/comedi_fops.c26
-rw-r--r--drivers/staging/comedi/comedi_ksyms.c7
-rw-r--r--drivers/staging/comedi/comedi_rt.h150
-rw-r--r--drivers/staging/comedi/comedidev.h2
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c1
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c1
-rw-r--r--drivers/staging/comedi/drivers/comedi_rt_timer.c756
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c1
-rw-r--r--drivers/staging/comedi/drivers/das16.c1
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c1
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1
-rw-r--r--drivers/staging/comedi/drivers/das6402.c1
-rw-r--r--drivers/staging/comedi/drivers/das800.c1
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c1
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c1
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c1
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c1
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c1
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c1
-rw-r--r--drivers/staging/comedi/drivers/me4000.c1
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c1
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c1
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c1
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c1
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c1
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c1
-rw-r--r--drivers/staging/comedi/drivers/rti800.c1
-rw-r--r--drivers/staging/comedi/drivers/s626.c1
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c9
-rw-r--r--drivers/staging/comedi/rt.c411
-rw-r--r--drivers/staging/comedi/rt_pend_tq.c113
-rw-r--r--drivers/staging/comedi/rt_pend_tq.h10
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
16config 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
23config COMEDI_PCI_DRIVERS 16config 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 @@
1obj-$(CONFIG_COMEDI) += comedi.o 1obj-$(CONFIG_COMEDI) += comedi.o
2obj-$(CONFIG_COMEDI_RT) += comedi_rt.o
3 2
4obj-$(CONFIG_COMEDI) += kcomedilib/ 3obj-$(CONFIG_COMEDI) += kcomedilib/
5obj-$(CONFIG_COMEDI) += drivers/ 4obj-$(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
15comedi_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);
46EXPORT_SYMBOL(range_unipolar10); 46EXPORT_SYMBOL(range_unipolar10);
47EXPORT_SYMBOL(range_unipolar5); 47EXPORT_SYMBOL(range_unipolar5);
48EXPORT_SYMBOL(range_unknown); 48EXPORT_SYMBOL(range_unknown);
49#ifdef CONFIG_COMEDI_RT
50EXPORT_SYMBOL(comedi_free_irq);
51EXPORT_SYMBOL(comedi_request_irq);
52EXPORT_SYMBOL(comedi_switch_to_rt);
53EXPORT_SYMBOL(comedi_switch_to_non_rt);
54EXPORT_SYMBOL(rt_pend_call);
55#endif
56#ifdef CONFIG_COMEDI_DEBUG 49#ifdef CONFIG_COMEDI_DEBUG
57EXPORT_SYMBOL(comedi_debug); 50EXPORT_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
60int comedi_request_irq(unsigned int irq, irq_handler_t handler,
61 unsigned long flags, const char *device,
62 struct comedi_device *dev_id);
63void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
64void comedi_rt_init(void);
65void comedi_rt_cleanup(void);
66int comedi_switch_to_rt(struct comedi_device *dev);
67void comedi_switch_to_non_rt(struct comedi_device *dev);
68void comedi_rt_pend_wakeup(wait_queue_head_t *q);
69extern 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
92static 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
115static 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 */
137static 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 */
523int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name); 523int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
524void comedi_usb_auto_unconfig(struct usb_device *usbdev); 524void 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/*
27Driver: comedi_rt_timer
28Description: Command emulator using real-time tasks
29Author: ds, fmhess
30Devices:
31Status: works
32
33This driver requires RTAI or RTLinux to work correctly. It doesn't
34actually drive hardware directly, but calls other drivers and uses
35a real-time task to emulate commands for drivers and devices that
36are incapable of native commands. Thus, you can get accurately
37timed I/O on any device.
38
39Since the timing is all done in software, sampling jitter is much
40higher than with a device that has an on-board timer, and maximum
41sample rate is much lower.
42
43Configuration 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/*
48TODO:
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 */
79static 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
148static int timer_attach(struct comedi_device *dev, struct comedi_devconfig *it);
149static int timer_detach(struct comedi_device *dev);
150static int timer_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
151 unsigned int trig_num);
152static int timer_start_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
153
154static 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
162COMEDI_INITCLEANUP(driver_timer);
163
164struct 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
190static 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 */
198inline 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 */
215inline 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 */
234static 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 */
259static 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 */
294static 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 */
316static 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
386static 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
424static 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
435static 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
472static 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
544static 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
595static 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
606static 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
635static 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 */
737static 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)
38This driver has suffered bitrot. 38This 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
39addition, the clock does not seem to be very accurate. 39addition, 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).
41IRQ is assigned but not used. 41IRQ 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
55struct 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
64static int comedi_rt_get_irq(struct comedi_irq_struct *it);
65static int comedi_rt_release_irq(struct comedi_irq_struct *it);
66
67static struct comedi_irq_struct *comedi_irqs[NR_IRQS];
68
69int 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
105void 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
124int 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
148void 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
168void wake_up_int_handler(int arg1, void *arg2)
169{
170 wake_up_interruptible((wait_queue_head_t *) arg2);
171}
172
173void 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) \
183static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); }
184
185static 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
198DECLARE_VOID_IRQ(0);
199DECLARE_VOID_IRQ(1);
200DECLARE_VOID_IRQ(2);
201DECLARE_VOID_IRQ(3);
202DECLARE_VOID_IRQ(4);
203DECLARE_VOID_IRQ(5);
204DECLARE_VOID_IRQ(6);
205DECLARE_VOID_IRQ(7);
206DECLARE_VOID_IRQ(8);
207DECLARE_VOID_IRQ(9);
208DECLARE_VOID_IRQ(10);
209DECLARE_VOID_IRQ(11);
210DECLARE_VOID_IRQ(12);
211DECLARE_VOID_IRQ(13);
212DECLARE_VOID_IRQ(14);
213DECLARE_VOID_IRQ(15);
214DECLARE_VOID_IRQ(16);
215DECLARE_VOID_IRQ(17);
216DECLARE_VOID_IRQ(18);
217DECLARE_VOID_IRQ(19);
218DECLARE_VOID_IRQ(20);
219DECLARE_VOID_IRQ(21);
220DECLARE_VOID_IRQ(22);
221DECLARE_VOID_IRQ(23);
222
223static 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
250static 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
258static 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
266static 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
281static 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
289void comedi_rt_init(void)
290{
291 rt_mount_rtai();
292 rt_pend_tq_init();
293}
294
295void 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
306static 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
314static 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
321static 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
328void comedi_rt_init(void)
329{
330 rt_pend_tq_init();
331}
332
333void 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
343static 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
355static 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
361static int comedi_rt_release_irq(struct comedi_irq_struct *it)
362{
363 rtl_free_global_irq(it->irq);
364 return 0;
365}
366
367void comedi_rt_init(void)
368{
369 rt_pend_tq_init();
370}
371
372void comedi_rt_cleanup(void)
373{
374 rt_pend_tq_cleanup();
375}
376
377#endif
378
379#ifdef CONFIG_COMEDI_PIRQ
380static 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
391static 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
402void comedi_rt_init(void)
403{
404 /* rt_pend_tq_init(); */
405}
406
407void 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
24volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE];
25volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq,
26 *volatile rt_pend_tail = rt_pend_tq;
27int rt_pend_tq_irq = 0;
28DEFINE_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
34int 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
68void rt_pend_irq_handler(void)
69#elif defined(CONFIG_COMEDI_FUSION)
70void rt_pend_irq_handler(void *cookie)
71#elif defined(CONFIG_COMEDI_RTL)
72void 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
81int 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
101void 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
2struct rt_pend_tq {
3 void (*func) (int arg1, void *arg2);
4 int arg1;
5 void *arg2;
6};
7extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
8 void *arg2);
9extern int rt_pend_tq_init(void);
10extern void rt_pend_tq_cleanup(void);