Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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()
...

+456 -1006
+2 -2
arch/m68k/Kconfig
··· 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
+9
arch/m68k/Kconfig.bus
··· 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
+31
arch/m68k/Kconfig.devices
··· 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"
+126 -166
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> ··· 17 45 #include <asm/amigaints.h> 18 46 #include <asm/amipcmcia.h> 19 47 20 - static void amiga_enable_irq(unsigned int irq); 21 - static void amiga_disable_irq(unsigned int irq); 22 - static irqreturn_t ami_int1(int irq, void *dev_id); 23 - static irqreturn_t ami_int3(int irq, void *dev_id); 24 - static irqreturn_t ami_int4(int irq, void *dev_id); 25 - static irqreturn_t ami_int5(int irq, void *dev_id); 26 48 27 - static struct irq_controller amiga_irq_controller = { 49 + /* 50 + * Enable/disable a particular machine specific interrupt source. 51 + * Note that this may affect other interrupts in case of a shared interrupt. 52 + * This function should only be called for a _very_ short time to change some 53 + * internal data, that may not be changed by the interrupt at the same time. 54 + */ 55 + 56 + static void amiga_irq_enable(struct irq_data *data) 57 + { 58 + amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER)); 59 + } 60 + 61 + static void amiga_irq_disable(struct irq_data *data) 62 + { 63 + amiga_custom.intena = 1 << (data->irq - IRQ_USER); 64 + } 65 + 66 + static struct irq_chip amiga_irq_chip = { 28 67 .name = "amiga", 29 - .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), 30 - .enable = amiga_enable_irq, 31 - .disable = amiga_disable_irq, 68 + .irq_enable = amiga_irq_enable, 69 + .irq_disable = amiga_irq_disable, 32 70 }; 71 + 72 + 73 + /* 74 + * The builtin Amiga hardware interrupt handlers. 75 + */ 76 + 77 + static void ami_int1(unsigned int irq, struct irq_desc *desc) 78 + { 79 + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 80 + 81 + /* if serial transmit buffer empty, interrupt */ 82 + if (ints & IF_TBE) { 83 + amiga_custom.intreq = IF_TBE; 84 + generic_handle_irq(IRQ_AMIGA_TBE); 85 + } 86 + 87 + /* if floppy disk transfer complete, interrupt */ 88 + if (ints & IF_DSKBLK) { 89 + amiga_custom.intreq = IF_DSKBLK; 90 + generic_handle_irq(IRQ_AMIGA_DSKBLK); 91 + } 92 + 93 + /* if software interrupt set, interrupt */ 94 + if (ints & IF_SOFT) { 95 + amiga_custom.intreq = IF_SOFT; 96 + generic_handle_irq(IRQ_AMIGA_SOFT); 97 + } 98 + } 99 + 100 + static void ami_int3(unsigned int irq, struct irq_desc *desc) 101 + { 102 + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 103 + 104 + /* if a blitter interrupt */ 105 + if (ints & IF_BLIT) { 106 + amiga_custom.intreq = IF_BLIT; 107 + generic_handle_irq(IRQ_AMIGA_BLIT); 108 + } 109 + 110 + /* if a copper interrupt */ 111 + if (ints & IF_COPER) { 112 + amiga_custom.intreq = IF_COPER; 113 + generic_handle_irq(IRQ_AMIGA_COPPER); 114 + } 115 + 116 + /* if a vertical blank interrupt */ 117 + if (ints & IF_VERTB) { 118 + amiga_custom.intreq = IF_VERTB; 119 + generic_handle_irq(IRQ_AMIGA_VERTB); 120 + } 121 + } 122 + 123 + static void ami_int4(unsigned int irq, struct irq_desc *desc) 124 + { 125 + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 126 + 127 + /* if audio 0 interrupt */ 128 + if (ints & IF_AUD0) { 129 + amiga_custom.intreq = IF_AUD0; 130 + generic_handle_irq(IRQ_AMIGA_AUD0); 131 + } 132 + 133 + /* if audio 1 interrupt */ 134 + if (ints & IF_AUD1) { 135 + amiga_custom.intreq = IF_AUD1; 136 + generic_handle_irq(IRQ_AMIGA_AUD1); 137 + } 138 + 139 + /* if audio 2 interrupt */ 140 + if (ints & IF_AUD2) { 141 + amiga_custom.intreq = IF_AUD2; 142 + generic_handle_irq(IRQ_AMIGA_AUD2); 143 + } 144 + 145 + /* if audio 3 interrupt */ 146 + if (ints & IF_AUD3) { 147 + amiga_custom.intreq = IF_AUD3; 148 + generic_handle_irq(IRQ_AMIGA_AUD3); 149 + } 150 + } 151 + 152 + static void ami_int5(unsigned int irq, struct irq_desc *desc) 153 + { 154 + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 155 + 156 + /* if serial receive buffer full interrupt */ 157 + if (ints & IF_RBF) { 158 + /* acknowledge of IF_RBF must be done by the serial interrupt */ 159 + generic_handle_irq(IRQ_AMIGA_RBF); 160 + } 161 + 162 + /* if a disk sync interrupt */ 163 + if (ints & IF_DSKSYN) { 164 + amiga_custom.intreq = IF_DSKSYN; 165 + generic_handle_irq(IRQ_AMIGA_DSKSYN); 166 + } 167 + } 168 + 33 169 34 170 /* 35 171 * void amiga_init_IRQ(void) ··· 152 72 153 73 void __init amiga_init_IRQ(void) 154 74 { 155 - if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) 156 - pr_err("Couldn't register int%d\n", 1); 157 - if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) 158 - pr_err("Couldn't register int%d\n", 3); 159 - if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) 160 - pr_err("Couldn't register int%d\n", 4); 161 - if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) 162 - pr_err("Couldn't register int%d\n", 5); 75 + m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, 76 + AMI_STD_IRQS); 163 77 164 - m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); 78 + irq_set_chained_handler(IRQ_AUTO_1, ami_int1); 79 + irq_set_chained_handler(IRQ_AUTO_3, ami_int3); 80 + irq_set_chained_handler(IRQ_AUTO_4, ami_int4); 81 + irq_set_chained_handler(IRQ_AUTO_5, ami_int5); 165 82 166 83 /* turn off PCMCIA interrupts */ 167 84 if (AMIGAHW_PRESENT(PCMCIA)) ··· 171 94 172 95 cia_init_IRQ(&ciaa_base); 173 96 cia_init_IRQ(&ciab_base); 174 - } 175 - 176 - /* 177 - * Enable/disable a particular machine specific interrupt source. 178 - * Note that this may affect other interrupts in case of a shared interrupt. 179 - * This function should only be called for a _very_ short time to change some 180 - * internal data, that may not be changed by the interrupt at the same time. 181 - */ 182 - 183 - static void amiga_enable_irq(unsigned int irq) 184 - { 185 - amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); 186 - } 187 - 188 - static void amiga_disable_irq(unsigned int irq) 189 - { 190 - amiga_custom.intena = 1 << (irq - IRQ_USER); 191 - } 192 - 193 - /* 194 - * The builtin Amiga hardware interrupt handlers. 195 - */ 196 - 197 - static irqreturn_t ami_int1(int irq, void *dev_id) 198 - { 199 - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 200 - 201 - /* if serial transmit buffer empty, interrupt */ 202 - if (ints & IF_TBE) { 203 - amiga_custom.intreq = IF_TBE; 204 - m68k_handle_int(IRQ_AMIGA_TBE); 205 - } 206 - 207 - /* if floppy disk transfer complete, interrupt */ 208 - if (ints & IF_DSKBLK) { 209 - amiga_custom.intreq = IF_DSKBLK; 210 - m68k_handle_int(IRQ_AMIGA_DSKBLK); 211 - } 212 - 213 - /* if software interrupt set, interrupt */ 214 - if (ints & IF_SOFT) { 215 - amiga_custom.intreq = IF_SOFT; 216 - m68k_handle_int(IRQ_AMIGA_SOFT); 217 - } 218 - return IRQ_HANDLED; 219 - } 220 - 221 - static irqreturn_t ami_int3(int irq, void *dev_id) 222 - { 223 - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 224 - 225 - /* if a blitter interrupt */ 226 - if (ints & IF_BLIT) { 227 - amiga_custom.intreq = IF_BLIT; 228 - m68k_handle_int(IRQ_AMIGA_BLIT); 229 - } 230 - 231 - /* if a copper interrupt */ 232 - if (ints & IF_COPER) { 233 - amiga_custom.intreq = IF_COPER; 234 - m68k_handle_int(IRQ_AMIGA_COPPER); 235 - } 236 - 237 - /* if a vertical blank interrupt */ 238 - if (ints & IF_VERTB) { 239 - amiga_custom.intreq = IF_VERTB; 240 - m68k_handle_int(IRQ_AMIGA_VERTB); 241 - } 242 - return IRQ_HANDLED; 243 - } 244 - 245 - static irqreturn_t ami_int4(int irq, void *dev_id) 246 - { 247 - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 248 - 249 - /* if audio 0 interrupt */ 250 - if (ints & IF_AUD0) { 251 - amiga_custom.intreq = IF_AUD0; 252 - m68k_handle_int(IRQ_AMIGA_AUD0); 253 - } 254 - 255 - /* if audio 1 interrupt */ 256 - if (ints & IF_AUD1) { 257 - amiga_custom.intreq = IF_AUD1; 258 - m68k_handle_int(IRQ_AMIGA_AUD1); 259 - } 260 - 261 - /* if audio 2 interrupt */ 262 - if (ints & IF_AUD2) { 263 - amiga_custom.intreq = IF_AUD2; 264 - m68k_handle_int(IRQ_AMIGA_AUD2); 265 - } 266 - 267 - /* if audio 3 interrupt */ 268 - if (ints & IF_AUD3) { 269 - amiga_custom.intreq = IF_AUD3; 270 - m68k_handle_int(IRQ_AMIGA_AUD3); 271 - } 272 - return IRQ_HANDLED; 273 - } 274 - 275 - static irqreturn_t ami_int5(int irq, void *dev_id) 276 - { 277 - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; 278 - 279 - /* if serial receive buffer full interrupt */ 280 - if (ints & IF_RBF) { 281 - /* acknowledge of IF_RBF must be done by the serial interrupt */ 282 - m68k_handle_int(IRQ_AMIGA_RBF); 283 - } 284 - 285 - /* if a disk sync interrupt */ 286 - if (ints & IF_DSKSYN) { 287 - amiga_custom.intreq = IF_DSKSYN; 288 - m68k_handle_int(IRQ_AMIGA_DSKSYN); 289 - } 290 - return IRQ_HANDLED; 291 97 }
+21 -18
arch/m68k/amiga/cia.c
··· 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) { ··· 114 113 } 115 114 } 116 115 117 - static void cia_disable_irq(unsigned int irq) 116 + static void cia_irq_disable(struct irq_data *data) 118 117 { 118 + unsigned int irq = data->irq; 119 + 119 120 if (irq >= IRQ_AMIGA_CIAB) 120 121 cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); 121 122 else 122 123 cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); 123 124 } 124 125 125 - static struct irq_controller cia_irq_controller = { 126 + static struct irq_chip cia_irq_chip = { 126 127 .name = "cia", 127 - .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), 128 - .enable = cia_enable_irq, 129 - .disable = cia_disable_irq, 128 + .irq_enable = cia_irq_enable, 129 + .irq_disable = cia_irq_disable, 130 130 }; 131 131 132 132 /* ··· 136 134 * into this chain. 137 135 */ 138 136 139 - static void auto_enable_irq(unsigned int irq) 137 + static void auto_irq_enable(struct irq_data *data) 140 138 { 141 - switch (irq) { 139 + switch (data->irq) { 142 140 case IRQ_AUTO_2: 143 141 amiga_custom.intena = IF_SETCLR | IF_PORTS; 144 142 break; ··· 148 146 } 149 147 } 150 148 151 - static void auto_disable_irq(unsigned int irq) 149 + static void auto_irq_disable(struct irq_data *data) 152 150 { 153 - switch (irq) { 151 + switch (data->irq) { 154 152 case IRQ_AUTO_2: 155 153 amiga_custom.intena = IF_PORTS; 156 154 break; ··· 160 158 } 161 159 } 162 160 163 - static struct irq_controller auto_irq_controller = { 161 + static struct irq_chip auto_irq_chip = { 164 162 .name = "auto", 165 - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), 166 - .enable = auto_enable_irq, 167 - .disable = auto_disable_irq, 163 + .irq_enable = auto_irq_enable, 164 + .irq_disable = auto_irq_disable, 168 165 }; 169 166 170 167 void __init cia_init_IRQ(struct ciabase *base) 171 168 { 172 - m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); 169 + m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq, 170 + base->cia_irq, CIA_IRQS); 173 171 174 172 /* clear any pending interrupt and turn off all interrupts */ 175 173 cia_set_irq(base, CIA_ICR_ALL); 176 174 cia_able_irq(base, CIA_ICR_ALL); 177 175 178 176 /* override auto int and install CIA handler */ 179 - m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); 180 - m68k_irq_startup(base->handler_irq); 177 + m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq, 178 + base->handler_irq, 1); 179 + m68k_irq_startup_irq(base->handler_irq); 181 180 if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, 182 181 base->name, base)) 183 182 pr_err("Couldn't register %s interrupt\n", base->name);
+19 -16
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 ··· 15 21 return 0; 16 22 } 17 23 18 - void apollo_irq_shutdown(unsigned int irq) 24 + void apollo_irq_shutdown(struct irq_data *data) 19 25 { 26 + unsigned int irq = data->irq; 27 + 20 28 if (irq < 8) 21 29 *(volatile unsigned char *)(pica+1) |= (1 << irq); 22 30 else 23 31 *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); 24 32 } 25 33 26 - static struct irq_controller apollo_irq_controller = { 34 + void apollo_irq_eoi(struct irq_data *data) 35 + { 36 + *(volatile unsigned char *)(pica) = 0x20; 37 + *(volatile unsigned char *)(picb) = 0x20; 38 + } 39 + 40 + static struct irq_chip apollo_irq_chip = { 27 41 .name = "apollo", 28 - .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), 29 - .startup = apollo_irq_startup, 30 - .shutdown = apollo_irq_shutdown, 42 + .irq_startup = apollo_irq_startup, 43 + .irq_shutdown = apollo_irq_shutdown, 44 + .irq_eoi = apollo_irq_eoi, 31 45 }; 32 46 33 47 34 48 void __init dn_init_IRQ(void) 35 49 { 36 - m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); 37 - m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); 50 + m68k_setup_user_interrupt(VEC_USER + 96, 16); 51 + m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, 52 + IRQ_APOLLO, 16); 38 53 }
+26 -248
arch/m68k/atari/ataints.c
··· 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 - 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 - /* 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 64 301 65 /* 302 66 * Bitmap for free interrupt vector numbers ··· 84 320 85 321 extern int atari_SCC_reset_done; 86 322 87 - static int atari_startup_irq(unsigned int irq) 323 + static unsigned int atari_irq_startup(struct irq_data *data) 88 324 { 89 - m68k_irq_startup(irq); 325 + unsigned int irq = data->irq; 326 + 327 + m68k_irq_startup(data); 90 328 atari_turnon_irq(irq); 91 329 atari_enable_irq(irq); 92 330 return 0; 93 331 } 94 332 95 - static void atari_shutdown_irq(unsigned int irq) 333 + static void atari_irq_shutdown(struct irq_data *data) 96 334 { 335 + unsigned int irq = data->irq; 336 + 97 337 atari_disable_irq(irq); 98 338 atari_turnoff_irq(irq); 99 - m68k_irq_shutdown(irq); 339 + m68k_irq_shutdown(data); 100 340 101 341 if (irq == IRQ_AUTO_4) 102 342 vectors[VEC_INT4] = falcon_hblhandler; 103 343 } 104 344 105 - static struct irq_controller atari_irq_controller = { 345 + static void atari_irq_enable(struct irq_data *data) 346 + { 347 + atari_enable_irq(data->irq); 348 + } 349 + 350 + static void atari_irq_disable(struct irq_data *data) 351 + { 352 + atari_disable_irq(data->irq); 353 + } 354 + 355 + static struct irq_chip atari_irq_chip = { 106 356 .name = "atari", 107 - .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), 108 - .startup = atari_startup_irq, 109 - .shutdown = atari_shutdown_irq, 110 - .enable = atari_enable_irq, 111 - .disable = atari_disable_irq, 357 + .irq_startup = atari_irq_startup, 358 + .irq_shutdown = atari_irq_shutdown, 359 + .irq_enable = atari_irq_enable, 360 + .irq_disable = atari_irq_disable, 112 361 }; 113 362 114 363 /* ··· 137 360 138 361 void __init atari_init_IRQ(void) 139 362 { 140 - m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); 141 - m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); 363 + m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER); 364 + m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1, 365 + NUM_ATARI_SOURCES - 1); 142 366 143 367 /* Initialize the MFP(s) */ 144 368
+1 -1
arch/m68k/bvme6000/config.c
··· 86 86 */ 87 87 static void __init bvme6000_init_IRQ(void) 88 88 { 89 - m68k_setup_user_interrupt(VEC_USER, 192, NULL); 89 + m68k_setup_user_interrupt(VEC_USER, 192); 90 90 } 91 91 92 92 void __init config_bvme6000(void)
+1 -1
arch/m68k/hp300/time.c
··· 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 */
+5
arch/m68k/include/asm/hardirq.h
··· 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;
+15 -54
arch/m68k/include/asm/irq.h
··· 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. ··· 49 54 50 55 #define IRQ_USER 8 51 56 52 - extern unsigned int irq_canonicalize(unsigned int irq); 53 - 54 - struct pt_regs; 55 - 56 57 /* 57 58 * various flags for request_irq() - the Amiga now uses the standard 58 59 * mechanism like all other architectures - IRQF_DISABLED and ··· 62 71 #define IRQ_FLG_STD (0x8000) /* internally used */ 63 72 #endif 64 73 65 - /* 66 - * This structure is used to chain together the ISRs for a particular 67 - * interrupt source (if it supports chaining). 68 - */ 69 - typedef struct irq_node { 70 - irqreturn_t (*handler)(int, void *); 71 - void *dev_id; 72 - struct irq_node *next; 73 - unsigned long flags; 74 - const char *devname; 75 - } irq_node_t; 74 + struct irq_data; 75 + struct irq_chip; 76 + struct irq_desc; 77 + extern unsigned int m68k_irq_startup(struct irq_data *data); 78 + extern unsigned int m68k_irq_startup_irq(unsigned int irq); 79 + extern void m68k_irq_shutdown(struct irq_data *data); 80 + extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, 81 + struct pt_regs *)); 82 + extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt); 83 + extern void m68k_setup_irq_controller(struct irq_chip *, 84 + void (*handle)(unsigned int irq, 85 + struct irq_desc *desc), 86 + unsigned int irq, unsigned int cnt); 76 87 77 - /* 78 - * This structure has only 4 elements for speed reasons 79 - */ 80 - struct irq_handler { 81 - int (*handler)(int, void *); 82 - unsigned long flags; 83 - void *dev_id; 84 - const char *devname; 85 - }; 86 - 87 - struct irq_controller { 88 - const char *name; 89 - spinlock_t lock; 90 - int (*startup)(unsigned int irq); 91 - void (*shutdown)(unsigned int irq); 92 - void (*enable)(unsigned int irq); 93 - void (*disable)(unsigned int irq); 94 - }; 95 - 96 - extern int m68k_irq_startup(unsigned int); 97 - extern void m68k_irq_shutdown(unsigned int); 98 - 99 - /* 100 - * This function returns a new irq_node_t 101 - */ 102 - extern irq_node_t *new_irq_node(void); 103 - 104 - extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); 105 - extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, 106 - void (*handler)(unsigned int, struct pt_regs *)); 107 - extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); 108 - 109 - asmlinkage void m68k_handle_int(unsigned int); 110 - asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); 88 + extern unsigned int irq_canonicalize(unsigned int irq); 111 89 112 90 #else 113 91 #define irq_canonicalize(irq) (irq) 114 92 #endif /* CONFIG_MMU */ 115 93 116 94 asmlinkage void do_IRQ(int irq, struct pt_regs *regs); 95 + extern atomic_t irq_err_count; 117 96 118 97 #endif /* _M68K_IRQ_H_ */
+2
arch/m68k/include/asm/macintosh.h
··· 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
-3
arch/m68k/include/asm/q40ints.h
··· 24 24 #define Q40_IRQ10_MASK (1<<5) 25 25 #define Q40_IRQ14_MASK (1<<6) 26 26 #define Q40_IRQ15_MASK (1<<7) 27 - 28 - extern unsigned long q40_probe_irq_on (void); 29 - extern int q40_probe_irq_off (unsigned long irqs);
+4 -5
arch/m68k/kernel/Makefile
··· 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 21 20
+3 -4
arch/m68k/kernel/entry_mm.S
··· 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 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 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)
+32 -293
arch/m68k/kernel/ints.c
··· 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> ··· 28 47 #endif 29 48 30 49 extern u32 auto_irqhandler_fixup[]; 31 - extern u32 user_irqhandler_fixup[]; 32 50 extern u16 user_irqvec_fixup[]; 33 - 34 - /* table for system interrupt handlers */ 35 - static struct irq_node *irq_list[NR_IRQS]; 36 - static struct irq_controller *irq_controller[NR_IRQS]; 37 - static int irq_depth[NR_IRQS]; 38 51 39 52 static int m68k_first_user_vec; 40 53 41 - static struct irq_controller auto_irq_controller = { 54 + static struct irq_chip auto_irq_chip = { 42 55 .name = "auto", 43 - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), 44 - .startup = m68k_irq_startup, 45 - .shutdown = m68k_irq_shutdown, 56 + .irq_startup = m68k_irq_startup, 57 + .irq_shutdown = m68k_irq_shutdown, 46 58 }; 47 59 48 - static struct irq_controller user_irq_controller = { 60 + static struct irq_chip user_irq_chip = { 49 61 .name = "user", 50 - .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), 51 - .startup = m68k_irq_startup, 52 - .shutdown = m68k_irq_shutdown, 62 + .irq_startup = m68k_irq_startup, 63 + .irq_shutdown = m68k_irq_shutdown, 53 64 }; 54 - 55 - #define NUM_IRQ_NODES 100 56 - static irq_node_t nodes[NUM_IRQ_NODES]; 57 65 58 66 /* 59 67 * void init_IRQ(void) ··· 66 96 } 67 97 68 98 for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) 69 - irq_controller[i] = &auto_irq_controller; 99 + irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq); 70 100 71 101 mach_init_IRQ(); 72 102 } ··· 76 106 * @handler: called from auto vector interrupts 77 107 * 78 108 * setup the handler to be called from auto vector interrupts instead of the 79 - * standard __m68k_handle_int(), it will be called with irq numbers in the range 109 + * standard do_IRQ(), it will be called with irq numbers in the range 80 110 * from IRQ_AUTO_1 - IRQ_AUTO_7. 81 111 */ 82 112 void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) ··· 90 120 * m68k_setup_user_interrupt 91 121 * @vec: first user vector interrupt to handle 92 122 * @cnt: number of active user vector interrupts 93 - * @handler: called from user vector interrupts 94 123 * 95 124 * setup user vector interrupts, this includes activating the specified range 96 125 * of interrupts, only then these interrupts can be requested (note: this is 97 - * different from auto vector interrupts). An optional handler can be installed 98 - * to be called instead of the default __m68k_handle_int(), it will be called 99 - * with irq numbers starting from IRQ_USER. 126 + * different from auto vector interrupts). 100 127 */ 101 - void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, 102 - void (*handler)(unsigned int, struct pt_regs *)) 128 + void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt) 103 129 { 104 130 int i; 105 131 106 132 BUG_ON(IRQ_USER + cnt > NR_IRQS); 107 133 m68k_first_user_vec = vec; 108 134 for (i = 0; i < cnt; i++) 109 - irq_controller[IRQ_USER + i] = &user_irq_controller; 135 + irq_set_chip(IRQ_USER + i, &user_irq_chip); 110 136 *user_irqvec_fixup = vec - IRQ_USER; 111 - if (handler) 112 - *user_irqhandler_fixup = (u32)handler; 113 137 flush_icache(); 114 138 } 115 139 116 140 /** 117 141 * m68k_setup_irq_controller 118 - * @contr: irq controller which controls specified irq 142 + * @chip: irq chip which controls specified irq 143 + * @handle: flow handler which handles specified irq 119 144 * @irq: first irq to be managed by the controller 145 + * @cnt: number of irqs to be managed by the controller 120 146 * 121 147 * Change the controller for the specified range of irq, which will be used to 122 148 * manage these irq. auto/user irq already have a default controller, which can 123 149 * be changed as well, but the controller probably should use m68k_irq_startup/ 124 150 * m68k_irq_shutdown. 125 151 */ 126 - void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, 152 + void m68k_setup_irq_controller(struct irq_chip *chip, 153 + irq_flow_handler_t handle, unsigned int irq, 127 154 unsigned int cnt) 128 155 { 129 156 int i; 130 157 131 - for (i = 0; i < cnt; i++) 132 - irq_controller[irq + i] = contr; 158 + for (i = 0; i < cnt; i++) { 159 + irq_set_chip(irq + i, chip); 160 + if (handle) 161 + irq_set_handler(irq + i, handle); 162 + } 133 163 } 134 164 135 - irq_node_t *new_irq_node(void) 136 - { 137 - irq_node_t *node; 138 - short i; 139 - 140 - for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { 141 - if (!node->handler) { 142 - memset(node, 0, sizeof(*node)); 143 - return node; 144 - } 145 - } 146 - 147 - printk ("new_irq_node: out of nodes\n"); 148 - return NULL; 149 - } 150 - 151 - int setup_irq(unsigned int irq, struct irq_node *node) 152 - { 153 - struct irq_controller *contr; 154 - struct irq_node **prev; 155 - unsigned long flags; 156 - 157 - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { 158 - printk("%s: Incorrect IRQ %d from %s\n", 159 - __func__, irq, node->devname); 160 - return -ENXIO; 161 - } 162 - 163 - spin_lock_irqsave(&contr->lock, flags); 164 - 165 - prev = irq_list + irq; 166 - if (*prev) { 167 - /* Can't share interrupts unless both agree to */ 168 - if (!((*prev)->flags & node->flags & IRQF_SHARED)) { 169 - spin_unlock_irqrestore(&contr->lock, flags); 170 - return -EBUSY; 171 - } 172 - while (*prev) 173 - prev = &(*prev)->next; 174 - } 175 - 176 - if (!irq_list[irq]) { 177 - if (contr->startup) 178 - contr->startup(irq); 179 - else 180 - contr->enable(irq); 181 - } 182 - node->next = NULL; 183 - *prev = node; 184 - 185 - spin_unlock_irqrestore(&contr->lock, flags); 186 - 187 - return 0; 188 - } 189 - 190 - int request_irq(unsigned int irq, 191 - irq_handler_t handler, 192 - unsigned long flags, const char *devname, void *dev_id) 193 - { 194 - struct irq_node *node; 195 - int res; 196 - 197 - node = new_irq_node(); 198 - if (!node) 199 - return -ENOMEM; 200 - 201 - node->handler = handler; 202 - node->flags = flags; 203 - node->dev_id = dev_id; 204 - node->devname = devname; 205 - 206 - res = setup_irq(irq, node); 207 - if (res) 208 - node->handler = NULL; 209 - 210 - return res; 211 - } 212 - 213 - EXPORT_SYMBOL(request_irq); 214 - 215 - void free_irq(unsigned int irq, void *dev_id) 216 - { 217 - struct irq_controller *contr; 218 - struct irq_node **p, *node; 219 - unsigned long flags; 220 - 221 - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { 222 - printk("%s: Incorrect IRQ %d\n", __func__, irq); 223 - return; 224 - } 225 - 226 - spin_lock_irqsave(&contr->lock, flags); 227 - 228 - p = irq_list + irq; 229 - while ((node = *p)) { 230 - if (node->dev_id == dev_id) 231 - break; 232 - p = &node->next; 233 - } 234 - 235 - if (node) { 236 - *p = node->next; 237 - node->handler = NULL; 238 - } else 239 - printk("%s: Removing probably wrong IRQ %d\n", 240 - __func__, irq); 241 - 242 - if (!irq_list[irq]) { 243 - if (contr->shutdown) 244 - contr->shutdown(irq); 245 - else 246 - contr->disable(irq); 247 - } 248 - 249 - spin_unlock_irqrestore(&contr->lock, flags); 250 - } 251 - 252 - EXPORT_SYMBOL(free_irq); 253 - 254 - void enable_irq(unsigned int irq) 255 - { 256 - struct irq_controller *contr; 257 - unsigned long flags; 258 - 259 - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { 260 - printk("%s: Incorrect IRQ %d\n", 261 - __func__, irq); 262 - return; 263 - } 264 - 265 - spin_lock_irqsave(&contr->lock, flags); 266 - if (irq_depth[irq]) { 267 - if (!--irq_depth[irq]) { 268 - if (contr->enable) 269 - contr->enable(irq); 270 - } 271 - } else 272 - WARN_ON(1); 273 - spin_unlock_irqrestore(&contr->lock, flags); 274 - } 275 - 276 - EXPORT_SYMBOL(enable_irq); 277 - 278 - void disable_irq(unsigned int irq) 279 - { 280 - struct irq_controller *contr; 281 - unsigned long flags; 282 - 283 - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { 284 - printk("%s: Incorrect IRQ %d\n", 285 - __func__, irq); 286 - return; 287 - } 288 - 289 - spin_lock_irqsave(&contr->lock, flags); 290 - if (!irq_depth[irq]++) { 291 - if (contr->disable) 292 - contr->disable(irq); 293 - } 294 - spin_unlock_irqrestore(&contr->lock, flags); 295 - } 296 - 297 - EXPORT_SYMBOL(disable_irq); 298 - 299 - void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); 300 - 301 - EXPORT_SYMBOL(disable_irq_nosync); 302 - 303 - int m68k_irq_startup(unsigned int irq) 165 + unsigned int m68k_irq_startup_irq(unsigned int irq) 304 166 { 305 167 if (irq <= IRQ_AUTO_7) 306 168 vectors[VEC_SPUR + irq] = auto_inthandler; ··· 141 339 return 0; 142 340 } 143 341 144 - void m68k_irq_shutdown(unsigned int irq) 342 + unsigned int m68k_irq_startup(struct irq_data *data) 145 343 { 344 + return m68k_irq_startup_irq(data->irq); 345 + } 346 + 347 + void m68k_irq_shutdown(struct irq_data *data) 348 + { 349 + unsigned int irq = data->irq; 350 + 146 351 if (irq <= IRQ_AUTO_7) 147 352 vectors[VEC_SPUR + irq] = bad_inthandler; 148 353 else 149 354 vectors[m68k_first_user_vec + irq - IRQ_USER] = bad_inthandler; 150 355 } 151 356 152 - 153 - /* 154 - * Do we need these probe functions on the m68k? 155 - * 156 - * ... may be useful with ISA devices 157 - */ 158 - unsigned long probe_irq_on (void) 159 - { 160 - #ifdef CONFIG_Q40 161 - if (MACH_IS_Q40) 162 - return q40_probe_irq_on(); 163 - #endif 164 - return 0; 165 - } 166 - 167 - EXPORT_SYMBOL(probe_irq_on); 168 - 169 - int probe_irq_off (unsigned long irqs) 170 - { 171 - #ifdef CONFIG_Q40 172 - if (MACH_IS_Q40) 173 - return q40_probe_irq_off(irqs); 174 - #endif 175 - return 0; 176 - } 177 - 178 - EXPORT_SYMBOL(probe_irq_off); 179 357 180 358 unsigned int irq_canonicalize(unsigned int irq) 181 359 { ··· 168 386 169 387 EXPORT_SYMBOL(irq_canonicalize); 170 388 171 - asmlinkage void m68k_handle_int(unsigned int irq) 172 - { 173 - struct irq_node *node; 174 - kstat_cpu(0).irqs[irq]++; 175 - node = irq_list[irq]; 176 - do { 177 - node->handler(irq, node->dev_id); 178 - node = node->next; 179 - } while (node); 180 - } 181 - 182 - asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) 183 - { 184 - struct pt_regs *old_regs; 185 - old_regs = set_irq_regs(regs); 186 - m68k_handle_int(irq); 187 - set_irq_regs(old_regs); 188 - } 189 389 190 390 asmlinkage void handle_badint(struct pt_regs *regs) 191 391 { 192 - kstat_cpu(0).irqs[0]++; 193 - printk("unexpected interrupt from %u\n", regs->vector); 392 + atomic_inc(&irq_err_count); 393 + pr_warn("unexpected interrupt from %u\n", regs->vector); 194 394 } 195 - 196 - int show_interrupts(struct seq_file *p, void *v) 197 - { 198 - struct irq_controller *contr; 199 - struct irq_node *node; 200 - int i = *(loff_t *) v; 201 - 202 - /* autovector interrupts */ 203 - if (irq_list[i]) { 204 - contr = irq_controller[i]; 205 - node = irq_list[i]; 206 - seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); 207 - while ((node = node->next)) 208 - seq_printf(p, ", %s", node->devname); 209 - seq_puts(p, "\n"); 210 - } 211 - return 0; 212 - } 213 - 214 - #ifdef CONFIG_PROC_FS 215 - void init_irq_proc(void) 216 - { 217 - /* Insert /proc/irq driver here */ 218 - } 219 - #endif
+9 -12
arch/m68k/mac/baboon.c
··· 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 19 #include <asm/mac_baboon.h> 21 20 22 21 /* #define DEBUG_IRQS */ 23 - 24 - extern void mac_enable_irq(unsigned int); 25 - extern void mac_disable_irq(unsigned int); 26 22 27 23 int baboon_present; 28 24 static volatile struct baboon *baboon; ··· 51 53 * Baboon interrupt handler. This works a lot like a VIA. 52 54 */ 53 55 54 - static irqreturn_t baboon_irq(int irq, void *dev_id) 56 + static void baboon_irq(unsigned int irq, struct irq_desc *desc) 55 57 { 56 58 int irq_bit, irq_num; 57 59 unsigned char events; ··· 62 64 (uint) baboon->mb_status); 63 65 #endif 64 66 65 - if (!(events = baboon->mb_ifr & 0x07)) 66 - return IRQ_NONE; 67 + events = baboon->mb_ifr & 0x07; 68 + if (!events) 69 + return; 67 70 68 71 irq_num = IRQ_BABOON_0; 69 72 irq_bit = 1; 70 73 do { 71 74 if (events & irq_bit) { 72 75 baboon->mb_ifr &= ~irq_bit; 73 - m68k_handle_int(irq_num); 76 + generic_handle_irq(irq_num); 74 77 } 75 78 irq_bit <<= 1; 76 79 irq_num++; ··· 81 82 /* for now we need to smash all interrupts */ 82 83 baboon->mb_ifr &= ~events; 83 84 #endif 84 - return IRQ_HANDLED; 85 85 } 86 86 87 87 /* ··· 90 92 void __init baboon_register_interrupts(void) 91 93 { 92 94 baboon_disabled = 0; 93 - if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon)) 94 - pr_err("Couldn't register baboon interrupt\n"); 95 + irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); 95 96 } 96 97 97 98 /* ··· 108 111 109 112 baboon_disabled &= ~(1 << irq_idx); 110 113 if (!baboon_disabled) 111 - mac_enable_irq(IRQ_NUBUS_C); 114 + mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C)); 112 115 } 113 116 114 117 void baboon_irq_disable(int irq) ··· 121 124 122 125 baboon_disabled |= 1 << irq_idx; 123 126 if (baboon_disabled) 124 - mac_disable_irq(IRQ_NUBUS_C); 127 + mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C)); 125 128 } 126 129 127 130 void baboon_irq_clear(int irq)
+4 -6
arch/m68k/mac/iop.c
··· 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])) {
+11 -13
arch/m68k/mac/macints.c
··· 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) ··· 201 205 #ifdef DEBUG_MACINTS 202 206 printk("mac_init_IRQ(): Setting things up...\n"); 203 207 #endif 204 - m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, 208 + m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER, 205 209 NUM_MAC_SOURCES - IRQ_USER); 206 210 /* Make sure the SONIC interrupt is cleared or things get ugly */ 207 211 #ifdef SHUTUP_SONIC ··· 237 241 } 238 242 239 243 /* 240 - * mac_enable_irq - enable an interrupt source 241 - * mac_disable_irq - disable an interrupt source 244 + * mac_irq_enable - enable an interrupt source 245 + * mac_irq_disable - disable an interrupt source 242 246 * mac_clear_irq - clears a pending interrupt 243 - * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending) 247 + * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending) 244 248 * 245 249 * These routines are just dispatchers to the VIA/OSS/PSC routines. 246 250 */ 247 251 248 - void mac_enable_irq(unsigned int irq) 252 + void mac_irq_enable(struct irq_data *data) 249 253 { 254 + int irq = data->irq; 250 255 int irq_src = IRQ_SRC(irq); 251 256 252 257 switch(irq_src) { ··· 280 283 } 281 284 } 282 285 283 - void mac_disable_irq(unsigned int irq) 286 + void mac_irq_disable(struct irq_data *data) 284 287 { 288 + int irq = data->irq; 285 289 int irq_src = IRQ_SRC(irq); 286 290 287 291 switch(irq_src) {
+21 -33
arch/m68k/mac/oss.c
··· 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> ··· 30 29 int oss_present; 31 30 volatile struct mac_oss *oss; 32 31 33 - static irqreturn_t oss_irq(int, void *); 34 - static irqreturn_t oss_nubus_irq(int, void *); 35 - 36 - extern irqreturn_t via1_irq(int, void *); 32 + extern void via1_irq(unsigned int irq, struct irq_desc *desc); 37 33 38 34 /* 39 35 * Initialize the OSS ··· 58 60 } 59 61 60 62 /* 61 - * Register the OSS and NuBus interrupt dispatchers. 62 - */ 63 - 64 - void __init oss_register_interrupts(void) 65 - { 66 - if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, 67 - "scsi", (void *) oss)) 68 - pr_err("Couldn't register %s interrupt\n", "scsi"); 69 - if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, 70 - "nubus", (void *) oss)) 71 - pr_err("Couldn't register %s interrupt\n", "nubus"); 72 - if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, 73 - "sound", (void *) oss)) 74 - pr_err("Couldn't register %s interrupt\n", "sound"); 75 - if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, 76 - "via1", (void *) via1)) 77 - pr_err("Couldn't register %s interrupt\n", "via1"); 78 - } 79 - 80 - /* 81 63 * Initialize OSS for Nubus access 82 64 */ 83 65 ··· 70 92 * and SCSI; everything else is routed to its own autovector IRQ. 71 93 */ 72 94 73 - static irqreturn_t oss_irq(int irq, void *dev_id) 95 + static void oss_irq(unsigned int irq, struct irq_desc *desc) 74 96 { 75 97 int events; 76 98 77 99 events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); 78 100 if (!events) 79 - return IRQ_NONE; 101 + return; 80 102 81 103 #ifdef DEBUG_IRQS 82 104 if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { 83 - printk("oss_irq: irq %d events = 0x%04X\n", irq, 105 + printk("oss_irq: irq %u events = 0x%04X\n", irq, 84 106 (int) oss->irq_pending); 85 107 } 86 108 #endif ··· 91 113 /* FIXME: call sound handler */ 92 114 } else if (events & OSS_IP_SCSI) { 93 115 oss->irq_pending &= ~OSS_IP_SCSI; 94 - m68k_handle_int(IRQ_MAC_SCSI); 116 + generic_handle_irq(IRQ_MAC_SCSI); 95 117 } else { 96 118 /* FIXME: error check here? */ 97 119 } 98 - return IRQ_HANDLED; 99 120 } 100 121 101 122 /* ··· 103 126 * Unlike the VIA/RBV this is on its own autovector interrupt level. 104 127 */ 105 128 106 - static irqreturn_t oss_nubus_irq(int irq, void *dev_id) 129 + static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) 107 130 { 108 131 int events, irq_bit, i; 109 132 110 133 events = oss->irq_pending & OSS_IP_NUBUS; 111 134 if (!events) 112 - return IRQ_NONE; 135 + return; 113 136 114 137 #ifdef DEBUG_NUBUS_INT 115 138 if (console_loglevel > 7) { ··· 125 148 irq_bit >>= 1; 126 149 if (events & irq_bit) { 127 150 oss->irq_pending &= ~irq_bit; 128 - m68k_handle_int(NUBUS_SOURCE_BASE + i); 151 + generic_handle_irq(NUBUS_SOURCE_BASE + i); 129 152 } 130 153 } while(events & (irq_bit - 1)); 131 - return IRQ_HANDLED; 154 + } 155 + 156 + /* 157 + * Register the OSS and NuBus interrupt dispatchers. 158 + */ 159 + 160 + void __init oss_register_interrupts(void) 161 + { 162 + irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); 163 + irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); 164 + irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq); 165 + irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); 132 166 } 133 167 134 168 /*
+24 -25
arch/m68k/mac/psc.c
··· 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 29 31 30 int psc_present; 32 31 volatile __u8 *psc; 33 - 34 - irqreturn_t psc_irq(int, void *); 35 32 36 33 /* 37 34 * Debugging dump, used in various places to see what's going on. ··· 111 112 } 112 113 113 114 /* 114 - * Register the PSC interrupt dispatchers for autovector interrupts 3-6. 115 - */ 116 - 117 - void __init psc_register_interrupts(void) 118 - { 119 - if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) 120 - pr_err("Couldn't register psc%d interrupt\n", 3); 121 - if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) 122 - pr_err("Couldn't register psc%d interrupt\n", 4); 123 - if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) 124 - pr_err("Couldn't register psc%d interrupt\n", 5); 125 - if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) 126 - pr_err("Couldn't register psc%d interrupt\n", 6); 127 - } 128 - 129 - /* 130 115 * PSC interrupt handler. It's a lot like the VIA interrupt handler. 131 116 */ 132 117 133 - irqreturn_t psc_irq(int irq, void *dev_id) 118 + static void psc_irq(unsigned int irq, struct irq_desc *desc) 134 119 { 135 - int pIFR = pIFRbase + ((int) dev_id); 136 - int pIER = pIERbase + ((int) dev_id); 120 + unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); 121 + int pIFR = pIFRbase + offset; 122 + int pIER = pIERbase + offset; 137 123 int irq_num; 138 124 unsigned char irq_bit, events; 139 125 140 126 #ifdef DEBUG_IRQS 141 - printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", 127 + printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n", 142 128 irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); 143 129 #endif 144 130 145 131 events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; 146 132 if (!events) 147 - return IRQ_NONE; 133 + return; 148 134 149 135 irq_num = irq << 3; 150 136 irq_bit = 1; 151 137 do { 152 138 if (events & irq_bit) { 153 139 psc_write_byte(pIFR, irq_bit); 154 - m68k_handle_int(irq_num); 140 + generic_handle_irq(irq_num); 155 141 } 156 142 irq_num++; 157 143 irq_bit <<= 1; 158 144 } while (events >= irq_bit); 159 - return IRQ_HANDLED; 145 + } 146 + 147 + /* 148 + * Register the PSC interrupt dispatchers for autovector interrupts 3-6. 149 + */ 150 + 151 + void __init psc_register_interrupts(void) 152 + { 153 + irq_set_chained_handler(IRQ_AUTO_3, psc_irq); 154 + irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); 155 + irq_set_chained_handler(IRQ_AUTO_4, psc_irq); 156 + irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); 157 + irq_set_chained_handler(IRQ_AUTO_5, psc_irq); 158 + irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); 159 + irq_set_chained_handler(IRQ_AUTO_6, psc_irq); 160 + irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); 160 161 } 161 162 162 163 void psc_irq_enable(int irq) {
+29 -45
arch/m68k/mac/via.c
··· 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> ··· 78 77 static u8 nubus_disabled; 79 78 80 79 void via_debug_dump(void); 81 - irqreturn_t via1_irq(int, void *); 82 - irqreturn_t via2_irq(int, void *); 83 - irqreturn_t via_nubus_irq(int, void *); 84 80 void via_irq_enable(int irq); 85 81 void via_irq_disable(int irq); 86 82 void via_irq_clear(int irq); ··· 279 281 via1[vT1CL] = MAC_CLOCK_LOW; 280 282 via1[vT1CH] = MAC_CLOCK_HIGH; 281 283 282 - if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func)) 284 + if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func)) 283 285 pr_err("Couldn't register %s interrupt\n", "timer"); 284 - } 285 - 286 - /* 287 - * Register the interrupt dispatchers for VIA or RBV machines only. 288 - */ 289 - 290 - void __init via_register_interrupts(void) 291 - { 292 - if (via_alt_mapping) { 293 - if (request_irq(IRQ_AUTO_1, via1_irq, 294 - IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", 295 - (void *) via1)) 296 - pr_err("Couldn't register %s interrupt\n", "software"); 297 - if (request_irq(IRQ_AUTO_6, via1_irq, 298 - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", 299 - (void *) via1)) 300 - pr_err("Couldn't register %s interrupt\n", "via1"); 301 - } else { 302 - if (request_irq(IRQ_AUTO_1, via1_irq, 303 - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", 304 - (void *) via1)) 305 - pr_err("Couldn't register %s interrupt\n", "via1"); 306 - } 307 - if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, 308 - "via2", (void *) via2)) 309 - pr_err("Couldn't register %s interrupt\n", "via2"); 310 - if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 311 - IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) 312 - pr_err("Couldn't register %s interrupt\n", "nubus"); 313 286 } 314 287 315 288 /* ··· 415 446 * via6522.c :-), disable/pending masks added. 416 447 */ 417 448 418 - irqreturn_t via1_irq(int irq, void *dev_id) 449 + void via1_irq(unsigned int irq, struct irq_desc *desc) 419 450 { 420 451 int irq_num; 421 452 unsigned char irq_bit, events; 422 453 423 454 events = via1[vIFR] & via1[vIER] & 0x7F; 424 455 if (!events) 425 - return IRQ_NONE; 456 + return; 426 457 427 458 irq_num = VIA1_SOURCE_BASE; 428 459 irq_bit = 1; 429 460 do { 430 461 if (events & irq_bit) { 431 462 via1[vIFR] = irq_bit; 432 - m68k_handle_int(irq_num); 463 + generic_handle_irq(irq_num); 433 464 } 434 465 ++irq_num; 435 466 irq_bit <<= 1; 436 467 } while (events >= irq_bit); 437 - return IRQ_HANDLED; 438 468 } 439 469 440 - irqreturn_t via2_irq(int irq, void *dev_id) 470 + static void via2_irq(unsigned int irq, struct irq_desc *desc) 441 471 { 442 472 int irq_num; 443 473 unsigned char irq_bit, events; 444 474 445 475 events = via2[gIFR] & via2[gIER] & 0x7F; 446 476 if (!events) 447 - return IRQ_NONE; 477 + return; 448 478 449 479 irq_num = VIA2_SOURCE_BASE; 450 480 irq_bit = 1; 451 481 do { 452 482 if (events & irq_bit) { 453 483 via2[gIFR] = irq_bit | rbv_clear; 454 - m68k_handle_int(irq_num); 484 + generic_handle_irq(irq_num); 455 485 } 456 486 ++irq_num; 457 487 irq_bit <<= 1; 458 488 } while (events >= irq_bit); 459 - return IRQ_HANDLED; 460 489 } 461 490 462 491 /* ··· 462 495 * VIA2 dispatcher as a fast interrupt handler. 463 496 */ 464 497 465 - irqreturn_t via_nubus_irq(int irq, void *dev_id) 498 + void via_nubus_irq(unsigned int irq, struct irq_desc *desc) 466 499 { 467 500 int slot_irq; 468 501 unsigned char slot_bit, events; ··· 473 506 else 474 507 events &= ~via2[vDirA]; 475 508 if (!events) 476 - return IRQ_NONE; 509 + return; 477 510 478 511 do { 479 512 slot_irq = IRQ_NUBUS_F; ··· 481 514 do { 482 515 if (events & slot_bit) { 483 516 events &= ~slot_bit; 484 - m68k_handle_int(slot_irq); 517 + generic_handle_irq(slot_irq); 485 518 } 486 519 --slot_irq; 487 520 slot_bit >>= 1; ··· 495 528 else 496 529 events &= ~via2[vDirA]; 497 530 } while (events); 498 - return IRQ_HANDLED; 531 + } 532 + 533 + /* 534 + * Register the interrupt dispatchers for VIA or RBV machines only. 535 + */ 536 + 537 + void __init via_register_interrupts(void) 538 + { 539 + if (via_alt_mapping) { 540 + /* software interrupt */ 541 + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); 542 + /* via1 interrupt */ 543 + irq_set_chained_handler(IRQ_AUTO_6, via1_irq); 544 + } else { 545 + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); 546 + } 547 + irq_set_chained_handler(IRQ_AUTO_2, via2_irq); 548 + irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); 499 549 } 500 550 501 551 void via_irq_enable(int irq) {
+2 -3
arch/m68k/mvme147/config.c
··· 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 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 */
+1 -1
arch/m68k/mvme16x/config.c
··· 117 117 118 118 static void __init mvme16x_init_IRQ (void) 119 119 { 120 - m68k_setup_user_interrupt(VEC_USER, 192, NULL); 120 + m68k_setup_user_interrupt(VEC_USER, 192); 121 121 } 122 122 123 123 #define pcc2chip ((volatile u_char *)0xfff42000)
+28 -32
arch/m68k/q40/q40ints.c
··· 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> ··· 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 /* ··· 82 81 83 82 void __init q40_init_IRQ(void) 84 83 { 85 - m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); 84 + m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, 85 + Q40_IRQ_MAX); 86 86 87 87 /* setup handler for ISA ints */ 88 88 m68k_setup_auto_interrupt(q40_irq_handler); 89 89 90 - m68k_irq_startup(IRQ_AUTO_2); 91 - m68k_irq_startup(IRQ_AUTO_4); 90 + m68k_irq_startup_irq(IRQ_AUTO_2); 91 + m68k_irq_startup_irq(IRQ_AUTO_4); 92 92 93 93 /* now enable some ints.. */ 94 94 master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ ··· 220 218 switch (irq) { 221 219 case 4: 222 220 case 6: 223 - __m68k_handle_int(Q40_IRQ_SAMPLE, fp); 221 + do_IRQ(Q40_IRQ_SAMPLE, fp); 224 222 return; 225 223 } 226 224 if (mir & Q40_IRQ_FRAME_MASK) { 227 - __m68k_handle_int(Q40_IRQ_FRAME, fp); 225 + do_IRQ(Q40_IRQ_FRAME, fp); 228 226 master_outb(-1, FRAME_CLEAR_REG); 229 227 } 230 228 if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { ··· 259 257 goto iirq; 260 258 } 261 259 q40_state[irq] |= IRQ_INPROGRESS; 262 - __m68k_handle_int(irq, fp); 260 + do_IRQ(irq, fp); 263 261 q40_state[irq] &= ~IRQ_INPROGRESS; 264 262 265 263 /* naively enable everything, if that fails than */ ··· 290 288 mir = master_inb(IIRQ_REG); 291 289 /* should test whether keyboard irq is really enabled, doing it in defhand */ 292 290 if (mir & Q40_IRQ_KEYB_MASK) 293 - __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); 291 + do_IRQ(Q40_IRQ_KEYBOARD, fp); 294 292 295 293 return; 296 294 } 297 295 298 - void q40_enable_irq(unsigned int irq) 296 + void q40_irq_enable(struct irq_data *data) 299 297 { 298 + unsigned int irq = data->irq; 299 + 300 300 if (irq >= 5 && irq <= 15) { 301 301 mext_disabled--; 302 302 if (mext_disabled > 0) 303 - printk("q40_enable_irq : nested disable/enable\n"); 303 + printk("q40_irq_enable : nested disable/enable\n"); 304 304 if (mext_disabled == 0) 305 305 master_outb(1, EXT_ENABLE_REG); 306 306 } 307 307 } 308 308 309 309 310 - void q40_disable_irq(unsigned int irq) 310 + void q40_irq_disable(struct irq_data *data) 311 311 { 312 + unsigned int irq = data->irq; 313 + 312 314 /* disable ISA iqs : only do something if the driver has been 313 315 * verified to be Q40 "compatible" - right now IDE, NE2K 314 316 * Any driver should not attempt to sleep across disable_irq !! ··· 324 318 if (mext_disabled > 1) 325 319 printk("disable_irq nesting count %d\n",mext_disabled); 326 320 } 327 - } 328 - 329 - unsigned long q40_probe_irq_on(void) 330 - { 331 - printk("irq probing not working - reconfigure the driver to avoid this\n"); 332 - return -1; 333 - } 334 - int q40_probe_irq_off(unsigned long irqs) 335 - { 336 - return -1; 337 321 }
+27 -19
arch/m68k/sun3/sun3ints.c
··· 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 ··· 83 79 return IRQ_HANDLED; 84 80 } 85 81 86 - static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) 82 + static void sun3_irq_enable(struct irq_data *data) 87 83 { 88 - *sun3_intreg &= ~(1 << irq); 84 + sun3_enable_irq(data->irq); 85 + }; 89 86 90 - __m68k_handle_int(irq, fp); 91 - } 87 + static void sun3_irq_disable(struct irq_data *data) 88 + { 89 + sun3_disable_irq(data->irq); 90 + }; 92 91 93 - static struct irq_controller sun3_irq_controller = { 92 + static struct irq_chip sun3_irq_chip = { 94 93 .name = "sun3", 95 - .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), 96 - .startup = m68k_irq_startup, 97 - .shutdown = m68k_irq_shutdown, 98 - .enable = sun3_enable_irq, 99 - .disable = sun3_disable_irq, 94 + .irq_startup = m68k_irq_startup, 95 + .irq_shutdown = m68k_irq_shutdown, 96 + .irq_enable = sun3_irq_enable, 97 + .irq_disable = sun3_irq_disable, 98 + .irq_mask = sun3_irq_disable, 99 + .irq_unmask = sun3_irq_enable, 100 100 }; 101 101 102 102 void __init sun3_init_IRQ(void) 103 103 { 104 104 *sun3_intreg = 1; 105 105 106 - m68k_setup_auto_interrupt(sun3_inthandle); 107 - m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); 108 - m68k_setup_user_interrupt(VEC_USER, 128, NULL); 106 + m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, 107 + 7); 108 + m68k_setup_user_interrupt(VEC_USER, 128); 109 109 110 110 if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) 111 111 pr_err("Couldn't register %s interrupt\n", "int5");
-1
drivers/ide/ide-cd.c
··· 43 43 /* For SCSI -> ATAPI command conversion */ 44 44 #include <scsi/scsi.h> 45 45 46 - #include <linux/irq.h> 47 46 #include <linux/io.h> 48 47 #include <asm/byteorder.h> 49 48 #include <linux/uaccess.h>
-1
drivers/ide/ide-floppy.c
··· 35 35 #include <scsi/scsi_ioctl.h> 36 36 37 37 #include <asm/byteorder.h> 38 - #include <linux/irq.h> 39 38 #include <linux/uaccess.h> 40 39 #include <linux/io.h> 41 40 #include <asm/unaligned.h>
-1
drivers/ide/ide-tape.c
··· 41 41 #include <scsi/scsi.h> 42 42 43 43 #include <asm/byteorder.h> 44 - #include <linux/irq.h> 45 44 #include <linux/uaccess.h> 46 45 #include <linux/io.h> 47 46 #include <asm/unaligned.h>
+1 -1
drivers/macintosh/via-macii.c
··· 159 159 err = macii_init_via(); 160 160 if (err) goto out; 161 161 162 - err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", 162 + err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", 163 163 macii_interrupt); 164 164 if (err) goto out; 165 165
+2 -2
drivers/macintosh/via-maciisi.c
··· 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 }