Lines Matching +full:parent +full:- +full:interrupt +full:- +full:base

1 // SPDX-License-Identifier: GPL-2.0
5 * Based on irq-renesas-rzg2l.c
18 #include <linux/irqchip/irq-renesas-rzv2h.h>
74 ICU_TSSR_TSSEL_PREP((GENMASK(((_field_width) - 2), 0)), (n), _field_width); \
80 BIT((_field_width) - 1) << ((n) * (_field_width)); \
96 * struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
119 * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
120 * @base: Controller's base address
126 void __iomem *base; member
145 guard(raw_spinlock_irqsave)(&priv->lock); in rzv2h_icu_register_dma_req()
147 icu_dmksely = readl(priv->base + ICU_DMkSELy(dmac_index, y)); in rzv2h_icu_register_dma_req()
149 writel(icu_dmksely, priv->base + ICU_DMkSELy(dmac_index, y)); in rzv2h_icu_register_dma_req()
155 return data->domain->host_data; in irq_data_to_priv()
165 scoped_guard(raw_spinlock, &priv->lock) { in rzv2h_icu_eoi()
167 tintirq_nr = hw_irq - ICU_TINT_START; in rzv2h_icu_eoi()
170 writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); in rzv2h_icu_eoi()
172 tintirq_nr = hw_irq - ICU_IRQ_START; in rzv2h_icu_eoi()
175 writel_relaxed(bit, priv->base + ICU_ISCLR); in rzv2h_icu_eoi()
177 writel_relaxed(ICU_NSCLR_NCLR, priv->base + ICU_NSCLR); in rzv2h_icu_eoi()
194 tint_nr = hw_irq - ICU_TINT_START; in rzv2h_tint_irq_endisable()
195 nr_tint = 32 / priv->info->field_width; in rzv2h_tint_irq_endisable()
199 guard(raw_spinlock)(&priv->lock); in rzv2h_tint_irq_endisable()
200 tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k)); in rzv2h_tint_irq_endisable()
202 tssr |= ICU_TSSR_TIEN(tssel_n, priv->info->field_width); in rzv2h_tint_irq_endisable()
204 tssr &= ~ICU_TSSR_TIEN(tssel_n, priv->info->field_width); in rzv2h_tint_irq_endisable()
205 writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k)); in rzv2h_tint_irq_endisable()
209 * interrupt. Clear the status flag after setting the ICU_TSSRk in rzv2h_tint_irq_endisable()
213 writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR); in rzv2h_tint_irq_endisable()
243 return -EINVAL; in rzv2h_nmi_set_type()
246 writel_relaxed(sense, priv->base + ICU_NITSR); in rzv2h_nmi_set_type()
253 unsigned int irq_nr = hwirq - ICU_IRQ_START; in rzv2h_clear_irq_int()
257 isctr = readl_relaxed(priv->base + ICU_ISCTR); in rzv2h_clear_irq_int()
258 iitsr = readl_relaxed(priv->base + ICU_IITSR); in rzv2h_clear_irq_int()
262 * When level sensing is used, the interrupt flag gets automatically cleared when the in rzv2h_clear_irq_int()
263 * interrupt signal is de-asserted by the source of the interrupt request, therefore clear in rzv2h_clear_irq_int()
264 * the interrupt only for edge triggered interrupts. in rzv2h_clear_irq_int()
267 writel_relaxed(bit, priv->base + ICU_ISCLR); in rzv2h_clear_irq_int()
274 u32 irq_nr = hwirq - ICU_IRQ_START; in rzv2h_irq_set_type()
295 return -EINVAL; in rzv2h_irq_set_type()
298 guard(raw_spinlock)(&priv->lock); in rzv2h_irq_set_type()
299 iitsr = readl_relaxed(priv->base + ICU_IITSR); in rzv2h_irq_set_type()
303 writel_relaxed(iitsr, priv->base + ICU_IITSR); in rzv2h_irq_set_type()
310 unsigned int tint_nr = hwirq - ICU_TINT_START; in rzv2h_clear_tint_int()
316 tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR); in rzv2h_clear_tint_int()
317 titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k)); in rzv2h_clear_tint_int()
322 * TSTATn = 1b and if it's a rising edge or a falling edge interrupt. in rzv2h_clear_tint_int()
326 writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); in rzv2h_clear_tint_int()
357 return -EINVAL; in rzv2h_tint_set_type()
362 if (tint > priv->info->max_tssel) in rzv2h_tint_set_type()
363 return -EINVAL; in rzv2h_tint_set_type()
365 if (priv->info->tssel_lut) in rzv2h_tint_set_type()
366 tint = priv->info->tssel_lut[tint]; in rzv2h_tint_set_type()
369 tint_nr = hwirq - ICU_TINT_START; in rzv2h_tint_set_type()
371 nr_tint = 32 / priv->info->field_width; in rzv2h_tint_set_type()
374 tien = ICU_TSSR_TIEN(tssel_n, priv->info->field_width); in rzv2h_tint_set_type()
379 guard(raw_spinlock)(&priv->lock); in rzv2h_tint_set_type()
381 tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); in rzv2h_tint_set_type()
382 tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien); in rzv2h_tint_set_type()
383 tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width); in rzv2h_tint_set_type()
385 writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); in rzv2h_tint_set_type()
387 titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); in rzv2h_tint_set_type()
391 writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); in rzv2h_tint_set_type()
395 writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); in rzv2h_tint_set_type()
419 .name = "rzv2h-icu",
436 struct rzv2h_icu_priv *priv = domain->host_data; in rzv2h_icu_alloc()
448 * fwspec->param[0]. in rzv2h_icu_alloc()
449 * hwirq is embedded in bits 0-15. in rzv2h_icu_alloc()
450 * TINT is embedded in bits 16-31. in rzv2h_icu_alloc()
457 return -EINVAL; in rzv2h_icu_alloc()
460 if (hwirq > (ICU_NUM_IRQ - 1)) in rzv2h_icu_alloc()
461 return -EINVAL; in rzv2h_icu_alloc()
468 return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &priv->fwspec[hwirq]); in rzv2h_icu_alloc()
488 of_phandle_args_to_fwspec(np, map.args, map.args_count, &priv->fwspec[i]); in rzv2h_icu_parse_interrupts()
499 static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent, in rzv2h_icu_init_common() argument
510 return -ENODEV; in rzv2h_icu_init_common()
512 ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device, in rzv2h_icu_init_common()
513 &pdev->dev); in rzv2h_icu_init_common()
517 parent_domain = irq_find_host(parent); in rzv2h_icu_init_common()
519 dev_err(&pdev->dev, "cannot find parent domain\n"); in rzv2h_icu_init_common()
520 return -ENODEV; in rzv2h_icu_init_common()
523 rzv2h_icu_data = devm_kzalloc(&pdev->dev, sizeof(*rzv2h_icu_data), GFP_KERNEL); in rzv2h_icu_init_common()
525 return -ENOMEM; in rzv2h_icu_init_common()
529 rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); in rzv2h_icu_init_common()
530 if (IS_ERR(rzv2h_icu_data->base)) in rzv2h_icu_init_common()
531 return PTR_ERR(rzv2h_icu_data->base); in rzv2h_icu_init_common()
535 dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret); in rzv2h_icu_init_common()
539 resetn = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL); in rzv2h_icu_init_common()
542 dev_err(&pdev->dev, "failed to acquire deasserted reset: %d\n", ret); in rzv2h_icu_init_common()
546 ret = devm_pm_runtime_enable(&pdev->dev); in rzv2h_icu_init_common()
548 dev_err(&pdev->dev, "devm_pm_runtime_enable failed, %d\n", ret); in rzv2h_icu_init_common()
552 ret = pm_runtime_resume_and_get(&pdev->dev); in rzv2h_icu_init_common()
554 dev_err(&pdev->dev, "pm_runtime_resume_and_get failed: %d\n", ret); in rzv2h_icu_init_common()
558 raw_spin_lock_init(&rzv2h_icu_data->lock); in rzv2h_icu_init_common()
564 dev_err(&pdev->dev, "failed to add irq domain\n"); in rzv2h_icu_init_common()
565 ret = -ENOMEM; in rzv2h_icu_init_common()
569 rzv2h_icu_data->info = hw_info; in rzv2h_icu_init_common()
573 * positive. We still need &pdev->dev after successfully returning from this function. in rzv2h_icu_init_common()
578 pm_runtime_put(&pdev->dev); in rzv2h_icu_init_common()
583 /* Mapping based on port index on Table 4.2-6 and TSSEL bits on Table 4.6-4 */
585 81, 82, 83, 84, 85, 86, 87, 88, /* P00-P07 */
586 89, 90, 91, 92, 93, 94, 95, 96, /* P10-P17 */
587 111, 112, /* P20-P21 */
588 97, 98, 99, 100, 101, 102, 103, 104, /* P30-P37 */
589 105, 106, 107, 108, 109, 110, /* P40-P45 */
590 113, 114, 115, 116, 117, 118, 119, /* P50-P56 */
591 120, 121, 122, 123, 124, 125, 126, /* P60-P66 */
592 127, 128, 129, 130, 131, 132, 133, 134, /* P70-P77 */
593 135, 136, 137, 138, 139, 140, /* P80-P85 */
594 43, 44, 45, 46, 47, 48, 49, 50, /* PA0-PA7 */
595 51, 52, 53, 54, 55, 56, 57, 58, /* PB0-PB7 */
596 59, 60, 61, /* PC0-PC2 */
597 62, 63, 64, 65, 66, 67, 68, 69, /* PD0-PD7 */
598 70, 71, 72, 73, 74, 75, 76, 77, /* PE0-PE7 */
599 78, 79, 80, /* PF0-PF2 */
600 25, 26, 27, 28, 29, 30, 31, 32, /* PG0-PG7 */
601 33, 34, 35, 36, 37, 38, /* PH0-PH5 */
602 4, 5, 6, 7, 8, /* PJ0-PJ4 */
603 39, 40, 41, 42, /* PK0-PK3 */
604 9, 10, 11, 12, 21, 22, 23, 24, /* PL0-PL7 */
605 13, 14, 15, 16, 17, 18, 19, 20, /* PM0-PM7 */
606 0, 1, 2, 3 /* PS0-PS3 */
622 static int rzg3e_icu_init(struct device_node *node, struct device_node *parent) in rzg3e_icu_init() argument
624 return rzv2h_icu_init_common(node, parent, &rzg3e_hw_params); in rzg3e_icu_init()
627 static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) in rzv2h_icu_init() argument
629 return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params); in rzv2h_icu_init()
633 IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_init)
634 IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)