aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2410/bast-irq.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2005-09-07 12:24:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-09-07 12:24:48 -0400
commitbafa49cc1b800df4748b29e2b038ff029d7c8747 (patch)
treec91d1c4cd3ed9acf0b7bc503600f0b60a06a910f /arch/arm/mach-s3c2410/bast-irq.c
parent7691d931aa55409ae3339d541ec0b87ab0a2adae (diff)
[ARM] 2884/1: BAST - fix PC104 IRQ routing
Patch from Ben Dooks This has been broken for a while now, so fix the problems with the code, test and bring up to date. This also makes the code conditional on an Kconfig option Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-s3c2410/bast-irq.c')
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 49914709fa09..fbbeb0553006 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/mach-s3c2410/bast-irq.c 1/* linux/arch/arm/mach-s3c2410/bast-irq.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2003,2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * http://www.simtec.co.uk/products/EB2410ITX/ 6 * http://www.simtec.co.uk/products/EB2410ITX/
@@ -21,7 +21,8 @@
21 * 21 *
22 * Modifications: 22 * Modifications:
23 * 08-Jan-2003 BJD Moved from central IRQ code 23 * 08-Jan-2003 BJD Moved from central IRQ code
24 */ 24 * 21-Aug-2005 BJD Fixed missing code and compile errors
25*/
25 26
26 27
27#include <linux/init.h> 28#include <linux/init.h>
@@ -30,12 +31,19 @@
30#include <linux/ptrace.h> 31#include <linux/ptrace.h>
31#include <linux/sysdev.h> 32#include <linux/sysdev.h>
32 33
34#include <asm/mach-types.h>
35
33#include <asm/hardware.h> 36#include <asm/hardware.h>
34#include <asm/irq.h> 37#include <asm/irq.h>
35#include <asm/io.h> 38#include <asm/io.h>
36 39
37#include <asm/mach/irq.h> 40#include <asm/mach/irq.h>
38#include <asm/hardware/s3c2410/irq.h> 41
42#include <asm/arch/regs-irq.h>
43#include <asm/arch/bast-map.h>
44#include <asm/arch/bast-irq.h>
45
46#include "irq.h"
39 47
40#if 0 48#if 0
41#include <asm/debug-ll.h> 49#include <asm/debug-ll.h>
@@ -79,15 +87,15 @@ bast_pc104_mask(unsigned int irqno)
79 temp = __raw_readb(BAST_VA_PC104_IRQMASK); 87 temp = __raw_readb(BAST_VA_PC104_IRQMASK);
80 temp &= ~bast_pc104_irqmasks[irqno]; 88 temp &= ~bast_pc104_irqmasks[irqno];
81 __raw_writeb(temp, BAST_VA_PC104_IRQMASK); 89 __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
82
83 if (temp == 0)
84 bast_extint_mask(IRQ_ISA);
85} 90}
86 91
87static void 92static void
88bast_pc104_ack(unsigned int irqno) 93bast_pc104_maskack(unsigned int irqno)
89{ 94{
90 bast_extint_ack(IRQ_ISA); 95 struct irqdesc *desc = irq_desc + IRQ_ISA;
96
97 bast_pc104_mask(irqno);
98 desc->chip->ack(IRQ_ISA);
91} 99}
92 100
93static void 101static void
@@ -98,14 +106,12 @@ bast_pc104_unmask(unsigned int irqno)
98 temp = __raw_readb(BAST_VA_PC104_IRQMASK); 106 temp = __raw_readb(BAST_VA_PC104_IRQMASK);
99 temp |= bast_pc104_irqmasks[irqno]; 107 temp |= bast_pc104_irqmasks[irqno];
100 __raw_writeb(temp, BAST_VA_PC104_IRQMASK); 108 __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
101
102 bast_extint_unmask(IRQ_ISA);
103} 109}
104 110
105static struct bast_pc104_chip = { 111static struct irqchip bast_pc104_chip = {
106 .mask = bast_pc104_mask, 112 .mask = bast_pc104_mask,
107 .unmask = bast_pc104_unmask, 113 .unmask = bast_pc104_unmask,
108 .ack = bast_pc104_ack 114 .ack = bast_pc104_maskack
109}; 115};
110 116
111static void 117static void
@@ -119,14 +125,49 @@ bast_irq_pc104_demux(unsigned int irq,
119 125
120 stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; 126 stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
121 127
122 for (i = 0; i < 4 && stat != 0; i++) { 128 if (unlikely(stat == 0)) {
123 if (stat & 1) { 129 /* ack if we get an irq with nothing (ie, startup) */
124 irqno = bast_pc104_irqs[i]; 130
125 desc = irq_desc + irqno; 131 desc = irq_desc + IRQ_ISA;
132 desc->chip->ack(IRQ_ISA);
133 } else {
134 /* handle the IRQ */
135
136 for (i = 0; stat != 0; i++, stat >>= 1) {
137 if (stat & 1) {
138 irqno = bast_pc104_irqs[i];
126 139
127 desc_handle_irq(irqno, desc, regs); 140 desc_handle_irq(irqno, irq_desc + irqno, regs);
141 }
128 } 142 }
143 }
144}
129 145
130 stat >>= 1; 146static __init int bast_irq_init(void)
147{
148 unsigned int i;
149
150 if (machine_is_bast()) {
151 printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n");
152
153 /* zap all the IRQs */
154
155 __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
156
157 set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
158
159 /* reigster our IRQs */
160
161 for (i = 0; i < 4; i++) {
162 unsigned int irqno = bast_pc104_irqs[i];
163
164 set_irq_chip(irqno, &bast_pc104_chip);
165 set_irq_handler(irqno, do_level_IRQ);
166 set_irq_flags(irqno, IRQF_VALID);
167 }
131 } 168 }
169
170 return 0;
132} 171}
172
173arch_initcall(bast_irq_init);