Merge remote-tracking branch 'moduleh/module.h-split'
[linux-2.6/next.git] / arch / arm / mach-lpc32xx / irq.c
blob4eae566dfdc710934e7e834cabd7b2e83c1184cd
1 /*
2 * arch/arm/mach-lpc32xx/irq.c
4 * Author: Kevin Wells <kevin.wells@nxp.com>
6 * Copyright (C) 2010 NXP Semiconductors
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
19 #include <linux/kernel.h>
20 #include <linux/types.h>
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/err.h>
24 #include <linux/io.h>
26 #include <mach/irqs.h>
27 #include <mach/hardware.h>
28 #include <mach/platform.h>
29 #include "common.h"
32 * Default value representing the Activation polarity of all internal
33 * interrupt sources
35 #define MIC_APR_DEFAULT 0x3FF0EFE0
36 #define SIC1_APR_DEFAULT 0xFBD27186
37 #define SIC2_APR_DEFAULT 0x801810C0
40 * Default value representing the Activation Type of all internal
41 * interrupt sources. All are level sensitive.
43 #define MIC_ATR_DEFAULT 0x00000000
44 #define SIC1_ATR_DEFAULT 0x00026000
45 #define SIC2_ATR_DEFAULT 0x00000000
47 struct lpc32xx_event_group_regs {
48 void __iomem *enab_reg;
49 void __iomem *edge_reg;
50 void __iomem *maskstat_reg;
51 void __iomem *rawstat_reg;
54 static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = {
55 .enab_reg = LPC32XX_CLKPWR_INT_ER,
56 .edge_reg = LPC32XX_CLKPWR_INT_AP,
57 .maskstat_reg = LPC32XX_CLKPWR_INT_SR,
58 .rawstat_reg = LPC32XX_CLKPWR_INT_RS,
61 static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = {
62 .enab_reg = LPC32XX_CLKPWR_PIN_ER,
63 .edge_reg = LPC32XX_CLKPWR_PIN_AP,
64 .maskstat_reg = LPC32XX_CLKPWR_PIN_SR,
65 .rawstat_reg = LPC32XX_CLKPWR_PIN_RS,
68 struct lpc32xx_event_info {
69 const struct lpc32xx_event_group_regs *event_group;
70 u32 mask;
74 * Maps an IRQ number to and event mask and register
76 static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
77 [IRQ_LPC32XX_GPI_08] = {
78 .event_group = &lpc32xx_event_pin_regs,
79 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT,
81 [IRQ_LPC32XX_GPI_09] = {
82 .event_group = &lpc32xx_event_pin_regs,
83 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT,
85 [IRQ_LPC32XX_GPI_19] = {
86 .event_group = &lpc32xx_event_pin_regs,
87 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT,
89 [IRQ_LPC32XX_GPI_07] = {
90 .event_group = &lpc32xx_event_pin_regs,
91 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT,
93 [IRQ_LPC32XX_GPI_00] = {
94 .event_group = &lpc32xx_event_pin_regs,
95 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT,
97 [IRQ_LPC32XX_GPI_01] = {
98 .event_group = &lpc32xx_event_pin_regs,
99 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT,
101 [IRQ_LPC32XX_GPI_02] = {
102 .event_group = &lpc32xx_event_pin_regs,
103 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT,
105 [IRQ_LPC32XX_GPI_03] = {
106 .event_group = &lpc32xx_event_pin_regs,
107 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT,
109 [IRQ_LPC32XX_GPI_04] = {
110 .event_group = &lpc32xx_event_pin_regs,
111 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT,
113 [IRQ_LPC32XX_GPI_05] = {
114 .event_group = &lpc32xx_event_pin_regs,
115 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT,
117 [IRQ_LPC32XX_GPI_06] = {
118 .event_group = &lpc32xx_event_pin_regs,
119 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
121 [IRQ_LPC32XX_GPIO_00] = {
122 .event_group = &lpc32xx_event_int_regs,
123 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
125 [IRQ_LPC32XX_GPIO_01] = {
126 .event_group = &lpc32xx_event_int_regs,
127 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT,
129 [IRQ_LPC32XX_GPIO_02] = {
130 .event_group = &lpc32xx_event_int_regs,
131 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT,
133 [IRQ_LPC32XX_GPIO_03] = {
134 .event_group = &lpc32xx_event_int_regs,
135 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT,
137 [IRQ_LPC32XX_GPIO_04] = {
138 .event_group = &lpc32xx_event_int_regs,
139 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT,
141 [IRQ_LPC32XX_GPIO_05] = {
142 .event_group = &lpc32xx_event_int_regs,
143 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT,
145 [IRQ_LPC32XX_KEY] = {
146 .event_group = &lpc32xx_event_int_regs,
147 .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
149 [IRQ_LPC32XX_USB_OTG_ATX] = {
150 .event_group = &lpc32xx_event_int_regs,
151 .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
153 [IRQ_LPC32XX_USB_HOST] = {
154 .event_group = &lpc32xx_event_int_regs,
155 .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT,
157 [IRQ_LPC32XX_RTC] = {
158 .event_group = &lpc32xx_event_int_regs,
159 .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT,
161 [IRQ_LPC32XX_MSTIMER] = {
162 .event_group = &lpc32xx_event_int_regs,
163 .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT,
165 [IRQ_LPC32XX_TS_AUX] = {
166 .event_group = &lpc32xx_event_int_regs,
167 .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT,
169 [IRQ_LPC32XX_TS_P] = {
170 .event_group = &lpc32xx_event_int_regs,
171 .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT,
173 [IRQ_LPC32XX_TS_IRQ] = {
174 .event_group = &lpc32xx_event_int_regs,
175 .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT,
179 static void get_controller(unsigned int irq, unsigned int *base,
180 unsigned int *irqbit)
182 if (irq < 32) {
183 *base = LPC32XX_MIC_BASE;
184 *irqbit = 1 << irq;
185 } else if (irq < 64) {
186 *base = LPC32XX_SIC1_BASE;
187 *irqbit = 1 << (irq - 32);
188 } else {
189 *base = LPC32XX_SIC2_BASE;
190 *irqbit = 1 << (irq - 64);
194 static void lpc32xx_mask_irq(struct irq_data *d)
196 unsigned int reg, ctrl, mask;
198 get_controller(d->irq, &ctrl, &mask);
200 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask;
201 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
204 static void lpc32xx_unmask_irq(struct irq_data *d)
206 unsigned int reg, ctrl, mask;
208 get_controller(d->irq, &ctrl, &mask);
210 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask;
211 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
214 static void lpc32xx_ack_irq(struct irq_data *d)
216 unsigned int ctrl, mask;
218 get_controller(d->irq, &ctrl, &mask);
220 __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl));
222 /* Also need to clear pending wake event */
223 if (lpc32xx_events[d->irq].mask != 0)
224 __raw_writel(lpc32xx_events[d->irq].mask,
225 lpc32xx_events[d->irq].event_group->rawstat_reg);
228 static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level,
229 int use_edge)
231 unsigned int reg, ctrl, mask;
233 get_controller(irq, &ctrl, &mask);
235 /* Activation level, high or low */
236 reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl));
237 if (use_high_level)
238 reg |= mask;
239 else
240 reg &= ~mask;
241 __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl));
243 /* Activation type, edge or level */
244 reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl));
245 if (use_edge)
246 reg |= mask;
247 else
248 reg &= ~mask;
249 __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl));
251 /* Use same polarity for the wake events */
252 if (lpc32xx_events[irq].mask != 0) {
253 reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg);
255 if (use_high_level)
256 reg |= lpc32xx_events[irq].mask;
257 else
258 reg &= ~lpc32xx_events[irq].mask;
260 __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg);
264 static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
266 switch (type) {
267 case IRQ_TYPE_EDGE_RISING:
268 /* Rising edge sensitive */
269 __lpc32xx_set_irq_type(d->irq, 1, 1);
270 break;
272 case IRQ_TYPE_EDGE_FALLING:
273 /* Falling edge sensitive */
274 __lpc32xx_set_irq_type(d->irq, 0, 1);
275 break;
277 case IRQ_TYPE_LEVEL_LOW:
278 /* Low level sensitive */
279 __lpc32xx_set_irq_type(d->irq, 0, 0);
280 break;
282 case IRQ_TYPE_LEVEL_HIGH:
283 /* High level sensitive */
284 __lpc32xx_set_irq_type(d->irq, 1, 0);
285 break;
287 /* Other modes are not supported */
288 default:
289 return -EINVAL;
292 /* Ok to use the level handler for all types */
293 irq_set_handler(d->irq, handle_level_irq);
295 return 0;
298 static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
300 unsigned long eventreg;
302 if (lpc32xx_events[d->irq].mask != 0) {
303 eventreg = __raw_readl(lpc32xx_events[d->irq].
304 event_group->enab_reg);
306 if (state)
307 eventreg |= lpc32xx_events[d->irq].mask;
308 else
309 eventreg &= ~lpc32xx_events[d->irq].mask;
311 __raw_writel(eventreg,
312 lpc32xx_events[d->irq].event_group->enab_reg);
314 return 0;
317 /* Clear event */
318 __raw_writel(lpc32xx_events[d->irq].mask,
319 lpc32xx_events[d->irq].event_group->rawstat_reg);
321 return -ENODEV;
324 static void __init lpc32xx_set_default_mappings(unsigned int apr,
325 unsigned int atr, unsigned int offset)
327 unsigned int i;
329 /* Set activation levels for each interrupt */
330 i = 0;
331 while (i < 32) {
332 __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1),
333 ((atr >> i) & 0x1));
334 i++;
338 static struct irq_chip lpc32xx_irq_chip = {
339 .irq_ack = lpc32xx_ack_irq,
340 .irq_mask = lpc32xx_mask_irq,
341 .irq_unmask = lpc32xx_unmask_irq,
342 .irq_set_type = lpc32xx_set_irq_type,
343 .irq_set_wake = lpc32xx_irq_wake
346 static void lpc32xx_sic1_handler(unsigned int irq, struct irq_desc *desc)
348 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE));
350 while (ints != 0) {
351 int irqno = fls(ints) - 1;
353 ints &= ~(1 << irqno);
355 generic_handle_irq(LPC32XX_SIC1_IRQ(irqno));
359 static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc)
361 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE));
363 while (ints != 0) {
364 int irqno = fls(ints) - 1;
366 ints &= ~(1 << irqno);
368 generic_handle_irq(LPC32XX_SIC2_IRQ(irqno));
372 void __init lpc32xx_init_irq(void)
374 unsigned int i;
376 /* Setup MIC */
377 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
378 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE));
379 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE));
381 /* Setup SIC1 */
382 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
383 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
384 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
386 /* Setup SIC2 */
387 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
388 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
389 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
391 /* Configure supported IRQ's */
392 for (i = 0; i < NR_IRQS; i++) {
393 irq_set_chip_and_handler(i, &lpc32xx_irq_chip,
394 handle_level_irq);
395 set_irq_flags(i, IRQF_VALID);
398 /* Set default mappings */
399 lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0);
400 lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32);
401 lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64);
403 /* mask all interrupts except SUBIRQ */
404 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
405 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
406 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
408 /* MIC SUBIRQx interrupts will route handling to the chain handlers */
409 irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
410 irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
412 /* Initially disable all wake events */
413 __raw_writel(0, LPC32XX_CLKPWR_P01_ER);
414 __raw_writel(0, LPC32XX_CLKPWR_INT_ER);
415 __raw_writel(0, LPC32XX_CLKPWR_PIN_ER);
418 * Default wake activation polarities, all pin sources are low edge
419 * triggered
421 __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT |
422 LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT |
423 LPC32XX_CLKPWR_INTSRC_RTC_BIT,
424 LPC32XX_CLKPWR_INT_AP);
425 __raw_writel(0, LPC32XX_CLKPWR_PIN_AP);
427 /* Clear latched wake event states */
428 __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS),
429 LPC32XX_CLKPWR_PIN_RS);
430 __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS),
431 LPC32XX_CLKPWR_INT_RS);