Lines Matching +full:imx +full:- +full:irqsteer
1 // SPDX-License-Identifier: GPL-2.0+
45 return (data->reg_num - irqnum / 32 - 1); in imx_irqsteer_get_reg_index()
50 struct irqsteer_data *data = d->chip_data; in imx_irqsteer_irq_unmask()
51 int idx = imx_irqsteer_get_reg_index(data, d->hwirq); in imx_irqsteer_irq_unmask()
55 raw_spin_lock_irqsave(&data->lock, flags); in imx_irqsteer_irq_unmask()
56 val = readl_relaxed(data->regs + CHANMASK(idx, data->reg_num)); in imx_irqsteer_irq_unmask()
57 val |= BIT(d->hwirq % 32); in imx_irqsteer_irq_unmask()
58 writel_relaxed(val, data->regs + CHANMASK(idx, data->reg_num)); in imx_irqsteer_irq_unmask()
59 raw_spin_unlock_irqrestore(&data->lock, flags); in imx_irqsteer_irq_unmask()
64 struct irqsteer_data *data = d->chip_data; in imx_irqsteer_irq_mask()
65 int idx = imx_irqsteer_get_reg_index(data, d->hwirq); in imx_irqsteer_irq_mask()
69 raw_spin_lock_irqsave(&data->lock, flags); in imx_irqsteer_irq_mask()
70 val = readl_relaxed(data->regs + CHANMASK(idx, data->reg_num)); in imx_irqsteer_irq_mask()
71 val &= ~BIT(d->hwirq % 32); in imx_irqsteer_irq_mask()
72 writel_relaxed(val, data->regs + CHANMASK(idx, data->reg_num)); in imx_irqsteer_irq_mask()
73 raw_spin_unlock_irqrestore(&data->lock, flags); in imx_irqsteer_irq_mask()
78 struct irqsteer_data *data = d->chip_data; in imx_irqsteer_irq_bus_lock()
80 pm_runtime_get_sync(data->dev); in imx_irqsteer_irq_bus_lock()
85 struct irqsteer_data *data = d->chip_data; in imx_irqsteer_irq_bus_sync_unlock()
87 pm_runtime_put_autosuspend(data->dev); in imx_irqsteer_irq_bus_sync_unlock()
91 .name = "irqsteer",
102 irq_set_chip_data(irq, h->host_data); in imx_irqsteer_irq_map()
117 for (i = 0; i < data->irq_count; i++) { in imx_irqsteer_get_hwirq_base()
118 if (data->irq[i] == irq) in imx_irqsteer_get_hwirq_base()
122 return -EINVAL; in imx_irqsteer_get_hwirq_base()
146 if (hwirq >= data->reg_num * 32) in imx_irqsteer_irq_handler()
149 irqmap = readl_relaxed(data->regs + in imx_irqsteer_irq_handler()
150 CHANSTATUS(idx, data->reg_num)); in imx_irqsteer_irq_handler()
153 generic_handle_domain_irq(data->domain, pos + hwirq); in imx_irqsteer_irq_handler()
161 struct device_node *np = pdev->dev.of_node; in imx_irqsteer_probe()
166 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); in imx_irqsteer_probe()
168 return -ENOMEM; in imx_irqsteer_probe()
170 data->dev = &pdev->dev; in imx_irqsteer_probe()
171 data->regs = devm_platform_ioremap_resource(pdev, 0); in imx_irqsteer_probe()
172 if (IS_ERR(data->regs)) { in imx_irqsteer_probe()
173 dev_err(&pdev->dev, "failed to initialize reg\n"); in imx_irqsteer_probe()
174 return PTR_ERR(data->regs); in imx_irqsteer_probe()
177 data->ipg_clk = devm_clk_get(&pdev->dev, "ipg"); in imx_irqsteer_probe()
178 if (IS_ERR(data->ipg_clk)) in imx_irqsteer_probe()
179 return dev_err_probe(&pdev->dev, PTR_ERR(data->ipg_clk), in imx_irqsteer_probe()
182 raw_spin_lock_init(&data->lock); in imx_irqsteer_probe()
184 ret = of_property_read_u32(np, "fsl,num-irqs", &irqs_num); in imx_irqsteer_probe()
187 ret = of_property_read_u32(np, "fsl,channel", &data->channel); in imx_irqsteer_probe()
195 data->irq_count = DIV_ROUND_UP(irqs_num, 64); in imx_irqsteer_probe()
196 data->reg_num = irqs_num / 32; in imx_irqsteer_probe()
199 data->saved_reg = devm_kzalloc(&pdev->dev, in imx_irqsteer_probe()
200 sizeof(u32) * data->reg_num, in imx_irqsteer_probe()
202 if (!data->saved_reg) in imx_irqsteer_probe()
203 return -ENOMEM; in imx_irqsteer_probe()
206 ret = clk_prepare_enable(data->ipg_clk); in imx_irqsteer_probe()
208 dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); in imx_irqsteer_probe()
213 writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); in imx_irqsteer_probe()
215 data->domain = irq_domain_add_linear(np, data->reg_num * 32, in imx_irqsteer_probe()
217 if (!data->domain) { in imx_irqsteer_probe()
218 dev_err(&pdev->dev, "failed to create IRQ domain\n"); in imx_irqsteer_probe()
219 ret = -ENOMEM; in imx_irqsteer_probe()
222 irq_domain_set_pm_device(data->domain, &pdev->dev); in imx_irqsteer_probe()
224 if (!data->irq_count || data->irq_count > CHAN_MAX_OUTPUT_INT) { in imx_irqsteer_probe()
225 ret = -EINVAL; in imx_irqsteer_probe()
229 for (i = 0; i < data->irq_count; i++) { in imx_irqsteer_probe()
230 data->irq[i] = irq_of_parse_and_map(np, i); in imx_irqsteer_probe()
231 if (!data->irq[i]) { in imx_irqsteer_probe()
232 ret = -EINVAL; in imx_irqsteer_probe()
236 irq_set_chained_handler_and_data(data->irq[i], in imx_irqsteer_probe()
243 pm_runtime_set_active(&pdev->dev); in imx_irqsteer_probe()
244 pm_runtime_enable(&pdev->dev); in imx_irqsteer_probe()
248 clk_disable_unprepare(data->ipg_clk); in imx_irqsteer_probe()
257 for (i = 0; i < irqsteer_data->irq_count; i++) in imx_irqsteer_remove()
258 irq_set_chained_handler_and_data(irqsteer_data->irq[i], in imx_irqsteer_remove()
261 irq_domain_remove(irqsteer_data->domain); in imx_irqsteer_remove()
263 clk_disable_unprepare(irqsteer_data->ipg_clk); in imx_irqsteer_remove()
271 for (i = 0; i < data->reg_num; i++) in imx_irqsteer_save_regs()
272 data->saved_reg[i] = readl_relaxed(data->regs + in imx_irqsteer_save_regs()
273 CHANMASK(i, data->reg_num)); in imx_irqsteer_save_regs()
280 writel_relaxed(BIT(data->channel), data->regs + CHANCTRL); in imx_irqsteer_restore_regs()
281 for (i = 0; i < data->reg_num; i++) in imx_irqsteer_restore_regs()
282 writel_relaxed(data->saved_reg[i], in imx_irqsteer_restore_regs()
283 data->regs + CHANMASK(i, data->reg_num)); in imx_irqsteer_restore_regs()
291 clk_disable_unprepare(irqsteer_data->ipg_clk); in imx_irqsteer_suspend()
301 ret = clk_prepare_enable(irqsteer_data->ipg_clk); in imx_irqsteer_resume()
320 { .compatible = "fsl,imx-irqsteer", },
326 .name = "imx-irqsteer",