diff options
Diffstat (limited to 'arch/arm/plat-s3c24xx/irq.c')
-rw-r--r-- | arch/arm/plat-s3c24xx/irq.c | 180 |
1 files changed, 86 insertions, 94 deletions
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index 91ce38393ba6..4434cb56bd9a 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c | |||
@@ -34,30 +34,29 @@ | |||
34 | #include <plat/irq.h> | 34 | #include <plat/irq.h> |
35 | 35 | ||
36 | static void | 36 | static void |
37 | s3c_irq_mask(unsigned int irqno) | 37 | s3c_irq_mask(struct irq_data *data) |
38 | { | 38 | { |
39 | unsigned int irqno = data->irq - IRQ_EINT0; | ||
39 | unsigned long mask; | 40 | unsigned long mask; |
40 | 41 | ||
41 | irqno -= IRQ_EINT0; | ||
42 | |||
43 | mask = __raw_readl(S3C2410_INTMSK); | 42 | mask = __raw_readl(S3C2410_INTMSK); |
44 | mask |= 1UL << irqno; | 43 | mask |= 1UL << irqno; |
45 | __raw_writel(mask, S3C2410_INTMSK); | 44 | __raw_writel(mask, S3C2410_INTMSK); |
46 | } | 45 | } |
47 | 46 | ||
48 | static inline void | 47 | static inline void |
49 | s3c_irq_ack(unsigned int irqno) | 48 | s3c_irq_ack(struct irq_data *data) |
50 | { | 49 | { |
51 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | 50 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); |
52 | 51 | ||
53 | __raw_writel(bitval, S3C2410_SRCPND); | 52 | __raw_writel(bitval, S3C2410_SRCPND); |
54 | __raw_writel(bitval, S3C2410_INTPND); | 53 | __raw_writel(bitval, S3C2410_INTPND); |
55 | } | 54 | } |
56 | 55 | ||
57 | static inline void | 56 | static inline void |
58 | s3c_irq_maskack(unsigned int irqno) | 57 | s3c_irq_maskack(struct irq_data *data) |
59 | { | 58 | { |
60 | unsigned long bitval = 1UL << (irqno - IRQ_EINT0); | 59 | unsigned long bitval = 1UL << (data->irq - IRQ_EINT0); |
61 | unsigned long mask; | 60 | unsigned long mask; |
62 | 61 | ||
63 | mask = __raw_readl(S3C2410_INTMSK); | 62 | mask = __raw_readl(S3C2410_INTMSK); |
@@ -69,8 +68,9 @@ s3c_irq_maskack(unsigned int irqno) | |||
69 | 68 | ||
70 | 69 | ||
71 | static void | 70 | static void |
72 | s3c_irq_unmask(unsigned int irqno) | 71 | s3c_irq_unmask(struct irq_data *data) |
73 | { | 72 | { |
73 | unsigned int irqno = data->irq; | ||
74 | unsigned long mask; | 74 | unsigned long mask; |
75 | 75 | ||
76 | if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) | 76 | if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23) |
@@ -85,40 +85,39 @@ s3c_irq_unmask(unsigned int irqno) | |||
85 | 85 | ||
86 | struct irq_chip s3c_irq_level_chip = { | 86 | struct irq_chip s3c_irq_level_chip = { |
87 | .name = "s3c-level", | 87 | .name = "s3c-level", |
88 | .ack = s3c_irq_maskack, | 88 | .irq_ack = s3c_irq_maskack, |
89 | .mask = s3c_irq_mask, | 89 | .irq_mask = s3c_irq_mask, |
90 | .unmask = s3c_irq_unmask, | 90 | .irq_unmask = s3c_irq_unmask, |
91 | .set_wake = s3c_irq_wake | 91 | .irq_set_wake = s3c_irq_wake |
92 | }; | 92 | }; |
93 | 93 | ||
94 | struct irq_chip s3c_irq_chip = { | 94 | struct irq_chip s3c_irq_chip = { |
95 | .name = "s3c", | 95 | .name = "s3c", |
96 | .ack = s3c_irq_ack, | 96 | .irq_ack = s3c_irq_ack, |
97 | .mask = s3c_irq_mask, | 97 | .irq_mask = s3c_irq_mask, |
98 | .unmask = s3c_irq_unmask, | 98 | .irq_unmask = s3c_irq_unmask, |
99 | .set_wake = s3c_irq_wake | 99 | .irq_set_wake = s3c_irq_wake |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static void | 102 | static void |
103 | s3c_irqext_mask(unsigned int irqno) | 103 | s3c_irqext_mask(struct irq_data *data) |
104 | { | 104 | { |
105 | unsigned int irqno = data->irq - EXTINT_OFF; | ||
105 | unsigned long mask; | 106 | unsigned long mask; |
106 | 107 | ||
107 | irqno -= EXTINT_OFF; | ||
108 | |||
109 | mask = __raw_readl(S3C24XX_EINTMASK); | 108 | mask = __raw_readl(S3C24XX_EINTMASK); |
110 | mask |= ( 1UL << irqno); | 109 | mask |= ( 1UL << irqno); |
111 | __raw_writel(mask, S3C24XX_EINTMASK); | 110 | __raw_writel(mask, S3C24XX_EINTMASK); |
112 | } | 111 | } |
113 | 112 | ||
114 | static void | 113 | static void |
115 | s3c_irqext_ack(unsigned int irqno) | 114 | s3c_irqext_ack(struct irq_data *data) |
116 | { | 115 | { |
117 | unsigned long req; | 116 | unsigned long req; |
118 | unsigned long bit; | 117 | unsigned long bit; |
119 | unsigned long mask; | 118 | unsigned long mask; |
120 | 119 | ||
121 | bit = 1UL << (irqno - EXTINT_OFF); | 120 | bit = 1UL << (data->irq - EXTINT_OFF); |
122 | 121 | ||
123 | mask = __raw_readl(S3C24XX_EINTMASK); | 122 | mask = __raw_readl(S3C24XX_EINTMASK); |
124 | 123 | ||
@@ -129,64 +128,57 @@ s3c_irqext_ack(unsigned int irqno) | |||
129 | 128 | ||
130 | /* not sure if we should be acking the parent irq... */ | 129 | /* not sure if we should be acking the parent irq... */ |
131 | 130 | ||
132 | if (irqno <= IRQ_EINT7 ) { | 131 | if (data->irq <= IRQ_EINT7) { |
133 | if ((req & 0xf0) == 0) | 132 | if ((req & 0xf0) == 0) |
134 | s3c_irq_ack(IRQ_EINT4t7); | 133 | s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7)); |
135 | } else { | 134 | } else { |
136 | if ((req >> 8) == 0) | 135 | if ((req >> 8) == 0) |
137 | s3c_irq_ack(IRQ_EINT8t23); | 136 | s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23)); |
138 | } | 137 | } |
139 | } | 138 | } |
140 | 139 | ||
141 | static void | 140 | static void |
142 | s3c_irqext_unmask(unsigned int irqno) | 141 | s3c_irqext_unmask(struct irq_data *data) |
143 | { | 142 | { |
143 | unsigned int irqno = data->irq - EXTINT_OFF; | ||
144 | unsigned long mask; | 144 | unsigned long mask; |
145 | 145 | ||
146 | irqno -= EXTINT_OFF; | ||
147 | |||
148 | mask = __raw_readl(S3C24XX_EINTMASK); | 146 | mask = __raw_readl(S3C24XX_EINTMASK); |
149 | mask &= ~( 1UL << irqno); | 147 | mask &= ~(1UL << irqno); |
150 | __raw_writel(mask, S3C24XX_EINTMASK); | 148 | __raw_writel(mask, S3C24XX_EINTMASK); |
151 | } | 149 | } |
152 | 150 | ||
153 | int | 151 | int |
154 | s3c_irqext_type(unsigned int irq, unsigned int type) | 152 | s3c_irqext_type(struct irq_data *data, unsigned int type) |
155 | { | 153 | { |
156 | void __iomem *extint_reg; | 154 | void __iomem *extint_reg; |
157 | void __iomem *gpcon_reg; | 155 | void __iomem *gpcon_reg; |
158 | unsigned long gpcon_offset, extint_offset; | 156 | unsigned long gpcon_offset, extint_offset; |
159 | unsigned long newvalue = 0, value; | 157 | unsigned long newvalue = 0, value; |
160 | 158 | ||
161 | if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) | 159 | if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) { |
162 | { | ||
163 | gpcon_reg = S3C2410_GPFCON; | 160 | gpcon_reg = S3C2410_GPFCON; |
164 | extint_reg = S3C24XX_EXTINT0; | 161 | extint_reg = S3C24XX_EXTINT0; |
165 | gpcon_offset = (irq - IRQ_EINT0) * 2; | 162 | gpcon_offset = (data->irq - IRQ_EINT0) * 2; |
166 | extint_offset = (irq - IRQ_EINT0) * 4; | 163 | extint_offset = (data->irq - IRQ_EINT0) * 4; |
167 | } | 164 | } else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) { |
168 | else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7)) | ||
169 | { | ||
170 | gpcon_reg = S3C2410_GPFCON; | 165 | gpcon_reg = S3C2410_GPFCON; |
171 | extint_reg = S3C24XX_EXTINT0; | 166 | extint_reg = S3C24XX_EXTINT0; |
172 | gpcon_offset = (irq - (EXTINT_OFF)) * 2; | 167 | gpcon_offset = (data->irq - (EXTINT_OFF)) * 2; |
173 | extint_offset = (irq - (EXTINT_OFF)) * 4; | 168 | extint_offset = (data->irq - (EXTINT_OFF)) * 4; |
174 | } | 169 | } else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) { |
175 | else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15)) | ||
176 | { | ||
177 | gpcon_reg = S3C2410_GPGCON; | 170 | gpcon_reg = S3C2410_GPGCON; |
178 | extint_reg = S3C24XX_EXTINT1; | 171 | extint_reg = S3C24XX_EXTINT1; |
179 | gpcon_offset = (irq - IRQ_EINT8) * 2; | 172 | gpcon_offset = (data->irq - IRQ_EINT8) * 2; |
180 | extint_offset = (irq - IRQ_EINT8) * 4; | 173 | extint_offset = (data->irq - IRQ_EINT8) * 4; |
181 | } | 174 | } else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) { |
182 | else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23)) | ||
183 | { | ||
184 | gpcon_reg = S3C2410_GPGCON; | 175 | gpcon_reg = S3C2410_GPGCON; |
185 | extint_reg = S3C24XX_EXTINT2; | 176 | extint_reg = S3C24XX_EXTINT2; |
186 | gpcon_offset = (irq - IRQ_EINT8) * 2; | 177 | gpcon_offset = (data->irq - IRQ_EINT8) * 2; |
187 | extint_offset = (irq - IRQ_EINT16) * 4; | 178 | extint_offset = (data->irq - IRQ_EINT16) * 4; |
188 | } else | 179 | } else { |
189 | return -1; | 180 | return -1; |
181 | } | ||
190 | 182 | ||
191 | /* Set the GPIO to external interrupt mode */ | 183 | /* Set the GPIO to external interrupt mode */ |
192 | value = __raw_readl(gpcon_reg); | 184 | value = __raw_readl(gpcon_reg); |
@@ -234,20 +226,20 @@ s3c_irqext_type(unsigned int irq, unsigned int type) | |||
234 | 226 | ||
235 | static struct irq_chip s3c_irqext_chip = { | 227 | static struct irq_chip s3c_irqext_chip = { |
236 | .name = "s3c-ext", | 228 | .name = "s3c-ext", |
237 | .mask = s3c_irqext_mask, | 229 | .irq_mask = s3c_irqext_mask, |
238 | .unmask = s3c_irqext_unmask, | 230 | .irq_unmask = s3c_irqext_unmask, |
239 | .ack = s3c_irqext_ack, | 231 | .irq_ack = s3c_irqext_ack, |
240 | .set_type = s3c_irqext_type, | 232 | .irq_set_type = s3c_irqext_type, |
241 | .irq_set_wake = s3c_irqext_wake | 233 | .irq_set_wake = s3c_irqext_wake |
242 | }; | 234 | }; |
243 | 235 | ||
244 | static struct irq_chip s3c_irq_eint0t4 = { | 236 | static struct irq_chip s3c_irq_eint0t4 = { |
245 | .name = "s3c-ext0", | 237 | .name = "s3c-ext0", |
246 | .ack = s3c_irq_ack, | 238 | .irq_ack = s3c_irq_ack, |
247 | .mask = s3c_irq_mask, | 239 | .irq_mask = s3c_irq_mask, |
248 | .unmask = s3c_irq_unmask, | 240 | .irq_unmask = s3c_irq_unmask, |
249 | .set_wake = s3c_irq_wake, | 241 | .irq_set_wake = s3c_irq_wake, |
250 | .set_type = s3c_irqext_type, | 242 | .irq_set_type = s3c_irqext_type, |
251 | }; | 243 | }; |
252 | 244 | ||
253 | /* mask values for the parent registers for each of the interrupt types */ | 245 | /* mask values for the parent registers for each of the interrupt types */ |
@@ -261,109 +253,109 @@ static struct irq_chip s3c_irq_eint0t4 = { | |||
261 | /* UART0 */ | 253 | /* UART0 */ |
262 | 254 | ||
263 | static void | 255 | static void |
264 | s3c_irq_uart0_mask(unsigned int irqno) | 256 | s3c_irq_uart0_mask(struct irq_data *data) |
265 | { | 257 | { |
266 | s3c_irqsub_mask(irqno, INTMSK_UART0, 7); | 258 | s3c_irqsub_mask(data->irq, INTMSK_UART0, 7); |
267 | } | 259 | } |
268 | 260 | ||
269 | static void | 261 | static void |
270 | s3c_irq_uart0_unmask(unsigned int irqno) | 262 | s3c_irq_uart0_unmask(struct irq_data *data) |
271 | { | 263 | { |
272 | s3c_irqsub_unmask(irqno, INTMSK_UART0); | 264 | s3c_irqsub_unmask(data->irq, INTMSK_UART0); |
273 | } | 265 | } |
274 | 266 | ||
275 | static void | 267 | static void |
276 | s3c_irq_uart0_ack(unsigned int irqno) | 268 | s3c_irq_uart0_ack(struct irq_data *data) |
277 | { | 269 | { |
278 | s3c_irqsub_maskack(irqno, INTMSK_UART0, 7); | 270 | s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7); |
279 | } | 271 | } |
280 | 272 | ||
281 | static struct irq_chip s3c_irq_uart0 = { | 273 | static struct irq_chip s3c_irq_uart0 = { |
282 | .name = "s3c-uart0", | 274 | .name = "s3c-uart0", |
283 | .mask = s3c_irq_uart0_mask, | 275 | .irq_mask = s3c_irq_uart0_mask, |
284 | .unmask = s3c_irq_uart0_unmask, | 276 | .irq_unmask = s3c_irq_uart0_unmask, |
285 | .ack = s3c_irq_uart0_ack, | 277 | .irq_ack = s3c_irq_uart0_ack, |
286 | }; | 278 | }; |
287 | 279 | ||
288 | /* UART1 */ | 280 | /* UART1 */ |
289 | 281 | ||
290 | static void | 282 | static void |
291 | s3c_irq_uart1_mask(unsigned int irqno) | 283 | s3c_irq_uart1_mask(struct irq_data *data) |
292 | { | 284 | { |
293 | s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3); | 285 | s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3); |
294 | } | 286 | } |
295 | 287 | ||
296 | static void | 288 | static void |
297 | s3c_irq_uart1_unmask(unsigned int irqno) | 289 | s3c_irq_uart1_unmask(struct irq_data *data) |
298 | { | 290 | { |
299 | s3c_irqsub_unmask(irqno, INTMSK_UART1); | 291 | s3c_irqsub_unmask(data->irq, INTMSK_UART1); |
300 | } | 292 | } |
301 | 293 | ||
302 | static void | 294 | static void |
303 | s3c_irq_uart1_ack(unsigned int irqno) | 295 | s3c_irq_uart1_ack(struct irq_data *data) |
304 | { | 296 | { |
305 | s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3); | 297 | s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3); |
306 | } | 298 | } |
307 | 299 | ||
308 | static struct irq_chip s3c_irq_uart1 = { | 300 | static struct irq_chip s3c_irq_uart1 = { |
309 | .name = "s3c-uart1", | 301 | .name = "s3c-uart1", |
310 | .mask = s3c_irq_uart1_mask, | 302 | .irq_mask = s3c_irq_uart1_mask, |
311 | .unmask = s3c_irq_uart1_unmask, | 303 | .irq_unmask = s3c_irq_uart1_unmask, |
312 | .ack = s3c_irq_uart1_ack, | 304 | .irq_ack = s3c_irq_uart1_ack, |
313 | }; | 305 | }; |
314 | 306 | ||
315 | /* UART2 */ | 307 | /* UART2 */ |
316 | 308 | ||
317 | static void | 309 | static void |
318 | s3c_irq_uart2_mask(unsigned int irqno) | 310 | s3c_irq_uart2_mask(struct irq_data *data) |
319 | { | 311 | { |
320 | s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6); | 312 | s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6); |
321 | } | 313 | } |
322 | 314 | ||
323 | static void | 315 | static void |
324 | s3c_irq_uart2_unmask(unsigned int irqno) | 316 | s3c_irq_uart2_unmask(struct irq_data *data) |
325 | { | 317 | { |
326 | s3c_irqsub_unmask(irqno, INTMSK_UART2); | 318 | s3c_irqsub_unmask(data->irq, INTMSK_UART2); |
327 | } | 319 | } |
328 | 320 | ||
329 | static void | 321 | static void |
330 | s3c_irq_uart2_ack(unsigned int irqno) | 322 | s3c_irq_uart2_ack(struct irq_data *data) |
331 | { | 323 | { |
332 | s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6); | 324 | s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6); |
333 | } | 325 | } |
334 | 326 | ||
335 | static struct irq_chip s3c_irq_uart2 = { | 327 | static struct irq_chip s3c_irq_uart2 = { |
336 | .name = "s3c-uart2", | 328 | .name = "s3c-uart2", |
337 | .mask = s3c_irq_uart2_mask, | 329 | .irq_mask = s3c_irq_uart2_mask, |
338 | .unmask = s3c_irq_uart2_unmask, | 330 | .irq_unmask = s3c_irq_uart2_unmask, |
339 | .ack = s3c_irq_uart2_ack, | 331 | .irq_ack = s3c_irq_uart2_ack, |
340 | }; | 332 | }; |
341 | 333 | ||
342 | /* ADC and Touchscreen */ | 334 | /* ADC and Touchscreen */ |
343 | 335 | ||
344 | static void | 336 | static void |
345 | s3c_irq_adc_mask(unsigned int irqno) | 337 | s3c_irq_adc_mask(struct irq_data *d) |
346 | { | 338 | { |
347 | s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9); | 339 | s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9); |
348 | } | 340 | } |
349 | 341 | ||
350 | static void | 342 | static void |
351 | s3c_irq_adc_unmask(unsigned int irqno) | 343 | s3c_irq_adc_unmask(struct irq_data *d) |
352 | { | 344 | { |
353 | s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT); | 345 | s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT); |
354 | } | 346 | } |
355 | 347 | ||
356 | static void | 348 | static void |
357 | s3c_irq_adc_ack(unsigned int irqno) | 349 | s3c_irq_adc_ack(struct irq_data *d) |
358 | { | 350 | { |
359 | s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9); | 351 | s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9); |
360 | } | 352 | } |
361 | 353 | ||
362 | static struct irq_chip s3c_irq_adc = { | 354 | static struct irq_chip s3c_irq_adc = { |
363 | .name = "s3c-adc", | 355 | .name = "s3c-adc", |
364 | .mask = s3c_irq_adc_mask, | 356 | .irq_mask = s3c_irq_adc_mask, |
365 | .unmask = s3c_irq_adc_unmask, | 357 | .irq_unmask = s3c_irq_adc_unmask, |
366 | .ack = s3c_irq_adc_ack, | 358 | .irq_ack = s3c_irq_adc_ack, |
367 | }; | 359 | }; |
368 | 360 | ||
369 | /* irq demux for adc */ | 361 | /* irq demux for adc */ |