[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260113125315.359967-3-biju.das.jz@bp.renesas.com>
Date: Tue, 13 Jan 2026 12:53:12 +0000
From: Biju <biju.das.au@...il.com>
To: Thomas Gleixner <tglx@...nel.org>
Cc: Biju Das <biju.das.jz@...renesas.com>,
Fabrizio Castro <fabrizio.castro.jz@...esas.com>,
linux-kernel@...r.kernel.org,
Geert Uytterhoeven <geert+renesas@...der.be>,
Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@...renesas.com>,
Biju Das <biju.das.au@...il.com>,
linux-renesas-soc@...r.kernel.org
Subject: [PATCH 2/2] irqchip/renesas-rzv2h: Add suspend/resume support
From: Biju Das <biju.das.jz@...renesas.com>
On RZ/G3E using PSCI, s2ram powers down the SoC. Add suspend/resume
callbacks to restore IRQ type for NMI, TINT and external IRQ interrupts.
Signed-off-by: Biju Das <biju.das.jz@...renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 60 +++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 9b4565375e83..6fc9e96d3169 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -20,6 +20,7 @@
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
/* DT "interrupts" indexes */
#define ICU_IRQ_START 1
@@ -89,6 +90,18 @@
#define ICU_RZG3E_TSSEL_MAX_VAL 0x8c
#define ICU_RZV2H_TSSEL_MAX_VAL 0x55
+/**
+ * struct rzv2h_irqc_reg_cache - registers cache (necessary for suspend/resume)
+ * @nitsr: ICU_NITSR register
+ * @iitsr: ICU_IITSR register
+ * @titsr: ICU_TITSR registers
+ */
+struct rzv2h_irqc_reg_cache {
+ u32 nitsr;
+ u32 iitsr;
+ u32 titsr[2];
+};
+
/**
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
* @tssel_lut: TINT lookup table
@@ -118,13 +131,15 @@ struct rzv2h_hw_info {
* @fwspec: IRQ firmware specific data
* @lock: Lock to serialize access to hardware registers
* @info: Pointer to struct rzv2h_hw_info
+ * @cache: Registers cache for suspend/resume
*/
-struct rzv2h_icu_priv {
+static struct rzv2h_icu_priv {
void __iomem *base;
struct irq_fwspec fwspec[ICU_NUM_IRQ];
raw_spinlock_t lock;
const struct rzv2h_hw_info *info;
-};
+ struct rzv2h_irqc_reg_cache cache;
+} *rzv2h_icu_data;
void rzv2h_icu_register_dma_req(struct platform_device *icu_dev, u8 dmac_index, u8 dmac_channel,
u16 req_no)
@@ -419,6 +434,44 @@ static int rzv2h_icu_set_type(struct irq_data *d, unsigned int type)
return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
}
+static int rzv2h_irqc_irq_suspend(void *data)
+{
+ struct rzv2h_irqc_reg_cache *cache = &rzv2h_icu_data->cache;
+ void __iomem *base = rzv2h_icu_data->base;
+
+ cache->nitsr = readl_relaxed(base + ICU_NITSR);
+ cache->iitsr = readl_relaxed(base + ICU_IITSR);
+ for (u8 i = 0; i < 2; i++)
+ cache->titsr[i] = readl_relaxed(base + rzv2h_icu_data->info->t_offs + ICU_TITSR(i));
+
+ return 0;
+}
+
+static void rzv2h_irqc_irq_resume(void *data)
+{
+ struct rzv2h_irqc_reg_cache *cache = &rzv2h_icu_data->cache;
+ void __iomem *base = rzv2h_icu_data->base;
+
+ /*
+ * Restore only interrupt type. TSSRx will be restored at the
+ * request of pin controller to avoid spurious interrupts due
+ * to invalid PIN states.
+ */
+ for (u8 i = 0; i < 2; i++)
+ writel_relaxed(cache->titsr[i], base + rzv2h_icu_data->info->t_offs + ICU_TITSR(i));
+ writel_relaxed(cache->iitsr, base + ICU_IITSR);
+ writel_relaxed(cache->nitsr, base + ICU_NITSR);
+}
+
+static const struct syscore_ops rzv2h_irqc_syscore_ops = {
+ .suspend = rzv2h_irqc_irq_suspend,
+ .resume = rzv2h_irqc_irq_resume,
+};
+
+static struct syscore rzv2h_irqc_syscore = {
+ .ops = &rzv2h_irqc_syscore_ops,
+};
+
static const struct irq_chip rzv2h_icu_chip = {
.name = "rzv2h-icu",
.irq_eoi = rzv2h_icu_eoi,
@@ -502,7 +555,6 @@ static int rzv2h_icu_probe_common(struct platform_device *pdev, struct device_no
{
struct irq_domain *irq_domain, *parent_domain;
struct device_node *node = pdev->dev.of_node;
- struct rzv2h_icu_priv *rzv2h_icu_data;
struct reset_control *resetn;
int ret;
@@ -560,6 +612,8 @@ static int rzv2h_icu_probe_common(struct platform_device *pdev, struct device_no
rzv2h_icu_data->info = hw_info;
+ register_syscore(&rzv2h_irqc_syscore);
+
/*
* coccicheck complains about a missing put_device call before returning, but it's a false
* positive. We still need &pdev->dev after successfully returning from this function.
--
2.43.0
Powered by blists - more mailing lists