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
52static struct irq_domain *lpc32xx_mic_domain;
53static struct device_node *lpc32xx_mic_np;
54
55struct 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
62static 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
69static 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
76struct 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 */
84static 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
195static 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
210static 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
220static 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
230static 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
244static 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
280static 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->hwirq, 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->hwirq, 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->hwirq, 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->hwirq, handle_level_irq);
305		break;
306
307	/* Other modes are not supported */
308	default:
309		return -EINVAL;
310	}
311
312	return 0;
313}
314
315static 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
350static 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
364static 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
373static void lpc32xx_sic1_handler(unsigned int irq, 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
386static void lpc32xx_sic2_handler(unsigned int irq, 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
399static 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
407static const struct of_device_id mic_of_match[] __initconst = {
408	{ .compatible = "nxp,lpc3220-mic", .data = __lpc32xx_mic_of_init },
409	{ }
410};
411
412void __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		set_irq_flags(i, IRQF_VALID);
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