* [PATCH 0/3] irqchip/renesas-rzt2h: support error and software-triggered interrupts
@ 2026-05-20 20:31 Cosmin Tanislav
2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Cosmin Tanislav @ 2026-05-20 20:31 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: Cosmin Tanislav, linux-kernel
The Renesas RZ/T2H ICU is able to report errors for CA55, GIC, and
various IPs. It also supports software-triggerable interrupts.
Add support for these two features, and, while at it, also fix a runtime
PM issue in the probe error path.
Both the error interrupts and software-triggered interrupts are handled
similarly to the RZ/V2H implementation.
Cosmin Tanislav (3):
irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path
irqchip/renesas-rzt2h: add software-triggered interrupts support
irqchip/renesas-rzt2h: add error interrupts support
drivers/irqchip/irq-renesas-rzt2h.c | 279 +++++++++++++++++++++++++++-
1 file changed, 275 insertions(+), 4 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path 2026-05-20 20:31 [PATCH 0/3] irqchip/renesas-rzt2h: support error and software-triggered interrupts Cosmin Tanislav @ 2026-05-20 20:31 ` Cosmin Tanislav 2026-05-21 9:50 ` [tip: irq/urgent] irqchip/renesas-rzt2h: Use " tip-bot2 for Cosmin Tanislav 2026-05-21 18:17 ` tip-bot2 for Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 2/3] irqchip/renesas-rzt2h: add software-triggered interrupts support Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 3/3] irqchip/renesas-rzt2h: add error " Cosmin Tanislav 2 siblings, 2 replies; 8+ messages in thread From: Cosmin Tanislav @ 2026-05-20 20:31 UTC (permalink / raw) To: Thomas Gleixner; +Cc: Cosmin Tanislav, linux-kernel pm_runtime_put() may trigger the idle check after pm_runtime_disable() is run as part of devm_pm_runtime_enable()'s cleanup action, leaving runtime PM active. Use pm_runtime_put_sync() to ensure the idle check runs synchronously. Fixes: 13e7b3305b64 ("irqchip: Add RZ/{T2H,N2H} Interrupt Controller (ICU) driver") Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- drivers/irqchip/irq-renesas-rzt2h.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index 53cf80e1155a..ecb69da55508 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -265,7 +265,7 @@ static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *pare irq_domain = irq_domain_create_hierarchy(parent_domain, 0, RZT2H_ICU_NUM_IRQ, dev_fwnode(dev), &rzt2h_icu_domain_ops, priv); if (!irq_domain) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); return -ENOMEM; } -- 2.54.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: irq/urgent] irqchip/renesas-rzt2h: Use pm_runtime_put_sync() in probe error path 2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav @ 2026-05-21 9:50 ` tip-bot2 for Cosmin Tanislav 2026-05-21 18:17 ` tip-bot2 for Cosmin Tanislav 1 sibling, 0 replies; 8+ messages in thread From: tip-bot2 for Cosmin Tanislav @ 2026-05-21 9:50 UTC (permalink / raw) To: linux-tip-commits Cc: Cosmin Tanislav, Thomas Gleixner, x86, linux-kernel, maz The following commit has been merged into the irq/urgent branch of tip: Commit-ID: b3b8fce2173a6e9c07a67e69b032e72564c3ccff Gitweb: https://git.kernel.org/tip/b3b8fce2173a6e9c07a67e69b032e72564c3ccff Author: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> AuthorDate: Wed, 20 May 2026 23:31:15 +03:00 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Thu, 21 May 2026 11:48:30 +02:00 irqchip/renesas-rzt2h: Use pm_runtime_put_sync() in probe error path pm_runtime_put() may trigger the idle check after pm_runtime_disable() is run as part of devm_pm_runtime_enable()'s cleanup action, leaving runtime PM active. Use pm_runtime_put_sync() to ensure the idle check runs synchronously. Fixes: 13e7b3305b64 ("irqchip: Add RZ/{T2H,N2H} Interrupt Controller (ICU) driver") Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260520203117.1516442-2-cosmin-gabriel.tanislav.xa@renesas.com --- drivers/irqchip/irq-renesas-rzt2h.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index 53cf80e..ecb69da 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -265,7 +265,7 @@ static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *pare irq_domain = irq_domain_create_hierarchy(parent_domain, 0, RZT2H_ICU_NUM_IRQ, dev_fwnode(dev), &rzt2h_icu_domain_ops, priv); if (!irq_domain) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); return -ENOMEM; } ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: irq/urgent] irqchip/renesas-rzt2h: Use pm_runtime_put_sync() in probe error path 2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav 2026-05-21 9:50 ` [tip: irq/urgent] irqchip/renesas-rzt2h: Use " tip-bot2 for Cosmin Tanislav @ 2026-05-21 18:17 ` tip-bot2 for Cosmin Tanislav 1 sibling, 0 replies; 8+ messages in thread From: tip-bot2 for Cosmin Tanislav @ 2026-05-21 18:17 UTC (permalink / raw) To: linux-tip-commits Cc: Cosmin Tanislav, Thomas Gleixner, x86, linux-kernel, maz The following commit has been merged into the irq/urgent branch of tip: Commit-ID: c9b7598eb013c6dbf2526dc050364bd8dc24f0d3 Gitweb: https://git.kernel.org/tip/c9b7598eb013c6dbf2526dc050364bd8dc24f0d3 Author: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> AuthorDate: Wed, 20 May 2026 23:31:15 +03:00 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Thu, 21 May 2026 20:11:29 +02:00 irqchip/renesas-rzt2h: Use pm_runtime_put_sync() in probe error path pm_runtime_put() may trigger the idle check after pm_runtime_disable() is run as part of devm_pm_runtime_enable()'s cleanup action, leaving runtime PM active. Use pm_runtime_put_sync() to ensure the idle check runs synchronously. Fixes: 13e7b3305b64 ("irqchip: Add RZ/{T2H,N2H} Interrupt Controller (ICU) driver") Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260520203117.1516442-2-cosmin-gabriel.tanislav.xa@renesas.com --- drivers/irqchip/irq-renesas-rzt2h.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index 53cf80e..ecb69da 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -265,7 +265,7 @@ static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *pare irq_domain = irq_domain_create_hierarchy(parent_domain, 0, RZT2H_ICU_NUM_IRQ, dev_fwnode(dev), &rzt2h_icu_domain_ops, priv); if (!irq_domain) { - pm_runtime_put(dev); + pm_runtime_put_sync(dev); return -ENOMEM; } ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] irqchip/renesas-rzt2h: add software-triggered interrupts support 2026-05-20 20:31 [PATCH 0/3] irqchip/renesas-rzt2h: support error and software-triggered interrupts Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav @ 2026-05-20 20:31 ` Cosmin Tanislav 2026-06-03 16:29 ` [tip: irq/drivers] irqchip/renesas-rzt2h: Add " tip-bot2 for Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 3/3] irqchip/renesas-rzt2h: add error " Cosmin Tanislav 2 siblings, 1 reply; 8+ messages in thread From: Cosmin Tanislav @ 2026-05-20 20:31 UTC (permalink / raw) To: Thomas Gleixner; +Cc: Cosmin Tanislav, linux-kernel The Renesas RZ/T2H ICU supports software-triggerable interrupts. Add a dedicated rzt2h_icu_intcpu_chip irq_chip which implements rzt2h_icu_intcpu_set_irqchip_state() to allow injecting these interrupts. Request the INTCPU IRQs when IRQ injection is enabled to report them when they occur. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- drivers/irqchip/irq-renesas-rzt2h.c | 133 +++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index ecb69da55508..3fd0381efa32 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -2,6 +2,7 @@ #include <linux/bitfield.h> #include <linux/err.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <linux/irqchip.h> #include <linux/irqchip/irq-renesas-rzt2h.h> @@ -40,6 +41,9 @@ ((n) >= RZT2H_ICU_##type##_START && \ (n) < RZT2H_ICU_##type##_START + RZT2H_ICU_##type##_COUNT) +#define RZT2H_ICU_SWINT 0x0 +#define RZT2H_ICU_SWINT_IC_MASK(i) BIT(i) + #define RZT2H_ICU_PORTNF_MD 0xc #define RZT2H_ICU_PORTNF_MDi_MASK(i) (GENMASK(1, 0) << ((i) * 2)) #define RZT2H_ICU_PORTNF_MDi_PREP(i, val) (FIELD_PREP(GENMASK(1, 0), val) << ((i) * 2)) @@ -99,6 +103,12 @@ static inline int rzt2h_icu_irq_to_offset(struct irq_data *d, void __iomem **bas } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, IRQ_S) || RZT2H_ICU_IRQ_IN_RANGE(hwirq, SEI)) { *offset = hwirq - RZT2H_ICU_IRQ_S_START; *base = priv->base_s; + } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_NS)) { + *offset = hwirq - RZT2H_ICU_INTCPU_NS_START; + *base = priv->base_ns; + } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_S)) { + *offset = hwirq - RZT2H_ICU_INTCPU_S_START; + *base = priv->base_s; } else { return -EINVAL; } @@ -164,6 +174,28 @@ static int rzt2h_icu_set_type(struct irq_data *d, unsigned int type) return irq_chip_set_type_parent(d, IRQ_TYPE_EDGE_RISING); } +static int rzt2h_icu_intcpu_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, + bool state) +{ + unsigned int offset; + void __iomem *base; + int ret; + + if (which != IRQCHIP_STATE_PENDING) + return irq_chip_set_parent_state(d, which, state); + + if (!state) + return 0; + + ret = rzt2h_icu_irq_to_offset(d, &base, &offset); + if (ret) + return ret; + + writel_relaxed(RZT2H_ICU_SWINT_IC_MASK(offset), base + RZT2H_ICU_SWINT); + + return 0; +} + static const struct irq_chip rzt2h_icu_chip = { .name = "rzt2h-icu", .irq_mask = irq_chip_mask_parent, @@ -180,10 +212,27 @@ static const struct irq_chip rzt2h_icu_chip = { IRQCHIP_SKIP_SET_WAKE, }; +static const struct irq_chip rzt2h_icu_intcpu_chip = { + .name = "rzt2h-icu", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = irq_chip_set_wake_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = rzt2h_icu_intcpu_set_irqchip_state, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE, +}; + static int rzt2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { struct rzt2h_icu_priv *priv = domain->host_data; + const struct irq_chip *chip; irq_hw_number_t hwirq; unsigned int type; int ret; @@ -192,7 +241,13 @@ static int rzt2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigne if (ret) return ret; - ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &rzt2h_icu_chip, NULL); + if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_NS) || + RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_S)) + chip = &rzt2h_icu_intcpu_chip; + else + chip = &rzt2h_icu_chip; + + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, NULL); if (ret) return ret; @@ -222,6 +277,68 @@ static int rzt2h_icu_parse_interrupts(struct rzt2h_icu_priv *priv, struct device return 0; } +static irqreturn_t rzt2h_icu_intcpu_irq(int irq, void *data) +{ + unsigned int intcpu = (uintptr_t)data; + + pr_info("INTCPU%u software interrupt\n", intcpu); + + return IRQ_HANDLED; +} + +static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domain *irq_domain, + unsigned int start, unsigned int count, irq_handler_t handler, + void *data) +{ + struct device *dev = &pdev->dev; + unsigned int offset, virq; + struct irq_fwspec fwspec; + int ret; + + for (offset = start; offset < start + count; offset++) { + fwspec.fwnode = irq_domain->fwnode; + fwspec.param_count = 2; + fwspec.param[0] = offset; + fwspec.param[1] = IRQ_TYPE_EDGE_RISING; + + virq = irq_create_fwspec_mapping(&fwspec); + if (!virq) { + return dev_err_probe(dev, -EINVAL, + "Failed to create IRQ %u mapping\n", offset); + } + + ret = devm_request_irq(dev, virq, handler, 0, dev_name(dev), + data ?: (void *)(uintptr_t)offset); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ %u\n", offset); + } + + return 0; +} + +static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain *irq_domain) +{ + int ret; + + if (IS_ENABLED(CONFIG_GENERIC_IRQ_INJECTION)) { + ret = rzt2h_icu_request_irqs(pdev, irq_domain, + RZT2H_ICU_INTCPU_NS_START, + RZT2H_ICU_INTCPU_NS_COUNT, + rzt2h_icu_intcpu_irq, NULL); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, + RZT2H_ICU_INTCPU_S_START, + RZT2H_ICU_INTCPU_S_COUNT, + rzt2h_icu_intcpu_irq, NULL); + if (ret) + return ret; + } + + return 0; +} + static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *parent) { struct irq_domain *irq_domain, *parent_domain; @@ -265,11 +382,21 @@ static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *pare irq_domain = irq_domain_create_hierarchy(parent_domain, 0, RZT2H_ICU_NUM_IRQ, dev_fwnode(dev), &rzt2h_icu_domain_ops, priv); if (!irq_domain) { - pm_runtime_put_sync(dev); - return -ENOMEM; + ret = -ENOMEM; + goto err_pm_put; } + ret = rzt2h_icu_setup_irqs(pdev, irq_domain); + if (ret) + goto err_irq_domain_free; + return 0; + +err_irq_domain_free: + irq_domain_remove(irq_domain); +err_pm_put: + pm_runtime_put_sync(dev); + return ret; } IRQCHIP_PLATFORM_DRIVER_BEGIN(rzt2h_icu) -- 2.54.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: irq/drivers] irqchip/renesas-rzt2h: Add software-triggered interrupts support 2026-05-20 20:31 ` [PATCH 2/3] irqchip/renesas-rzt2h: add software-triggered interrupts support Cosmin Tanislav @ 2026-06-03 16:29 ` tip-bot2 for Cosmin Tanislav 0 siblings, 0 replies; 8+ messages in thread From: tip-bot2 for Cosmin Tanislav @ 2026-06-03 16:29 UTC (permalink / raw) To: linux-tip-commits; +Cc: Cosmin Tanislav, Thomas Gleixner, x86, linux-kernel The following commit has been merged into the irq/drivers branch of tip: Commit-ID: a964dabc28a18fe62ff79e734cf54167ed322134 Gitweb: https://git.kernel.org/tip/a964dabc28a18fe62ff79e734cf54167ed322134 Author: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> AuthorDate: Wed, 20 May 2026 23:31:16 +03:00 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Wed, 03 Jun 2026 18:27:05 +02:00 irqchip/renesas-rzt2h: Add software-triggered interrupts support The Renesas RZ/T2H ICU supports software-triggerable interrupts. Add a dedicated rzt2h_icu_intcpu_chip irq_chip which implements rzt2h_icu_intcpu_set_irqchip_state() to allow injecting these interrupts. Request the INTCPU IRQs when IRQ injection is enabled to report them when they occur. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260520203117.1516442-3-cosmin-gabriel.tanislav.xa@renesas.com --- drivers/irqchip/irq-renesas-rzt2h.c | 123 ++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index ecb69da..f7813d3 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -2,6 +2,7 @@ #include <linux/bitfield.h> #include <linux/err.h> +#include <linux/interrupt.h> #include <linux/io.h> #include <linux/irqchip.h> #include <linux/irqchip/irq-renesas-rzt2h.h> @@ -40,6 +41,9 @@ ((n) >= RZT2H_ICU_##type##_START && \ (n) < RZT2H_ICU_##type##_START + RZT2H_ICU_##type##_COUNT) +#define RZT2H_ICU_SWINT 0x0 +#define RZT2H_ICU_SWINT_IC_MASK(i) BIT(i) + #define RZT2H_ICU_PORTNF_MD 0xc #define RZT2H_ICU_PORTNF_MDi_MASK(i) (GENMASK(1, 0) << ((i) * 2)) #define RZT2H_ICU_PORTNF_MDi_PREP(i, val) (FIELD_PREP(GENMASK(1, 0), val) << ((i) * 2)) @@ -99,6 +103,12 @@ static inline int rzt2h_icu_irq_to_offset(struct irq_data *d, void __iomem **bas } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, IRQ_S) || RZT2H_ICU_IRQ_IN_RANGE(hwirq, SEI)) { *offset = hwirq - RZT2H_ICU_IRQ_S_START; *base = priv->base_s; + } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_NS)) { + *offset = hwirq - RZT2H_ICU_INTCPU_NS_START; + *base = priv->base_ns; + } else if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_S)) { + *offset = hwirq - RZT2H_ICU_INTCPU_S_START; + *base = priv->base_s; } else { return -EINVAL; } @@ -164,6 +174,28 @@ static int rzt2h_icu_set_type(struct irq_data *d, unsigned int type) return irq_chip_set_type_parent(d, IRQ_TYPE_EDGE_RISING); } +static int rzt2h_icu_intcpu_set_irqchip_state(struct irq_data *d, enum irqchip_irq_state which, + bool state) +{ + unsigned int offset; + void __iomem *base; + int ret; + + if (which != IRQCHIP_STATE_PENDING) + return irq_chip_set_parent_state(d, which, state); + + if (!state) + return 0; + + ret = rzt2h_icu_irq_to_offset(d, &base, &offset); + if (ret) + return ret; + + writel_relaxed(RZT2H_ICU_SWINT_IC_MASK(offset), base + RZT2H_ICU_SWINT); + + return 0; +} + static const struct irq_chip rzt2h_icu_chip = { .name = "rzt2h-icu", .irq_mask = irq_chip_mask_parent, @@ -180,10 +212,27 @@ static const struct irq_chip rzt2h_icu_chip = { IRQCHIP_SKIP_SET_WAKE, }; +static const struct irq_chip rzt2h_icu_intcpu_chip = { + .name = "rzt2h-icu", + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = irq_chip_set_wake_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = rzt2h_icu_intcpu_set_irqchip_state, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SET_TYPE_MASKED | + IRQCHIP_SKIP_SET_WAKE, +}; + static int rzt2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { struct rzt2h_icu_priv *priv = domain->host_data; + const struct irq_chip *chip; irq_hw_number_t hwirq; unsigned int type; int ret; @@ -192,7 +241,12 @@ static int rzt2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigne if (ret) return ret; - ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &rzt2h_icu_chip, NULL); + if (RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_NS) || RZT2H_ICU_IRQ_IN_RANGE(hwirq, INTCPU_S)) + chip = &rzt2h_icu_intcpu_chip; + else + chip = &rzt2h_icu_chip; + + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, chip, NULL); if (ret) return ret; @@ -222,6 +276,60 @@ static int rzt2h_icu_parse_interrupts(struct rzt2h_icu_priv *priv, struct device return 0; } +static irqreturn_t rzt2h_icu_intcpu_irq(int irq, void *data) +{ + unsigned int intcpu = (uintptr_t)data; + + pr_info("INTCPU%u software interrupt\n", intcpu); + return IRQ_HANDLED; +} + +static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domain *irq_domain, + unsigned int start, unsigned int count, irq_handler_t handler, + void *data) +{ + struct device *dev = &pdev->dev; + unsigned int offset, virq; + struct irq_fwspec fwspec; + int ret; + + for (offset = start; offset < start + count; offset++) { + fwspec.fwnode = irq_domain->fwnode; + fwspec.param_count = 2; + fwspec.param[0] = offset; + fwspec.param[1] = IRQ_TYPE_EDGE_RISING; + + virq = irq_create_fwspec_mapping(&fwspec); + if (!virq) + return dev_err_probe(dev, -EINVAL, "Failed to create IRQ %u mapping\n", offset); + + ret = devm_request_irq(dev, virq, handler, 0, dev_name(dev), + data ?: (void *)(uintptr_t)offset); + if (ret) + return dev_err_probe(dev, ret, "Failed to request IRQ %u\n", offset); + } + + return 0; +} + +static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain *irq_domain) +{ + if (IS_ENABLED(CONFIG_GENERIC_IRQ_INJECTION)) { + int ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_INTCPU_NS_START, + RZT2H_ICU_INTCPU_NS_COUNT, rzt2h_icu_intcpu_irq, + NULL); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_INTCPU_S_START, + RZT2H_ICU_INTCPU_S_COUNT, rzt2h_icu_intcpu_irq, NULL); + if (ret) + return ret; + } + + return 0; +} + static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *parent) { struct irq_domain *irq_domain, *parent_domain; @@ -265,11 +373,20 @@ static int rzt2h_icu_init(struct platform_device *pdev, struct device_node *pare irq_domain = irq_domain_create_hierarchy(parent_domain, 0, RZT2H_ICU_NUM_IRQ, dev_fwnode(dev), &rzt2h_icu_domain_ops, priv); if (!irq_domain) { - pm_runtime_put_sync(dev); - return -ENOMEM; + ret = -ENOMEM; + goto err_pm_put; } + ret = rzt2h_icu_setup_irqs(pdev, irq_domain); + if (ret) + goto err_irq_domain_free; return 0; + +err_irq_domain_free: + irq_domain_remove(irq_domain); +err_pm_put: + pm_runtime_put_sync(dev); + return ret; } IRQCHIP_PLATFORM_DRIVER_BEGIN(rzt2h_icu) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] irqchip/renesas-rzt2h: add error interrupts support 2026-05-20 20:31 [PATCH 0/3] irqchip/renesas-rzt2h: support error and software-triggered interrupts Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 2/3] irqchip/renesas-rzt2h: add software-triggered interrupts support Cosmin Tanislav @ 2026-05-20 20:31 ` Cosmin Tanislav 2026-06-03 16:29 ` [tip: irq/drivers] irqchip/renesas-rzt2h: Add " tip-bot2 for Cosmin Tanislav 2 siblings, 1 reply; 8+ messages in thread From: Cosmin Tanislav @ 2026-05-20 20:31 UTC (permalink / raw) To: Thomas Gleixner; +Cc: Cosmin Tanislav, linux-kernel The Renesas RZ/T2H ICU is able to report errors for CA55, GIC, and various IPs. Unmask these errors, request the IRQs and report them when they occur. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> --- drivers/irqchip/irq-renesas-rzt2h.c | 146 +++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index 3fd0381efa32..b04ea7a00b2c 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -31,11 +31,36 @@ RZT2H_ICU_IRQ_S_COUNT) #define RZT2H_ICU_SEI_COUNT 1 +#define RZT2H_ICU_CA55_ERR_START (RZT2H_ICU_SEI_START + \ + RZT2H_ICU_SEI_COUNT) +#define RZT2H_ICU_CA55_ERR_COUNT 2 + +#define RZT2H_ICU_CR52_ERR_START (RZT2H_ICU_CA55_ERR_START + \ + RZT2H_ICU_CA55_ERR_COUNT) +#define RZT2H_ICU_CR52_ERR_COUNT 4 + +#define RZT2H_ICU_PERI_ERR_START (RZT2H_ICU_CR52_ERR_START + \ + RZT2H_ICU_CR52_ERR_COUNT) +#define RZT2H_ICU_PERI_ERR_COUNT 2 + +#define RZT2H_ICU_DSMIF_ERR_START (RZT2H_ICU_PERI_ERR_START + \ + RZT2H_ICU_PERI_ERR_COUNT) +#define RZT2H_ICU_DSMIF_ERR_COUNT 2 + +#define RZT2H_ICU_ENCIF_ERR_START (RZT2H_ICU_DSMIF_ERR_START + \ + RZT2H_ICU_DSMIF_ERR_COUNT) +#define RZT2H_ICU_ENCIF_ERR_COUNT 2 + #define RZT2H_ICU_NUM_IRQ (RZT2H_ICU_INTCPU_NS_COUNT + \ RZT2H_ICU_INTCPU_S_COUNT + \ RZT2H_ICU_IRQ_NS_COUNT + \ RZT2H_ICU_IRQ_S_COUNT + \ - RZT2H_ICU_SEI_COUNT) + RZT2H_ICU_SEI_COUNT + \ + RZT2H_ICU_CA55_ERR_COUNT + \ + RZT2H_ICU_CR52_ERR_COUNT + \ + RZT2H_ICU_PERI_ERR_COUNT + \ + RZT2H_ICU_DSMIF_ERR_COUNT + \ + RZT2H_ICU_ENCIF_ERR_COUNT) #define RZT2H_ICU_IRQ_IN_RANGE(n, type) \ ((n) >= RZT2H_ICU_##type##_START && \ @@ -53,6 +78,29 @@ #define RZT2H_ICU_MD_RISING_EDGE 0b10 #define RZT2H_ICU_MD_BOTH_EDGES 0b11 +#define RZT2H_ICU_CA55ERR_E0MSK 0x50 +#define RZT2H_ICU_CA55ERR_CLR 0x60 +#define RZT2H_ICU_CA55ERR_STAT 0x64 +#define RZT2H_ICU_CA55ERR_MASK GENMASK(12, 0) + +#define RZT2H_ICU_PERIERR_E0MSKn(n) (0x98 + 0x4 * (n)) +#define RZT2H_ICU_PERIERR_CLRn(n) (0xc8 + 0x4 * (n)) +#define RZT2H_ICU_PERIERR_STAT 0xd4 +#define RZT2H_ICU_PERIERR_NUM 3 +#define RZT2H_ICU_PERIERR_MASK GENMASK(31, 0) + +#define RZT2H_ICU_DSMIFERR_E0MSKn(n) (0xe0 + 0x4 * (n)) +#define RZT2H_ICU_DSMIFERR_CLRn(n) (0x1a0 + 0x4 * (n)) +#define RZT2H_ICU_DSMIFERR_STAT 0x1d0 +#define RZT2H_ICU_DSMIFERR_NUM 12 +#define RZT2H_ICU_DSMIFERR_MASK GENMASK(31, 0) + +#define RZT2H_ICU_ENCIFERR_E0MSKn(n) (0x200 + 0x4 * (n)) +#define RZT2H_ICU_ENCIFERR_CLRn(n) (0x250 + 0x4 * (n)) +#define RZT2H_ICU_ENCIFERR_STAT 0x264 +#define RZT2H_ICU_ENCIFERR_NUM 5 +#define RZT2H_ICU_ENCIFERR_MASK GENMASK(31, 0) + #define RZT2H_ICU_DMACn_RSSELi(n, i) (0x7d0 + 0x18 * (n) + 0x4 * (i)) #define RZT2H_ICU_DMAC_REQ_SELx_MASK(x) (GENMASK(9, 0) << ((x) * 10)) #define RZT2H_ICU_DMAC_REQ_SELx_PREP(x, val) (FIELD_PREP(GENMASK(9, 0), val) << ((x) * 10)) @@ -286,6 +334,52 @@ static irqreturn_t rzt2h_icu_intcpu_irq(int irq, void *data) return IRQ_HANDLED; } +static irqreturn_t rzt2h_icu_err_irq(struct rzt2h_icu_priv *priv, const char *name, + unsigned int num, u32 stat_base, u32 clr_base) +{ + bool handled = false; + + for (unsigned int n = 0; n < num; n++) { + u32 stat = readl(priv->base_ns + stat_base + n * 0x4); + + if (!stat) + continue; + + handled = true; + + pr_err("rzt2h-icu: %s error n=%u status=0x%08x\n", + name, n, stat); + + writel_relaxed(stat, priv->base_ns + clr_base + n * 0x4); + } + + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t rzt2h_icu_ca55_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "CA55", 1, + RZT2H_ICU_CA55ERR_STAT, RZT2H_ICU_CA55ERR_CLR); +} + +static irqreturn_t rzt2h_icu_peri_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "peripheral", RZT2H_ICU_PERIERR_NUM, + RZT2H_ICU_PERIERR_STAT, RZT2H_ICU_PERIERR_CLRn(0)); +} + +static irqreturn_t rzt2h_icu_dsmif_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "DSMIF", RZT2H_ICU_DSMIFERR_NUM, + RZT2H_ICU_DSMIFERR_STAT, RZT2H_ICU_DSMIFERR_CLRn(0)); +} + +static irqreturn_t rzt2h_icu_encif_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "ENCIF", RZT2H_ICU_ENCIFERR_NUM, + RZT2H_ICU_ENCIFERR_STAT, RZT2H_ICU_ENCIFERR_CLRn(0)); +} + static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domain *irq_domain, unsigned int start, unsigned int count, irq_handler_t handler, void *data) @@ -318,6 +412,8 @@ static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domai static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain *irq_domain) { + struct rzt2h_icu_priv *priv = platform_get_drvdata(pdev); + unsigned int n; int ret; if (IS_ENABLED(CONFIG_GENERIC_IRQ_INJECTION)) { @@ -336,6 +432,54 @@ static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain return ret; } + /* + * There are two error interrupts and two error masks that can be used + * separately for each error type. It would not be very useful to + * receive two interrupts for the same error, so use only the first one. + */ + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_CA55_ERR_START, 1, + rzt2h_icu_ca55_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_PERI_ERR_START, 1, + rzt2h_icu_peri_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_DSMIF_ERR_START, 1, + rzt2h_icu_dsmif_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_ENCIF_ERR_START, 1, + rzt2h_icu_encif_err_irq, priv); + if (ret) + return ret; + + /* Clear and unmask CA55 error events */ + writel_relaxed(RZT2H_ICU_CA55ERR_MASK, priv->base_ns + RZT2H_ICU_CA55ERR_CLR); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_CA55ERR_E0MSK); + + /* Clear and unmask peripheral error events */ + for (n = 0; n < RZT2H_ICU_PERIERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_PERIERR_MASK, priv->base_ns + RZT2H_ICU_PERIERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_PERIERR_E0MSKn(n)); + } + + /* Clear and unmask DSMIF error events */ + for (n = 0; n < RZT2H_ICU_DSMIFERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_DSMIFERR_MASK, priv->base_ns + RZT2H_ICU_DSMIFERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_DSMIFERR_E0MSKn(n)); + } + + /* Clear and unmask ENCIF error events */ + for (n = 0; n < RZT2H_ICU_ENCIFERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_ENCIFERR_MASK, priv->base_ns + RZT2H_ICU_ENCIFERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_ENCIFERR_E0MSKn(n)); + } + return 0; } -- 2.54.0 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: irq/drivers] irqchip/renesas-rzt2h: Add error interrupts support 2026-05-20 20:31 ` [PATCH 3/3] irqchip/renesas-rzt2h: add error " Cosmin Tanislav @ 2026-06-03 16:29 ` tip-bot2 for Cosmin Tanislav 0 siblings, 0 replies; 8+ messages in thread From: tip-bot2 for Cosmin Tanislav @ 2026-06-03 16:29 UTC (permalink / raw) To: linux-tip-commits; +Cc: Cosmin Tanislav, Thomas Gleixner, x86, linux-kernel The following commit has been merged into the irq/drivers branch of tip: Commit-ID: 8d721c08dd67af96664ce381f6b2790d15de7213 Gitweb: https://git.kernel.org/tip/8d721c08dd67af96664ce381f6b2790d15de7213 Author: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> AuthorDate: Wed, 20 May 2026 23:31:17 +03:00 Committer: Thomas Gleixner <tglx@kernel.org> CommitterDate: Wed, 03 Jun 2026 18:27:05 +02:00 irqchip/renesas-rzt2h: Add error interrupts support The Renesas RZ/T2H ICU is able to report errors for CA55, GIC, and various IPs. Unmask these errors, request the IRQs and report them when they occur. Signed-off-by: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260520203117.1516442-4-cosmin-gabriel.tanislav.xa@renesas.com --- drivers/irqchip/irq-renesas-rzt2h.c | 151 ++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-renesas-rzt2h.c b/drivers/irqchip/irq-renesas-rzt2h.c index f7813d3..e06264a 100644 --- a/drivers/irqchip/irq-renesas-rzt2h.c +++ b/drivers/irqchip/irq-renesas-rzt2h.c @@ -31,11 +31,36 @@ RZT2H_ICU_IRQ_S_COUNT) #define RZT2H_ICU_SEI_COUNT 1 +#define RZT2H_ICU_CA55_ERR_START (RZT2H_ICU_SEI_START + \ + RZT2H_ICU_SEI_COUNT) +#define RZT2H_ICU_CA55_ERR_COUNT 2 + +#define RZT2H_ICU_CR52_ERR_START (RZT2H_ICU_CA55_ERR_START + \ + RZT2H_ICU_CA55_ERR_COUNT) +#define RZT2H_ICU_CR52_ERR_COUNT 4 + +#define RZT2H_ICU_PERI_ERR_START (RZT2H_ICU_CR52_ERR_START + \ + RZT2H_ICU_CR52_ERR_COUNT) +#define RZT2H_ICU_PERI_ERR_COUNT 2 + +#define RZT2H_ICU_DSMIF_ERR_START (RZT2H_ICU_PERI_ERR_START + \ + RZT2H_ICU_PERI_ERR_COUNT) +#define RZT2H_ICU_DSMIF_ERR_COUNT 2 + +#define RZT2H_ICU_ENCIF_ERR_START (RZT2H_ICU_DSMIF_ERR_START + \ + RZT2H_ICU_DSMIF_ERR_COUNT) +#define RZT2H_ICU_ENCIF_ERR_COUNT 2 + #define RZT2H_ICU_NUM_IRQ (RZT2H_ICU_INTCPU_NS_COUNT + \ RZT2H_ICU_INTCPU_S_COUNT + \ RZT2H_ICU_IRQ_NS_COUNT + \ RZT2H_ICU_IRQ_S_COUNT + \ - RZT2H_ICU_SEI_COUNT) + RZT2H_ICU_SEI_COUNT + \ + RZT2H_ICU_CA55_ERR_COUNT + \ + RZT2H_ICU_CR52_ERR_COUNT + \ + RZT2H_ICU_PERI_ERR_COUNT + \ + RZT2H_ICU_DSMIF_ERR_COUNT + \ + RZT2H_ICU_ENCIF_ERR_COUNT) #define RZT2H_ICU_IRQ_IN_RANGE(n, type) \ ((n) >= RZT2H_ICU_##type##_START && \ @@ -53,6 +78,29 @@ #define RZT2H_ICU_MD_RISING_EDGE 0b10 #define RZT2H_ICU_MD_BOTH_EDGES 0b11 +#define RZT2H_ICU_CA55ERR_E0MSK 0x50 +#define RZT2H_ICU_CA55ERR_CLR 0x60 +#define RZT2H_ICU_CA55ERR_STAT 0x64 +#define RZT2H_ICU_CA55ERR_MASK GENMASK(12, 0) + +#define RZT2H_ICU_PERIERR_E0MSKn(n) (0x98 + 0x4 * (n)) +#define RZT2H_ICU_PERIERR_CLRn(n) (0xc8 + 0x4 * (n)) +#define RZT2H_ICU_PERIERR_STAT 0xd4 +#define RZT2H_ICU_PERIERR_NUM 3 +#define RZT2H_ICU_PERIERR_MASK GENMASK(31, 0) + +#define RZT2H_ICU_DSMIFERR_E0MSKn(n) (0xe0 + 0x4 * (n)) +#define RZT2H_ICU_DSMIFERR_CLRn(n) (0x1a0 + 0x4 * (n)) +#define RZT2H_ICU_DSMIFERR_STAT 0x1d0 +#define RZT2H_ICU_DSMIFERR_NUM 12 +#define RZT2H_ICU_DSMIFERR_MASK GENMASK(31, 0) + +#define RZT2H_ICU_ENCIFERR_E0MSKn(n) (0x200 + 0x4 * (n)) +#define RZT2H_ICU_ENCIFERR_CLRn(n) (0x250 + 0x4 * (n)) +#define RZT2H_ICU_ENCIFERR_STAT 0x264 +#define RZT2H_ICU_ENCIFERR_NUM 5 +#define RZT2H_ICU_ENCIFERR_MASK GENMASK(31, 0) + #define RZT2H_ICU_DMACn_RSSELi(n, i) (0x7d0 + 0x18 * (n) + 0x4 * (i)) #define RZT2H_ICU_DMAC_REQ_SELx_MASK(x) (GENMASK(9, 0) << ((x) * 10)) #define RZT2H_ICU_DMAC_REQ_SELx_PREP(x, val) (FIELD_PREP(GENMASK(9, 0), val) << ((x) * 10)) @@ -284,6 +332,50 @@ static irqreturn_t rzt2h_icu_intcpu_irq(int irq, void *data) return IRQ_HANDLED; } +static irqreturn_t rzt2h_icu_err_irq(struct rzt2h_icu_priv *priv, const char *name, + unsigned int num, u32 stat_base, u32 clr_base) +{ + bool handled = false; + + for (unsigned int n = 0; n < num; n++) { + u32 stat = readl(priv->base_ns + stat_base + n * 0x4); + + if (!stat) + continue; + + handled = true; + + pr_err("rzt2h-icu: %s error n=%u status=0x%08x\n", name, n, stat); + + writel_relaxed(stat, priv->base_ns + clr_base + n * 0x4); + } + + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static irqreturn_t rzt2h_icu_ca55_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "CA55", 1, RZT2H_ICU_CA55ERR_STAT, RZT2H_ICU_CA55ERR_CLR); +} + +static irqreturn_t rzt2h_icu_peri_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "peripheral", RZT2H_ICU_PERIERR_NUM, RZT2H_ICU_PERIERR_STAT, + RZT2H_ICU_PERIERR_CLRn(0)); +} + +static irqreturn_t rzt2h_icu_dsmif_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "DSMIF", RZT2H_ICU_DSMIFERR_NUM, RZT2H_ICU_DSMIFERR_STAT, + RZT2H_ICU_DSMIFERR_CLRn(0)); +} + +static irqreturn_t rzt2h_icu_encif_err_irq(int irq, void *data) +{ + return rzt2h_icu_err_irq(data, "ENCIF", RZT2H_ICU_ENCIFERR_NUM, RZT2H_ICU_ENCIFERR_STAT, + RZT2H_ICU_ENCIFERR_CLRn(0)); +} + static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domain *irq_domain, unsigned int start, unsigned int count, irq_handler_t handler, void *data) @@ -314,10 +406,13 @@ static int rzt2h_icu_request_irqs(struct platform_device *pdev, struct irq_domai static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain *irq_domain) { + struct rzt2h_icu_priv *priv = platform_get_drvdata(pdev); + unsigned int n; + int ret; + if (IS_ENABLED(CONFIG_GENERIC_IRQ_INJECTION)) { - int ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_INTCPU_NS_START, - RZT2H_ICU_INTCPU_NS_COUNT, rzt2h_icu_intcpu_irq, - NULL); + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_INTCPU_NS_START, + RZT2H_ICU_INTCPU_NS_COUNT, rzt2h_icu_intcpu_irq, NULL); if (ret) return ret; @@ -327,6 +422,54 @@ static int rzt2h_icu_setup_irqs(struct platform_device *pdev, struct irq_domain return ret; } + /* + * There are two error interrupts and two error masks that can be used + * separately for each error type. It would not be very useful to + * receive two interrupts for the same error, so use only the first one. + */ + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_CA55_ERR_START, 1, + rzt2h_icu_ca55_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_PERI_ERR_START, 1, + rzt2h_icu_peri_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_DSMIF_ERR_START, 1, + rzt2h_icu_dsmif_err_irq, priv); + if (ret) + return ret; + + ret = rzt2h_icu_request_irqs(pdev, irq_domain, RZT2H_ICU_ENCIF_ERR_START, 1, + rzt2h_icu_encif_err_irq, priv); + if (ret) + return ret; + + /* Clear and unmask CA55 error events */ + writel_relaxed(RZT2H_ICU_CA55ERR_MASK, priv->base_ns + RZT2H_ICU_CA55ERR_CLR); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_CA55ERR_E0MSK); + + /* Clear and unmask peripheral error events */ + for (n = 0; n < RZT2H_ICU_PERIERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_PERIERR_MASK, priv->base_ns + RZT2H_ICU_PERIERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_PERIERR_E0MSKn(n)); + } + + /* Clear and unmask DSMIF error events */ + for (n = 0; n < RZT2H_ICU_DSMIFERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_DSMIFERR_MASK, priv->base_ns + RZT2H_ICU_DSMIFERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_DSMIFERR_E0MSKn(n)); + } + + /* Clear and unmask ENCIF error events */ + for (n = 0; n < RZT2H_ICU_ENCIFERR_NUM; n++) { + writel_relaxed(RZT2H_ICU_ENCIFERR_MASK, priv->base_ns + RZT2H_ICU_ENCIFERR_CLRn(n)); + writel_relaxed(0, priv->base_ns + RZT2H_ICU_ENCIFERR_E0MSKn(n)); + } + return 0; } ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-06-03 16:29 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-05-20 20:31 [PATCH 0/3] irqchip/renesas-rzt2h: support error and software-triggered interrupts Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 1/3] irqchip/renesas-rzt2h: use pm_runtime_put_sync() in probe error path Cosmin Tanislav 2026-05-21 9:50 ` [tip: irq/urgent] irqchip/renesas-rzt2h: Use " tip-bot2 for Cosmin Tanislav 2026-05-21 18:17 ` tip-bot2 for Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 2/3] irqchip/renesas-rzt2h: add software-triggered interrupts support Cosmin Tanislav 2026-06-03 16:29 ` [tip: irq/drivers] irqchip/renesas-rzt2h: Add " tip-bot2 for Cosmin Tanislav 2026-05-20 20:31 ` [PATCH 3/3] irqchip/renesas-rzt2h: add error " Cosmin Tanislav 2026-06-03 16:29 ` [tip: irq/drivers] irqchip/renesas-rzt2h: Add " tip-bot2 for Cosmin Tanislav
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®