Linux-2.6.12-rc2
[pandora-kernel.git] / arch / m68k / bvme6000 / bvmeints.c
1 /*
2  * arch/m68k/bvme6000/bvmeints.c
3  *
4  * Copyright (C) 1997 Richard Hirst [richard@sleepie.demon.co.uk]
5  *
6  * based on amiints.c -- Amiga Linux interrupt handling code
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License.  See the file README.legal in the main directory of this archive
10  * for more details.
11  *
12  */
13
14 #include <linux/types.h>
15 #include <linux/kernel.h>
16 #include <linux/errno.h>
17 #include <linux/seq_file.h>
18
19 #include <asm/ptrace.h>
20 #include <asm/system.h>
21 #include <asm/irq.h>
22 #include <asm/traps.h>
23
24 static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp);
25
26 /*
27  * This should ideally be 4 elements only, for speed.
28  */
29
30 static struct {
31         irqreturn_t     (*handler)(int, void *, struct pt_regs *);
32         unsigned long   flags;
33         void            *dev_id;
34         const char      *devname;
35         unsigned        count;
36 } irq_tab[256];
37
38 /*
39  * void bvme6000_init_IRQ (void)
40  *
41  * Parameters:  None
42  *
43  * Returns:     Nothing
44  *
45  * This function is called during kernel startup to initialize
46  * the bvme6000 IRQ handling routines.
47  */
48
49 void bvme6000_init_IRQ (void)
50 {
51         int i;
52
53         for (i = 0; i < 256; i++) {
54                 irq_tab[i].handler = bvme6000_defhand;
55                 irq_tab[i].flags = IRQ_FLG_STD;
56                 irq_tab[i].dev_id = NULL;
57                 irq_tab[i].devname = NULL;
58                 irq_tab[i].count = 0;
59         }
60 }
61
62 int bvme6000_request_irq(unsigned int irq,
63                 irqreturn_t (*handler)(int, void *, struct pt_regs *),
64                 unsigned long flags, const char *devname, void *dev_id)
65 {
66         if (irq > 255) {
67                 printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
68                 return -ENXIO;
69         }
70 #if 0
71         /* Nothing special about auto-vectored devices for the BVME6000,
72          * but treat it specially to avoid changes elsewhere.
73          */
74
75         if (irq >= VEC_INT1 && irq <= VEC_INT7)
76                 return cpu_request_irq(irq - VEC_SPUR, handler, flags,
77                                                 devname, dev_id);
78 #endif
79         if (!(irq_tab[irq].flags & IRQ_FLG_STD)) {
80                 if (irq_tab[irq].flags & IRQ_FLG_LOCK) {
81                         printk("%s: IRQ %d from %s is not replaceable\n",
82                                __FUNCTION__, irq, irq_tab[irq].devname);
83                         return -EBUSY;
84                 }
85                 if (flags & IRQ_FLG_REPLACE) {
86                         printk("%s: %s can't replace IRQ %d from %s\n",
87                                __FUNCTION__, devname, irq, irq_tab[irq].devname);
88                         return -EBUSY;
89                 }
90         }
91         irq_tab[irq].handler = handler;
92         irq_tab[irq].flags   = flags;
93         irq_tab[irq].dev_id  = dev_id;
94         irq_tab[irq].devname = devname;
95         return 0;
96 }
97
98 void bvme6000_free_irq(unsigned int irq, void *dev_id)
99 {
100         if (irq > 255) {
101                 printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
102                 return;
103         }
104 #if 0
105         if (irq >= VEC_INT1 && irq <= VEC_INT7) {
106                 cpu_free_irq(irq - VEC_SPUR, dev_id);
107                 return;
108         }
109 #endif
110         if (irq_tab[irq].dev_id != dev_id)
111                 printk("%s: Removing probably wrong IRQ %d from %s\n",
112                        __FUNCTION__, irq, irq_tab[irq].devname);
113
114         irq_tab[irq].handler = bvme6000_defhand;
115         irq_tab[irq].flags   = IRQ_FLG_STD;
116         irq_tab[irq].dev_id  = NULL;
117         irq_tab[irq].devname = NULL;
118 }
119
120 irqreturn_t bvme6000_process_int (unsigned long vec, struct pt_regs *fp)
121 {
122         if (vec > 255) {
123                 printk ("bvme6000_process_int: Illegal vector %ld", vec);
124                 return IRQ_NONE;
125         } else {
126                 irq_tab[vec].count++;
127                 irq_tab[vec].handler(vec, irq_tab[vec].dev_id, fp);
128                 return IRQ_HANDLED;
129         }
130 }
131
132 int show_bvme6000_interrupts(struct seq_file *p, void *v)
133 {
134         int i;
135
136         for (i = 0; i < 256; i++) {
137                 if (irq_tab[i].count)
138                         seq_printf(p, "Vec 0x%02x: %8d  %s\n",
139                             i, irq_tab[i].count,
140                             irq_tab[i].devname ? irq_tab[i].devname : "free");
141         }
142         return 0;
143 }
144
145
146 static irqreturn_t bvme6000_defhand (int irq, void *dev_id, struct pt_regs *fp)
147 {
148         printk ("Unknown interrupt 0x%02x\n", irq);
149         return IRQ_NONE;
150 }
151
152 void bvme6000_enable_irq (unsigned int irq)
153 {
154 }
155
156
157 void bvme6000_disable_irq (unsigned int irq)
158 {
159 }
160