Lines Matching +full:irqc +full:- +full:rzg2l

1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas RZ/G2L IRQC Driver
7 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
63 * struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
73 * struct rzg2l_irqc_priv - IRQ controller private data structure
90 return data->domain->host_data; in irq_data_to_priv()
95 unsigned int hw_irq = hwirq - IRQC_IRQ_START; in rzg2l_clear_irq_int()
99 iscr = readl_relaxed(priv->base + ISCR); in rzg2l_clear_irq_int()
100 iitsr = readl_relaxed(priv->base + IITSR); in rzg2l_clear_irq_int()
103 * ISCR can only be cleared if the type is falling-edge, rising-edge or in rzg2l_clear_irq_int()
104 * falling/rising-edge. in rzg2l_clear_irq_int()
107 writel_relaxed(iscr & ~bit, priv->base + ISCR); in rzg2l_clear_irq_int()
112 readl_relaxed(priv->base + ISCR); in rzg2l_clear_irq_int()
118 u32 bit = BIT(hwirq - IRQC_TINT_START); in rzg2l_clear_tint_int()
121 reg = readl_relaxed(priv->base + TSCR); in rzg2l_clear_tint_int()
123 writel_relaxed(reg & ~bit, priv->base + TSCR); in rzg2l_clear_tint_int()
128 readl_relaxed(priv->base + TSCR); in rzg2l_clear_tint_int()
137 raw_spin_lock(&priv->lock); in rzg2l_irqc_eoi()
142 raw_spin_unlock(&priv->lock); in rzg2l_irqc_eoi()
149 u32 bit = BIT(hwirq - IRQC_IRQ_START); in rzfive_irqc_mask_irq_interrupt()
151 writel_relaxed(readl_relaxed(priv->base + IMSK) | bit, priv->base + IMSK); in rzfive_irqc_mask_irq_interrupt()
157 u32 bit = BIT(hwirq - IRQC_IRQ_START); in rzfive_irqc_unmask_irq_interrupt()
159 writel_relaxed(readl_relaxed(priv->base + IMSK) & ~bit, priv->base + IMSK); in rzfive_irqc_unmask_irq_interrupt()
165 u32 bit = BIT(hwirq - IRQC_TINT_START); in rzfive_irqc_mask_tint_interrupt()
167 writel_relaxed(readl_relaxed(priv->base + TMSK) | bit, priv->base + TMSK); in rzfive_irqc_mask_tint_interrupt()
173 u32 bit = BIT(hwirq - IRQC_TINT_START); in rzfive_irqc_unmask_tint_interrupt()
175 writel_relaxed(readl_relaxed(priv->base + TMSK) & ~bit, priv->base + TMSK); in rzfive_irqc_unmask_tint_interrupt()
183 raw_spin_lock(&priv->lock); in rzfive_irqc_mask()
188 raw_spin_unlock(&priv->lock); in rzfive_irqc_mask()
197 raw_spin_lock(&priv->lock); in rzfive_irqc_unmask()
202 raw_spin_unlock(&priv->lock); in rzfive_irqc_unmask()
212 u32 offset = hwirq - IRQC_TINT_START; in rzfive_tint_irq_endisable()
217 raw_spin_lock(&priv->lock); in rzfive_tint_irq_endisable()
222 reg = readl_relaxed(priv->base + TSSR(tssr_index)); in rzfive_tint_irq_endisable()
227 writel_relaxed(reg, priv->base + TSSR(tssr_index)); in rzfive_tint_irq_endisable()
228 raw_spin_unlock(&priv->lock); in rzfive_tint_irq_endisable()
230 raw_spin_lock(&priv->lock); in rzfive_tint_irq_endisable()
235 raw_spin_unlock(&priv->lock); in rzfive_tint_irq_endisable()
257 u32 offset = hw_irq - IRQC_TINT_START; in rzg2l_tint_irq_endisable()
262 raw_spin_lock(&priv->lock); in rzg2l_tint_irq_endisable()
263 reg = readl_relaxed(priv->base + TSSR(tssr_index)); in rzg2l_tint_irq_endisable()
268 writel_relaxed(reg, priv->base + TSSR(tssr_index)); in rzg2l_tint_irq_endisable()
269 raw_spin_unlock(&priv->lock); in rzg2l_tint_irq_endisable()
289 u32 iitseln = hwirq - IRQC_IRQ_START; in rzg2l_irq_set_type()
314 return -EINVAL; in rzg2l_irq_set_type()
317 raw_spin_lock(&priv->lock); in rzg2l_irq_set_type()
318 tmp = readl_relaxed(priv->base + IITSR); in rzg2l_irq_set_type()
323 writel_relaxed(tmp, priv->base + IITSR); in rzg2l_irq_set_type()
324 raw_spin_unlock(&priv->lock); in rzg2l_irq_set_type()
339 writel_relaxed(reg, priv->base + TSSR(tssr_index)); in rzg2l_disable_tint_and_set_tint_source()
348 u32 titseln = hwirq - IRQC_TINT_START; in rzg2l_tint_set_edge()
364 return -EINVAL; in rzg2l_tint_set_edge()
369 titseln -= TITSR0_MAX_INT; in rzg2l_tint_set_edge()
373 raw_spin_lock(&priv->lock); in rzg2l_tint_set_edge()
374 tssr = readl_relaxed(priv->base + TSSR(tssr_index)); in rzg2l_tint_set_edge()
376 reg = readl_relaxed(priv->base + TITSR(index)); in rzg2l_tint_set_edge()
379 writel_relaxed(reg, priv->base + TITSR(index)); in rzg2l_tint_set_edge()
381 writel_relaxed(tssr, priv->base + TSSR(tssr_index)); in rzg2l_tint_set_edge()
382 raw_spin_unlock(&priv->lock); in rzg2l_tint_set_edge()
390 int ret = -EINVAL; in rzg2l_irqc_set_type()
404 struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache; in rzg2l_irqc_irq_suspend()
405 void __iomem *base = rzg2l_irqc_data->base; in rzg2l_irqc_irq_suspend()
407 cache->iitsr = readl_relaxed(base + IITSR); in rzg2l_irqc_irq_suspend()
409 cache->titsr[i] = readl_relaxed(base + TITSR(i)); in rzg2l_irqc_irq_suspend()
416 struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache; in rzg2l_irqc_irq_resume()
417 void __iomem *base = rzg2l_irqc_data->base; in rzg2l_irqc_irq_resume()
425 writel_relaxed(cache->titsr[i], base + TITSR(i)); in rzg2l_irqc_irq_resume()
426 writel_relaxed(cache->iitsr, base + IITSR); in rzg2l_irqc_irq_resume()
435 .name = "rzg2l-irqc",
452 .name = "rzfive-irqc",
471 struct rzg2l_irqc_priv *priv = domain->host_data; in rzg2l_irqc_alloc()
482 * For TINT interrupts ie where pinctrl driver is child of irqc domain in rzg2l_irqc_alloc()
483 * the hwirq and TINT are encoded in fwspec->param[0]. in rzg2l_irqc_alloc()
484 * hwirq for TINT range from 9-40, hwirq is embedded 0-15 bits and TINT in rzg2l_irqc_alloc()
485 * from 16-31 bits. TINT from the pinctrl driver needs to be programmed in rzg2l_irqc_alloc()
486 * in IRQC registers to enable a given gpio pin as interrupt. in rzg2l_irqc_alloc()
493 return -EINVAL; in rzg2l_irqc_alloc()
496 if (hwirq > (IRQC_NUM_IRQ - 1)) in rzg2l_irqc_alloc()
497 return -EINVAL; in rzg2l_irqc_alloc()
499 ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, priv->irqchip, in rzg2l_irqc_alloc()
504 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &priv->fwspec[hwirq]); in rzg2l_irqc_alloc()
525 &priv->fwspec[i]); in rzg2l_irqc_parse_interrupts()
535 struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL; in rzg2l_irqc_common_init()
541 return -ENODEV; in rzg2l_irqc_common_init()
545 dev_err(&pdev->dev, "cannot find parent domain\n"); in rzg2l_irqc_common_init()
546 return -ENODEV; in rzg2l_irqc_common_init()
549 rzg2l_irqc_data = devm_kzalloc(&pdev->dev, sizeof(*rzg2l_irqc_data), GFP_KERNEL); in rzg2l_irqc_common_init()
551 return -ENOMEM; in rzg2l_irqc_common_init()
553 rzg2l_irqc_data->irqchip = irq_chip; in rzg2l_irqc_common_init()
555 rzg2l_irqc_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); in rzg2l_irqc_common_init()
556 if (IS_ERR(rzg2l_irqc_data->base)) in rzg2l_irqc_common_init()
557 return PTR_ERR(rzg2l_irqc_data->base); in rzg2l_irqc_common_init()
561 dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret); in rzg2l_irqc_common_init()
565 resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL); in rzg2l_irqc_common_init()
571 dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret); in rzg2l_irqc_common_init()
575 pm_runtime_enable(&pdev->dev); in rzg2l_irqc_common_init()
576 ret = pm_runtime_resume_and_get(&pdev->dev); in rzg2l_irqc_common_init()
578 dev_err(&pdev->dev, "pm_runtime_resume_and_get failed: %d\n", ret); in rzg2l_irqc_common_init()
582 raw_spin_lock_init(&rzg2l_irqc_data->lock); in rzg2l_irqc_common_init()
588 dev_err(&pdev->dev, "failed to add irq domain\n"); in rzg2l_irqc_common_init()
589 ret = -ENOMEM; in rzg2l_irqc_common_init()
609 pm_runtime_put(&pdev->dev); in rzg2l_irqc_common_init()
611 pm_runtime_disable(&pdev->dev); in rzg2l_irqc_common_init()
629 IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init)
630 IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_init)
632 MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
633 MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver");