Commit 8f042aa75afccc45c5b60517f51644bce3f52545
Exists in
master
and in
6 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k: (29 commits) m68k/mac: Remove mac_irq_{en,dis}able() wrappers m68k/irq: Remove obsolete support for user vector interrupt fixups m68k/irq: Remove obsolete m68k irq framework m68k/q40: Convert Q40/Q60 to genirq m68k/sun3: Convert Sun3/3x to genirq m68k/sun3: Use the kstat_irqs_cpu() wrapper m68k/apollo: Convert Apollo to genirq m68k/vme: Convert VME to genirq m68k/hp300: Convert HP9000/300 and HP9000/400 to genirq m68k/mac: Optimize interrupts using chain handlers m68k/mac: Convert Mac to genirq m68k/amiga: Optimize interrupts using chain handlers m68k/amiga: Convert Amiga to genirq m68k/amiga: Refactor amiints.c m68k/atari: Remove code and comments about different irq types m68k/atari: Convert Atari to genirq m68k/irq: Add genirq support m68k/irq: Remove obsolete IRQ_FLG_* users m68k/irq: Rename {,__}m68k_handle_int() m68k/irq: Add m68k_setup_irq_controller() ...
Showing 31 changed files Side-by-side Diff
- arch/m68k/Kconfig
- arch/m68k/Kconfig.bus
- arch/m68k/Kconfig.devices
- arch/m68k/amiga/amiints.c
- arch/m68k/amiga/cia.c
- arch/m68k/apollo/dn_ints.c
- arch/m68k/atari/ataints.c
- arch/m68k/bvme6000/config.c
- arch/m68k/hp300/time.c
- arch/m68k/include/asm/hardirq.h
- arch/m68k/include/asm/irq.h
- arch/m68k/include/asm/macintosh.h
- arch/m68k/include/asm/q40ints.h
- arch/m68k/kernel/Makefile
- arch/m68k/kernel/entry_mm.S
- arch/m68k/kernel/ints.c
- arch/m68k/mac/baboon.c
- arch/m68k/mac/iop.c
- arch/m68k/mac/macints.c
- arch/m68k/mac/oss.c
- arch/m68k/mac/psc.c
- arch/m68k/mac/via.c
- arch/m68k/mvme147/config.c
- arch/m68k/mvme16x/config.c
- arch/m68k/q40/q40ints.c
- arch/m68k/sun3/sun3ints.c
- drivers/ide/ide-cd.c
- drivers/ide/ide-floppy.c
- drivers/ide/ide-tape.c
- drivers/macintosh/via-macii.c
- drivers/macintosh/via-maciisi.c
arch/m68k/Kconfig
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | select HAVE_IDE |
5 | 5 | select HAVE_AOUT if MMU |
6 | 6 | select GENERIC_ATOMIC64 if MMU |
7 | - select HAVE_GENERIC_HARDIRQS if !MMU | |
8 | - select GENERIC_IRQ_SHOW if !MMU | |
7 | + select HAVE_GENERIC_HARDIRQS | |
8 | + select GENERIC_IRQ_SHOW | |
9 | 9 | select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS |
10 | 10 | |
11 | 11 | config RWSEM_GENERIC_SPINLOCK |
arch/m68k/Kconfig.bus
... | ... | @@ -2,6 +2,15 @@ |
2 | 2 | |
3 | 3 | comment "Bus Support" |
4 | 4 | |
5 | +config DIO | |
6 | + bool "DIO bus support" | |
7 | + depends on HP300 | |
8 | + default y | |
9 | + help | |
10 | + Say Y here to enable support for the "DIO" expansion bus used in | |
11 | + HP300 machines. If you are using such a system you almost certainly | |
12 | + want this. | |
13 | + | |
5 | 14 | config NUBUS |
6 | 15 | bool |
7 | 16 | depends on MAC |
arch/m68k/Kconfig.devices
... | ... | @@ -24,6 +24,37 @@ |
24 | 24 | including the model, CPU, MMU, clock speed, BogoMIPS rating, |
25 | 25 | and memory size. |
26 | 26 | |
27 | +config NATFEAT | |
28 | + bool "ARAnyM emulator support" | |
29 | + depends on ATARI | |
30 | + help | |
31 | + This option enables support for ARAnyM native features, such as | |
32 | + access to a disk image as /dev/hda. | |
33 | + | |
34 | +config NFBLOCK | |
35 | + tristate "NatFeat block device support" | |
36 | + depends on BLOCK && NATFEAT | |
37 | + help | |
38 | + Say Y to include support for the ARAnyM NatFeat block device | |
39 | + which allows direct access to the hard drives without using | |
40 | + the hardware emulation. | |
41 | + | |
42 | +config NFCON | |
43 | + tristate "NatFeat console driver" | |
44 | + depends on NATFEAT | |
45 | + help | |
46 | + Say Y to include support for the ARAnyM NatFeat console driver | |
47 | + which allows the console output to be redirected to the stderr | |
48 | + output of ARAnyM. | |
49 | + | |
50 | +config NFETH | |
51 | + tristate "NatFeat Ethernet support" | |
52 | + depends on ETHERNET && NATFEAT | |
53 | + help | |
54 | + Say Y to include support for the ARAnyM NatFeat network device | |
55 | + which will emulate a regular ethernet device while presenting an | |
56 | + ethertap device to the host system. | |
57 | + | |
27 | 58 | endmenu |
28 | 59 | |
29 | 60 | menu "Character devices" |
arch/m68k/amiga/amiints.c
1 | 1 | /* |
2 | - * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code | |
2 | + * Amiga Linux interrupt handling code | |
3 | 3 | * |
4 | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | 5 | * License. See the file COPYING in the main directory of this archive |
6 | 6 | * for more details. |
7 | - * | |
8 | - * 11/07/96: rewritten interrupt handling, irq lists are exists now only for | |
9 | - * this sources where it makes sense (VERTB/PORTS/EXTER) and you must | |
10 | - * be careful that dev_id for this sources is unique since this the | |
11 | - * only possibility to distinguish between different handlers for | |
12 | - * free_irq. irq lists also have different irq flags: | |
13 | - * - IRQ_FLG_FAST: handler is inserted at top of list (after other | |
14 | - * fast handlers) | |
15 | - * - IRQ_FLG_SLOW: handler is inserted at bottom of list and before | |
16 | - * they're executed irq level is set to the previous | |
17 | - * one, but handlers don't need to be reentrant, if | |
18 | - * reentrance occurred, slow handlers will be just | |
19 | - * called again. | |
20 | - * The whole interrupt handling for CIAs is moved to cia.c | |
21 | - * /Roman Zippel | |
22 | - * | |
23 | - * 07/08/99: rewamp of the interrupt handling - we now have two types of | |
24 | - * interrupts, normal and fast handlers, fast handlers being | |
25 | - * marked with IRQF_DISABLED and runs with all other interrupts | |
26 | - * disabled. Normal interrupts disable their own source but | |
27 | - * run with all other interrupt sources enabled. | |
28 | - * PORTS and EXTER interrupts are always shared even if the | |
29 | - * drivers do not explicitly mark this when calling | |
30 | - * request_irq which they really should do. | |
31 | - * This is similar to the way interrupts are handled on all | |
32 | - * other architectures and makes a ton of sense besides | |
33 | - * having the advantage of making it easier to share | |
34 | - * drivers. | |
35 | - * /Jes | |
36 | 7 | */ |
37 | 8 | |
38 | 9 | #include <linux/init.h> |
39 | 10 | #include <linux/interrupt.h> |
40 | 11 | #include <linux/errno.h> |
12 | +#include <linux/irq.h> | |
41 | 13 | |
42 | 14 | #include <asm/irq.h> |
43 | 15 | #include <asm/traps.h> |
44 | 16 | |
45 | 17 | |
46 | 18 | |
47 | 19 | |
48 | 20 | |
49 | 21 | |
50 | 22 | |
51 | 23 | |
52 | 24 | |
53 | 25 | |
54 | 26 | |
55 | 27 | |
56 | 28 | |
57 | 29 | |
58 | 30 | |
59 | 31 | |
60 | 32 | |
61 | 33 | |
62 | 34 | |
63 | 35 | |
64 | 36 | |
65 | 37 | |
66 | 38 | |
67 | 39 | |
68 | 40 | |
69 | 41 | |
70 | 42 | |
... | ... | @@ -45,171 +17,159 @@ |
45 | 17 | #include <asm/amigaints.h> |
46 | 18 | #include <asm/amipcmcia.h> |
47 | 19 | |
48 | -static void amiga_enable_irq(unsigned int irq); | |
49 | -static void amiga_disable_irq(unsigned int irq); | |
50 | -static irqreturn_t ami_int1(int irq, void *dev_id); | |
51 | -static irqreturn_t ami_int3(int irq, void *dev_id); | |
52 | -static irqreturn_t ami_int4(int irq, void *dev_id); | |
53 | -static irqreturn_t ami_int5(int irq, void *dev_id); | |
54 | 20 | |
55 | -static struct irq_controller amiga_irq_controller = { | |
56 | - .name = "amiga", | |
57 | - .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), | |
58 | - .enable = amiga_enable_irq, | |
59 | - .disable = amiga_disable_irq, | |
60 | -}; | |
61 | - | |
62 | 21 | /* |
63 | - * void amiga_init_IRQ(void) | |
64 | - * | |
65 | - * Parameters: None | |
66 | - * | |
67 | - * Returns: Nothing | |
68 | - * | |
69 | - * This function should be called during kernel startup to initialize | |
70 | - * the amiga IRQ handling routines. | |
71 | - */ | |
72 | - | |
73 | -void __init amiga_init_IRQ(void) | |
74 | -{ | |
75 | - if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) | |
76 | - pr_err("Couldn't register int%d\n", 1); | |
77 | - if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) | |
78 | - pr_err("Couldn't register int%d\n", 3); | |
79 | - if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) | |
80 | - pr_err("Couldn't register int%d\n", 4); | |
81 | - if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) | |
82 | - pr_err("Couldn't register int%d\n", 5); | |
83 | - | |
84 | - m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); | |
85 | - | |
86 | - /* turn off PCMCIA interrupts */ | |
87 | - if (AMIGAHW_PRESENT(PCMCIA)) | |
88 | - gayle.inten = GAYLE_IRQ_IDE; | |
89 | - | |
90 | - /* turn off all interrupts and enable the master interrupt bit */ | |
91 | - amiga_custom.intena = 0x7fff; | |
92 | - amiga_custom.intreq = 0x7fff; | |
93 | - amiga_custom.intena = IF_SETCLR | IF_INTEN; | |
94 | - | |
95 | - cia_init_IRQ(&ciaa_base); | |
96 | - cia_init_IRQ(&ciab_base); | |
97 | -} | |
98 | - | |
99 | -/* | |
100 | 22 | * Enable/disable a particular machine specific interrupt source. |
101 | 23 | * Note that this may affect other interrupts in case of a shared interrupt. |
102 | 24 | * This function should only be called for a _very_ short time to change some |
103 | 25 | * internal data, that may not be changed by the interrupt at the same time. |
104 | 26 | */ |
105 | 27 | |
106 | -static void amiga_enable_irq(unsigned int irq) | |
28 | +static void amiga_irq_enable(struct irq_data *data) | |
107 | 29 | { |
108 | - amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); | |
30 | + amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER)); | |
109 | 31 | } |
110 | 32 | |
111 | -static void amiga_disable_irq(unsigned int irq) | |
33 | +static void amiga_irq_disable(struct irq_data *data) | |
112 | 34 | { |
113 | - amiga_custom.intena = 1 << (irq - IRQ_USER); | |
35 | + amiga_custom.intena = 1 << (data->irq - IRQ_USER); | |
114 | 36 | } |
115 | 37 | |
38 | +static struct irq_chip amiga_irq_chip = { | |
39 | + .name = "amiga", | |
40 | + .irq_enable = amiga_irq_enable, | |
41 | + .irq_disable = amiga_irq_disable, | |
42 | +}; | |
43 | + | |
44 | + | |
116 | 45 | /* |
117 | 46 | * The builtin Amiga hardware interrupt handlers. |
118 | 47 | */ |
119 | 48 | |
120 | -static irqreturn_t ami_int1(int irq, void *dev_id) | |
49 | +static void ami_int1(unsigned int irq, struct irq_desc *desc) | |
121 | 50 | { |
122 | 51 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
123 | 52 | |
124 | 53 | /* if serial transmit buffer empty, interrupt */ |
125 | 54 | if (ints & IF_TBE) { |
126 | 55 | amiga_custom.intreq = IF_TBE; |
127 | - m68k_handle_int(IRQ_AMIGA_TBE); | |
56 | + generic_handle_irq(IRQ_AMIGA_TBE); | |
128 | 57 | } |
129 | 58 | |
130 | 59 | /* if floppy disk transfer complete, interrupt */ |
131 | 60 | if (ints & IF_DSKBLK) { |
132 | 61 | amiga_custom.intreq = IF_DSKBLK; |
133 | - m68k_handle_int(IRQ_AMIGA_DSKBLK); | |
62 | + generic_handle_irq(IRQ_AMIGA_DSKBLK); | |
134 | 63 | } |
135 | 64 | |
136 | 65 | /* if software interrupt set, interrupt */ |
137 | 66 | if (ints & IF_SOFT) { |
138 | 67 | amiga_custom.intreq = IF_SOFT; |
139 | - m68k_handle_int(IRQ_AMIGA_SOFT); | |
68 | + generic_handle_irq(IRQ_AMIGA_SOFT); | |
140 | 69 | } |
141 | - return IRQ_HANDLED; | |
142 | 70 | } |
143 | 71 | |
144 | -static irqreturn_t ami_int3(int irq, void *dev_id) | |
72 | +static void ami_int3(unsigned int irq, struct irq_desc *desc) | |
145 | 73 | { |
146 | 74 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
147 | 75 | |
148 | 76 | /* if a blitter interrupt */ |
149 | 77 | if (ints & IF_BLIT) { |
150 | 78 | amiga_custom.intreq = IF_BLIT; |
151 | - m68k_handle_int(IRQ_AMIGA_BLIT); | |
79 | + generic_handle_irq(IRQ_AMIGA_BLIT); | |
152 | 80 | } |
153 | 81 | |
154 | 82 | /* if a copper interrupt */ |
155 | 83 | if (ints & IF_COPER) { |
156 | 84 | amiga_custom.intreq = IF_COPER; |
157 | - m68k_handle_int(IRQ_AMIGA_COPPER); | |
85 | + generic_handle_irq(IRQ_AMIGA_COPPER); | |
158 | 86 | } |
159 | 87 | |
160 | 88 | /* if a vertical blank interrupt */ |
161 | 89 | if (ints & IF_VERTB) { |
162 | 90 | amiga_custom.intreq = IF_VERTB; |
163 | - m68k_handle_int(IRQ_AMIGA_VERTB); | |
91 | + generic_handle_irq(IRQ_AMIGA_VERTB); | |
164 | 92 | } |
165 | - return IRQ_HANDLED; | |
166 | 93 | } |
167 | 94 | |
168 | -static irqreturn_t ami_int4(int irq, void *dev_id) | |
95 | +static void ami_int4(unsigned int irq, struct irq_desc *desc) | |
169 | 96 | { |
170 | 97 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
171 | 98 | |
172 | 99 | /* if audio 0 interrupt */ |
173 | 100 | if (ints & IF_AUD0) { |
174 | 101 | amiga_custom.intreq = IF_AUD0; |
175 | - m68k_handle_int(IRQ_AMIGA_AUD0); | |
102 | + generic_handle_irq(IRQ_AMIGA_AUD0); | |
176 | 103 | } |
177 | 104 | |
178 | 105 | /* if audio 1 interrupt */ |
179 | 106 | if (ints & IF_AUD1) { |
180 | 107 | amiga_custom.intreq = IF_AUD1; |
181 | - m68k_handle_int(IRQ_AMIGA_AUD1); | |
108 | + generic_handle_irq(IRQ_AMIGA_AUD1); | |
182 | 109 | } |
183 | 110 | |
184 | 111 | /* if audio 2 interrupt */ |
185 | 112 | if (ints & IF_AUD2) { |
186 | 113 | amiga_custom.intreq = IF_AUD2; |
187 | - m68k_handle_int(IRQ_AMIGA_AUD2); | |
114 | + generic_handle_irq(IRQ_AMIGA_AUD2); | |
188 | 115 | } |
189 | 116 | |
190 | 117 | /* if audio 3 interrupt */ |
191 | 118 | if (ints & IF_AUD3) { |
192 | 119 | amiga_custom.intreq = IF_AUD3; |
193 | - m68k_handle_int(IRQ_AMIGA_AUD3); | |
120 | + generic_handle_irq(IRQ_AMIGA_AUD3); | |
194 | 121 | } |
195 | - return IRQ_HANDLED; | |
196 | 122 | } |
197 | 123 | |
198 | -static irqreturn_t ami_int5(int irq, void *dev_id) | |
124 | +static void ami_int5(unsigned int irq, struct irq_desc *desc) | |
199 | 125 | { |
200 | 126 | unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; |
201 | 127 | |
202 | 128 | /* if serial receive buffer full interrupt */ |
203 | 129 | if (ints & IF_RBF) { |
204 | 130 | /* acknowledge of IF_RBF must be done by the serial interrupt */ |
205 | - m68k_handle_int(IRQ_AMIGA_RBF); | |
131 | + generic_handle_irq(IRQ_AMIGA_RBF); | |
206 | 132 | } |
207 | 133 | |
208 | 134 | /* if a disk sync interrupt */ |
209 | 135 | if (ints & IF_DSKSYN) { |
210 | 136 | amiga_custom.intreq = IF_DSKSYN; |
211 | - m68k_handle_int(IRQ_AMIGA_DSKSYN); | |
137 | + generic_handle_irq(IRQ_AMIGA_DSKSYN); | |
212 | 138 | } |
213 | - return IRQ_HANDLED; | |
139 | +} | |
140 | + | |
141 | + | |
142 | +/* | |
143 | + * void amiga_init_IRQ(void) | |
144 | + * | |
145 | + * Parameters: None | |
146 | + * | |
147 | + * Returns: Nothing | |
148 | + * | |
149 | + * This function should be called during kernel startup to initialize | |
150 | + * the amiga IRQ handling routines. | |
151 | + */ | |
152 | + | |
153 | +void __init amiga_init_IRQ(void) | |
154 | +{ | |
155 | + m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, | |
156 | + AMI_STD_IRQS); | |
157 | + | |
158 | + irq_set_chained_handler(IRQ_AUTO_1, ami_int1); | |
159 | + irq_set_chained_handler(IRQ_AUTO_3, ami_int3); | |
160 | + irq_set_chained_handler(IRQ_AUTO_4, ami_int4); | |
161 | + irq_set_chained_handler(IRQ_AUTO_5, ami_int5); | |
162 | + | |
163 | + /* turn off PCMCIA interrupts */ | |
164 | + if (AMIGAHW_PRESENT(PCMCIA)) | |
165 | + gayle.inten = GAYLE_IRQ_IDE; | |
166 | + | |
167 | + /* turn off all interrupts and enable the master interrupt bit */ | |
168 | + amiga_custom.intena = 0x7fff; | |
169 | + amiga_custom.intreq = 0x7fff; | |
170 | + amiga_custom.intena = IF_SETCLR | IF_INTEN; | |
171 | + | |
172 | + cia_init_IRQ(&ciaa_base); | |
173 | + cia_init_IRQ(&ciab_base); | |
214 | 174 | } |
arch/m68k/amiga/cia.c
... | ... | @@ -93,13 +93,14 @@ |
93 | 93 | amiga_custom.intreq = base->int_mask; |
94 | 94 | for (; ints; mach_irq++, ints >>= 1) { |
95 | 95 | if (ints & 1) |
96 | - m68k_handle_int(mach_irq); | |
96 | + generic_handle_irq(mach_irq); | |
97 | 97 | } |
98 | 98 | return IRQ_HANDLED; |
99 | 99 | } |
100 | 100 | |
101 | -static void cia_enable_irq(unsigned int irq) | |
101 | +static void cia_irq_enable(struct irq_data *data) | |
102 | 102 | { |
103 | + unsigned int irq = data->irq; | |
103 | 104 | unsigned char mask; |
104 | 105 | |
105 | 106 | if (irq >= IRQ_AMIGA_CIAB) { |
106 | 107 | |
107 | 108 | |
108 | 109 | |
... | ... | @@ -113,19 +114,20 @@ |
113 | 114 | } |
114 | 115 | } |
115 | 116 | |
116 | -static void cia_disable_irq(unsigned int irq) | |
117 | +static void cia_irq_disable(struct irq_data *data) | |
117 | 118 | { |
119 | + unsigned int irq = data->irq; | |
120 | + | |
118 | 121 | if (irq >= IRQ_AMIGA_CIAB) |
119 | 122 | cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); |
120 | 123 | else |
121 | 124 | cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); |
122 | 125 | } |
123 | 126 | |
124 | -static struct irq_controller cia_irq_controller = { | |
127 | +static struct irq_chip cia_irq_chip = { | |
125 | 128 | .name = "cia", |
126 | - .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), | |
127 | - .enable = cia_enable_irq, | |
128 | - .disable = cia_disable_irq, | |
129 | + .irq_enable = cia_irq_enable, | |
130 | + .irq_disable = cia_irq_disable, | |
129 | 131 | }; |
130 | 132 | |
131 | 133 | /* |
132 | 134 | |
... | ... | @@ -134,9 +136,9 @@ |
134 | 136 | * into this chain. |
135 | 137 | */ |
136 | 138 | |
137 | -static void auto_enable_irq(unsigned int irq) | |
139 | +static void auto_irq_enable(struct irq_data *data) | |
138 | 140 | { |
139 | - switch (irq) { | |
141 | + switch (data->irq) { | |
140 | 142 | case IRQ_AUTO_2: |
141 | 143 | amiga_custom.intena = IF_SETCLR | IF_PORTS; |
142 | 144 | break; |
143 | 145 | |
... | ... | @@ -146,9 +148,9 @@ |
146 | 148 | } |
147 | 149 | } |
148 | 150 | |
149 | -static void auto_disable_irq(unsigned int irq) | |
151 | +static void auto_irq_disable(struct irq_data *data) | |
150 | 152 | { |
151 | - switch (irq) { | |
153 | + switch (data->irq) { | |
152 | 154 | case IRQ_AUTO_2: |
153 | 155 | amiga_custom.intena = IF_PORTS; |
154 | 156 | break; |
155 | 157 | |
156 | 158 | |
157 | 159 | |
... | ... | @@ -158,24 +160,25 @@ |
158 | 160 | } |
159 | 161 | } |
160 | 162 | |
161 | -static struct irq_controller auto_irq_controller = { | |
163 | +static struct irq_chip auto_irq_chip = { | |
162 | 164 | .name = "auto", |
163 | - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), | |
164 | - .enable = auto_enable_irq, | |
165 | - .disable = auto_disable_irq, | |
165 | + .irq_enable = auto_irq_enable, | |
166 | + .irq_disable = auto_irq_disable, | |
166 | 167 | }; |
167 | 168 | |
168 | 169 | void __init cia_init_IRQ(struct ciabase *base) |
169 | 170 | { |
170 | - m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); | |
171 | + m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq, | |
172 | + base->cia_irq, CIA_IRQS); | |
171 | 173 | |
172 | 174 | /* clear any pending interrupt and turn off all interrupts */ |
173 | 175 | cia_set_irq(base, CIA_ICR_ALL); |
174 | 176 | cia_able_irq(base, CIA_ICR_ALL); |
175 | 177 | |
176 | 178 | /* override auto int and install CIA handler */ |
177 | - m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); | |
178 | - m68k_irq_startup(base->handler_irq); | |
179 | + m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq, | |
180 | + base->handler_irq, 1); | |
181 | + m68k_irq_startup_irq(base->handler_irq); | |
179 | 182 | if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, |
180 | 183 | base->name, base)) |
181 | 184 | pr_err("Couldn't register %s interrupt\n", base->name); |
arch/m68k/apollo/dn_ints.c
1 | 1 | #include <linux/interrupt.h> |
2 | +#include <linux/irq.h> | |
2 | 3 | |
3 | -#include <asm/irq.h> | |
4 | 4 | #include <asm/traps.h> |
5 | 5 | #include <asm/apollohw.h> |
6 | 6 | |
7 | -void dn_process_int(unsigned int irq, struct pt_regs *fp) | |
7 | +unsigned int apollo_irq_startup(struct irq_data *data) | |
8 | 8 | { |
9 | - __m68k_handle_int(irq, fp); | |
9 | + unsigned int irq = data->irq; | |
10 | 10 | |
11 | - *(volatile unsigned char *)(pica)=0x20; | |
12 | - *(volatile unsigned char *)(picb)=0x20; | |
13 | -} | |
14 | - | |
15 | -int apollo_irq_startup(unsigned int irq) | |
16 | -{ | |
17 | 11 | if (irq < 8) |
18 | 12 | *(volatile unsigned char *)(pica+1) &= ~(1 << irq); |
19 | 13 | else |
20 | 14 | |
21 | 15 | |
22 | 16 | |
23 | 17 | |
... | ... | @@ -21,25 +15,34 @@ |
21 | 15 | return 0; |
22 | 16 | } |
23 | 17 | |
24 | -void apollo_irq_shutdown(unsigned int irq) | |
18 | +void apollo_irq_shutdown(struct irq_data *data) | |
25 | 19 | { |
20 | + unsigned int irq = data->irq; | |
21 | + | |
26 | 22 | if (irq < 8) |
27 | 23 | *(volatile unsigned char *)(pica+1) |= (1 << irq); |
28 | 24 | else |
29 | 25 | *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); |
30 | 26 | } |
31 | 27 | |
32 | -static struct irq_controller apollo_irq_controller = { | |
28 | +void apollo_irq_eoi(struct irq_data *data) | |
29 | +{ | |
30 | + *(volatile unsigned char *)(pica) = 0x20; | |
31 | + *(volatile unsigned char *)(picb) = 0x20; | |
32 | +} | |
33 | + | |
34 | +static struct irq_chip apollo_irq_chip = { | |
33 | 35 | .name = "apollo", |
34 | - .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), | |
35 | - .startup = apollo_irq_startup, | |
36 | - .shutdown = apollo_irq_shutdown, | |
36 | + .irq_startup = apollo_irq_startup, | |
37 | + .irq_shutdown = apollo_irq_shutdown, | |
38 | + .irq_eoi = apollo_irq_eoi, | |
37 | 39 | }; |
38 | 40 | |
39 | 41 | |
40 | 42 | void __init dn_init_IRQ(void) |
41 | 43 | { |
42 | - m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); | |
43 | - m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); | |
44 | + m68k_setup_user_interrupt(VEC_USER + 96, 16); | |
45 | + m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, | |
46 | + IRQ_APOLLO, 16); | |
44 | 47 | } |
arch/m68k/atari/ataints.c
... | ... | @@ -60,245 +60,9 @@ |
60 | 60 | * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP, |
61 | 61 | * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can |
62 | 62 | * be allocated by atari_register_vme_int(). |
63 | - * | |
64 | - * Each interrupt can be of three types: | |
65 | - * | |
66 | - * - SLOW: The handler runs with all interrupts enabled, except the one it | |
67 | - * was called by (to avoid reentering). This should be the usual method. | |
68 | - * But it is currently possible only for MFP ints, since only the MFP | |
69 | - * offers an easy way to mask interrupts. | |
70 | - * | |
71 | - * - FAST: The handler runs with all interrupts disabled. This should be used | |
72 | - * only for really fast handlers, that just do actions immediately | |
73 | - * necessary, and let the rest do a bottom half or task queue. | |
74 | - * | |
75 | - * - PRIORITIZED: The handler can be interrupted by higher-level ints | |
76 | - * (greater IPL, no MFP priorities!). This is the method of choice for ints | |
77 | - * which should be slow, but are not from a MFP. | |
78 | - * | |
79 | - * The feature of more than one handler for one int source is still there, but | |
80 | - * only applicable if all handers are of the same type. To not slow down | |
81 | - * processing of ints with only one handler by the chaining feature, the list | |
82 | - * calling function atari_call_irq_list() is only plugged in at the time the | |
83 | - * second handler is registered. | |
84 | - * | |
85 | - * Implementation notes: For fast-as-possible int handling, there are separate | |
86 | - * entry points for each type (slow/fast/prio). The assembler handler calls | |
87 | - * the irq directly in the usual case, no C wrapper is involved. In case of | |
88 | - * multiple handlers, atari_call_irq_list() is registered as handler and calls | |
89 | - * in turn the real irq's. To ease access from assembler level to the irq | |
90 | - * function pointer and accompanying data, these two are stored in a separate | |
91 | - * array, irq_handler[]. The rest of data (type, name) are put into a second | |
92 | - * array, irq_param, that is accessed from C only. For each slow interrupt (32 | |
93 | - * in all) there are separate handler functions, which makes it possible to | |
94 | - * hard-code the MFP register address and value, are necessary to mask the | |
95 | - * int. If there'd be only one generic function, lots of calculations would be | |
96 | - * needed to determine MFP register and int mask from the vector number :-( | |
97 | - * | |
98 | - * Furthermore, slow ints may not lower the IPL below its previous value | |
99 | - * (before the int happened). This is needed so that an int of class PRIO, on | |
100 | - * that this int may be stacked, cannot be reentered. This feature is | |
101 | - * implemented as follows: If the stack frame format is 1 (throwaway), the int | |
102 | - * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level | |
103 | - * 2, which still blocks the HSYNC, but no interrupts of interest. If the | |
104 | - * frame format is 0, the int is nested, and the old IPL value can be found in | |
105 | - * the sr copy in the frame. | |
106 | 63 | */ |
107 | 64 | |
108 | -#if 0 | |
109 | - | |
110 | -#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES) | |
111 | - | |
112 | -typedef void (*asm_irq_handler)(void); | |
113 | - | |
114 | -struct irqhandler { | |
115 | - irqreturn_t (*handler)(int, void *, struct pt_regs *); | |
116 | - void *dev_id; | |
117 | -}; | |
118 | - | |
119 | -struct irqparam { | |
120 | - unsigned long flags; | |
121 | - const char *devname; | |
122 | -}; | |
123 | - | |
124 | 65 | /* |
125 | - * Array with irq's and their parameter data. This array is accessed from low | |
126 | - * level assembler code, so an element size of 8 allows usage of index scaling | |
127 | - * addressing mode. | |
128 | - */ | |
129 | -static struct irqhandler irq_handler[NUM_INT_SOURCES]; | |
130 | - | |
131 | -/* | |
132 | - * This array hold the rest of parameters of int handlers: type | |
133 | - * (slow,fast,prio) and the name of the handler. These values are only | |
134 | - * accessed from C | |
135 | - */ | |
136 | -static struct irqparam irq_param[NUM_INT_SOURCES]; | |
137 | - | |
138 | -/* check for valid int number (complex, sigh...) */ | |
139 | -#define IS_VALID_INTNO(n) \ | |
140 | - ((n) > 0 && \ | |
141 | - /* autovec and ST-MFP ok anyway */ \ | |
142 | - (((n) < TTMFP_SOURCE_BASE) || \ | |
143 | - /* TT-MFP ok if present */ \ | |
144 | - ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \ | |
145 | - ATARIHW_PRESENT(TT_MFP)) || \ | |
146 | - /* SCC ok if present and number even */ \ | |
147 | - ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \ | |
148 | - !((n) & 1) && ATARIHW_PRESENT(SCC)) || \ | |
149 | - /* greater numbers ok if they are registered VME vectors */ \ | |
150 | - ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \ | |
151 | - free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE))))) | |
152 | - | |
153 | - | |
154 | -/* | |
155 | - * Here start the assembler entry points for interrupts | |
156 | - */ | |
157 | - | |
158 | -#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void) | |
159 | - | |
160 | -#define BUILD_SLOW_IRQ(n) \ | |
161 | -asmlinkage void IRQ_NAME(n); \ | |
162 | -/* Dummy function to allow asm with operands. */ \ | |
163 | -void atari_slow_irq_##n##_dummy (void) { \ | |
164 | -__asm__ (__ALIGN_STR "\n" \ | |
165 | -"atari_slow_irq_" #n "_handler:\t" \ | |
166 | -" addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \ | |
167 | - SAVE_ALL_INT "\n" \ | |
168 | - GET_CURRENT(%%d0) "\n" \ | |
169 | -" andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \ | |
170 | - /* get old IPL from stack frame */ \ | |
171 | -" bfextu %%sp@(%c2){#5,#3},%%d0\n" \ | |
172 | -" movew %%sr,%%d1\n" \ | |
173 | -" bfins %%d0,%%d1{#21,#3}\n" \ | |
174 | -" movew %%d1,%%sr\n" /* set IPL = previous value */ \ | |
175 | -" addql #1,%a0\n" \ | |
176 | -" lea %a1,%%a0\n" \ | |
177 | -" pea %%sp@\n" /* push addr of frame */ \ | |
178 | -" movel %%a0@(4),%%sp@-\n" /* push handler data */ \ | |
179 | -" pea (%c3+8)\n" /* push int number */ \ | |
180 | -" movel %%a0@,%%a0\n" \ | |
181 | -" jbsr %%a0@\n" /* call the handler */ \ | |
182 | -" addql #8,%%sp\n" \ | |
183 | -" addql #4,%%sp\n" \ | |
184 | -" orw #0x0600,%%sr\n" \ | |
185 | -" andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \ | |
186 | -" orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \ | |
187 | -" jbra ret_from_interrupt\n" \ | |
188 | - : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ | |
189 | - "n" (PT_OFF_SR), "n" (n), \ | |
190 | - "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ | |
191 | - : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ | |
192 | - "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ | |
193 | -); \ | |
194 | - for (;;); /* fake noreturn */ \ | |
195 | -} | |
196 | - | |
197 | -BUILD_SLOW_IRQ(0); | |
198 | -BUILD_SLOW_IRQ(1); | |
199 | -BUILD_SLOW_IRQ(2); | |
200 | -BUILD_SLOW_IRQ(3); | |
201 | -BUILD_SLOW_IRQ(4); | |
202 | -BUILD_SLOW_IRQ(5); | |
203 | -BUILD_SLOW_IRQ(6); | |
204 | -BUILD_SLOW_IRQ(7); | |
205 | -BUILD_SLOW_IRQ(8); | |
206 | -BUILD_SLOW_IRQ(9); | |
207 | -BUILD_SLOW_IRQ(10); | |
208 | -BUILD_SLOW_IRQ(11); | |
209 | -BUILD_SLOW_IRQ(12); | |
210 | -BUILD_SLOW_IRQ(13); | |
211 | -BUILD_SLOW_IRQ(14); | |
212 | -BUILD_SLOW_IRQ(15); | |
213 | -BUILD_SLOW_IRQ(16); | |
214 | -BUILD_SLOW_IRQ(17); | |
215 | -BUILD_SLOW_IRQ(18); | |
216 | -BUILD_SLOW_IRQ(19); | |
217 | -BUILD_SLOW_IRQ(20); | |
218 | -BUILD_SLOW_IRQ(21); | |
219 | -BUILD_SLOW_IRQ(22); | |
220 | -BUILD_SLOW_IRQ(23); | |
221 | -BUILD_SLOW_IRQ(24); | |
222 | -BUILD_SLOW_IRQ(25); | |
223 | -BUILD_SLOW_IRQ(26); | |
224 | -BUILD_SLOW_IRQ(27); | |
225 | -BUILD_SLOW_IRQ(28); | |
226 | -BUILD_SLOW_IRQ(29); | |
227 | -BUILD_SLOW_IRQ(30); | |
228 | -BUILD_SLOW_IRQ(31); | |
229 | - | |
230 | -asm_irq_handler slow_handlers[32] = { | |
231 | - [0] = atari_slow_irq_0_handler, | |
232 | - [1] = atari_slow_irq_1_handler, | |
233 | - [2] = atari_slow_irq_2_handler, | |
234 | - [3] = atari_slow_irq_3_handler, | |
235 | - [4] = atari_slow_irq_4_handler, | |
236 | - [5] = atari_slow_irq_5_handler, | |
237 | - [6] = atari_slow_irq_6_handler, | |
238 | - [7] = atari_slow_irq_7_handler, | |
239 | - [8] = atari_slow_irq_8_handler, | |
240 | - [9] = atari_slow_irq_9_handler, | |
241 | - [10] = atari_slow_irq_10_handler, | |
242 | - [11] = atari_slow_irq_11_handler, | |
243 | - [12] = atari_slow_irq_12_handler, | |
244 | - [13] = atari_slow_irq_13_handler, | |
245 | - [14] = atari_slow_irq_14_handler, | |
246 | - [15] = atari_slow_irq_15_handler, | |
247 | - [16] = atari_slow_irq_16_handler, | |
248 | - [17] = atari_slow_irq_17_handler, | |
249 | - [18] = atari_slow_irq_18_handler, | |
250 | - [19] = atari_slow_irq_19_handler, | |
251 | - [20] = atari_slow_irq_20_handler, | |
252 | - [21] = atari_slow_irq_21_handler, | |
253 | - [22] = atari_slow_irq_22_handler, | |
254 | - [23] = atari_slow_irq_23_handler, | |
255 | - [24] = atari_slow_irq_24_handler, | |
256 | - [25] = atari_slow_irq_25_handler, | |
257 | - [26] = atari_slow_irq_26_handler, | |
258 | - [27] = atari_slow_irq_27_handler, | |
259 | - [28] = atari_slow_irq_28_handler, | |
260 | - [29] = atari_slow_irq_29_handler, | |
261 | - [30] = atari_slow_irq_30_handler, | |
262 | - [31] = atari_slow_irq_31_handler | |
263 | -}; | |
264 | - | |
265 | -asmlinkage void atari_fast_irq_handler( void ); | |
266 | -asmlinkage void atari_prio_irq_handler( void ); | |
267 | - | |
268 | -/* Dummy function to allow asm with operands. */ | |
269 | -void atari_fast_prio_irq_dummy (void) { | |
270 | -__asm__ (__ALIGN_STR "\n" | |
271 | -"atari_fast_irq_handler:\n\t" | |
272 | - "orw #0x700,%%sr\n" /* disable all interrupts */ | |
273 | -"atari_prio_irq_handler:\n\t" | |
274 | - "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */ | |
275 | - SAVE_ALL_INT "\n\t" | |
276 | - GET_CURRENT(%%d0) "\n\t" | |
277 | - /* get vector number from stack frame and convert to source */ | |
278 | - "bfextu %%sp@(%c1){#4,#10},%%d0\n\t" | |
279 | - "subw #(0x40-8),%%d0\n\t" | |
280 | - "jpl 1f\n\t" | |
281 | - "addw #(0x40-8-0x18),%%d0\n" | |
282 | - "1:\tlea %a0,%%a0\n\t" | |
283 | - "addql #1,%%a0@(%%d0:l:4)\n\t" | |
284 | - "lea irq_handler,%%a0\n\t" | |
285 | - "lea %%a0@(%%d0:l:8),%%a0\n\t" | |
286 | - "pea %%sp@\n\t" /* push frame address */ | |
287 | - "movel %%a0@(4),%%sp@-\n\t" /* push handler data */ | |
288 | - "movel %%d0,%%sp@-\n\t" /* push int number */ | |
289 | - "movel %%a0@,%%a0\n\t" | |
290 | - "jsr %%a0@\n\t" /* and call the handler */ | |
291 | - "addql #8,%%sp\n\t" | |
292 | - "addql #4,%%sp\n\t" | |
293 | - "jbra ret_from_interrupt" | |
294 | - : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC), | |
295 | - "m" (preempt_count()), "di" (HARDIRQ_OFFSET) | |
296 | -); | |
297 | - for (;;); | |
298 | -} | |
299 | -#endif | |
300 | - | |
301 | -/* | |
302 | 66 | * Bitmap for free interrupt vector numbers |
303 | 67 | * (new vectors starting from 0x70 can be allocated by |
304 | 68 | * atari_register_vme_int()) |
305 | 69 | |
306 | 70 | |
307 | 71 | |
308 | 72 | |
309 | 73 | |
310 | 74 | |
... | ... | @@ -320,31 +84,44 @@ |
320 | 84 | |
321 | 85 | extern int atari_SCC_reset_done; |
322 | 86 | |
323 | -static int atari_startup_irq(unsigned int irq) | |
87 | +static unsigned int atari_irq_startup(struct irq_data *data) | |
324 | 88 | { |
325 | - m68k_irq_startup(irq); | |
89 | + unsigned int irq = data->irq; | |
90 | + | |
91 | + m68k_irq_startup(data); | |
326 | 92 | atari_turnon_irq(irq); |
327 | 93 | atari_enable_irq(irq); |
328 | 94 | return 0; |
329 | 95 | } |
330 | 96 | |
331 | -static void atari_shutdown_irq(unsigned int irq) | |
97 | +static void atari_irq_shutdown(struct irq_data *data) | |
332 | 98 | { |
99 | + unsigned int irq = data->irq; | |
100 | + | |
333 | 101 | atari_disable_irq(irq); |
334 | 102 | atari_turnoff_irq(irq); |
335 | - m68k_irq_shutdown(irq); | |
103 | + m68k_irq_shutdown(data); | |
336 | 104 | |
337 | 105 | if (irq == IRQ_AUTO_4) |
338 | 106 | vectors[VEC_INT4] = falcon_hblhandler; |
339 | 107 | } |
340 | 108 | |
341 | -static struct irq_controller atari_irq_controller = { | |
109 | +static void atari_irq_enable(struct irq_data *data) | |
110 | +{ | |
111 | + atari_enable_irq(data->irq); | |
112 | +} | |
113 | + | |
114 | +static void atari_irq_disable(struct irq_data *data) | |
115 | +{ | |
116 | + atari_disable_irq(data->irq); | |
117 | +} | |
118 | + | |
119 | +static struct irq_chip atari_irq_chip = { | |
342 | 120 | .name = "atari", |
343 | - .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), | |
344 | - .startup = atari_startup_irq, | |
345 | - .shutdown = atari_shutdown_irq, | |
346 | - .enable = atari_enable_irq, | |
347 | - .disable = atari_disable_irq, | |
121 | + .irq_startup = atari_irq_startup, | |
122 | + .irq_shutdown = atari_irq_shutdown, | |
123 | + .irq_enable = atari_irq_enable, | |
124 | + .irq_disable = atari_irq_disable, | |
348 | 125 | }; |
349 | 126 | |
350 | 127 | /* |
... | ... | @@ -360,8 +137,9 @@ |
360 | 137 | |
361 | 138 | void __init atari_init_IRQ(void) |
362 | 139 | { |
363 | - m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); | |
364 | - m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); | |
140 | + m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER); | |
141 | + m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1, | |
142 | + NUM_ATARI_SOURCES - 1); | |
365 | 143 | |
366 | 144 | /* Initialize the MFP(s) */ |
367 | 145 |
arch/m68k/bvme6000/config.c
arch/m68k/hp300/time.c
... | ... | @@ -70,7 +70,7 @@ |
70 | 70 | |
71 | 71 | asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); |
72 | 72 | |
73 | - if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector)) | |
73 | + if (request_irq(IRQ_AUTO_6, hp300_tick, 0, "timer tick", vector)) | |
74 | 74 | pr_err("Couldn't register timer interrupt\n"); |
75 | 75 | |
76 | 76 | out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ |
arch/m68k/include/asm/hardirq.h
... | ... | @@ -18,6 +18,11 @@ |
18 | 18 | |
19 | 19 | #ifdef CONFIG_MMU |
20 | 20 | |
21 | +static inline void ack_bad_irq(unsigned int irq) | |
22 | +{ | |
23 | + pr_crit("unexpected IRQ trap at vector %02x\n", irq); | |
24 | +} | |
25 | + | |
21 | 26 | /* entry.S is sensitive to the offsets of these fields */ |
22 | 27 | typedef struct { |
23 | 28 | unsigned int __softirq_pending; |
arch/m68k/include/asm/irq.h
... | ... | @@ -27,11 +27,6 @@ |
27 | 27 | |
28 | 28 | #ifdef CONFIG_MMU |
29 | 29 | |
30 | -#include <linux/linkage.h> | |
31 | -#include <linux/hardirq.h> | |
32 | -#include <linux/irqreturn.h> | |
33 | -#include <linux/spinlock_types.h> | |
34 | - | |
35 | 30 | /* |
36 | 31 | * Interrupt source definitions |
37 | 32 | * General interrupt sources are the level 1-7. |
... | ... | @@ -54,10 +49,6 @@ |
54 | 49 | |
55 | 50 | #define IRQ_USER 8 |
56 | 51 | |
57 | -extern unsigned int irq_canonicalize(unsigned int irq); | |
58 | - | |
59 | -struct pt_regs; | |
60 | - | |
61 | 52 | /* |
62 | 53 | * various flags for request_irq() - the Amiga now uses the standard |
63 | 54 | * mechanism like all other architectures - IRQF_DISABLED and |
64 | 55 | |
65 | 56 | |
66 | 57 | |
... | ... | @@ -71,58 +62,28 @@ |
71 | 62 | #define IRQ_FLG_STD (0x8000) /* internally used */ |
72 | 63 | #endif |
73 | 64 | |
74 | -/* | |
75 | - * This structure is used to chain together the ISRs for a particular | |
76 | - * interrupt source (if it supports chaining). | |
77 | - */ | |
78 | -typedef struct irq_node { | |
79 | - irqreturn_t (*handler)(int, void *); | |
80 | - void *dev_id; | |
81 | - struct irq_node *next; | |
82 | - unsigned long flags; | |
83 | - const char *devname; | |
84 | -} irq_node_t; | |
65 | +struct irq_data; | |
66 | +struct irq_chip; | |
67 | +struct irq_desc; | |
68 | +extern unsigned int m68k_irq_startup(struct irq_data *data); | |
69 | +extern unsigned int m68k_irq_startup_irq(unsigned int irq); | |
70 | +extern void m68k_irq_shutdown(struct irq_data *data); | |
71 | +extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, | |
72 | + struct pt_regs *)); | |
73 | +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt); | |
74 | +extern void m68k_setup_irq_controller(struct irq_chip *, | |
75 | + void (*handle)(unsigned int irq, | |
76 | + struct irq_desc *desc), | |
77 | + unsigned int irq, unsigned int cnt); | |
85 | 78 | |
86 | -/* | |
87 | - * This structure has only 4 elements for speed reasons | |
88 | - */ | |
89 | -struct irq_handler { | |
90 | - int (*handler)(int, void *); | |
91 | - unsigned long flags; | |
92 | - void *dev_id; | |
93 | - const char *devname; | |
94 | -}; | |
79 | +extern unsigned int irq_canonicalize(unsigned int irq); | |
95 | 80 | |
96 | -struct irq_controller { | |
97 | - const char *name; | |
98 | - spinlock_t lock; | |
99 | - int (*startup)(unsigned int irq); | |
100 | - void (*shutdown)(unsigned int irq); | |
101 | - void (*enable)(unsigned int irq); | |
102 | - void (*disable)(unsigned int irq); | |
103 | -}; | |
104 | - | |
105 | -extern int m68k_irq_startup(unsigned int); | |
106 | -extern void m68k_irq_shutdown(unsigned int); | |
107 | - | |
108 | -/* | |
109 | - * This function returns a new irq_node_t | |
110 | - */ | |
111 | -extern irq_node_t *new_irq_node(void); | |
112 | - | |
113 | -extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); | |
114 | -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | |
115 | - void (*handler)(unsigned int, struct pt_regs *)); | |
116 | -extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); | |
117 | - | |
118 | -asmlinkage void m68k_handle_int(unsigned int); | |
119 | -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); | |
120 | - | |
121 | 81 | #else |
122 | 82 | #define irq_canonicalize(irq) (irq) |
123 | 83 | #endif /* CONFIG_MMU */ |
124 | 84 | |
125 | 85 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs); |
86 | +extern atomic_t irq_err_count; | |
126 | 87 | |
127 | 88 | #endif /* _M68K_IRQ_H_ */ |
arch/m68k/include/asm/macintosh.h
... | ... | @@ -12,6 +12,8 @@ |
12 | 12 | extern void mac_poweroff(void); |
13 | 13 | extern void mac_init_IRQ(void); |
14 | 14 | extern int mac_irq_pending(unsigned int); |
15 | +extern void mac_irq_enable(struct irq_data *data); | |
16 | +extern void mac_irq_disable(struct irq_data *data); | |
15 | 17 | |
16 | 18 | /* |
17 | 19 | * Floppy driver magic hook - probably shouldn't be here |
arch/m68k/include/asm/q40ints.h
arch/m68k/kernel/Makefile
... | ... | @@ -6,16 +6,15 @@ |
6 | 6 | extra-$(CONFIG_SUN3) := sun3-head.o |
7 | 7 | extra-y += vmlinux.lds |
8 | 8 | |
9 | -obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \ | |
10 | - sys_m68k.o syscalltable.o time.o traps.o | |
9 | +obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \ | |
10 | + signal.o sys_m68k.o syscalltable.o time.o traps.o | |
11 | 11 | |
12 | -obj-$(CONFIG_MMU) += ints.o devres.o vectors.o | |
13 | -devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o | |
12 | +obj-$(CONFIG_MMU) += ints.o vectors.o | |
14 | 13 | |
15 | 14 | ifndef CONFIG_MMU_SUN3 |
16 | 15 | obj-y += dma.o |
17 | 16 | endif |
18 | 17 | ifndef CONFIG_MMU |
19 | -obj-y += init_task.o irq.o | |
18 | +obj-y += init_task.o | |
20 | 19 | endif |
arch/m68k/kernel/entry_mm.S
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | .globl sys_fork, sys_clone, sys_vfork |
49 | 49 | .globl ret_from_interrupt, bad_interrupt |
50 | 50 | .globl auto_irqhandler_fixup |
51 | -.globl user_irqvec_fixup, user_irqhandler_fixup | |
51 | +.globl user_irqvec_fixup | |
52 | 52 | |
53 | 53 | .text |
54 | 54 | ENTRY(buserr) |
... | ... | @@ -207,7 +207,7 @@ |
207 | 207 | movel %sp,%sp@- |
208 | 208 | movel %d0,%sp@- | put vector # on stack |
209 | 209 | auto_irqhandler_fixup = . + 2 |
210 | - jsr __m68k_handle_int | process the IRQ | |
210 | + jsr do_IRQ | process the IRQ | |
211 | 211 | addql #8,%sp | pop parameters off stack |
212 | 212 | |
213 | 213 | ret_from_interrupt: |
... | ... | @@ -240,8 +240,7 @@ |
240 | 240 | |
241 | 241 | movel %sp,%sp@- |
242 | 242 | movel %d0,%sp@- | put vector # on stack |
243 | -user_irqhandler_fixup = . + 2 | |
244 | - jsr __m68k_handle_int | process the IRQ | |
243 | + jsr do_IRQ | process the IRQ | |
245 | 244 | addql #8,%sp | pop parameters off stack |
246 | 245 | |
247 | 246 | subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) |
arch/m68k/kernel/ints.c
... | ... | @@ -4,25 +4,6 @@ |
4 | 4 | * This file is subject to the terms and conditions of the GNU General Public |
5 | 5 | * License. See the file COPYING in the main directory of this archive |
6 | 6 | * for more details. |
7 | - * | |
8 | - * 07/03/96: Timer initialization, and thus mach_sched_init(), | |
9 | - * removed from request_irq() and moved to init_time(). | |
10 | - * We should therefore consider renaming our add_isr() and | |
11 | - * remove_isr() to request_irq() and free_irq() | |
12 | - * respectively, so they are compliant with the other | |
13 | - * architectures. /Jes | |
14 | - * 11/07/96: Changed all add_/remove_isr() to request_/free_irq() calls. | |
15 | - * Removed irq list support, if any machine needs an irq server | |
16 | - * it must implement this itself (as it's already done), instead | |
17 | - * only default handler are used with mach_default_handler. | |
18 | - * request_irq got some flags different from other architectures: | |
19 | - * - IRQ_FLG_REPLACE : Replace an existing handler (the default one | |
20 | - * can be replaced without this flag) | |
21 | - * - IRQ_FLG_LOCK : handler can't be replaced | |
22 | - * There are other machine depending flags, see there | |
23 | - * If you want to replace a default handler you should know what | |
24 | - * you're doing, since it might handle different other irq sources | |
25 | - * which must be served /Roman Zippel | |
26 | 7 | */ |
27 | 8 | |
28 | 9 | #include <linux/module.h> |
29 | 10 | |
30 | 11 | |
31 | 12 | |
32 | 13 | |
33 | 14 | |
34 | 15 | |
... | ... | @@ -47,33 +28,22 @@ |
47 | 28 | #endif |
48 | 29 | |
49 | 30 | extern u32 auto_irqhandler_fixup[]; |
50 | -extern u32 user_irqhandler_fixup[]; | |
51 | 31 | extern u16 user_irqvec_fixup[]; |
52 | 32 | |
53 | -/* table for system interrupt handlers */ | |
54 | -static struct irq_node *irq_list[NR_IRQS]; | |
55 | -static struct irq_controller *irq_controller[NR_IRQS]; | |
56 | -static int irq_depth[NR_IRQS]; | |
57 | - | |
58 | 33 | static int m68k_first_user_vec; |
59 | 34 | |
60 | -static struct irq_controller auto_irq_controller = { | |
35 | +static struct irq_chip auto_irq_chip = { | |
61 | 36 | .name = "auto", |
62 | - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), | |
63 | - .startup = m68k_irq_startup, | |
64 | - .shutdown = m68k_irq_shutdown, | |
37 | + .irq_startup = m68k_irq_startup, | |
38 | + .irq_shutdown = m68k_irq_shutdown, | |
65 | 39 | }; |
66 | 40 | |
67 | -static struct irq_controller user_irq_controller = { | |
41 | +static struct irq_chip user_irq_chip = { | |
68 | 42 | .name = "user", |
69 | - .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), | |
70 | - .startup = m68k_irq_startup, | |
71 | - .shutdown = m68k_irq_shutdown, | |
43 | + .irq_startup = m68k_irq_startup, | |
44 | + .irq_shutdown = m68k_irq_shutdown, | |
72 | 45 | }; |
73 | 46 | |
74 | -#define NUM_IRQ_NODES 100 | |
75 | -static irq_node_t nodes[NUM_IRQ_NODES]; | |
76 | - | |
77 | 47 | /* |
78 | 48 | * void init_IRQ(void) |
79 | 49 | * |
... | ... | @@ -96,7 +66,7 @@ |
96 | 66 | } |
97 | 67 | |
98 | 68 | for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) |
99 | - irq_controller[i] = &auto_irq_controller; | |
69 | + irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq); | |
100 | 70 | |
101 | 71 | mach_init_IRQ(); |
102 | 72 | } |
... | ... | @@ -106,7 +76,7 @@ |
106 | 76 | * @handler: called from auto vector interrupts |
107 | 77 | * |
108 | 78 | * setup the handler to be called from auto vector interrupts instead of the |
109 | - * standard __m68k_handle_int(), it will be called with irq numbers in the range | |
79 | + * standard do_IRQ(), it will be called with irq numbers in the range | |
110 | 80 | * from IRQ_AUTO_1 - IRQ_AUTO_7. |
111 | 81 | */ |
112 | 82 | void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) |
113 | 83 | |
114 | 84 | |
115 | 85 | |
116 | 86 | |
117 | 87 | |
118 | 88 | |
119 | 89 | |
120 | 90 | |
121 | 91 | |
122 | 92 | |
123 | 93 | |
124 | 94 | |
125 | 95 | |
126 | 96 | |
127 | 97 | |
128 | 98 | |
129 | 99 | |
130 | 100 | |
... | ... | @@ -120,261 +90,73 @@ |
120 | 90 | * m68k_setup_user_interrupt |
121 | 91 | * @vec: first user vector interrupt to handle |
122 | 92 | * @cnt: number of active user vector interrupts |
123 | - * @handler: called from user vector interrupts | |
124 | 93 | * |
125 | 94 | * setup user vector interrupts, this includes activating the specified range |
126 | 95 | * of interrupts, only then these interrupts can be requested (note: this is |
127 | - * different from auto vector interrupts). An optional handler can be installed | |
128 | - * to be called instead of the default __m68k_handle_int(), it will be called | |
129 | - * with irq numbers starting from IRQ_USER. | |
96 | + * different from auto vector interrupts). | |
130 | 97 | */ |
131 | -void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, | |
132 | - void (*handler)(unsigned int, struct pt_regs *)) | |
98 | +void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt) | |
133 | 99 | { |
134 | 100 | int i; |
135 | 101 | |
136 | 102 | BUG_ON(IRQ_USER + cnt > NR_IRQS); |
137 | 103 | m68k_first_user_vec = vec; |
138 | 104 | for (i = 0; i < cnt; i++) |
139 | - irq_controller[IRQ_USER + i] = &user_irq_controller; | |
105 | + irq_set_chip(IRQ_USER + i, &user_irq_chip); | |
140 | 106 | *user_irqvec_fixup = vec - IRQ_USER; |
141 | - if (handler) | |
142 | - *user_irqhandler_fixup = (u32)handler; | |
143 | 107 | flush_icache(); |
144 | 108 | } |
145 | 109 | |
146 | 110 | /** |
147 | 111 | * m68k_setup_irq_controller |
148 | - * @contr: irq controller which controls specified irq | |
112 | + * @chip: irq chip which controls specified irq | |
113 | + * @handle: flow handler which handles specified irq | |
149 | 114 | * @irq: first irq to be managed by the controller |
115 | + * @cnt: number of irqs to be managed by the controller | |
150 | 116 | * |
151 | 117 | * Change the controller for the specified range of irq, which will be used to |
152 | 118 | * manage these irq. auto/user irq already have a default controller, which can |
153 | 119 | * be changed as well, but the controller probably should use m68k_irq_startup/ |
154 | 120 | * m68k_irq_shutdown. |
155 | 121 | */ |
156 | -void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, | |
122 | +void m68k_setup_irq_controller(struct irq_chip *chip, | |
123 | + irq_flow_handler_t handle, unsigned int irq, | |
157 | 124 | unsigned int cnt) |
158 | 125 | { |
159 | 126 | int i; |
160 | 127 | |
161 | - for (i = 0; i < cnt; i++) | |
162 | - irq_controller[irq + i] = contr; | |
163 | -} | |
164 | - | |
165 | -irq_node_t *new_irq_node(void) | |
166 | -{ | |
167 | - irq_node_t *node; | |
168 | - short i; | |
169 | - | |
170 | - for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { | |
171 | - if (!node->handler) { | |
172 | - memset(node, 0, sizeof(*node)); | |
173 | - return node; | |
174 | - } | |
128 | + for (i = 0; i < cnt; i++) { | |
129 | + irq_set_chip(irq + i, chip); | |
130 | + if (handle) | |
131 | + irq_set_handler(irq + i, handle); | |
175 | 132 | } |
176 | - | |
177 | - printk ("new_irq_node: out of nodes\n"); | |
178 | - return NULL; | |
179 | 133 | } |
180 | 134 | |
181 | -int setup_irq(unsigned int irq, struct irq_node *node) | |
135 | +unsigned int m68k_irq_startup_irq(unsigned int irq) | |
182 | 136 | { |
183 | - struct irq_controller *contr; | |
184 | - struct irq_node **prev; | |
185 | - unsigned long flags; | |
186 | - | |
187 | - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | |
188 | - printk("%s: Incorrect IRQ %d from %s\n", | |
189 | - __func__, irq, node->devname); | |
190 | - return -ENXIO; | |
191 | - } | |
192 | - | |
193 | - spin_lock_irqsave(&contr->lock, flags); | |
194 | - | |
195 | - prev = irq_list + irq; | |
196 | - if (*prev) { | |
197 | - /* Can't share interrupts unless both agree to */ | |
198 | - if (!((*prev)->flags & node->flags & IRQF_SHARED)) { | |
199 | - spin_unlock_irqrestore(&contr->lock, flags); | |
200 | - return -EBUSY; | |
201 | - } | |
202 | - while (*prev) | |
203 | - prev = &(*prev)->next; | |
204 | - } | |
205 | - | |
206 | - if (!irq_list[irq]) { | |
207 | - if (contr->startup) | |
208 | - contr->startup(irq); | |
209 | - else | |
210 | - contr->enable(irq); | |
211 | - } | |
212 | - node->next = NULL; | |
213 | - *prev = node; | |
214 | - | |
215 | - spin_unlock_irqrestore(&contr->lock, flags); | |
216 | - | |
137 | + if (irq <= IRQ_AUTO_7) | |
138 | + vectors[VEC_SPUR + irq] = auto_inthandler; | |
139 | + else | |
140 | + vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler; | |
217 | 141 | return 0; |
218 | 142 | } |
219 | 143 | |
220 | -int request_irq(unsigned int irq, | |
221 | - irq_handler_t handler, | |
222 | - unsigned long flags, const char *devname, void *dev_id) | |
144 | +unsigned int m68k_irq_startup(struct irq_data *data) | |
223 | 145 | { |
224 | - struct irq_node *node; | |
225 | - int res; | |
226 | - | |
227 | - node = new_irq_node(); | |
228 | - if (!node) | |
229 | - return -ENOMEM; | |
230 | - | |
231 | - node->handler = handler; | |
232 | - node->flags = flags; | |
233 | - node->dev_id = dev_id; | |
234 | - node->devname = devname; | |
235 | - | |
236 | - res = setup_irq(irq, node); | |
237 | - if (res) | |
238 | - node->handler = NULL; | |
239 | - | |
240 | - return res; | |
146 | + return m68k_irq_startup_irq(data->irq); | |
241 | 147 | } |
242 | 148 | |
243 | -EXPORT_SYMBOL(request_irq); | |
244 | - | |
245 | -void free_irq(unsigned int irq, void *dev_id) | |
149 | +void m68k_irq_shutdown(struct irq_data *data) | |
246 | 150 | { |
247 | - struct irq_controller *contr; | |
248 | - struct irq_node **p, *node; | |
249 | - unsigned long flags; | |
151 | + unsigned int irq = data->irq; | |
250 | 152 | |
251 | - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | |
252 | - printk("%s: Incorrect IRQ %d\n", __func__, irq); | |
253 | - return; | |
254 | - } | |
255 | - | |
256 | - spin_lock_irqsave(&contr->lock, flags); | |
257 | - | |
258 | - p = irq_list + irq; | |
259 | - while ((node = *p)) { | |
260 | - if (node->dev_id == dev_id) | |
261 | - break; | |
262 | - p = &node->next; | |
263 | - } | |
264 | - | |
265 | - if (node) { | |
266 | - *p = node->next; | |
267 | - node->handler = NULL; | |
268 | - } else | |
269 | - printk("%s: Removing probably wrong IRQ %d\n", | |
270 | - __func__, irq); | |
271 | - | |
272 | - if (!irq_list[irq]) { | |
273 | - if (contr->shutdown) | |
274 | - contr->shutdown(irq); | |
275 | - else | |
276 | - contr->disable(irq); | |
277 | - } | |
278 | - | |
279 | - spin_unlock_irqrestore(&contr->lock, flags); | |
280 | -} | |
281 | - | |
282 | -EXPORT_SYMBOL(free_irq); | |
283 | - | |
284 | -void enable_irq(unsigned int irq) | |
285 | -{ | |
286 | - struct irq_controller *contr; | |
287 | - unsigned long flags; | |
288 | - | |
289 | - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | |
290 | - printk("%s: Incorrect IRQ %d\n", | |
291 | - __func__, irq); | |
292 | - return; | |
293 | - } | |
294 | - | |
295 | - spin_lock_irqsave(&contr->lock, flags); | |
296 | - if (irq_depth[irq]) { | |
297 | - if (!--irq_depth[irq]) { | |
298 | - if (contr->enable) | |
299 | - contr->enable(irq); | |
300 | - } | |
301 | - } else | |
302 | - WARN_ON(1); | |
303 | - spin_unlock_irqrestore(&contr->lock, flags); | |
304 | -} | |
305 | - | |
306 | -EXPORT_SYMBOL(enable_irq); | |
307 | - | |
308 | -void disable_irq(unsigned int irq) | |
309 | -{ | |
310 | - struct irq_controller *contr; | |
311 | - unsigned long flags; | |
312 | - | |
313 | - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { | |
314 | - printk("%s: Incorrect IRQ %d\n", | |
315 | - __func__, irq); | |
316 | - return; | |
317 | - } | |
318 | - | |
319 | - spin_lock_irqsave(&contr->lock, flags); | |
320 | - if (!irq_depth[irq]++) { | |
321 | - if (contr->disable) | |
322 | - contr->disable(irq); | |
323 | - } | |
324 | - spin_unlock_irqrestore(&contr->lock, flags); | |
325 | -} | |
326 | - | |
327 | -EXPORT_SYMBOL(disable_irq); | |
328 | - | |
329 | -void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); | |
330 | - | |
331 | -EXPORT_SYMBOL(disable_irq_nosync); | |
332 | - | |
333 | -int m68k_irq_startup(unsigned int irq) | |
334 | -{ | |
335 | 153 | if (irq <= IRQ_AUTO_7) |
336 | - vectors[VEC_SPUR + irq] = auto_inthandler; | |
337 | - else | |
338 | - vectors[m68k_first_user_vec + irq - IRQ_USER] = user_inthandler; | |
339 | - return 0; | |
340 | -} | |
341 | - | |
342 | -void m68k_irq_shutdown(unsigned int irq) | |
343 | -{ | |
344 | - if (irq <= IRQ_AUTO_7) | |
345 | 154 | vectors[VEC_SPUR + irq] = bad_inthandler; |
346 | 155 | else |
347 | 156 | vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; |
348 | 157 | } |
349 | 158 | |
350 | 159 | |
351 | -/* | |
352 | - * Do we need these probe functions on the m68k? | |
353 | - * | |
354 | - * ... may be useful with ISA devices | |
355 | - */ | |
356 | -unsigned long probe_irq_on (void) | |
357 | -{ | |
358 | -#ifdef CONFIG_Q40 | |
359 | - if (MACH_IS_Q40) | |
360 | - return q40_probe_irq_on(); | |
361 | -#endif | |
362 | - return 0; | |
363 | -} | |
364 | - | |
365 | -EXPORT_SYMBOL(probe_irq_on); | |
366 | - | |
367 | -int probe_irq_off (unsigned long irqs) | |
368 | -{ | |
369 | -#ifdef CONFIG_Q40 | |
370 | - if (MACH_IS_Q40) | |
371 | - return q40_probe_irq_off(irqs); | |
372 | -#endif | |
373 | - return 0; | |
374 | -} | |
375 | - | |
376 | -EXPORT_SYMBOL(probe_irq_off); | |
377 | - | |
378 | 160 | unsigned int irq_canonicalize(unsigned int irq) |
379 | 161 | { |
380 | 162 | #ifdef CONFIG_Q40 |
381 | 163 | |
382 | 164 | |
383 | 165 | |
... | ... | @@ -386,53 +168,10 @@ |
386 | 168 | |
387 | 169 | EXPORT_SYMBOL(irq_canonicalize); |
388 | 170 | |
389 | -asmlinkage void m68k_handle_int(unsigned int irq) | |
390 | -{ | |
391 | - struct irq_node *node; | |
392 | - kstat_cpu(0).irqs[irq]++; | |
393 | - node = irq_list[irq]; | |
394 | - do { | |
395 | - node->handler(irq, node->dev_id); | |
396 | - node = node->next; | |
397 | - } while (node); | |
398 | -} | |
399 | 171 | |
400 | -asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) | |
401 | -{ | |
402 | - struct pt_regs *old_regs; | |
403 | - old_regs = set_irq_regs(regs); | |
404 | - m68k_handle_int(irq); | |
405 | - set_irq_regs(old_regs); | |
406 | -} | |
407 | - | |
408 | 172 | asmlinkage void handle_badint(struct pt_regs *regs) |
409 | 173 | { |
410 | - kstat_cpu(0).irqs[0]++; | |
411 | - printk("unexpected interrupt from %u\n", regs->vector); | |
174 | + atomic_inc(&irq_err_count); | |
175 | + pr_warn("unexpected interrupt from %u\n", regs->vector); | |
412 | 176 | } |
413 | - | |
414 | -int show_interrupts(struct seq_file *p, void *v) | |
415 | -{ | |
416 | - struct irq_controller *contr; | |
417 | - struct irq_node *node; | |
418 | - int i = *(loff_t *) v; | |
419 | - | |
420 | - /* autovector interrupts */ | |
421 | - if (irq_list[i]) { | |
422 | - contr = irq_controller[i]; | |
423 | - node = irq_list[i]; | |
424 | - seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); | |
425 | - while ((node = node->next)) | |
426 | - seq_printf(p, ", %s", node->devname); | |
427 | - seq_puts(p, "\n"); | |
428 | - } | |
429 | - return 0; | |
430 | -} | |
431 | - | |
432 | -#ifdef CONFIG_PROC_FS | |
433 | -void init_irq_proc(void) | |
434 | -{ | |
435 | - /* Insert /proc/irq driver here */ | |
436 | -} | |
437 | -#endif |
arch/m68k/mac/baboon.c
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include <linux/mm.h> |
12 | 12 | #include <linux/delay.h> |
13 | 13 | #include <linux/init.h> |
14 | +#include <linux/irq.h> | |
14 | 15 | |
15 | 16 | #include <asm/traps.h> |
16 | 17 | #include <asm/bootinfo.h> |
... | ... | @@ -20,9 +21,6 @@ |
20 | 21 | |
21 | 22 | /* #define DEBUG_IRQS */ |
22 | 23 | |
23 | -extern void mac_enable_irq(unsigned int); | |
24 | -extern void mac_disable_irq(unsigned int); | |
25 | - | |
26 | 24 | int baboon_present; |
27 | 25 | static volatile struct baboon *baboon; |
28 | 26 | static unsigned char baboon_disabled; |
... | ... | @@ -53,7 +51,7 @@ |
53 | 51 | * Baboon interrupt handler. This works a lot like a VIA. |
54 | 52 | */ |
55 | 53 | |
56 | -static irqreturn_t baboon_irq(int irq, void *dev_id) | |
54 | +static void baboon_irq(unsigned int irq, struct irq_desc *desc) | |
57 | 55 | { |
58 | 56 | int irq_bit, irq_num; |
59 | 57 | unsigned char events; |
60 | 58 | |
... | ... | @@ -64,15 +62,16 @@ |
64 | 62 | (uint) baboon->mb_status); |
65 | 63 | #endif |
66 | 64 | |
67 | - if (!(events = baboon->mb_ifr & 0x07)) | |
68 | - return IRQ_NONE; | |
65 | + events = baboon->mb_ifr & 0x07; | |
66 | + if (!events) | |
67 | + return; | |
69 | 68 | |
70 | 69 | irq_num = IRQ_BABOON_0; |
71 | 70 | irq_bit = 1; |
72 | 71 | do { |
73 | 72 | if (events & irq_bit) { |
74 | 73 | baboon->mb_ifr &= ~irq_bit; |
75 | - m68k_handle_int(irq_num); | |
74 | + generic_handle_irq(irq_num); | |
76 | 75 | } |
77 | 76 | irq_bit <<= 1; |
78 | 77 | irq_num++; |
... | ... | @@ -82,7 +81,6 @@ |
82 | 81 | /* for now we need to smash all interrupts */ |
83 | 82 | baboon->mb_ifr &= ~events; |
84 | 83 | #endif |
85 | - return IRQ_HANDLED; | |
86 | 84 | } |
87 | 85 | |
88 | 86 | /* |
... | ... | @@ -92,8 +90,7 @@ |
92 | 90 | void __init baboon_register_interrupts(void) |
93 | 91 | { |
94 | 92 | baboon_disabled = 0; |
95 | - if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon)) | |
96 | - pr_err("Couldn't register baboon interrupt\n"); | |
93 | + irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); | |
97 | 94 | } |
98 | 95 | |
99 | 96 | /* |
... | ... | @@ -111,7 +108,7 @@ |
111 | 108 | |
112 | 109 | baboon_disabled &= ~(1 << irq_idx); |
113 | 110 | if (!baboon_disabled) |
114 | - mac_enable_irq(IRQ_NUBUS_C); | |
111 | + mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C)); | |
115 | 112 | } |
116 | 113 | |
117 | 114 | void baboon_irq_disable(int irq) |
... | ... | @@ -124,7 +121,7 @@ |
124 | 121 | |
125 | 122 | baboon_disabled |= 1 << irq_idx; |
126 | 123 | if (baboon_disabled) |
127 | - mac_disable_irq(IRQ_NUBUS_C); | |
124 | + mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C)); | |
128 | 125 | } |
129 | 126 | |
130 | 127 | void baboon_irq_clear(int irq) |
arch/m68k/mac/iop.c
... | ... | @@ -305,15 +305,13 @@ |
305 | 305 | { |
306 | 306 | if (iop_ism_present) { |
307 | 307 | if (oss_present) { |
308 | - if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, | |
309 | - IRQ_FLG_LOCK, "ISM IOP", | |
310 | - (void *) IOP_NUM_ISM)) | |
308 | + if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0, | |
309 | + "ISM IOP", (void *)IOP_NUM_ISM)) | |
311 | 310 | pr_err("Couldn't register ISM IOP interrupt\n"); |
312 | 311 | oss_irq_enable(IRQ_MAC_ADB); |
313 | 312 | } else { |
314 | - if (request_irq(IRQ_VIA2_0, iop_ism_irq, | |
315 | - IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP", | |
316 | - (void *) IOP_NUM_ISM)) | |
313 | + if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP", | |
314 | + (void *)IOP_NUM_ISM)) | |
317 | 315 | pr_err("Couldn't register ISM IOP interrupt\n"); |
318 | 316 | } |
319 | 317 | if (!iop_alive(iop_base[IOP_NUM_ISM])) { |
arch/m68k/mac/macints.c
... | ... | @@ -190,14 +190,10 @@ |
190 | 190 | |
191 | 191 | /* #define DEBUG_MACINTS */ |
192 | 192 | |
193 | -void mac_enable_irq(unsigned int irq); | |
194 | -void mac_disable_irq(unsigned int irq); | |
195 | - | |
196 | -static struct irq_controller mac_irq_controller = { | |
193 | +static struct irq_chip mac_irq_chip = { | |
197 | 194 | .name = "mac", |
198 | - .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock), | |
199 | - .enable = mac_enable_irq, | |
200 | - .disable = mac_disable_irq, | |
195 | + .irq_enable = mac_irq_enable, | |
196 | + .irq_disable = mac_irq_disable, | |
201 | 197 | }; |
202 | 198 | |
203 | 199 | void __init mac_init_IRQ(void) |
... | ... | @@ -205,7 +201,7 @@ |
205 | 201 | #ifdef DEBUG_MACINTS |
206 | 202 | printk("mac_init_IRQ(): Setting things up...\n"); |
207 | 203 | #endif |
208 | - m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, | |
204 | + m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER, | |
209 | 205 | NUM_MAC_SOURCES - IRQ_USER); |
210 | 206 | /* Make sure the SONIC interrupt is cleared or things get ugly */ |
211 | 207 | #ifdef SHUTUP_SONIC |
212 | 208 | |
213 | 209 | |
214 | 210 | |
... | ... | @@ -241,16 +237,17 @@ |
241 | 237 | } |
242 | 238 | |
243 | 239 | /* |
244 | - * mac_enable_irq - enable an interrupt source | |
245 | - * mac_disable_irq - disable an interrupt source | |
240 | + * mac_irq_enable - enable an interrupt source | |
241 | + * mac_irq_disable - disable an interrupt source | |
246 | 242 | * mac_clear_irq - clears a pending interrupt |
247 | - * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending) | |
243 | + * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending) | |
248 | 244 | * |
249 | 245 | * These routines are just dispatchers to the VIA/OSS/PSC routines. |
250 | 246 | */ |
251 | 247 | |
252 | -void mac_enable_irq(unsigned int irq) | |
248 | +void mac_irq_enable(struct irq_data *data) | |
253 | 249 | { |
250 | + int irq = data->irq; | |
254 | 251 | int irq_src = IRQ_SRC(irq); |
255 | 252 | |
256 | 253 | switch(irq_src) { |
257 | 254 | |
... | ... | @@ -283,8 +280,9 @@ |
283 | 280 | } |
284 | 281 | } |
285 | 282 | |
286 | -void mac_disable_irq(unsigned int irq) | |
283 | +void mac_irq_disable(struct irq_data *data) | |
287 | 284 | { |
285 | + int irq = data->irq; | |
288 | 286 | int irq_src = IRQ_SRC(irq); |
289 | 287 | |
290 | 288 | switch(irq_src) { |
arch/m68k/mac/oss.c
... | ... | @@ -19,6 +19,7 @@ |
19 | 19 | #include <linux/mm.h> |
20 | 20 | #include <linux/delay.h> |
21 | 21 | #include <linux/init.h> |
22 | +#include <linux/irq.h> | |
22 | 23 | |
23 | 24 | #include <asm/bootinfo.h> |
24 | 25 | #include <asm/macintosh.h> |
25 | 26 | |
... | ... | @@ -29,11 +30,8 @@ |
29 | 30 | int oss_present; |
30 | 31 | volatile struct mac_oss *oss; |
31 | 32 | |
32 | -static irqreturn_t oss_irq(int, void *); | |
33 | -static irqreturn_t oss_nubus_irq(int, void *); | |
33 | +extern void via1_irq(unsigned int irq, struct irq_desc *desc); | |
34 | 34 | |
35 | -extern irqreturn_t via1_irq(int, void *); | |
36 | - | |
37 | 35 | /* |
38 | 36 | * Initialize the OSS |
39 | 37 | * |
... | ... | @@ -60,26 +58,6 @@ |
60 | 58 | } |
61 | 59 | |
62 | 60 | /* |
63 | - * Register the OSS and NuBus interrupt dispatchers. | |
64 | - */ | |
65 | - | |
66 | -void __init oss_register_interrupts(void) | |
67 | -{ | |
68 | - if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, | |
69 | - "scsi", (void *) oss)) | |
70 | - pr_err("Couldn't register %s interrupt\n", "scsi"); | |
71 | - if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, | |
72 | - "nubus", (void *) oss)) | |
73 | - pr_err("Couldn't register %s interrupt\n", "nubus"); | |
74 | - if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, | |
75 | - "sound", (void *) oss)) | |
76 | - pr_err("Couldn't register %s interrupt\n", "sound"); | |
77 | - if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, | |
78 | - "via1", (void *) via1)) | |
79 | - pr_err("Couldn't register %s interrupt\n", "via1"); | |
80 | -} | |
81 | - | |
82 | -/* | |
83 | 61 | * Initialize OSS for Nubus access |
84 | 62 | */ |
85 | 63 | |
86 | 64 | |
87 | 65 | |
... | ... | @@ -92,17 +70,17 @@ |
92 | 70 | * and SCSI; everything else is routed to its own autovector IRQ. |
93 | 71 | */ |
94 | 72 | |
95 | -static irqreturn_t oss_irq(int irq, void *dev_id) | |
73 | +static void oss_irq(unsigned int irq, struct irq_desc *desc) | |
96 | 74 | { |
97 | 75 | int events; |
98 | 76 | |
99 | 77 | events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); |
100 | 78 | if (!events) |
101 | - return IRQ_NONE; | |
79 | + return; | |
102 | 80 | |
103 | 81 | #ifdef DEBUG_IRQS |
104 | 82 | if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { |
105 | - printk("oss_irq: irq %d events = 0x%04X\n", irq, | |
83 | + printk("oss_irq: irq %u events = 0x%04X\n", irq, | |
106 | 84 | (int) oss->irq_pending); |
107 | 85 | } |
108 | 86 | #endif |
109 | 87 | |
... | ... | @@ -113,11 +91,10 @@ |
113 | 91 | /* FIXME: call sound handler */ |
114 | 92 | } else if (events & OSS_IP_SCSI) { |
115 | 93 | oss->irq_pending &= ~OSS_IP_SCSI; |
116 | - m68k_handle_int(IRQ_MAC_SCSI); | |
94 | + generic_handle_irq(IRQ_MAC_SCSI); | |
117 | 95 | } else { |
118 | 96 | /* FIXME: error check here? */ |
119 | 97 | } |
120 | - return IRQ_HANDLED; | |
121 | 98 | } |
122 | 99 | |
123 | 100 | /* |
124 | 101 | |
... | ... | @@ -126,13 +103,13 @@ |
126 | 103 | * Unlike the VIA/RBV this is on its own autovector interrupt level. |
127 | 104 | */ |
128 | 105 | |
129 | -static irqreturn_t oss_nubus_irq(int irq, void *dev_id) | |
106 | +static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) | |
130 | 107 | { |
131 | 108 | int events, irq_bit, i; |
132 | 109 | |
133 | 110 | events = oss->irq_pending & OSS_IP_NUBUS; |
134 | 111 | if (!events) |
135 | - return IRQ_NONE; | |
112 | + return; | |
136 | 113 | |
137 | 114 | #ifdef DEBUG_NUBUS_INT |
138 | 115 | if (console_loglevel > 7) { |
139 | 116 | |
... | ... | @@ -148,10 +125,21 @@ |
148 | 125 | irq_bit >>= 1; |
149 | 126 | if (events & irq_bit) { |
150 | 127 | oss->irq_pending &= ~irq_bit; |
151 | - m68k_handle_int(NUBUS_SOURCE_BASE + i); | |
128 | + generic_handle_irq(NUBUS_SOURCE_BASE + i); | |
152 | 129 | } |
153 | 130 | } while(events & (irq_bit - 1)); |
154 | - return IRQ_HANDLED; | |
131 | +} | |
132 | + | |
133 | +/* | |
134 | + * Register the OSS and NuBus interrupt dispatchers. | |
135 | + */ | |
136 | + | |
137 | +void __init oss_register_interrupts(void) | |
138 | +{ | |
139 | + irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); | |
140 | + irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); | |
141 | + irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq); | |
142 | + irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); | |
155 | 143 | } |
156 | 144 | |
157 | 145 | /* |
arch/m68k/mac/psc.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include <linux/mm.h> |
19 | 19 | #include <linux/delay.h> |
20 | 20 | #include <linux/init.h> |
21 | +#include <linux/irq.h> | |
21 | 22 | |
22 | 23 | #include <asm/traps.h> |
23 | 24 | #include <asm/bootinfo.h> |
... | ... | @@ -30,8 +31,6 @@ |
30 | 31 | int psc_present; |
31 | 32 | volatile __u8 *psc; |
32 | 33 | |
33 | -irqreturn_t psc_irq(int, void *); | |
34 | - | |
35 | 34 | /* |
36 | 35 | * Debugging dump, used in various places to see what's going on. |
37 | 36 | */ |
38 | 37 | |
39 | 38 | |
40 | 39 | |
41 | 40 | |
42 | 41 | |
43 | 42 | |
... | ... | @@ -112,52 +111,52 @@ |
112 | 111 | } |
113 | 112 | |
114 | 113 | /* |
115 | - * Register the PSC interrupt dispatchers for autovector interrupts 3-6. | |
116 | - */ | |
117 | - | |
118 | -void __init psc_register_interrupts(void) | |
119 | -{ | |
120 | - if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) | |
121 | - pr_err("Couldn't register psc%d interrupt\n", 3); | |
122 | - if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) | |
123 | - pr_err("Couldn't register psc%d interrupt\n", 4); | |
124 | - if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) | |
125 | - pr_err("Couldn't register psc%d interrupt\n", 5); | |
126 | - if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) | |
127 | - pr_err("Couldn't register psc%d interrupt\n", 6); | |
128 | -} | |
129 | - | |
130 | -/* | |
131 | 114 | * PSC interrupt handler. It's a lot like the VIA interrupt handler. |
132 | 115 | */ |
133 | 116 | |
134 | -irqreturn_t psc_irq(int irq, void *dev_id) | |
117 | +static void psc_irq(unsigned int irq, struct irq_desc *desc) | |
135 | 118 | { |
136 | - int pIFR = pIFRbase + ((int) dev_id); | |
137 | - int pIER = pIERbase + ((int) dev_id); | |
119 | + unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); | |
120 | + int pIFR = pIFRbase + offset; | |
121 | + int pIER = pIERbase + offset; | |
138 | 122 | int irq_num; |
139 | 123 | unsigned char irq_bit, events; |
140 | 124 | |
141 | 125 | #ifdef DEBUG_IRQS |
142 | - printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", | |
126 | + printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n", | |
143 | 127 | irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); |
144 | 128 | #endif |
145 | 129 | |
146 | 130 | events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; |
147 | 131 | if (!events) |
148 | - return IRQ_NONE; | |
132 | + return; | |
149 | 133 | |
150 | 134 | irq_num = irq << 3; |
151 | 135 | irq_bit = 1; |
152 | 136 | do { |
153 | 137 | if (events & irq_bit) { |
154 | 138 | psc_write_byte(pIFR, irq_bit); |
155 | - m68k_handle_int(irq_num); | |
139 | + generic_handle_irq(irq_num); | |
156 | 140 | } |
157 | 141 | irq_num++; |
158 | 142 | irq_bit <<= 1; |
159 | 143 | } while (events >= irq_bit); |
160 | - return IRQ_HANDLED; | |
144 | +} | |
145 | + | |
146 | +/* | |
147 | + * Register the PSC interrupt dispatchers for autovector interrupts 3-6. | |
148 | + */ | |
149 | + | |
150 | +void __init psc_register_interrupts(void) | |
151 | +{ | |
152 | + irq_set_chained_handler(IRQ_AUTO_3, psc_irq); | |
153 | + irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); | |
154 | + irq_set_chained_handler(IRQ_AUTO_4, psc_irq); | |
155 | + irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); | |
156 | + irq_set_chained_handler(IRQ_AUTO_5, psc_irq); | |
157 | + irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); | |
158 | + irq_set_chained_handler(IRQ_AUTO_6, psc_irq); | |
159 | + irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); | |
161 | 160 | } |
162 | 161 | |
163 | 162 | void psc_irq_enable(int irq) { |
arch/m68k/mac/via.c
... | ... | @@ -28,6 +28,7 @@ |
28 | 28 | #include <linux/delay.h> |
29 | 29 | #include <linux/init.h> |
30 | 30 | #include <linux/module.h> |
31 | +#include <linux/irq.h> | |
31 | 32 | |
32 | 33 | #include <asm/bootinfo.h> |
33 | 34 | #include <asm/macintosh.h> |
... | ... | @@ -77,9 +78,6 @@ |
77 | 78 | static u8 nubus_disabled; |
78 | 79 | |
79 | 80 | void via_debug_dump(void); |
80 | -irqreturn_t via1_irq(int, void *); | |
81 | -irqreturn_t via2_irq(int, void *); | |
82 | -irqreturn_t via_nubus_irq(int, void *); | |
83 | 81 | void via_irq_enable(int irq); |
84 | 82 | void via_irq_disable(int irq); |
85 | 83 | void via_irq_clear(int irq); |
86 | 84 | |
... | ... | @@ -281,40 +279,11 @@ |
281 | 279 | via1[vT1CL] = MAC_CLOCK_LOW; |
282 | 280 | via1[vT1CH] = MAC_CLOCK_HIGH; |
283 | 281 | |
284 | - if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func)) | |
282 | + if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func)) | |
285 | 283 | pr_err("Couldn't register %s interrupt\n", "timer"); |
286 | 284 | } |
287 | 285 | |
288 | 286 | /* |
289 | - * Register the interrupt dispatchers for VIA or RBV machines only. | |
290 | - */ | |
291 | - | |
292 | -void __init via_register_interrupts(void) | |
293 | -{ | |
294 | - if (via_alt_mapping) { | |
295 | - if (request_irq(IRQ_AUTO_1, via1_irq, | |
296 | - IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", | |
297 | - (void *) via1)) | |
298 | - pr_err("Couldn't register %s interrupt\n", "software"); | |
299 | - if (request_irq(IRQ_AUTO_6, via1_irq, | |
300 | - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", | |
301 | - (void *) via1)) | |
302 | - pr_err("Couldn't register %s interrupt\n", "via1"); | |
303 | - } else { | |
304 | - if (request_irq(IRQ_AUTO_1, via1_irq, | |
305 | - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", | |
306 | - (void *) via1)) | |
307 | - pr_err("Couldn't register %s interrupt\n", "via1"); | |
308 | - } | |
309 | - if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, | |
310 | - "via2", (void *) via2)) | |
311 | - pr_err("Couldn't register %s interrupt\n", "via2"); | |
312 | - if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, | |
313 | - IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) | |
314 | - pr_err("Couldn't register %s interrupt\n", "nubus"); | |
315 | -} | |
316 | - | |
317 | -/* | |
318 | 287 | * Debugging dump, used in various places to see what's going on. |
319 | 288 | */ |
320 | 289 | |
321 | 290 | |
322 | 291 | |
323 | 292 | |
324 | 293 | |
325 | 294 | |
326 | 295 | |
327 | 296 | |
... | ... | @@ -446,48 +415,46 @@ |
446 | 415 | * via6522.c :-), disable/pending masks added. |
447 | 416 | */ |
448 | 417 | |
449 | -irqreturn_t via1_irq(int irq, void *dev_id) | |
418 | +void via1_irq(unsigned int irq, struct irq_desc *desc) | |
450 | 419 | { |
451 | 420 | int irq_num; |
452 | 421 | unsigned char irq_bit, events; |
453 | 422 | |
454 | 423 | events = via1[vIFR] & via1[vIER] & 0x7F; |
455 | 424 | if (!events) |
456 | - return IRQ_NONE; | |
425 | + return; | |
457 | 426 | |
458 | 427 | irq_num = VIA1_SOURCE_BASE; |
459 | 428 | irq_bit = 1; |
460 | 429 | do { |
461 | 430 | if (events & irq_bit) { |
462 | 431 | via1[vIFR] = irq_bit; |
463 | - m68k_handle_int(irq_num); | |
432 | + generic_handle_irq(irq_num); | |
464 | 433 | } |
465 | 434 | ++irq_num; |
466 | 435 | irq_bit <<= 1; |
467 | 436 | } while (events >= irq_bit); |
468 | - return IRQ_HANDLED; | |
469 | 437 | } |
470 | 438 | |
471 | -irqreturn_t via2_irq(int irq, void *dev_id) | |
439 | +static void via2_irq(unsigned int irq, struct irq_desc *desc) | |
472 | 440 | { |
473 | 441 | int irq_num; |
474 | 442 | unsigned char irq_bit, events; |
475 | 443 | |
476 | 444 | events = via2[gIFR] & via2[gIER] & 0x7F; |
477 | 445 | if (!events) |
478 | - return IRQ_NONE; | |
446 | + return; | |
479 | 447 | |
480 | 448 | irq_num = VIA2_SOURCE_BASE; |
481 | 449 | irq_bit = 1; |
482 | 450 | do { |
483 | 451 | if (events & irq_bit) { |
484 | 452 | via2[gIFR] = irq_bit | rbv_clear; |
485 | - m68k_handle_int(irq_num); | |
453 | + generic_handle_irq(irq_num); | |
486 | 454 | } |
487 | 455 | ++irq_num; |
488 | 456 | irq_bit <<= 1; |
489 | 457 | } while (events >= irq_bit); |
490 | - return IRQ_HANDLED; | |
491 | 458 | } |
492 | 459 | |
493 | 460 | /* |
... | ... | @@ -495,7 +462,7 @@ |
495 | 462 | * VIA2 dispatcher as a fast interrupt handler. |
496 | 463 | */ |
497 | 464 | |
498 | -irqreturn_t via_nubus_irq(int irq, void *dev_id) | |
465 | +void via_nubus_irq(unsigned int irq, struct irq_desc *desc) | |
499 | 466 | { |
500 | 467 | int slot_irq; |
501 | 468 | unsigned char slot_bit, events; |
... | ... | @@ -506,7 +473,7 @@ |
506 | 473 | else |
507 | 474 | events &= ~via2[vDirA]; |
508 | 475 | if (!events) |
509 | - return IRQ_NONE; | |
476 | + return; | |
510 | 477 | |
511 | 478 | do { |
512 | 479 | slot_irq = IRQ_NUBUS_F; |
... | ... | @@ -514,7 +481,7 @@ |
514 | 481 | do { |
515 | 482 | if (events & slot_bit) { |
516 | 483 | events &= ~slot_bit; |
517 | - m68k_handle_int(slot_irq); | |
484 | + generic_handle_irq(slot_irq); | |
518 | 485 | } |
519 | 486 | --slot_irq; |
520 | 487 | slot_bit >>= 1; |
... | ... | @@ -528,7 +495,24 @@ |
528 | 495 | else |
529 | 496 | events &= ~via2[vDirA]; |
530 | 497 | } while (events); |
531 | - return IRQ_HANDLED; | |
498 | +} | |
499 | + | |
500 | +/* | |
501 | + * Register the interrupt dispatchers for VIA or RBV machines only. | |
502 | + */ | |
503 | + | |
504 | +void __init via_register_interrupts(void) | |
505 | +{ | |
506 | + if (via_alt_mapping) { | |
507 | + /* software interrupt */ | |
508 | + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | |
509 | + /* via1 interrupt */ | |
510 | + irq_set_chained_handler(IRQ_AUTO_6, via1_irq); | |
511 | + } else { | |
512 | + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); | |
513 | + } | |
514 | + irq_set_chained_handler(IRQ_AUTO_2, via2_irq); | |
515 | + irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); | |
532 | 516 | } |
533 | 517 | |
534 | 518 | void via_irq_enable(int irq) { |
arch/m68k/mvme147/config.c
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | |
82 | 82 | void __init mvme147_init_IRQ(void) |
83 | 83 | { |
84 | - m68k_setup_user_interrupt(VEC_USER, 192, NULL); | |
84 | + m68k_setup_user_interrupt(VEC_USER, 192); | |
85 | 85 | } |
86 | 86 | |
87 | 87 | void __init config_mvme147(void) |
... | ... | @@ -114,8 +114,7 @@ |
114 | 114 | void mvme147_sched_init (irq_handler_t timer_routine) |
115 | 115 | { |
116 | 116 | tick_handler = timer_routine; |
117 | - if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE, | |
118 | - "timer 1", NULL)) | |
117 | + if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL)) | |
119 | 118 | pr_err("Couldn't register timer interrupt\n"); |
120 | 119 | |
121 | 120 | /* Init the clock with a value */ |
arch/m68k/mvme16x/config.c
arch/m68k/q40/q40ints.c
... | ... | @@ -15,10 +15,10 @@ |
15 | 15 | #include <linux/kernel.h> |
16 | 16 | #include <linux/errno.h> |
17 | 17 | #include <linux/interrupt.h> |
18 | +#include <linux/irq.h> | |
18 | 19 | |
19 | 20 | #include <asm/ptrace.h> |
20 | 21 | #include <asm/system.h> |
21 | -#include <asm/irq.h> | |
22 | 22 | #include <asm/traps.h> |
23 | 23 | |
24 | 24 | #include <asm/q40_master.h> |
25 | 25 | |
26 | 26 | |
27 | 27 | |
28 | 28 | |
29 | 29 | |
30 | 30 | |
... | ... | @@ -35,35 +35,36 @@ |
35 | 35 | */ |
36 | 36 | |
37 | 37 | static void q40_irq_handler(unsigned int, struct pt_regs *fp); |
38 | -static void q40_enable_irq(unsigned int); | |
39 | -static void q40_disable_irq(unsigned int); | |
38 | +static void q40_irq_enable(struct irq_data *data); | |
39 | +static void q40_irq_disable(struct irq_data *data); | |
40 | 40 | |
41 | 41 | unsigned short q40_ablecount[35]; |
42 | 42 | unsigned short q40_state[35]; |
43 | 43 | |
44 | -static int q40_irq_startup(unsigned int irq) | |
44 | +static unsigned int q40_irq_startup(struct irq_data *data) | |
45 | 45 | { |
46 | + unsigned int irq = data->irq; | |
47 | + | |
46 | 48 | /* test for ISA ints not implemented by HW */ |
47 | 49 | switch (irq) { |
48 | 50 | case 1: case 2: case 8: case 9: |
49 | 51 | case 11: case 12: case 13: |
50 | 52 | printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); |
51 | - return -ENXIO; | |
53 | + /* FIXME return -ENXIO; */ | |
52 | 54 | } |
53 | 55 | return 0; |
54 | 56 | } |
55 | 57 | |
56 | -static void q40_irq_shutdown(unsigned int irq) | |
58 | +static void q40_irq_shutdown(struct irq_data *data) | |
57 | 59 | { |
58 | 60 | } |
59 | 61 | |
60 | -static struct irq_controller q40_irq_controller = { | |
62 | +static struct irq_chip q40_irq_chip = { | |
61 | 63 | .name = "q40", |
62 | - .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), | |
63 | - .startup = q40_irq_startup, | |
64 | - .shutdown = q40_irq_shutdown, | |
65 | - .enable = q40_enable_irq, | |
66 | - .disable = q40_disable_irq, | |
64 | + .irq_startup = q40_irq_startup, | |
65 | + .irq_shutdown = q40_irq_shutdown, | |
66 | + .irq_enable = q40_irq_enable, | |
67 | + .irq_disable = q40_irq_disable, | |
67 | 68 | }; |
68 | 69 | |
69 | 70 | /* |
70 | 71 | |
... | ... | @@ -81,13 +82,14 @@ |
81 | 82 | |
82 | 83 | void __init q40_init_IRQ(void) |
83 | 84 | { |
84 | - m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); | |
85 | + m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, | |
86 | + Q40_IRQ_MAX); | |
85 | 87 | |
86 | 88 | /* setup handler for ISA ints */ |
87 | 89 | m68k_setup_auto_interrupt(q40_irq_handler); |
88 | 90 | |
89 | - m68k_irq_startup(IRQ_AUTO_2); | |
90 | - m68k_irq_startup(IRQ_AUTO_4); | |
91 | + m68k_irq_startup_irq(IRQ_AUTO_2); | |
92 | + m68k_irq_startup_irq(IRQ_AUTO_4); | |
91 | 93 | |
92 | 94 | /* now enable some ints.. */ |
93 | 95 | master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ |
94 | 96 | |
... | ... | @@ -218,11 +220,11 @@ |
218 | 220 | switch (irq) { |
219 | 221 | case 4: |
220 | 222 | case 6: |
221 | - __m68k_handle_int(Q40_IRQ_SAMPLE, fp); | |
223 | + do_IRQ(Q40_IRQ_SAMPLE, fp); | |
222 | 224 | return; |
223 | 225 | } |
224 | 226 | if (mir & Q40_IRQ_FRAME_MASK) { |
225 | - __m68k_handle_int(Q40_IRQ_FRAME, fp); | |
227 | + do_IRQ(Q40_IRQ_FRAME, fp); | |
226 | 228 | master_outb(-1, FRAME_CLEAR_REG); |
227 | 229 | } |
228 | 230 | if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { |
... | ... | @@ -257,7 +259,7 @@ |
257 | 259 | goto iirq; |
258 | 260 | } |
259 | 261 | q40_state[irq] |= IRQ_INPROGRESS; |
260 | - __m68k_handle_int(irq, fp); | |
262 | + do_IRQ(irq, fp); | |
261 | 263 | q40_state[irq] &= ~IRQ_INPROGRESS; |
262 | 264 | |
263 | 265 | /* naively enable everything, if that fails than */ |
264 | 266 | |
265 | 267 | |
266 | 268 | |
267 | 269 | |
268 | 270 | |
... | ... | @@ -288,25 +290,29 @@ |
288 | 290 | mir = master_inb(IIRQ_REG); |
289 | 291 | /* should test whether keyboard irq is really enabled, doing it in defhand */ |
290 | 292 | if (mir & Q40_IRQ_KEYB_MASK) |
291 | - __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); | |
293 | + do_IRQ(Q40_IRQ_KEYBOARD, fp); | |
292 | 294 | |
293 | 295 | return; |
294 | 296 | } |
295 | 297 | |
296 | -void q40_enable_irq(unsigned int irq) | |
298 | +void q40_irq_enable(struct irq_data *data) | |
297 | 299 | { |
300 | + unsigned int irq = data->irq; | |
301 | + | |
298 | 302 | if (irq >= 5 && irq <= 15) { |
299 | 303 | mext_disabled--; |
300 | 304 | if (mext_disabled > 0) |
301 | - printk("q40_enable_irq : nested disable/enable\n"); | |
305 | + printk("q40_irq_enable : nested disable/enable\n"); | |
302 | 306 | if (mext_disabled == 0) |
303 | 307 | master_outb(1, EXT_ENABLE_REG); |
304 | 308 | } |
305 | 309 | } |
306 | 310 | |
307 | 311 | |
308 | -void q40_disable_irq(unsigned int irq) | |
312 | +void q40_irq_disable(struct irq_data *data) | |
309 | 313 | { |
314 | + unsigned int irq = data->irq; | |
315 | + | |
310 | 316 | /* disable ISA iqs : only do something if the driver has been |
311 | 317 | * verified to be Q40 "compatible" - right now IDE, NE2K |
312 | 318 | * Any driver should not attempt to sleep across disable_irq !! |
... | ... | @@ -318,15 +324,5 @@ |
318 | 324 | if (mext_disabled > 1) |
319 | 325 | printk("disable_irq nesting count %d\n",mext_disabled); |
320 | 326 | } |
321 | -} | |
322 | - | |
323 | -unsigned long q40_probe_irq_on(void) | |
324 | -{ | |
325 | - printk("irq probing not working - reconfigure the driver to avoid this\n"); | |
326 | - return -1; | |
327 | -} | |
328 | -int q40_probe_irq_off(unsigned long irqs) | |
329 | -{ | |
330 | - return -1; | |
331 | 327 | } |
arch/m68k/sun3/sun3ints.c
... | ... | @@ -51,25 +51,29 @@ |
51 | 51 | |
52 | 52 | static irqreturn_t sun3_int7(int irq, void *dev_id) |
53 | 53 | { |
54 | - *sun3_intreg |= (1 << irq); | |
55 | - if (!(kstat_cpu(0).irqs[irq] % 2000)) | |
56 | - sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]); | |
54 | + unsigned int cnt; | |
55 | + | |
56 | + cnt = kstat_irqs_cpu(irq, 0); | |
57 | + if (!(cnt % 2000)) | |
58 | + sun3_leds(led_pattern[cnt % 16000 / 2000]); | |
57 | 59 | return IRQ_HANDLED; |
58 | 60 | } |
59 | 61 | |
60 | 62 | static irqreturn_t sun3_int5(int irq, void *dev_id) |
61 | 63 | { |
64 | + unsigned int cnt; | |
65 | + | |
62 | 66 | #ifdef CONFIG_SUN3 |
63 | 67 | intersil_clear(); |
64 | 68 | #endif |
65 | - *sun3_intreg |= (1 << irq); | |
66 | 69 | #ifdef CONFIG_SUN3 |
67 | 70 | intersil_clear(); |
68 | 71 | #endif |
69 | 72 | xtime_update(1); |
70 | 73 | update_process_times(user_mode(get_irq_regs())); |
71 | - if (!(kstat_cpu(0).irqs[irq] % 20)) | |
72 | - sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); | |
74 | + cnt = kstat_irqs_cpu(irq, 0); | |
75 | + if (!(cnt % 20)) | |
76 | + sun3_leds(led_pattern[cnt % 160 / 20]); | |
73 | 77 | return IRQ_HANDLED; |
74 | 78 | } |
75 | 79 | |
76 | 80 | |
77 | 81 | |
78 | 82 | |
79 | 83 | |
80 | 84 | |
... | ... | @@ -79,29 +83,33 @@ |
79 | 83 | return IRQ_HANDLED; |
80 | 84 | } |
81 | 85 | |
82 | -static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) | |
86 | +static void sun3_irq_enable(struct irq_data *data) | |
83 | 87 | { |
84 | - *sun3_intreg &= ~(1 << irq); | |
88 | + sun3_enable_irq(data->irq); | |
89 | +}; | |
85 | 90 | |
86 | - __m68k_handle_int(irq, fp); | |
87 | -} | |
91 | +static void sun3_irq_disable(struct irq_data *data) | |
92 | +{ | |
93 | + sun3_disable_irq(data->irq); | |
94 | +}; | |
88 | 95 | |
89 | -static struct irq_controller sun3_irq_controller = { | |
96 | +static struct irq_chip sun3_irq_chip = { | |
90 | 97 | .name = "sun3", |
91 | - .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), | |
92 | - .startup = m68k_irq_startup, | |
93 | - .shutdown = m68k_irq_shutdown, | |
94 | - .enable = sun3_enable_irq, | |
95 | - .disable = sun3_disable_irq, | |
98 | + .irq_startup = m68k_irq_startup, | |
99 | + .irq_shutdown = m68k_irq_shutdown, | |
100 | + .irq_enable = sun3_irq_enable, | |
101 | + .irq_disable = sun3_irq_disable, | |
102 | + .irq_mask = sun3_irq_disable, | |
103 | + .irq_unmask = sun3_irq_enable, | |
96 | 104 | }; |
97 | 105 | |
98 | 106 | void __init sun3_init_IRQ(void) |
99 | 107 | { |
100 | 108 | *sun3_intreg = 1; |
101 | 109 | |
102 | - m68k_setup_auto_interrupt(sun3_inthandle); | |
103 | - m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); | |
104 | - m68k_setup_user_interrupt(VEC_USER, 128, NULL); | |
110 | + m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, | |
111 | + 7); | |
112 | + m68k_setup_user_interrupt(VEC_USER, 128); | |
105 | 113 | |
106 | 114 | if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) |
107 | 115 | pr_err("Couldn't register %s interrupt\n", "int5"); |
drivers/ide/ide-cd.c
drivers/ide/ide-floppy.c
drivers/ide/ide-tape.c
drivers/macintosh/via-macii.c
drivers/macintosh/via-maciisi.c
... | ... | @@ -122,8 +122,8 @@ |
122 | 122 | return err; |
123 | 123 | } |
124 | 124 | |
125 | - if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, | |
126 | - "ADB", maciisi_interrupt)) { | |
125 | + if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB", | |
126 | + maciisi_interrupt)) { | |
127 | 127 | printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB); |
128 | 128 | return -EAGAIN; |
129 | 129 | } |