Linux-2.6.12-rc2
[linux-2.6] / arch / m68k / mvme16x / 16xints.c
1 /*
2  * arch/m68k/mvme16x/16xints.c
3  *
4  * Copyright (C) 1995 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/system.h>
20 #include <asm/ptrace.h>
21 #include <asm/irq.h>
22
23 static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp);
24
25 /*
26  * This should ideally be 4 elements only, for speed.
27  */
28
29 static struct {
30         irqreturn_t     (*handler)(int, void *, struct pt_regs *);
31         unsigned long   flags;
32         void            *dev_id;
33         const char      *devname;
34         unsigned        count;
35 } irq_tab[192];
36
37 /*
38  * void mvme16x_init_IRQ (void)
39  *
40  * Parameters:  None
41  *
42  * Returns:     Nothing
43  *
44  * This function is called during kernel startup to initialize
45  * the mvme16x IRQ handling routines.  Should probably ensure
46  * that the base vectors for the VMEChip2 and PCCChip2 are valid.
47  */
48
49 void mvme16x_init_IRQ (void)
50 {
51         int i;
52
53         for (i = 0; i < 192; i++) {
54                 irq_tab[i].handler = mvme16x_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 mvme16x_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 < 64 || irq > 255) {
67                 printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
68                 return -ENXIO;
69         }
70
71         if (!(irq_tab[irq-64].flags & IRQ_FLG_STD)) {
72                 if (irq_tab[irq-64].flags & IRQ_FLG_LOCK) {
73                         printk("%s: IRQ %d from %s is not replaceable\n",
74                                __FUNCTION__, irq, irq_tab[irq-64].devname);
75                         return -EBUSY;
76                 }
77                 if (flags & IRQ_FLG_REPLACE) {
78                         printk("%s: %s can't replace IRQ %d from %s\n",
79                                __FUNCTION__, devname, irq, irq_tab[irq-64].devname);
80                         return -EBUSY;
81                 }
82         }
83         irq_tab[irq-64].handler = handler;
84         irq_tab[irq-64].flags   = flags;
85         irq_tab[irq-64].dev_id  = dev_id;
86         irq_tab[irq-64].devname = devname;
87         return 0;
88 }
89
90 void mvme16x_free_irq(unsigned int irq, void *dev_id)
91 {
92         if (irq < 64 || irq > 255) {
93                 printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
94                 return;
95         }
96
97         if (irq_tab[irq-64].dev_id != dev_id)
98                 printk("%s: Removing probably wrong IRQ %d from %s\n",
99                        __FUNCTION__, irq, irq_tab[irq-64].devname);
100
101         irq_tab[irq-64].handler = mvme16x_defhand;
102         irq_tab[irq-64].flags   = IRQ_FLG_STD;
103         irq_tab[irq-64].dev_id  = NULL;
104         irq_tab[irq-64].devname = NULL;
105 }
106
107 irqreturn_t mvme16x_process_int (unsigned long vec, struct pt_regs *fp)
108 {
109         if (vec < 64 || vec > 255) {
110                 printk ("mvme16x_process_int: Illegal vector %ld", vec);
111                 return IRQ_NONE;
112         } else {
113                 irq_tab[vec-64].count++;
114                 irq_tab[vec-64].handler(vec, irq_tab[vec-64].dev_id, fp);
115                 return IRQ_HANDLED;
116         }
117 }
118
119 int show_mvme16x_interrupts (struct seq_file *p, void *v)
120 {
121         int i;
122
123         for (i = 0; i < 192; i++) {
124                 if (irq_tab[i].count)
125                         seq_printf(p, "Vec 0x%02x: %8d  %s\n",
126                             i+64, irq_tab[i].count,
127                             irq_tab[i].devname ? irq_tab[i].devname : "free");
128         }
129         return 0;
130 }
131
132
133 static irqreturn_t mvme16x_defhand (int irq, void *dev_id, struct pt_regs *fp)
134 {
135         printk ("Unknown interrupt 0x%02x\n", irq);
136         return IRQ_NONE;
137 }
138
139
140 void mvme16x_enable_irq (unsigned int irq)
141 {
142 }
143
144
145 void mvme16x_disable_irq (unsigned int irq)
146 {
147 }
148
149