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>
56 #include <linux/pm_runtime.h>
58 #define CHANIER(n) (0x10 + (0x40 * n))
59 #define CHANIPR(n) (0x20 + (0x40 * n))
61 #define CHAN_MAX_NUM 0x8
63 struct intmux_irqchip_data
{
68 struct irq_domain
*domain
;
76 struct intmux_irqchip_data irqchip_data
[];
79 static void imx_intmux_irq_mask(struct irq_data
*d
)
81 struct intmux_irqchip_data
*irqchip_data
= d
->chip_data
;
82 int idx
= irqchip_data
->chanidx
;
83 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
89 raw_spin_lock_irqsave(&data
->lock
, flags
);
90 reg
= data
->regs
+ CHANIER(idx
);
91 val
= readl_relaxed(reg
);
92 /* disable the interrupt source of this channel */
93 val
&= ~BIT(d
->hwirq
);
94 writel_relaxed(val
, reg
);
95 raw_spin_unlock_irqrestore(&data
->lock
, flags
);
98 static void imx_intmux_irq_unmask(struct irq_data
*d
)
100 struct intmux_irqchip_data
*irqchip_data
= d
->chip_data
;
101 int idx
= irqchip_data
->chanidx
;
102 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
108 raw_spin_lock_irqsave(&data
->lock
, flags
);
109 reg
= data
->regs
+ CHANIER(idx
);
110 val
= readl_relaxed(reg
);
111 /* enable the interrupt source of this channel */
112 val
|= BIT(d
->hwirq
);
113 writel_relaxed(val
, reg
);
114 raw_spin_unlock_irqrestore(&data
->lock
, flags
);
117 static struct irq_chip imx_intmux_irq_chip
= {
119 .irq_mask
= imx_intmux_irq_mask
,
120 .irq_unmask
= imx_intmux_irq_unmask
,
123 static int imx_intmux_irq_map(struct irq_domain
*h
, unsigned int irq
,
124 irq_hw_number_t hwirq
)
126 struct intmux_irqchip_data
*data
= h
->host_data
;
128 irq_set_chip_data(irq
, data
);
129 irq_set_chip_and_handler(irq
, &data
->chip
, handle_level_irq
);
134 static int imx_intmux_irq_xlate(struct irq_domain
*d
, struct device_node
*node
,
135 const u32
*intspec
, unsigned int intsize
,
136 unsigned long *out_hwirq
, unsigned int *out_type
)
138 struct intmux_irqchip_data
*irqchip_data
= d
->host_data
;
139 int idx
= irqchip_data
->chanidx
;
140 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
144 * two cells needed in interrupt specifier:
145 * the 1st cell: hw interrupt number
146 * the 2nd cell: channel index
148 if (WARN_ON(intsize
!= 2))
151 if (WARN_ON(intspec
[1] >= data
->channum
))
154 *out_hwirq
= intspec
[0];
155 *out_type
= IRQ_TYPE_LEVEL_HIGH
;
160 static int imx_intmux_irq_select(struct irq_domain
*d
, struct irq_fwspec
*fwspec
,
161 enum irq_domain_bus_token bus_token
)
163 struct intmux_irqchip_data
*irqchip_data
= d
->host_data
;
166 if (fwspec
->fwnode
!= d
->fwnode
)
169 return irqchip_data
->chanidx
== fwspec
->param
[1];
172 static const struct irq_domain_ops imx_intmux_domain_ops
= {
173 .map
= imx_intmux_irq_map
,
174 .xlate
= imx_intmux_irq_xlate
,
175 .select
= imx_intmux_irq_select
,
178 static void imx_intmux_irq_handler(struct irq_desc
*desc
)
180 struct intmux_irqchip_data
*irqchip_data
= irq_desc_get_handler_data(desc
);
181 int idx
= irqchip_data
->chanidx
;
182 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
184 unsigned long irqstat
;
187 chained_irq_enter(irq_desc_get_chip(desc
), desc
);
189 /* read the interrupt source pending status of this channel */
190 irqstat
= readl_relaxed(data
->regs
+ CHANIPR(idx
));
192 for_each_set_bit(pos
, &irqstat
, 32) {
193 virq
= irq_find_mapping(irqchip_data
->domain
, pos
);
195 generic_handle_irq(virq
);
198 chained_irq_exit(irq_desc_get_chip(desc
), desc
);
201 static int imx_intmux_probe(struct platform_device
*pdev
)
203 struct device_node
*np
= pdev
->dev
.of_node
;
204 struct irq_domain
*domain
;
205 struct intmux_data
*data
;
209 channum
= platform_irq_count(pdev
);
210 if (channum
== -EPROBE_DEFER
) {
211 return -EPROBE_DEFER
;
212 } else if (channum
> CHAN_MAX_NUM
) {
213 dev_err(&pdev
->dev
, "supports up to %d multiplex channels\n",
218 data
= devm_kzalloc(&pdev
->dev
, struct_size(data
, irqchip_data
, channum
), GFP_KERNEL
);
222 data
->regs
= devm_platform_ioremap_resource(pdev
, 0);
223 if (IS_ERR(data
->regs
)) {
224 dev_err(&pdev
->dev
, "failed to initialize reg\n");
225 return PTR_ERR(data
->regs
);
228 data
->ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
229 if (IS_ERR(data
->ipg_clk
))
230 return dev_err_probe(&pdev
->dev
, PTR_ERR(data
->ipg_clk
),
231 "failed to get ipg clk\n");
233 data
->channum
= channum
;
234 raw_spin_lock_init(&data
->lock
);
236 pm_runtime_get_noresume(&pdev
->dev
);
237 pm_runtime_set_active(&pdev
->dev
);
238 pm_runtime_enable(&pdev
->dev
);
240 ret
= clk_prepare_enable(data
->ipg_clk
);
242 dev_err(&pdev
->dev
, "failed to enable ipg clk: %d\n", ret
);
246 for (i
= 0; i
< channum
; i
++) {
247 data
->irqchip_data
[i
].chip
= imx_intmux_irq_chip
;
248 data
->irqchip_data
[i
].chip
.parent_device
= &pdev
->dev
;
249 data
->irqchip_data
[i
].chanidx
= i
;
251 data
->irqchip_data
[i
].irq
= irq_of_parse_and_map(np
, i
);
252 if (data
->irqchip_data
[i
].irq
<= 0) {
254 dev_err(&pdev
->dev
, "failed to get irq\n");
258 domain
= irq_domain_add_linear(np
, 32, &imx_intmux_domain_ops
,
259 &data
->irqchip_data
[i
]);
262 dev_err(&pdev
->dev
, "failed to create IRQ domain\n");
265 data
->irqchip_data
[i
].domain
= domain
;
267 /* disable all interrupt sources of this channel firstly */
268 writel_relaxed(0, data
->regs
+ CHANIER(i
));
270 irq_set_chained_handler_and_data(data
->irqchip_data
[i
].irq
,
271 imx_intmux_irq_handler
,
272 &data
->irqchip_data
[i
]);
275 platform_set_drvdata(pdev
, data
);
278 * Let pm_runtime_put() disable clock.
279 * If CONFIG_PM is not enabled, the clock will stay powered.
281 pm_runtime_put(&pdev
->dev
);
285 clk_disable_unprepare(data
->ipg_clk
);
289 static int imx_intmux_remove(struct platform_device
*pdev
)
291 struct intmux_data
*data
= platform_get_drvdata(pdev
);
294 for (i
= 0; i
< data
->channum
; i
++) {
295 /* disable all interrupt sources of this channel */
296 writel_relaxed(0, data
->regs
+ CHANIER(i
));
298 irq_set_chained_handler_and_data(data
->irqchip_data
[i
].irq
,
301 irq_domain_remove(data
->irqchip_data
[i
].domain
);
304 pm_runtime_disable(&pdev
->dev
);
310 static int imx_intmux_runtime_suspend(struct device
*dev
)
312 struct intmux_data
*data
= dev_get_drvdata(dev
);
313 struct intmux_irqchip_data
*irqchip_data
;
316 for (i
= 0; i
< data
->channum
; i
++) {
317 irqchip_data
= &data
->irqchip_data
[i
];
318 irqchip_data
->saved_reg
= readl_relaxed(data
->regs
+ CHANIER(i
));
321 clk_disable_unprepare(data
->ipg_clk
);
326 static int imx_intmux_runtime_resume(struct device
*dev
)
328 struct intmux_data
*data
= dev_get_drvdata(dev
);
329 struct intmux_irqchip_data
*irqchip_data
;
332 ret
= clk_prepare_enable(data
->ipg_clk
);
334 dev_err(dev
, "failed to enable ipg clk: %d\n", ret
);
338 for (i
= 0; i
< data
->channum
; i
++) {
339 irqchip_data
= &data
->irqchip_data
[i
];
340 writel_relaxed(irqchip_data
->saved_reg
, data
->regs
+ CHANIER(i
));
347 static const struct dev_pm_ops imx_intmux_pm_ops
= {
348 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
349 pm_runtime_force_resume
)
350 SET_RUNTIME_PM_OPS(imx_intmux_runtime_suspend
,
351 imx_intmux_runtime_resume
, NULL
)
354 static const struct of_device_id imx_intmux_id
[] = {
355 { .compatible
= "fsl,imx-intmux", },
359 static struct platform_driver imx_intmux_driver
= {
361 .name
= "imx-intmux",
362 .of_match_table
= imx_intmux_id
,
363 .pm
= &imx_intmux_pm_ops
,
365 .probe
= imx_intmux_probe
,
366 .remove
= imx_intmux_remove
,
368 builtin_platform_driver(imx_intmux_driver
);