aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2007-10-04 16:41:20 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-10-12 18:43:42 -0400
commitf3fb5a556c99118186581e6546a9c41e1f73cf6f (patch)
treec5a79ca0dd682f91d2c25ae4eeba064e95a98892
parent361c7ad607bc0e84ef0fef8c3f11c47b33c06e41 (diff)
[ARM] 4596/1: S3C2412: Correct IRQs for SDI+CF and add decoding support
Fix the IRQ numbers of the CF and SDI interface on the S3C2412 and S3C2413. Add support to handle these IRQs properly and ensure that the SDI controller platform device is correctly renumbered. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-s3c2412/irq.c58
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c5
-rw-r--r--include/asm-arm/arch-s3c2410/irqs.h7
3 files changed, 70 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index f0d66828f965..e9d0c769f5da 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -38,6 +38,9 @@
38#include <asm/plat-s3c24xx/irq.h> 38#include <asm/plat-s3c24xx/irq.h>
39#include <asm/plat-s3c24xx/pm.h> 39#include <asm/plat-s3c24xx/pm.h>
40 40
41#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
42#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
43
41/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by 44/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
42 * having them turn up in both the INT* and the EINT* registers. Whilst 45 * having them turn up in both the INT* and the EINT* registers. Whilst
43 * both show the status, they both now need to be acked when the IRQs 46 * both show the status, they both now need to be acked when the IRQs
@@ -105,6 +108,51 @@ static struct irq_chip s3c2412_irq_eint0t4 = {
105 .set_type = s3c_irqext_type, 108 .set_type = s3c_irqext_type,
106}; 109};
107 110
111#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
112
113/* CF and SDI sub interrupts */
114
115static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
116{
117 unsigned int subsrc, submsk;
118
119 subsrc = __raw_readl(S3C2410_SUBSRCPND);
120 submsk = __raw_readl(S3C2410_INTSUBMSK);
121
122 subsrc &= ~submsk;
123
124 if (subsrc & INTBIT(IRQ_S3C2412_SDI))
125 desc_handle_irq(IRQ_S3C2412_SDI, irq_desc + IRQ_S3C2412_SDI);
126
127 if (subsrc & INTBIT(IRQ_S3C2412_CF))
128 desc_handle_irq(IRQ_S3C2412_CF, irq_desc + IRQ_S3C2412_CF);
129}
130
131#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
132#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
133
134static void s3c2412_irq_cfsdi_mask(unsigned int irqno)
135{
136 s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
137}
138
139static void s3c2412_irq_cfsdi_unmask(unsigned int irqno)
140{
141 s3c_irqsub_unmask(irqno, INTMSK_CFSDI);
142}
143
144static void s3c2412_irq_cfsdi_ack(unsigned int irqno)
145{
146 s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI);
147}
148
149static struct irq_chip s3c2412_irq_cfsdi = {
150 .name = "s3c2412-cfsdi",
151 .ack = s3c2412_irq_cfsdi_ack,
152 .mask = s3c2412_irq_cfsdi_mask,
153 .unmask = s3c2412_irq_cfsdi_unmask,
154};
155
108static int s3c2412_irq_add(struct sys_device *sysdev) 156static int s3c2412_irq_add(struct sys_device *sysdev)
109{ 157{
110 unsigned int irqno; 158 unsigned int irqno;
@@ -115,6 +163,16 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
115 set_irq_flags(irqno, IRQF_VALID); 163 set_irq_flags(irqno, IRQF_VALID);
116 } 164 }
117 165
166 /* add demux support for CF/SDI */
167
168 set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
169
170 for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
171 set_irq_chip(irqno, &s3c2412_irq_cfsdi);
172 set_irq_handler(irqno, handle_level_irq);
173 set_irq_flags(irqno, IRQF_VALID);
174 }
175
118 return 0; 176 return 0;
119} 177}
120 178
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index e0ccb404623f..4f92a1562d77 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -78,6 +78,11 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
78 s3c_device_lcd.name = "s3c2412-lcd"; 78 s3c_device_lcd.name = "s3c2412-lcd";
79 s3c_device_nand.name = "s3c2412-nand"; 79 s3c_device_nand.name = "s3c2412-nand";
80 80
81 /* alter IRQ of SDI controller */
82
83 s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
84 s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI;
85
81 /* spi channel related changes, s3c2412/13 specific */ 86 /* spi channel related changes, s3c2412/13 specific */
82 s3c_device_spi0.name = "s3c2412-spi"; 87 s3c_device_spi0.name = "s3c2412-spi";
83 s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24; 88 s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 3b49cd1c345c..996f65488d2d 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -112,6 +112,13 @@
112#define IRQ_TC S3C2410_IRQSUB(9) 112#define IRQ_TC S3C2410_IRQSUB(9)
113#define IRQ_ADC S3C2410_IRQSUB(10) 113#define IRQ_ADC S3C2410_IRQSUB(10)
114 114
115/* extra irqs for s3c2412 */
116
117#define IRQ_S3C2412_CFSDI S3C2410_IRQ(21)
118
119#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
120#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
121
115/* extra irqs for s3c2440 */ 122/* extra irqs for s3c2440 */
116 123
117#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */ 124#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */