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