1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright 2015-2016 Vladimir Zapolskiy <vz@mleia.com>
6 #define pr_fmt(fmt) "%s: " fmt, __func__
9 #include <linux/irqchip.h>
10 #include <linux/irqchip/chained_irq.h>
11 #include <linux/of_address.h>
12 #include <linux/of_irq.h>
13 #include <linux/of_platform.h>
14 #include <linux/seq_file.h>
15 #include <linux/slab.h>
16 #include <asm/exception.h>
18 #define LPC32XX_INTC_MASK 0x00
19 #define LPC32XX_INTC_RAW 0x04
20 #define LPC32XX_INTC_STAT 0x08
21 #define LPC32XX_INTC_POL 0x0C
22 #define LPC32XX_INTC_TYPE 0x10
23 #define LPC32XX_INTC_FIQ 0x14
25 #define NR_LPC32XX_IC_IRQS 32
27 struct lpc32xx_irq_chip
{
30 struct irq_domain
*domain
;
33 static struct lpc32xx_irq_chip
*lpc32xx_mic_irqc
;
35 static inline u32
lpc32xx_ic_read(struct lpc32xx_irq_chip
*ic
, u32 reg
)
37 return readl_relaxed(ic
->base
+ reg
);
40 static inline void lpc32xx_ic_write(struct lpc32xx_irq_chip
*ic
,
43 writel_relaxed(val
, ic
->base
+ reg
);
46 static void lpc32xx_irq_mask(struct irq_data
*d
)
48 struct lpc32xx_irq_chip
*ic
= irq_data_get_irq_chip_data(d
);
49 u32 val
, mask
= BIT(d
->hwirq
);
51 val
= lpc32xx_ic_read(ic
, LPC32XX_INTC_MASK
) & ~mask
;
52 lpc32xx_ic_write(ic
, LPC32XX_INTC_MASK
, val
);
55 static void lpc32xx_irq_unmask(struct irq_data
*d
)
57 struct lpc32xx_irq_chip
*ic
= irq_data_get_irq_chip_data(d
);
58 u32 val
, mask
= BIT(d
->hwirq
);
60 val
= lpc32xx_ic_read(ic
, LPC32XX_INTC_MASK
) | mask
;
61 lpc32xx_ic_write(ic
, LPC32XX_INTC_MASK
, val
);
64 static void lpc32xx_irq_ack(struct irq_data
*d
)
66 struct lpc32xx_irq_chip
*ic
= irq_data_get_irq_chip_data(d
);
67 u32 mask
= BIT(d
->hwirq
);
69 lpc32xx_ic_write(ic
, LPC32XX_INTC_RAW
, mask
);
72 static int lpc32xx_irq_set_type(struct irq_data
*d
, unsigned int type
)
74 struct lpc32xx_irq_chip
*ic
= irq_data_get_irq_chip_data(d
);
75 u32 val
, mask
= BIT(d
->hwirq
);
79 case IRQ_TYPE_EDGE_RISING
:
83 case IRQ_TYPE_EDGE_FALLING
:
87 case IRQ_TYPE_LEVEL_HIGH
:
91 case IRQ_TYPE_LEVEL_LOW
:
96 pr_info("unsupported irq type %d\n", type
);
100 irqd_set_trigger_type(d
, type
);
102 val
= lpc32xx_ic_read(ic
, LPC32XX_INTC_POL
);
107 lpc32xx_ic_write(ic
, LPC32XX_INTC_POL
, val
);
109 val
= lpc32xx_ic_read(ic
, LPC32XX_INTC_TYPE
);
112 irq_set_handler_locked(d
, handle_edge_irq
);
115 irq_set_handler_locked(d
, handle_level_irq
);
117 lpc32xx_ic_write(ic
, LPC32XX_INTC_TYPE
, val
);
122 static void lpc32xx_irq_print_chip(struct irq_data
*d
, struct seq_file
*p
)
124 struct lpc32xx_irq_chip
*ic
= irq_data_get_irq_chip_data(d
);
126 if (ic
== lpc32xx_mic_irqc
)
127 seq_printf(p
, "%08x.mic", ic
->addr
);
129 seq_printf(p
, "%08x.sic", ic
->addr
);
132 static const struct irq_chip lpc32xx_chip
= {
133 .irq_ack
= lpc32xx_irq_ack
,
134 .irq_mask
= lpc32xx_irq_mask
,
135 .irq_unmask
= lpc32xx_irq_unmask
,
136 .irq_set_type
= lpc32xx_irq_set_type
,
137 .irq_print_chip
= lpc32xx_irq_print_chip
,
140 static void __exception_irq_entry
lpc32xx_handle_irq(struct pt_regs
*regs
)
142 struct lpc32xx_irq_chip
*ic
= lpc32xx_mic_irqc
;
143 u32 hwirq
= lpc32xx_ic_read(ic
, LPC32XX_INTC_STAT
), irq
;
148 generic_handle_domain_irq(lpc32xx_mic_irqc
->domain
, irq
);
152 static void lpc32xx_sic_handler(struct irq_desc
*desc
)
154 struct lpc32xx_irq_chip
*ic
= irq_desc_get_handler_data(desc
);
155 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
156 u32 hwirq
= lpc32xx_ic_read(ic
, LPC32XX_INTC_STAT
), irq
;
158 chained_irq_enter(chip
, desc
);
163 generic_handle_domain_irq(ic
->domain
, irq
);
166 chained_irq_exit(chip
, desc
);
169 static int lpc32xx_irq_domain_map(struct irq_domain
*id
, unsigned int virq
,
172 struct lpc32xx_irq_chip
*ic
= id
->host_data
;
174 irq_set_chip_data(virq
, ic
);
175 irq_set_chip_and_handler(virq
, &lpc32xx_chip
, handle_level_irq
);
176 irq_set_status_flags(virq
, IRQ_LEVEL
);
177 irq_set_noprobe(virq
);
182 static void lpc32xx_irq_domain_unmap(struct irq_domain
*id
, unsigned int virq
)
184 irq_set_chip_and_handler(virq
, NULL
, NULL
);
187 static const struct irq_domain_ops lpc32xx_irq_domain_ops
= {
188 .map
= lpc32xx_irq_domain_map
,
189 .unmap
= lpc32xx_irq_domain_unmap
,
190 .xlate
= irq_domain_xlate_twocell
,
193 static int __init
lpc32xx_of_ic_init(struct device_node
*node
,
194 struct device_node
*parent
)
196 struct lpc32xx_irq_chip
*irqc
;
197 bool is_mic
= of_device_is_compatible(node
, "nxp,lpc3220-mic");
198 const __be32
*reg
= of_get_property(node
, "reg", NULL
);
199 u32 parent_irq
, i
, addr
= reg
? be32_to_cpu(*reg
) : 0;
201 irqc
= kzalloc(sizeof(*irqc
), GFP_KERNEL
);
206 irqc
->base
= of_iomap(node
, 0);
208 pr_err("%pOF: unable to map registers\n", node
);
213 irqc
->domain
= irq_domain_add_linear(node
, NR_LPC32XX_IC_IRQS
,
214 &lpc32xx_irq_domain_ops
, irqc
);
216 pr_err("unable to add irq domain\n");
223 lpc32xx_mic_irqc
= irqc
;
224 set_handle_irq(lpc32xx_handle_irq
);
226 for (i
= 0; i
< of_irq_count(node
); i
++) {
227 parent_irq
= irq_of_parse_and_map(node
, i
);
229 irq_set_chained_handler_and_data(parent_irq
,
230 lpc32xx_sic_handler
, irqc
);
234 lpc32xx_ic_write(irqc
, LPC32XX_INTC_MASK
, 0x00);
235 lpc32xx_ic_write(irqc
, LPC32XX_INTC_POL
, 0x00);
236 lpc32xx_ic_write(irqc
, LPC32XX_INTC_TYPE
, 0x00);
241 IRQCHIP_DECLARE(nxp_lpc32xx_mic
, "nxp,lpc3220-mic", lpc32xx_of_ic_init
);
242 IRQCHIP_DECLARE(nxp_lpc32xx_sic
, "nxp,lpc3220-sic", lpc32xx_of_ic_init
);