Commit | Line | Data |
---|---|---|
1da177e4 LT |
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> | |
b5dc7840 | 17 | #include <linux/interrupt.h> |
1da177e4 LT |
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 |