Commit 25436dc9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: comedi: remove RT code

This removes the unused RT code from the comedi subsystem.

A lot of drivers needed to then include interrupt.h on their own, as they
were picking it up through the comedi_rt.h inclusion.

Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5f74ea14
......@@ -13,13 +13,6 @@ config COMEDI_DEBUG
This is an option for use by developers; most people should
say N here. This enables comedi core and driver debugging.
config COMEDI_RT
tristate "Comedi Real-time support"
depends on COMEDI && RT
default N
---help---
Enable Real time support for the Comedi core.
config COMEDI_PCI_DRIVERS
tristate "Comedi PCI drivers"
depends on COMEDI && PCI
......
obj-$(CONFIG_COMEDI) += comedi.o
obj-$(CONFIG_COMEDI_RT) += comedi_rt.o
obj-$(CONFIG_COMEDI) += kcomedilib/
obj-$(CONFIG_COMEDI) += drivers/
......@@ -11,7 +10,3 @@ comedi-objs := \
drivers.o \
comedi_compat32.o \
comedi_ksyms.o \
comedi_rt-objs := \
rt_pend_tq.o \
rt.o
......@@ -1079,13 +1079,6 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING);
#ifdef CONFIG_COMEDI_RT
if (async->cmd.flags & TRIG_RT) {
if (comedi_switch_to_rt(dev) == 0)
comedi_set_subdevice_runflags(s, SRF_RT, SRF_RT);
}
#endif
ret = s->do_cmd(dev, s);
if (ret == 0)
return 0;
......@@ -1720,12 +1713,6 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
struct comedi_async *async = s->async;
comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
#ifdef CONFIG_COMEDI_RT
if (comedi_get_subdevice_runflags(s) & SRF_RT) {
comedi_switch_to_non_rt(dev);
comedi_set_subdevice_runflags(s, SRF_RT, 0);
}
#endif
if (async) {
comedi_reset_async_buf(async);
async->inttrig = NULL;
......@@ -1952,8 +1939,6 @@ static int __init comedi_init(void)
}
}
comedi_rt_init();
comedi_register_ioctl32();
return 0;
......@@ -1974,8 +1959,6 @@ static void __exit comedi_cleanup(void)
comedi_proc_cleanup();
comedi_rt_cleanup();
comedi_unregister_ioctl32();
}
......@@ -2015,15 +1998,8 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
if (async->cb_mask & s->async->events) {
if (comedi_get_subdevice_runflags(s) & SRF_USER) {
if (dev->rt) {
#ifdef CONFIG_COMEDI_RT
/* pend wake up */
comedi_rt_pend_wakeup(&async->wait_head);
#else
printk
("BUG: comedi_event() code unreachable\n");
#endif
printk("BUG: comedi_event() code unreachable\n");
} else {
wake_up_interruptible(&async->wait_head);
if (s->subdev_flags & SDF_CMD_READ) {
......
......@@ -46,13 +46,6 @@ EXPORT_SYMBOL(range_bipolar2_5);
EXPORT_SYMBOL(range_unipolar10);
EXPORT_SYMBOL(range_unipolar5);
EXPORT_SYMBOL(range_unknown);
#ifdef CONFIG_COMEDI_RT
EXPORT_SYMBOL(comedi_free_irq);
EXPORT_SYMBOL(comedi_request_irq);
EXPORT_SYMBOL(comedi_switch_to_rt);
EXPORT_SYMBOL(comedi_switch_to_non_rt);
EXPORT_SYMBOL(rt_pend_call);
#endif
#ifdef CONFIG_COMEDI_DEBUG
EXPORT_SYMBOL(comedi_debug);
#endif
......
/*
module/comedi_rt.h
header file for real-time structures, variables, and constants
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _COMEDI_RT_H
#define _COMEDI_RT_H
#ifndef _COMEDIDEV_H
#error comedi_rt.h should only be included by comedidev.h
#endif
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#ifdef CONFIG_COMEDI_RT
#ifdef CONFIG_COMEDI_RTAI
#include <rtai.h>
#include <rtai_sched.h>
#include <rtai_version.h>
#endif
#ifdef CONFIG_COMEDI_RTL
#include <rtl_core.h>
#include <rtl_time.h>
/* #ifdef RTLINUX_VERSION_CODE */
#include <rtl_sync.h>
/* #endif */
#define rt_printk rtl_printf
#endif
#ifdef CONFIG_COMEDI_FUSION
#define rt_printk(format, args...) printk(format , ## args)
#endif /* CONFIG_COMEDI_FUSION */
#ifdef CONFIG_PRIORITY_IRQ
#define rt_printk printk
#endif
int comedi_request_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *device,
struct comedi_device *dev_id);
void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
void comedi_rt_init(void);
void comedi_rt_cleanup(void);
int comedi_switch_to_rt(struct comedi_device *dev);
void comedi_switch_to_non_rt(struct comedi_device *dev);
void comedi_rt_pend_wakeup(wait_queue_head_t *q);
extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
void *arg2);
#else
#define comedi_request_irq(a, b, c, d, e) request_irq(a, b, c, d, e)
#define comedi_free_irq(a, b) free_irq(a, b)
#define comedi_rt_init() do {} while (0)
#define comedi_rt_cleanup() do {} while (0)
#define comedi_switch_to_rt(a) (-1)
#define comedi_switch_to_non_rt(a) do {} while (0)
#define comedi_rt_pend_wakeup(a) do {} while (0)
#define rt_printk(format, args...) printk(format, ##args)
#endif
/* Define a spin_lock_irqsave function that will work with rt or without.
* Use inline functions instead of just macros to enforce some type checking.
*/
#define comedi_spin_lock_irqsave(lock_ptr, flags) \
(flags = __comedi_spin_lock_irqsave(lock_ptr))
static inline unsigned long __comedi_spin_lock_irqsave(spinlock_t *lock_ptr)
{
unsigned long flags;
#if defined(CONFIG_COMEDI_RTAI)
flags = rt_spin_lock_irqsave(lock_ptr);
#elif defined(CONFIG_COMEDI_RTL)
rtl_spin_lock_irqsave(lock_ptr, flags);
#elif defined(CONFIG_COMEDI_RTL_V1)
rtl_spin_lock_irqsave(lock_ptr, flags);
#elif defined(CONFIG_COMEDI_FUSION)
rthal_spin_lock_irqsave(lock_ptr, flags);
#else
spin_lock_irqsave(lock_ptr, flags);
#endif
return flags;
}
static inline void comedi_spin_unlock_irqrestore(spinlock_t *lock_ptr,
unsigned long flags)
{
#if defined(CONFIG_COMEDI_RTAI)
rt_spin_unlock_irqrestore(flags, lock_ptr);
#elif defined(CONFIG_COMEDI_RTL)
rtl_spin_unlock_irqrestore(lock_ptr, flags);
#elif defined(CONFIG_COMEDI_RTL_V1)
rtl_spin_unlock_irqrestore(lock_ptr, flags);
#elif defined(CONFIG_COMEDI_FUSION)
rthal_spin_unlock_irqrestore(lock_ptr, flags);
#else
spin_unlock_irqrestore(lock_ptr, flags);
#endif
}
/* define a RT safe udelay */
static inline void comedi_udelay(unsigned int usec)
{
#if defined(CONFIG_COMEDI_RTAI)
static const int nanosec_per_usec = 1000;
rt_busy_sleep(usec * nanosec_per_usec);
#elif defined(CONFIG_COMEDI_RTL)
static const int nanosec_per_usec = 1000;
rtl_delay(usec * nanosec_per_usec);
#else
udelay(usec);
#endif
}
#endif
......@@ -523,8 +523,6 @@ struct usb_device; /* forward declaration */
int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
void comedi_usb_auto_unconfig(struct usb_device *usbdev);
#include "comedi_rt.h"
#ifdef CONFIG_COMEDI_PCI_DRIVERS
#define CONFIG_COMEDI_PCI
#endif
......
......@@ -31,6 +31,7 @@ Status: experimental
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/pci.h>
......
......@@ -43,6 +43,7 @@ See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "comedi_pci.h"
#include "plx9052.h"
......
This diff is collapsed.
......@@ -119,6 +119,7 @@ Configuration options:
#include "../comedidev.h"
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "comedi_pci.h"
#include "8255.h"
......
......@@ -79,6 +79,7 @@ Computer boards manuals also available from their website www.measurementcomputi
*/
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <asm/dma.h>
#include "../comedidev.h"
......
......@@ -59,6 +59,7 @@ irq can be omitted, although the cmd interface will not work without it.
*/
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "8255.h"
......
......@@ -100,6 +100,7 @@ Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
read insn for analog out
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -38,6 +38,7 @@ Devices: [Keithley Metrabyte] DAS6402 (das6402)
This driver has suffered bitrot.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -62,6 +62,7 @@ cmd triggers supported:
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -74,6 +74,7 @@ Configuration Options:
* options that are used with comedi_config.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -45,6 +45,7 @@ Configuration options:
[4] - D/A 1 range (same choices)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -39,6 +39,7 @@ a power of 10, from 1 to 10^7, of which only 3 or 4 are useful. In
addition, the clock does not seem to be very accurate.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -59,6 +59,7 @@ AO commands are not supported.
#define DEBUG 1
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -45,6 +45,7 @@ support could be added to this driver.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -50,6 +50,7 @@ There are 4 x 12-bit Analogue Outputs. Ranges : 5V, 10V, +/-5V, +/-10V
[1] - PCI slot number
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -51,6 +51,7 @@ broken.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -50,6 +50,7 @@ from http://www.comedi.org
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "comedi_pci.h"
......
......@@ -29,6 +29,7 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -41,6 +41,7 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
#define DEBUG 1
#define DEBUG_FLAGS
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "mite.h"
......
......@@ -50,6 +50,7 @@ except maybe the 6514.
#define _GNU_SOURCE
#define DEBUG 1
#define DEBUG_FLAGS
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "mite.h"
......
......@@ -40,6 +40,7 @@ DAQ 6601/6602 User Manual (NI 322137B-01)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "mite.h"
#include "ni_tio.h"
......
......@@ -41,6 +41,7 @@ Commands are not supported.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "mite.h"
......
......@@ -64,6 +64,7 @@ TRIG_WAKE_EOS
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -93,6 +93,7 @@ are not supported.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -35,6 +35,7 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
*
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -41,6 +41,7 @@ emu as port A output, port B input, port C N/A).
IRQ is assigned but not used.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -40,6 +40,7 @@ the PCMCIA interface.
/* #define LABPC_DEBUG */ /* enable debugging messages */
#undef LABPC_DEBUG
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -76,6 +76,7 @@ NI manuals:
#undef LABPC_DEBUG
/* #define LABPC_DEBUG enable debugging messages */
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -61,6 +61,7 @@
/* #define DEBUG_STATUS_A */
/* #define DEBUG_STATUS_B */
#include <linux/interrupt.h>
#include "8255.h"
#include "mite.h"
#include "comedi_fc.h"
......
......@@ -69,6 +69,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
/* #define DEBUG 1 */
/* #define DEBUG_FLAGS */
#include <linux/interrupt.h>
#include "../comedidev.h"
#include "mite.h"
......
......@@ -58,6 +58,7 @@ supported.
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -107,6 +107,7 @@ Options for ACL-8113, ISO-813:
3= 20V unipolar inputs
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/delay.h>
......
......@@ -41,6 +41,7 @@ Configuration options:
1 = two's complement
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -73,6 +73,7 @@ Configuration Options:
[1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/pci.h> /* for PCI devices */
......
......@@ -75,6 +75,7 @@ Configuration Options:
[2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/pci.h> /* for PCI devices */
......
......@@ -101,6 +101,7 @@ Configuration options:
*/
#include <linux/interrupt.h>
#include <linux/delay.h>
#include "../comedidev.h"
......
......@@ -52,6 +52,7 @@ Configuration options:
[8] - DAC 1 encoding (same as DAC 0)
*/
#include <linux/interrupt.h>
#include "../comedidev.h"
#include <linux/ioport.h>
......
......@@ -68,6 +68,7 @@ INSN_CONFIG instructions:
comedi_do_insn(cf,&insn); //executing configuration
*/
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/types.h>
......
......@@ -150,10 +150,6 @@ int comedi_command(void *d, struct comedi_cmd *cmd)
runflags = SRF_RUNNING;
#ifdef CONFIG_COMEDI_RT
if (comedi_switch_to_rt(dev) == 0)
runflags |= SRF_RT;
#endif
comedi_set_subdevice_runflags(s, ~0, runflags);
comedi_reset_async_buf(async);
......@@ -449,11 +445,6 @@ int comedi_cancel(void *d, unsigned int subdevice)
if (ret)
return ret;
#ifdef CONFIG_COMEDI_RT
if (comedi_get_subdevice_runflags(s) & SRF_RT)
comedi_switch_to_non_rt(dev);
#endif
comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0);
s->async->inttrig = NULL;
s->busy = NULL;
......
/*
comedi/rt.c
comedi kernel module
COMEDI - Linux Control and Measurement Device Interface
Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#undef DEBUG
#define __NO_VERSION__
#include <linux/comedidev.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "rt_pend_tq.h"
#ifdef CONFIG_COMEDI_RTAI
#include <rtai.h>
#endif
#ifdef CONFIG_COMEDI_FUSION
#include <nucleus/asm/hal.h>
#endif
#ifdef CONFIG_COMEDI_RTL
#include <rtl_core.h>
#include <rtl_sync.h>
#endif
struct comedi_irq_struct {
int rt;
int irq;
irq_handler_t handler;
unsigned long flags;
const char *device;
struct comedi_device *dev_id;
};
static int comedi_rt_get_irq(struct comedi_irq_struct *it);
static int comedi_rt_release_irq(struct comedi_irq_struct *it);
static struct comedi_irq_struct *comedi_irqs[NR_IRQS];
int comedi_request_irq(unsigned irq, irq_handler_t handler, unsigned long flags,
const char *device, struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
int ret;
/* null shared interrupt flag, since rt interrupt handlers do not
* support it, and this version of comedi_request_irq() is only
* called for kernels with rt support */
unsigned long unshared_flags = flags & ~IRQF_SHARED;
ret = request_irq(irq, handler, unshared_flags, device, dev_id);
if (ret < 0) {
/* we failed, so fall back on allowing shared interrupt (which we won't ever make RT) */
if (flags & IRQF_SHARED) {
rt_printk
("comedi: cannot get unshared interrupt, will not use RT interrupts.\n");
ret = request_irq(irq, handler, flags, device, dev_id);
}
if (ret < 0)
return ret;
} else {
it = kzalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL);
if (!it)
return -ENOMEM;
it->handler = handler;
it->irq = irq;
it->dev_id = dev_id;
it->device = device;
it->flags = unshared_flags;
comedi_irqs[irq] = it;
}
return 0;
}
void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
free_irq(irq, dev_id);
it = comedi_irqs[irq];
if (it == NULL)
return;
if (it->rt) {
printk("real-time IRQ allocated at board removal (ignore)\n");
comedi_rt_release_irq(it);
}
kfree(it);
comedi_irqs[irq] = NULL;
}
int comedi_switch_to_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
it = comedi_irqs[dev->irq];
/* drivers might not be using an interrupt for commands,
or we might not have been able to get an unshared irq */
if (it == NULL)
return -1;
comedi_spin_lock_irqsave(&dev->spinlock, flags);
if (!dev->rt)
comedi_rt_get_irq(it);
dev->rt++;
it->rt = 1;
comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
return 0;
}
void comedi_switch_to_non_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
it = comedi_irqs[dev->irq];
if (it == NULL)
return;
comedi_spin_lock_irqsave(&dev->spinlock, flags);
dev->rt--;
if (!dev->rt)
comedi_rt_release_irq(it);
it->rt = 0;
comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
}
void wake_up_int_handler(int arg1, void *arg2)
{
wake_up_interruptible((wait_queue_head_t *) arg2);
}
void comedi_rt_pend_wakeup(wait_queue_head_t *q)
{
rt_pend_call(wake_up_int_handler, 0, q);
}
/* RTAI section */
#ifdef CONFIG_COMEDI_RTAI
#ifndef HAVE_RT_REQUEST_IRQ_WITH_ARG
#define DECLARE_VOID_IRQ(irq) \
static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); }
static void handle_void_irq(int irq)
{
struct comedi_irq_struct *it;
it = comedi_irqs[irq];
if (it == NULL) {
rt_printk("comedi: null irq struct?\n");
return;
}
it->handler(irq, it->dev_id);
rt_enable_irq(irq); /* needed by rtai-adeos, seems like it shouldn't hurt earlier versions */
}
DECLARE_VOID_IRQ(0);
DECLARE_VOID_IRQ(1);
DECLARE_VOID_IRQ(2);
DECLARE_VOID_IRQ(3);
DECLARE_VOID_IRQ(4);
DECLARE_VOID_IRQ(5);
DECLARE_VOID_IRQ(6);
DECLARE_VOID_IRQ(7);
DECLARE_VOID_IRQ(8);
DECLARE_VOID_IRQ(9);
DECLARE_VOID_IRQ(10);
DECLARE_VOID_IRQ(11);
DECLARE_VOID_IRQ(12);
DECLARE_VOID_IRQ(13);
DECLARE_VOID_IRQ(14);
DECLARE_VOID_IRQ(15);
DECLARE_VOID_IRQ(16);
DECLARE_VOID_IRQ(17);
DECLARE_VOID_IRQ(18);
DECLARE_VOID_IRQ(19);
DECLARE_VOID_IRQ(20);
DECLARE_VOID_IRQ(21);
DECLARE_VOID_IRQ(22);
DECLARE_VOID_IRQ(23);
static void handle_void_irq_ptrs[] = {
handle_void_irq_0,
handle_void_irq_1,
handle_void_irq_2,
handle_void_irq_3,
handle_void_irq_4,
handle_void_irq_5,
handle_void_irq_6,
handle_void_irq_7,
handle_void_irq_8,
handle_void_irq_9,
handle_void_irq_10,
handle_void_irq_11,
handle_void_irq_12,
handle_void_irq_13,
handle_void_irq_14,
handle_void_irq_15,
handle_void_irq_16,
handle_void_irq_17,
handle_void_irq_18,
handle_void_irq_19,
handle_void_irq_20,
handle_void_irq_21,
handle_void_irq_22,
handle_void_irq_23,
};
static int comedi_rt_get_irq(struct comedi_irq_struct *it)
{
rt_request_global_irq(it->irq, handle_void_irq_ptrs[it->irq]);
rt_startup_irq(it->irq);
return 0;
}
static int comedi_rt_release_irq(struct comedi_irq_struct *it)
{
rt_shutdown_irq(it->irq);
rt_free_global_irq(it->irq);
return 0;
}
#else
static int comedi_rt_get_irq(struct comedi_irq_struct *it)
{
int ret;
ret = rt_request_global_irq_arg(it->irq, it->handler, it->flags,
it->device, it->dev_id);
if (ret < 0) {
rt_printk("rt_request_global_irq_arg() returned %d\n", ret);
return ret;
}
rt_startup_irq(it->irq);
return 0;
}
static int comedi_rt_release_irq(struct comedi_irq_struct *it)
{
rt_shutdown_irq(it->irq);
rt_free_global_irq(it->irq);
return 0;
}
#endif
void comedi_rt_init(void)
{
rt_mount_rtai();
rt_pend_tq_init();
}
void comedi_rt_cleanup(void)
{
rt_umount_rtai();
rt_pend_tq_cleanup();
}
#endif
/* Fusion section */
#ifdef CONFIG_COMEDI_FUSION
static void fusion_handle_irq(unsigned int irq, void *cookie)
{
struct comedi_irq_struct *it = cookie;
it->handler(irq, it->dev_id);
rthal_irq_enable(irq);
}
static int comedi_rt_get_irq(struct comedi_irq_struct *it)
{
rthal_irq_request(it->irq, fusion_handle_irq, it);
rthal_irq_enable(it->irq);
return 0;
}
static int comedi_rt_release_irq(struct comedi_irq_struct *it)
{
rthal_irq_disable(it->irq);
rthal_irq_release(it->irq);
return 0;
}
void comedi_rt_init(void)
{
rt_pend_tq_init();
}
void comedi_rt_cleanup(void)
{
rt_pend_tq_cleanup();
}
#endif /*CONFIG_COMEDI_FUSION */
/* RTLinux section */
#ifdef CONFIG_COMEDI_RTL
static unsigned int handle_rtl_irq(unsigned int irq)
{
struct comedi_irq_struct *it;
it = comedi_irqs[irq];
if (it == NULL)
return 0;
it->handler(irq, it->dev_id);
rtl_hard_enable_irq(irq);
return 0;
}
static int comedi_rt_get_irq(struct comedi_irq_struct *it)
{
rtl_request_global_irq(it->irq, handle_rtl_irq);
return 0;
}
static int comedi_rt_release_irq(struct comedi_irq_struct *it)
{
rtl_free_global_irq(it->irq);
return 0;
}
void comedi_rt_init(void)
{
rt_pend_tq_init();
}
void comedi_rt_cleanup(void)
{
rt_pend_tq_cleanup();
}
#endif
#ifdef CONFIG_COMEDI_PIRQ
static int comedi_rt_get_irq(struct comedi_irq_struct *it)
{
int ret;
free_irq(it->irq, it->dev_id);
ret = request_irq(it->irq, it->handler, it->flags | SA_PRIORITY,
it->device, it->dev_id);
return ret;
}
static int comedi_rt_release_irq(struct comedi_irq_struct *it)
{
int ret;
free_irq(it->irq, it->dev_id);
ret = request_irq(it->irq, it->handler, it->flags,
it->device, it->dev_id);
return ret;
}
void comedi_rt_init(void)
{
/* rt_pend_tq_init(); */
}
void comedi_rt_cleanup(void)
{
/* rt_pend_tq_cleanup(); */
}
#endif
#define __NO_VERSION__
/* rt_pend_tq.c */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include "comedidev.h" /* for rt spinlocks */
#include "rt_pend_tq.h"
#ifdef CONFIG_COMEDI_RTAI
#include <rtai.h>
#endif
#ifdef CONFIG_COMEDI_FUSION
#include <nucleus/asm/hal.h>
#endif
#ifdef CONFIG_COMEDI_RTL
#include <rtl_core.h>
#endif
#ifdef standalone
#include <linux/module.h>
#define rt_pend_tq_init init_module
#define rt_pend_tq_cleanup cleanup_module
#endif
volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE];
volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq,
*volatile rt_pend_tail = rt_pend_tq;
int rt_pend_tq_irq = 0;
DEFINE_SPINLOCK(rt_pend_tq_lock);
/* WARNING: following code not checked against race conditions yet. */
#define INC_CIRCULAR_PTR (ptr, begin, size) do {if (++ (ptr)>= (begin)+ (size)) (ptr)= (begin); } while (0)
#define DEC_CIRCULAR_PTR (ptr, begin, size) do {if (-- (ptr)< (begin)) (ptr)= (begin)+ (size)-1; } while (0)
int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, void *arg2)
{
unsigned long flags;
if (func == NULL)
return -EINVAL;
if (rt_pend_tq_irq <= 0)
return -ENODEV;
comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags);
INC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
if (rt_pend_head == rt_pend_tail) {
/* overflow, we just refuse to take this request */
DEC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags);
return -EAGAIN;
}
rt_pend_head->func = func;
rt_pend_head->arg1 = arg1;
rt_pend_head->arg2 = arg2;
comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags);
#ifdef CONFIG_COMEDI_RTAI
rt_pend_linux_srq(rt_pend_tq_irq);
#endif
#ifdef CONFIG_COMEDI_FUSION
rthal_apc_schedule(rt_pend_tq_irq);
#endif
#ifdef CONFIG_COMEDI_RTL
rtl_global_pend_irq(rt_pend_tq_irq);
#endif
return 0;
}
#ifdef CONFIG_COMEDI_RTAI
void rt_pend_irq_handler(void)
#elif defined(CONFIG_COMEDI_FUSION)
void rt_pend_irq_handler(void *cookie)
#elif defined(CONFIG_COMEDI_RTL)
void rt_pend_irq_handler(int irq, void *dev)
#endif
{
while (rt_pend_head != rt_pend_tail) {
INC_CIRCULAR_PTR(rt_pend_tail, rt_pend_tq, RT_PEND_TQ_SIZE);
rt_pend_tail->func(rt_pend_tail->arg1, rt_pend_tail->arg2);
}
}
int rt_pend_tq_init(void)
{
rt_pend_head = rt_pend_tail = rt_pend_tq;
#ifdef CONFIG_COMEDI_RTAI
rt_pend_tq_irq = rt_request_srq(0, rt_pend_irq_handler, NULL);
#endif
#ifdef CONFIG_COMEDI_FUSION
rt_pend_tq_irq =
rthal_apc_alloc("comedi APC", rt_pend_irq_handler, NULL);
#endif
#ifdef CONFIG_COMEDI_RTL
rt_pend_tq_irq = rtl_get_soft_irq(rt_pend_irq_handler, "rt_pend_irq");
#endif
if (rt_pend_tq_irq > 0)
printk("rt_pend_tq: RT bottom half scheduler initialized OK\n");
else
printk("rt_pend_tq: rtl_get_soft_irq failed\n");
return 0;
}
void rt_pend_tq_cleanup(void)
{
printk("rt_pend_tq: unloading\n");
#ifdef CONFIG_COMEDI_RTAI
rt_free_srq(rt_pend_tq_irq);
#endif
#ifdef CONFIG_COMEDI_FUSION
rthal_apc_free(rt_pend_tq_irq);
#endif
#ifdef CONFIG_COMEDI_RTL
free_irq(rt_pend_tq_irq, NULL);
#endif
}
#define RT_PEND_TQ_SIZE 16
struct rt_pend_tq {
void (*func) (int arg1, void *arg2);
int arg1;
void *arg2;
};
extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
void *arg2);
extern int rt_pend_tq_init(void);
extern void rt_pend_tq_cleanup(void);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment