• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * arch/arm/mach-lpc32xx/irq.c
3  *
4  * Author: Kevin Wells <kevin.wells@nxp.com>
5  *
6  * Copyright (C) 2010 NXP Semiconductors
7  *
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.
12  *
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.
17  */
18 
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>
25 #include <linux/of.h>
26 #include <linux/of_address.h>
27 #include <linux/of_irq.h>
28 #include <linux/irqdomain.h>
29 #include <linux/module.h>
30 
31 #include <mach/irqs.h>
32 #include <mach/hardware.h>
33 #include <mach/platform.h>
34 #include "common.h"
35 
36 /*
37  * Default value representing the Activation polarity of all internal
38  * interrupt sources
39  */
40 #define MIC_APR_DEFAULT		0x3FF0EFE0
41 #define SIC1_APR_DEFAULT	0xFBD27186
42 #define SIC2_APR_DEFAULT	0x801810C0
43 
44 /*
45  * Default value representing the Activation Type of all internal
46  * interrupt sources. All are level sensitive.
47  */
48 #define MIC_ATR_DEFAULT		0x00000000
49 #define SIC1_ATR_DEFAULT	0x00026000
50 #define SIC2_ATR_DEFAULT	0x00000000
51 
52 static struct irq_domain *lpc32xx_mic_domain;
53 static struct device_node *lpc32xx_mic_np;
54 
55 struct lpc32xx_event_group_regs {
56 	void __iomem *enab_reg;
57 	void __iomem *edge_reg;
58 	void __iomem *maskstat_reg;
59 	void __iomem *rawstat_reg;
60 };
61 
62 static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = {
63 	.enab_reg = LPC32XX_CLKPWR_INT_ER,
64 	.edge_reg = LPC32XX_CLKPWR_INT_AP,
65 	.maskstat_reg = LPC32XX_CLKPWR_INT_SR,
66 	.rawstat_reg = LPC32XX_CLKPWR_INT_RS,
67 };
68 
69 static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = {
70 	.enab_reg = LPC32XX_CLKPWR_PIN_ER,
71 	.edge_reg = LPC32XX_CLKPWR_PIN_AP,
72 	.maskstat_reg = LPC32XX_CLKPWR_PIN_SR,
73 	.rawstat_reg = LPC32XX_CLKPWR_PIN_RS,
74 };
75 
76 struct lpc32xx_event_info {
77 	const struct lpc32xx_event_group_regs *event_group;
78 	u32 mask;
79 };
80 
81 /*
82  * Maps an IRQ number to and event mask and register
83  */
84 static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
85 	[IRQ_LPC32XX_GPI_08] = {
86 		.event_group = &lpc32xx_event_pin_regs,
87 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT,
88 	},
89 	[IRQ_LPC32XX_GPI_09] = {
90 		.event_group = &lpc32xx_event_pin_regs,
91 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT,
92 	},
93 	[IRQ_LPC32XX_GPI_19] = {
94 		.event_group = &lpc32xx_event_pin_regs,
95 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT,
96 	},
97 	[IRQ_LPC32XX_GPI_07] = {
98 		.event_group = &lpc32xx_event_pin_regs,
99 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT,
100 	},
101 	[IRQ_LPC32XX_GPI_00] = {
102 		.event_group = &lpc32xx_event_pin_regs,
103 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT,
104 	},
105 	[IRQ_LPC32XX_GPI_01] = {
106 		.event_group = &lpc32xx_event_pin_regs,
107 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT,
108 	},
109 	[IRQ_LPC32XX_GPI_02] = {
110 		.event_group = &lpc32xx_event_pin_regs,
111 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT,
112 	},
113 	[IRQ_LPC32XX_GPI_03] = {
114 		.event_group = &lpc32xx_event_pin_regs,
115 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT,
116 	},
117 	[IRQ_LPC32XX_GPI_04] = {
118 		.event_group = &lpc32xx_event_pin_regs,
119 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT,
120 	},
121 	[IRQ_LPC32XX_GPI_05] = {
122 		.event_group = &lpc32xx_event_pin_regs,
123 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT,
124 	},
125 	[IRQ_LPC32XX_GPI_06] = {
126 		.event_group = &lpc32xx_event_pin_regs,
127 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
128 	},
129 	[IRQ_LPC32XX_GPI_28] = {
130 		.event_group = &lpc32xx_event_pin_regs,
131 		.mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT,
132 	},
133 	[IRQ_LPC32XX_GPIO_00] = {
134 		.event_group = &lpc32xx_event_int_regs,
135 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
136 	},
137 	[IRQ_LPC32XX_GPIO_01] = {
138 		.event_group = &lpc32xx_event_int_regs,
139 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT,
140 	},
141 	[IRQ_LPC32XX_GPIO_02] = {
142 		.event_group = &lpc32xx_event_int_regs,
143 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT,
144 	},
145 	[IRQ_LPC32XX_GPIO_03] = {
146 		.event_group = &lpc32xx_event_int_regs,
147 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT,
148 	},
149 	[IRQ_LPC32XX_GPIO_04] = {
150 		.event_group = &lpc32xx_event_int_regs,
151 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT,
152 	},
153 	[IRQ_LPC32XX_GPIO_05] = {
154 		.event_group = &lpc32xx_event_int_regs,
155 		.mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT,
156 	},
157 	[IRQ_LPC32XX_KEY] = {
158 		.event_group = &lpc32xx_event_int_regs,
159 		.mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
160 	},
161 	[IRQ_LPC32XX_ETHERNET] = {
162 		.event_group = &lpc32xx_event_int_regs,
163 		.mask = LPC32XX_CLKPWR_INTSRC_MAC_BIT,
164 	},
165 	[IRQ_LPC32XX_USB_OTG_ATX] = {
166 		.event_group = &lpc32xx_event_int_regs,
167 		.mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
168 	},
169 	[IRQ_LPC32XX_USB_HOST] = {
170 		.event_group = &lpc32xx_event_int_regs,
171 		.mask = LPC32XX_CLKPWR_INTSRC_USB_BIT,
172 	},
173 	[IRQ_LPC32XX_RTC] = {
174 		.event_group = &lpc32xx_event_int_regs,
175 		.mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT,
176 	},
177 	[IRQ_LPC32XX_MSTIMER] = {
178 		.event_group = &lpc32xx_event_int_regs,
179 		.mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT,
180 	},
181 	[IRQ_LPC32XX_TS_AUX] = {
182 		.event_group = &lpc32xx_event_int_regs,
183 		.mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT,
184 	},
185 	[IRQ_LPC32XX_TS_P] = {
186 		.event_group = &lpc32xx_event_int_regs,
187 		.mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT,
188 	},
189 	[IRQ_LPC32XX_TS_IRQ] = {
190 		.event_group = &lpc32xx_event_int_regs,
191 		.mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT,
192 	},
193 };
194 
get_controller(unsigned int irq,unsigned int * base,unsigned int * irqbit)195 static void get_controller(unsigned int irq, unsigned int *base,
196 	unsigned int *irqbit)
197 {
198 	if (irq < 32) {
199 		*base = LPC32XX_MIC_BASE;
200 		*irqbit = 1 << irq;
201 	} else if (irq < 64) {
202 		*base = LPC32XX_SIC1_BASE;
203 		*irqbit = 1 << (irq - 32);
204 	} else {
205 		*base = LPC32XX_SIC2_BASE;
206 		*irqbit = 1 << (irq - 64);
207 	}
208 }
209 
lpc32xx_mask_irq(struct irq_data * d)210 static void lpc32xx_mask_irq(struct irq_data *d)
211 {
212 	unsigned int reg, ctrl, mask;
213 
214 	get_controller(d->hwirq, &ctrl, &mask);
215 
216 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask;
217 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
218 }
219 
lpc32xx_unmask_irq(struct irq_data * d)220 static void lpc32xx_unmask_irq(struct irq_data *d)
221 {
222 	unsigned int reg, ctrl, mask;
223 
224 	get_controller(d->hwirq, &ctrl, &mask);
225 
226 	reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask;
227 	__raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
228 }
229 
lpc32xx_ack_irq(struct irq_data * d)230 static void lpc32xx_ack_irq(struct irq_data *d)
231 {
232 	unsigned int ctrl, mask;
233 
234 	get_controller(d->hwirq, &ctrl, &mask);
235 
236 	__raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl));
237 
238 	/* Also need to clear pending wake event */
239 	if (lpc32xx_events[d->hwirq].mask != 0)
240 		__raw_writel(lpc32xx_events[d->hwirq].mask,
241 			lpc32xx_events[d->hwirq].event_group->rawstat_reg);
242 }
243 
__lpc32xx_set_irq_type(unsigned int irq,int use_high_level,int use_edge)244 static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level,
245 	int use_edge)
246 {
247 	unsigned int reg, ctrl, mask;
248 
249 	get_controller(irq, &ctrl, &mask);
250 
251 	/* Activation level, high or low */
252 	reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl));
253 	if (use_high_level)
254 		reg |= mask;
255 	else
256 		reg &= ~mask;
257 	__raw_writel(reg, LPC32XX_INTC_POLAR(ctrl));
258 
259 	/* Activation type, edge or level */
260 	reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl));
261 	if (use_edge)
262 		reg |= mask;
263 	else
264 		reg &= ~mask;
265 	__raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl));
266 
267 	/* Use same polarity for the wake events */
268 	if (lpc32xx_events[irq].mask != 0) {
269 		reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg);
270 
271 		if (use_high_level)
272 			reg |= lpc32xx_events[irq].mask;
273 		else
274 			reg &= ~lpc32xx_events[irq].mask;
275 
276 		__raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg);
277 	}
278 }
279 
lpc32xx_set_irq_type(struct irq_data * d,unsigned int type)280 static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
281 {
282 	switch (type) {
283 	case IRQ_TYPE_EDGE_RISING:
284 		/* Rising edge sensitive */
285 		__lpc32xx_set_irq_type(d->hwirq, 1, 1);
286 		irq_set_handler_locked(d, handle_edge_irq);
287 		break;
288 
289 	case IRQ_TYPE_EDGE_FALLING:
290 		/* Falling edge sensitive */
291 		__lpc32xx_set_irq_type(d->hwirq, 0, 1);
292 		irq_set_handler_locked(d, handle_edge_irq);
293 		break;
294 
295 	case IRQ_TYPE_LEVEL_LOW:
296 		/* Low level sensitive */
297 		__lpc32xx_set_irq_type(d->hwirq, 0, 0);
298 		irq_set_handler_locked(d, handle_level_irq);
299 		break;
300 
301 	case IRQ_TYPE_LEVEL_HIGH:
302 		/* High level sensitive */
303 		__lpc32xx_set_irq_type(d->hwirq, 1, 0);
304 		irq_set_handler_locked(d, handle_level_irq);
305 		break;
306 
307 	/* Other modes are not supported */
308 	default:
309 		return -EINVAL;
310 	}
311 
312 	return 0;
313 }
314 
lpc32xx_irq_wake(struct irq_data * d,unsigned int state)315 static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
316 {
317 	unsigned long eventreg;
318 
319 	if (lpc32xx_events[d->hwirq].mask != 0) {
320 		eventreg = __raw_readl(lpc32xx_events[d->hwirq].
321 			event_group->enab_reg);
322 
323 		if (state)
324 			eventreg |= lpc32xx_events[d->hwirq].mask;
325 		else {
326 			eventreg &= ~lpc32xx_events[d->hwirq].mask;
327 
328 			/*
329 			 * When disabling the wakeup, clear the latched
330 			 * event
331 			 */
332 			__raw_writel(lpc32xx_events[d->hwirq].mask,
333 				lpc32xx_events[d->hwirq].
334 				event_group->rawstat_reg);
335 		}
336 
337 		__raw_writel(eventreg,
338 			lpc32xx_events[d->hwirq].event_group->enab_reg);
339 
340 		return 0;
341 	}
342 
343 	/* Clear event */
344 	__raw_writel(lpc32xx_events[d->hwirq].mask,
345 		lpc32xx_events[d->hwirq].event_group->rawstat_reg);
346 
347 	return -ENODEV;
348 }
349 
lpc32xx_set_default_mappings(unsigned int apr,unsigned int atr,unsigned int offset)350 static void __init lpc32xx_set_default_mappings(unsigned int apr,
351 	unsigned int atr, unsigned int offset)
352 {
353 	unsigned int i;
354 
355 	/* Set activation levels for each interrupt */
356 	i = 0;
357 	while (i < 32) {
358 		__lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1),
359 			((atr >> i) & 0x1));
360 		i++;
361 	}
362 }
363 
364 static struct irq_chip lpc32xx_irq_chip = {
365 	.name = "MIC",
366 	.irq_ack = lpc32xx_ack_irq,
367 	.irq_mask = lpc32xx_mask_irq,
368 	.irq_unmask = lpc32xx_unmask_irq,
369 	.irq_set_type = lpc32xx_set_irq_type,
370 	.irq_set_wake = lpc32xx_irq_wake
371 };
372 
lpc32xx_sic1_handler(struct irq_desc * desc)373 static void lpc32xx_sic1_handler(struct irq_desc *desc)
374 {
375 	unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE));
376 
377 	while (ints != 0) {
378 		int irqno = fls(ints) - 1;
379 
380 		ints &= ~(1 << irqno);
381 
382 		generic_handle_irq(LPC32XX_SIC1_IRQ(irqno));
383 	}
384 }
385 
lpc32xx_sic2_handler(struct irq_desc * desc)386 static void lpc32xx_sic2_handler(struct irq_desc *desc)
387 {
388 	unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE));
389 
390 	while (ints != 0) {
391 		int irqno = fls(ints) - 1;
392 
393 		ints &= ~(1 << irqno);
394 
395 		generic_handle_irq(LPC32XX_SIC2_IRQ(irqno));
396 	}
397 }
398 
__lpc32xx_mic_of_init(struct device_node * node,struct device_node * parent)399 static int __init __lpc32xx_mic_of_init(struct device_node *node,
400 					struct device_node *parent)
401 {
402 	lpc32xx_mic_np = node;
403 
404 	return 0;
405 }
406 
407 static const struct of_device_id mic_of_match[] __initconst = {
408 	{ .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init },
409 	{ }
410 };
411 
lpc32xx_init_irq(void)412 void __init lpc32xx_init_irq(void)
413 {
414 	unsigned int i;
415 
416 	/* Setup MIC */
417 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
418 	__raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE));
419 	__raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE));
420 
421 	/* Setup SIC1 */
422 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
423 	__raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
424 	__raw_writel(SIC1_ATR_DEFAULT,
425 				LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
426 
427 	/* Setup SIC2 */
428 	__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
429 	__raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
430 	__raw_writel(SIC2_ATR_DEFAULT,
431 				LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
432 
433 	/* Configure supported IRQ's */
434 	for (i = 0; i < NR_IRQS; i++) {
435 		irq_set_chip_and_handler(i, &lpc32xx_irq_chip,
436 					 handle_level_irq);
437 		irq_clear_status_flags(i, IRQ_NOREQUEST);
438 	}
439 
440 	/* Set default mappings */
441 	lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0);
442 	lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32);
443 	lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64);
444 
445 	/* Initially disable all wake events */
446 	__raw_writel(0, LPC32XX_CLKPWR_P01_ER);
447 	__raw_writel(0, LPC32XX_CLKPWR_INT_ER);
448 	__raw_writel(0, LPC32XX_CLKPWR_PIN_ER);
449 
450 	/*
451 	 * Default wake activation polarities, all pin sources are low edge
452 	 * triggered
453 	 */
454 	__raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT |
455 		LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT |
456 		LPC32XX_CLKPWR_INTSRC_RTC_BIT,
457 		LPC32XX_CLKPWR_INT_AP);
458 	__raw_writel(0, LPC32XX_CLKPWR_PIN_AP);
459 
460 	/* Clear latched wake event states */
461 	__raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS),
462 		LPC32XX_CLKPWR_PIN_RS);
463 	__raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS),
464 		LPC32XX_CLKPWR_INT_RS);
465 
466 	of_irq_init(mic_of_match);
467 
468 	lpc32xx_mic_domain = irq_domain_add_legacy(lpc32xx_mic_np, NR_IRQS,
469 						   0, 0, &irq_domain_simple_ops,
470 						   NULL);
471 	if (!lpc32xx_mic_domain)
472 		panic("Unable to add MIC irq domain\n");
473 
474 	/* MIC SUBIRQx interrupts will route handling to the chain handlers */
475 	irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
476 	irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
477 }
478