1 // SPDX-License-Identifier: GPL-2.0
4 /* INTMUX Block Diagram
7 * interrupt source # 0 +---->| |
9 * interrupt source # 1 +++-->| |
10 * ... | | | channel # 0 |--------->interrupt out # 0
13 * interrupt source # X-1 +++-->|________________|
16 * | | | ________________
20 * | | | | channel # 1 |--------->interrupt out # 1
23 * | | | |________________|
29 * | | | ________________
33 * | | channel # N |--------->interrupt out # N
39 * N: Interrupt Channel Instance Number (N=7)
40 * X: Interrupt Source Number for each channel (X=32)
42 * The INTMUX interrupt multiplexer has 8 channels, each channel receives 32
43 * interrupt sources and generates 1 interrupt output.
47 #include <linux/clk.h>
48 #include <linux/interrupt.h>
49 #include <linux/irq.h>
50 #include <linux/irqchip/chained_irq.h>
51 #include <linux/irqdomain.h>
52 #include <linux/kernel.h>
53 #include <linux/of_irq.h>
54 #include <linux/of_platform.h>
55 #include <linux/spinlock.h>
57 #define CHANIER(n) (0x10 + (0x40 * n))
58 #define CHANIPR(n) (0x20 + (0x40 * n))
60 #define CHAN_MAX_NUM 0x8
62 struct intmux_irqchip_data
{
65 struct irq_domain
*domain
;
73 struct intmux_irqchip_data irqchip_data
[];
76 static void imx_intmux_irq_mask(struct irq_data
*d
)
78 struct intmux_irqchip_data
*irqchip_data
= d
->chip_data
;
79 int idx
= irqchip_data
->chanidx
;
80 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
86 raw_spin_lock_irqsave(&data
->lock
, flags
);
87 reg
= data
->regs
+ CHANIER(idx
);
88 val
= readl_relaxed(reg
);
89 /* disable the interrupt source of this channel */
90 val
&= ~BIT(d
->hwirq
);
91 writel_relaxed(val
, reg
);
92 raw_spin_unlock_irqrestore(&data
->lock
, flags
);
95 static void imx_intmux_irq_unmask(struct irq_data
*d
)
97 struct intmux_irqchip_data
*irqchip_data
= d
->chip_data
;
98 int idx
= irqchip_data
->chanidx
;
99 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
105 raw_spin_lock_irqsave(&data
->lock
, flags
);
106 reg
= data
->regs
+ CHANIER(idx
);
107 val
= readl_relaxed(reg
);
108 /* enable the interrupt source of this channel */
109 val
|= BIT(d
->hwirq
);
110 writel_relaxed(val
, reg
);
111 raw_spin_unlock_irqrestore(&data
->lock
, flags
);
114 static struct irq_chip imx_intmux_irq_chip
= {
116 .irq_mask
= imx_intmux_irq_mask
,
117 .irq_unmask
= imx_intmux_irq_unmask
,
120 static int imx_intmux_irq_map(struct irq_domain
*h
, unsigned int irq
,
121 irq_hw_number_t hwirq
)
123 irq_set_chip_data(irq
, h
->host_data
);
124 irq_set_chip_and_handler(irq
, &imx_intmux_irq_chip
, handle_level_irq
);
129 static int imx_intmux_irq_xlate(struct irq_domain
*d
, struct device_node
*node
,
130 const u32
*intspec
, unsigned int intsize
,
131 unsigned long *out_hwirq
, unsigned int *out_type
)
133 struct intmux_irqchip_data
*irqchip_data
= d
->host_data
;
134 int idx
= irqchip_data
->chanidx
;
135 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
139 * two cells needed in interrupt specifier:
140 * the 1st cell: hw interrupt number
141 * the 2nd cell: channel index
143 if (WARN_ON(intsize
!= 2))
146 if (WARN_ON(intspec
[1] >= data
->channum
))
149 *out_hwirq
= intspec
[0];
150 *out_type
= IRQ_TYPE_LEVEL_HIGH
;
155 static int imx_intmux_irq_select(struct irq_domain
*d
, struct irq_fwspec
*fwspec
,
156 enum irq_domain_bus_token bus_token
)
158 struct intmux_irqchip_data
*irqchip_data
= d
->host_data
;
161 if (fwspec
->fwnode
!= d
->fwnode
)
164 return irqchip_data
->chanidx
== fwspec
->param
[1];
167 static const struct irq_domain_ops imx_intmux_domain_ops
= {
168 .map
= imx_intmux_irq_map
,
169 .xlate
= imx_intmux_irq_xlate
,
170 .select
= imx_intmux_irq_select
,
173 static void imx_intmux_irq_handler(struct irq_desc
*desc
)
175 struct intmux_irqchip_data
*irqchip_data
= irq_desc_get_handler_data(desc
);
176 int idx
= irqchip_data
->chanidx
;
177 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
179 unsigned long irqstat
;
182 chained_irq_enter(irq_desc_get_chip(desc
), desc
);
184 /* read the interrupt source pending status of this channel */
185 irqstat
= readl_relaxed(data
->regs
+ CHANIPR(idx
));
187 for_each_set_bit(pos
, &irqstat
, 32) {
188 virq
= irq_find_mapping(irqchip_data
->domain
, pos
);
190 generic_handle_irq(virq
);
193 chained_irq_exit(irq_desc_get_chip(desc
), desc
);
196 static int imx_intmux_probe(struct platform_device
*pdev
)
198 struct device_node
*np
= pdev
->dev
.of_node
;
199 struct irq_domain
*domain
;
200 struct intmux_data
*data
;
204 channum
= platform_irq_count(pdev
);
205 if (channum
== -EPROBE_DEFER
) {
206 return -EPROBE_DEFER
;
207 } else if (channum
> CHAN_MAX_NUM
) {
208 dev_err(&pdev
->dev
, "supports up to %d multiplex channels\n",
213 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
) +
214 channum
* sizeof(data
->irqchip_data
[0]), GFP_KERNEL
);
218 data
->regs
= devm_platform_ioremap_resource(pdev
, 0);
219 if (IS_ERR(data
->regs
)) {
220 dev_err(&pdev
->dev
, "failed to initialize reg\n");
221 return PTR_ERR(data
->regs
);
224 data
->ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
225 if (IS_ERR(data
->ipg_clk
)) {
226 ret
= PTR_ERR(data
->ipg_clk
);
227 if (ret
!= -EPROBE_DEFER
)
228 dev_err(&pdev
->dev
, "failed to get ipg clk: %d\n", ret
);
232 data
->channum
= channum
;
233 raw_spin_lock_init(&data
->lock
);
235 ret
= clk_prepare_enable(data
->ipg_clk
);
237 dev_err(&pdev
->dev
, "failed to enable ipg clk: %d\n", ret
);
241 for (i
= 0; i
< channum
; i
++) {
242 data
->irqchip_data
[i
].chanidx
= i
;
244 data
->irqchip_data
[i
].irq
= irq_of_parse_and_map(np
, i
);
245 if (data
->irqchip_data
[i
].irq
<= 0) {
247 dev_err(&pdev
->dev
, "failed to get irq\n");
251 domain
= irq_domain_add_linear(np
, 32, &imx_intmux_domain_ops
,
252 &data
->irqchip_data
[i
]);
255 dev_err(&pdev
->dev
, "failed to create IRQ domain\n");
258 data
->irqchip_data
[i
].domain
= domain
;
260 /* disable all interrupt sources of this channel firstly */
261 writel_relaxed(0, data
->regs
+ CHANIER(i
));
263 irq_set_chained_handler_and_data(data
->irqchip_data
[i
].irq
,
264 imx_intmux_irq_handler
,
265 &data
->irqchip_data
[i
]);
268 platform_set_drvdata(pdev
, data
);
272 clk_disable_unprepare(data
->ipg_clk
);
276 static int imx_intmux_remove(struct platform_device
*pdev
)
278 struct intmux_data
*data
= platform_get_drvdata(pdev
);
281 for (i
= 0; i
< data
->channum
; i
++) {
282 /* disable all interrupt sources of this channel */
283 writel_relaxed(0, data
->regs
+ CHANIER(i
));
285 irq_set_chained_handler_and_data(data
->irqchip_data
[i
].irq
,
288 irq_domain_remove(data
->irqchip_data
[i
].domain
);
291 clk_disable_unprepare(data
->ipg_clk
);
296 static const struct of_device_id imx_intmux_id
[] = {
297 { .compatible
= "fsl,imx-intmux", },
301 static struct platform_driver imx_intmux_driver
= {
303 .name
= "imx-intmux",
304 .of_match_table
= imx_intmux_id
,
306 .probe
= imx_intmux_probe
,
307 .remove
= imx_intmux_remove
,
309 builtin_platform_driver(imx_intmux_driver
);