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>
26 #include <mach/irqs.h>
27 #include <mach/hardware.h>
28 #include <mach/platform.h>
32 * Default value representing the Activation polarity of all internal
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
;
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_GPI_28
] = {
122 .event_group
= &lpc32xx_event_pin_regs
,
123 .mask
= LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT
,
125 [IRQ_LPC32XX_GPIO_00
] = {
126 .event_group
= &lpc32xx_event_int_regs
,
127 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT
,
129 [IRQ_LPC32XX_GPIO_01
] = {
130 .event_group
= &lpc32xx_event_int_regs
,
131 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT
,
133 [IRQ_LPC32XX_GPIO_02
] = {
134 .event_group
= &lpc32xx_event_int_regs
,
135 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT
,
137 [IRQ_LPC32XX_GPIO_03
] = {
138 .event_group
= &lpc32xx_event_int_regs
,
139 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT
,
141 [IRQ_LPC32XX_GPIO_04
] = {
142 .event_group
= &lpc32xx_event_int_regs
,
143 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT
,
145 [IRQ_LPC32XX_GPIO_05
] = {
146 .event_group
= &lpc32xx_event_int_regs
,
147 .mask
= LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT
,
149 [IRQ_LPC32XX_KEY
] = {
150 .event_group
= &lpc32xx_event_int_regs
,
151 .mask
= LPC32XX_CLKPWR_INTSRC_KEY_BIT
,
153 [IRQ_LPC32XX_USB_OTG_ATX
] = {
154 .event_group
= &lpc32xx_event_int_regs
,
155 .mask
= LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT
,
157 [IRQ_LPC32XX_USB_HOST
] = {
158 .event_group
= &lpc32xx_event_int_regs
,
159 .mask
= LPC32XX_CLKPWR_INTSRC_USB_BIT
,
161 [IRQ_LPC32XX_RTC
] = {
162 .event_group
= &lpc32xx_event_int_regs
,
163 .mask
= LPC32XX_CLKPWR_INTSRC_RTC_BIT
,
165 [IRQ_LPC32XX_MSTIMER
] = {
166 .event_group
= &lpc32xx_event_int_regs
,
167 .mask
= LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT
,
169 [IRQ_LPC32XX_TS_AUX
] = {
170 .event_group
= &lpc32xx_event_int_regs
,
171 .mask
= LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT
,
173 [IRQ_LPC32XX_TS_P
] = {
174 .event_group
= &lpc32xx_event_int_regs
,
175 .mask
= LPC32XX_CLKPWR_INTSRC_TS_P_BIT
,
177 [IRQ_LPC32XX_TS_IRQ
] = {
178 .event_group
= &lpc32xx_event_int_regs
,
179 .mask
= LPC32XX_CLKPWR_INTSRC_ADC_BIT
,
183 static void get_controller(unsigned int irq
, unsigned int *base
,
184 unsigned int *irqbit
)
187 *base
= LPC32XX_MIC_BASE
;
189 } else if (irq
< 64) {
190 *base
= LPC32XX_SIC1_BASE
;
191 *irqbit
= 1 << (irq
- 32);
193 *base
= LPC32XX_SIC2_BASE
;
194 *irqbit
= 1 << (irq
- 64);
198 static void lpc32xx_mask_irq(struct irq_data
*d
)
200 unsigned int reg
, ctrl
, mask
;
202 get_controller(d
->irq
, &ctrl
, &mask
);
204 reg
= __raw_readl(LPC32XX_INTC_MASK(ctrl
)) & ~mask
;
205 __raw_writel(reg
, LPC32XX_INTC_MASK(ctrl
));
208 static void lpc32xx_unmask_irq(struct irq_data
*d
)
210 unsigned int reg
, ctrl
, mask
;
212 get_controller(d
->irq
, &ctrl
, &mask
);
214 reg
= __raw_readl(LPC32XX_INTC_MASK(ctrl
)) | mask
;
215 __raw_writel(reg
, LPC32XX_INTC_MASK(ctrl
));
218 static void lpc32xx_ack_irq(struct irq_data
*d
)
220 unsigned int ctrl
, mask
;
222 get_controller(d
->irq
, &ctrl
, &mask
);
224 __raw_writel(mask
, LPC32XX_INTC_RAW_STAT(ctrl
));
226 /* Also need to clear pending wake event */
227 if (lpc32xx_events
[d
->irq
].mask
!= 0)
228 __raw_writel(lpc32xx_events
[d
->irq
].mask
,
229 lpc32xx_events
[d
->irq
].event_group
->rawstat_reg
);
232 static void __lpc32xx_set_irq_type(unsigned int irq
, int use_high_level
,
235 unsigned int reg
, ctrl
, mask
;
237 get_controller(irq
, &ctrl
, &mask
);
239 /* Activation level, high or low */
240 reg
= __raw_readl(LPC32XX_INTC_POLAR(ctrl
));
245 __raw_writel(reg
, LPC32XX_INTC_POLAR(ctrl
));
247 /* Activation type, edge or level */
248 reg
= __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl
));
253 __raw_writel(reg
, LPC32XX_INTC_ACT_TYPE(ctrl
));
255 /* Use same polarity for the wake events */
256 if (lpc32xx_events
[irq
].mask
!= 0) {
257 reg
= __raw_readl(lpc32xx_events
[irq
].event_group
->edge_reg
);
260 reg
|= lpc32xx_events
[irq
].mask
;
262 reg
&= ~lpc32xx_events
[irq
].mask
;
264 __raw_writel(reg
, lpc32xx_events
[irq
].event_group
->edge_reg
);
268 static int lpc32xx_set_irq_type(struct irq_data
*d
, unsigned int type
)
271 case IRQ_TYPE_EDGE_RISING
:
272 /* Rising edge sensitive */
273 __lpc32xx_set_irq_type(d
->irq
, 1, 1);
276 case IRQ_TYPE_EDGE_FALLING
:
277 /* Falling edge sensitive */
278 __lpc32xx_set_irq_type(d
->irq
, 0, 1);
281 case IRQ_TYPE_LEVEL_LOW
:
282 /* Low level sensitive */
283 __lpc32xx_set_irq_type(d
->irq
, 0, 0);
286 case IRQ_TYPE_LEVEL_HIGH
:
287 /* High level sensitive */
288 __lpc32xx_set_irq_type(d
->irq
, 1, 0);
291 /* Other modes are not supported */
296 /* Ok to use the level handler for all types */
297 irq_set_handler(d
->irq
, handle_level_irq
);
302 static int lpc32xx_irq_wake(struct irq_data
*d
, unsigned int state
)
304 unsigned long eventreg
;
306 if (lpc32xx_events
[d
->irq
].mask
!= 0) {
307 eventreg
= __raw_readl(lpc32xx_events
[d
->irq
].
308 event_group
->enab_reg
);
311 eventreg
|= lpc32xx_events
[d
->irq
].mask
;
313 eventreg
&= ~lpc32xx_events
[d
->irq
].mask
;
316 * When disabling the wakeup, clear the latched
319 __raw_writel(lpc32xx_events
[d
->irq
].mask
,
320 lpc32xx_events
[d
->irq
].
321 event_group
->rawstat_reg
);
324 __raw_writel(eventreg
,
325 lpc32xx_events
[d
->irq
].event_group
->enab_reg
);
331 __raw_writel(lpc32xx_events
[d
->irq
].mask
,
332 lpc32xx_events
[d
->irq
].event_group
->rawstat_reg
);
337 static void __init
lpc32xx_set_default_mappings(unsigned int apr
,
338 unsigned int atr
, unsigned int offset
)
342 /* Set activation levels for each interrupt */
345 __lpc32xx_set_irq_type(offset
+ i
, ((apr
>> i
) & 0x1),
351 static struct irq_chip lpc32xx_irq_chip
= {
352 .irq_ack
= lpc32xx_ack_irq
,
353 .irq_mask
= lpc32xx_mask_irq
,
354 .irq_unmask
= lpc32xx_unmask_irq
,
355 .irq_set_type
= lpc32xx_set_irq_type
,
356 .irq_set_wake
= lpc32xx_irq_wake
359 static void lpc32xx_sic1_handler(unsigned int irq
, struct irq_desc
*desc
)
361 unsigned long ints
= __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE
));
364 int irqno
= fls(ints
) - 1;
366 ints
&= ~(1 << irqno
);
368 generic_handle_irq(LPC32XX_SIC1_IRQ(irqno
));
372 static void lpc32xx_sic2_handler(unsigned int irq
, struct irq_desc
*desc
)
374 unsigned long ints
= __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE
));
377 int irqno
= fls(ints
) - 1;
379 ints
&= ~(1 << irqno
);
381 generic_handle_irq(LPC32XX_SIC2_IRQ(irqno
));
385 void __init
lpc32xx_init_irq(void)
390 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE
));
391 __raw_writel(MIC_APR_DEFAULT
, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE
));
392 __raw_writel(MIC_ATR_DEFAULT
, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE
));
395 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE
));
396 __raw_writel(SIC1_APR_DEFAULT
, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE
));
397 __raw_writel(SIC1_ATR_DEFAULT
,
398 LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE
));
401 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE
));
402 __raw_writel(SIC2_APR_DEFAULT
, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE
));
403 __raw_writel(SIC2_ATR_DEFAULT
,
404 LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE
));
406 /* Configure supported IRQ's */
407 for (i
= 0; i
< NR_IRQS
; i
++) {
408 irq_set_chip_and_handler(i
, &lpc32xx_irq_chip
,
410 set_irq_flags(i
, IRQF_VALID
);
413 /* Set default mappings */
414 lpc32xx_set_default_mappings(MIC_APR_DEFAULT
, MIC_ATR_DEFAULT
, 0);
415 lpc32xx_set_default_mappings(SIC1_APR_DEFAULT
, SIC1_ATR_DEFAULT
, 32);
416 lpc32xx_set_default_mappings(SIC2_APR_DEFAULT
, SIC2_ATR_DEFAULT
, 64);
418 /* mask all interrupts except SUBIRQ */
419 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE
));
420 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE
));
421 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE
));
423 /* MIC SUBIRQx interrupts will route handling to the chain handlers */
424 irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ
, lpc32xx_sic1_handler
);
425 irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ
, lpc32xx_sic2_handler
);
427 /* Initially disable all wake events */
428 __raw_writel(0, LPC32XX_CLKPWR_P01_ER
);
429 __raw_writel(0, LPC32XX_CLKPWR_INT_ER
);
430 __raw_writel(0, LPC32XX_CLKPWR_PIN_ER
);
433 * Default wake activation polarities, all pin sources are low edge
436 __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT
|
437 LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT
|
438 LPC32XX_CLKPWR_INTSRC_RTC_BIT
,
439 LPC32XX_CLKPWR_INT_AP
);
440 __raw_writel(0, LPC32XX_CLKPWR_PIN_AP
);
442 /* Clear latched wake event states */
443 __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS
),
444 LPC32XX_CLKPWR_PIN_RS
);
445 __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS
),
446 LPC32XX_CLKPWR_INT_RS
);