diff options
Diffstat (limited to 'arch/arm/mach-s3c2412')
-rw-r--r-- | arch/arm/mach-s3c2412/irq.c | 58 | ||||
-rw-r--r-- | arch/arm/mach-s3c2412/s3c2412.c | 5 |
2 files changed, 63 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 | |||
115 | static 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 | |||
134 | static void s3c2412_irq_cfsdi_mask(unsigned int irqno) | ||
135 | { | ||
136 | s3c_irqsub_mask(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); | ||
137 | } | ||
138 | |||
139 | static void s3c2412_irq_cfsdi_unmask(unsigned int irqno) | ||
140 | { | ||
141 | s3c_irqsub_unmask(irqno, INTMSK_CFSDI); | ||
142 | } | ||
143 | |||
144 | static void s3c2412_irq_cfsdi_ack(unsigned int irqno) | ||
145 | { | ||
146 | s3c_irqsub_maskack(irqno, INTMSK_CFSDI, SUBMSK_CFSDI); | ||
147 | } | ||
148 | |||
149 | static 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 | |||
108 | static int s3c2412_irq_add(struct sys_device *sysdev) | 156 | static 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; |