staging: comedi, remove interrupt.h
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / rt_pend_tq.c
CommitLineData
ed9eccbe
DS
1#define __NO_VERSION__
2/* rt_pend_tq.c */
3#include <linux/kernel.h>
4#include <linux/errno.h>
5#include <linux/sched.h>
b6c77757 6#include "comedidev.h" /* for rt spinlocks */
ed9eccbe
DS
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;
fc0cb7d1 28DEFINE_SPINLOCK(rt_pend_tq_lock);
ed9eccbe 29
b6c77757 30/* WARNING: following code not checked against race conditions yet. */
ed9eccbe
DS
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) {
b6c77757 45 /* overflow, we just refuse to take this request */
ed9eccbe
DS
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)
70265d24 72void rt_pend_irq_handler(int irq, void *dev)
ed9eccbe
DS
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}