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/mod_devicetable.h>
54 #include <linux/of_irq.h>
55 #include <linux/platform_device.h>
56 #include <linux/spinlock.h>
57 #include <linux/pm_runtime.h>
59 #define CHANIER(n) (0x10 + (0x40 * n))
60 #define CHANIPR(n) (0x20 + (0x40 * n))
62 #define CHAN_MAX_NUM 0x8
64 struct intmux_irqchip_data
{
68 struct irq_domain
*domain
;
76 struct intmux_irqchip_data irqchip_data
[] __counted_by(channum
);
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 __ro_after_init
= {
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
, &imx_intmux_irq_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 /* Handle pure domain searches */
170 if (!fwspec
->param_count
)
171 return d
->bus_token
== bus_token
;
173 return irqchip_data
->chanidx
== fwspec
->param
[1];
176 static const struct irq_domain_ops imx_intmux_domain_ops
= {
177 .map
= imx_intmux_irq_map
,
178 .xlate
= imx_intmux_irq_xlate
,
179 .select
= imx_intmux_irq_select
,
182 static void imx_intmux_irq_handler(struct irq_desc
*desc
)
184 struct intmux_irqchip_data
*irqchip_data
= irq_desc_get_handler_data(desc
);
185 int idx
= irqchip_data
->chanidx
;
186 struct intmux_data
*data
= container_of(irqchip_data
, struct intmux_data
,
188 unsigned long irqstat
;
191 chained_irq_enter(irq_desc_get_chip(desc
), desc
);
193 /* read the interrupt source pending status of this channel */
194 irqstat
= readl_relaxed(data
->regs
+ CHANIPR(idx
));
196 for_each_set_bit(pos
, &irqstat
, 32)
197 generic_handle_domain_irq(irqchip_data
->domain
, pos
);
199 chained_irq_exit(irq_desc_get_chip(desc
), desc
);
202 static int imx_intmux_probe(struct platform_device
*pdev
)
204 struct device_node
*np
= pdev
->dev
.of_node
;
205 struct irq_domain
*domain
;
206 struct intmux_data
*data
;
210 channum
= platform_irq_count(pdev
);
211 if (channum
== -EPROBE_DEFER
) {
212 return -EPROBE_DEFER
;
213 } else if (channum
> CHAN_MAX_NUM
) {
214 dev_err(&pdev
->dev
, "supports up to %d multiplex channels\n",
219 data
= devm_kzalloc(&pdev
->dev
, struct_size(data
, irqchip_data
, channum
), GFP_KERNEL
);
223 data
->regs
= devm_platform_ioremap_resource(pdev
, 0);
224 if (IS_ERR(data
->regs
)) {
225 dev_err(&pdev
->dev
, "failed to initialize reg\n");
226 return PTR_ERR(data
->regs
);
229 data
->ipg_clk
= devm_clk_get(&pdev
->dev
, "ipg");
230 if (IS_ERR(data
->ipg_clk
))
231 return dev_err_probe(&pdev
->dev
, PTR_ERR(data
->ipg_clk
),
232 "failed to get ipg clk\n");
234 data
->channum
= channum
;
235 raw_spin_lock_init(&data
->lock
);
237 pm_runtime_get_noresume(&pdev
->dev
);
238 pm_runtime_set_active(&pdev
->dev
);
239 pm_runtime_enable(&pdev
->dev
);
241 ret
= clk_prepare_enable(data
->ipg_clk
);
243 dev_err(&pdev
->dev
, "failed to enable ipg clk: %d\n", ret
);
247 for (i
= 0; i
< channum
; i
++) {
248 data
->irqchip_data
[i
].chanidx
= i
;
250 data
->irqchip_data
[i
].irq
= irq_of_parse_and_map(np
, i
);
251 if (data
->irqchip_data
[i
].irq
<= 0) {
253 dev_err(&pdev
->dev
, "failed to get irq\n");
257 domain
= irq_domain_add_linear(np
, 32, &imx_intmux_domain_ops
,
258 &data
->irqchip_data
[i
]);
261 dev_err(&pdev
->dev
, "failed to create IRQ domain\n");
264 data
->irqchip_data
[i
].domain
= domain
;
265 irq_domain_set_pm_device(domain
, &pdev
->dev
);
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 void 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
);
308 static int imx_intmux_runtime_suspend(struct device
*dev
)
310 struct intmux_data
*data
= dev_get_drvdata(dev
);
311 struct intmux_irqchip_data
*irqchip_data
;
314 for (i
= 0; i
< data
->channum
; i
++) {
315 irqchip_data
= &data
->irqchip_data
[i
];
316 irqchip_data
->saved_reg
= readl_relaxed(data
->regs
+ CHANIER(i
));
319 clk_disable_unprepare(data
->ipg_clk
);
324 static int imx_intmux_runtime_resume(struct device
*dev
)
326 struct intmux_data
*data
= dev_get_drvdata(dev
);
327 struct intmux_irqchip_data
*irqchip_data
;
330 ret
= clk_prepare_enable(data
->ipg_clk
);
332 dev_err(dev
, "failed to enable ipg clk: %d\n", ret
);
336 for (i
= 0; i
< data
->channum
; i
++) {
337 irqchip_data
= &data
->irqchip_data
[i
];
338 writel_relaxed(irqchip_data
->saved_reg
, data
->regs
+ CHANIER(i
));
345 static const struct dev_pm_ops imx_intmux_pm_ops
= {
346 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
347 pm_runtime_force_resume
)
348 SET_RUNTIME_PM_OPS(imx_intmux_runtime_suspend
,
349 imx_intmux_runtime_resume
, NULL
)
352 static const struct of_device_id imx_intmux_id
[] = {
353 { .compatible
= "fsl,imx-intmux", },
357 static struct platform_driver imx_intmux_driver
= {
359 .name
= "imx-intmux",
360 .of_match_table
= imx_intmux_id
,
361 .pm
= &imx_intmux_pm_ops
,
363 .probe
= imx_intmux_probe
,
364 .remove
= imx_intmux_remove
,
366 builtin_platform_driver(imx_intmux_driver
);