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