All of lore.kernel.org
 help / color / mirror / Atom feed
From: "tip-bot2 for Claudiu Beznea" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	x86@kernel.org, linux-kernel@vger.kernel.org, maz@kernel.org
Subject: [tip: irq/core] irqchip/renesas-rzg2l: Add support for suspend to RAM
Date: Fri, 08 Dec 2023 21:14:40 -0000	[thread overview]
Message-ID: <170207008017.398.9006634586293096788.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20231120111820.87398-8-claudiu.beznea.uj@bp.renesas.com>

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     e1f581386680631316611d554e71523a087d8f58
Gitweb:        https://git.kernel.org/tip/e1f581386680631316611d554e71523a087d8f58
Author:        Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
AuthorDate:    Mon, 20 Nov 2023 13:18:18 +02:00
Committer:     Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 08 Dec 2023 22:06:35 +01:00

irqchip/renesas-rzg2l: Add support for suspend to RAM

The irqchip-renesas-rzg2l driver is used on RZ/G3S SoC. RZ/G3S can go into
deep sleep states where power to different SoC's parts is cut off and RAM
is switched to self-refresh. The resume from these states is done with the
help of the bootloader.

The IA55 IRQ controller needs to be reconfigured when resuming from deep
sleep state. For this the IA55 registers are cached in suspend and restored
in resume.

The IA55 IRQ controller is connected to GPIO controller and GIC as follows:

                                      ┌──────────┐          ┌──────────┐
                                      │          │ SPIX     │          │
                                      │          ├─────────►│          │
                                      │          │          │          │
                                      │          │          │          │
              ┌────────┐IRQ0-7        │  IA55    │          │  GIC     │
 Pin0 ───────►│        ├─────────────►│          │          │          │
              │        │              │          │ PPIY     │          │
 ...          │  GPIO  │              │          ├─────────►│          │
              │        │GPIOINT0-127  │          │          │          │
 PinN ───────►│        ├─────────────►│          │          │          │
              └────────┘              └──────────┘          └──────────┘

where:
  - Pin0 is the first GPIO controller pin
  - PinN is the last GPIO controller pin

  - SPIX is the SPI interrupt with identifier X
  - PPIY is the PPI interrupt with identifier Y

Implement suspend/resume functionality with syscore_ops to be able to
cache/restore the registers after/before the GPIO controller suspend/resume
functions are invoked.

As the syscore_ops suspend/resume functions do not take any argument make
the driver private data static so it can be accessed from the
suspend/resume functions.

The IA55 interrupt controller is resumed before the GPIO controller. As
GPIO pins could be in an a state which causes spurious interrupts, the
reconfiguration of the interrupt controller is restricted to restore the
interrupt type and leave them disabled.

An eventually required interrupt enable operation will be done as part of
the GPIO controller resume function after restoring the GPIO state.

[ tglx: Massaged changelog ]

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20231120111820.87398-8-claudiu.beznea.uj@bp.renesas.com

---
 drivers/irqchip/irq-renesas-rzg2l.c | 68 +++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 34add75..9494fc2 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -18,6 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
 #include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
 
 #define IRQC_IRQ_START			1
 #define IRQC_IRQ_COUNT			8
@@ -56,16 +57,28 @@
 #define TINT_EXTRACT_GPIOINT(x)		FIELD_GET(GENMASK(31, 16), (x))
 
 /**
+ * struct rzg2l_irqc_reg_cache - registers cache (necessary for suspend/resume)
+ * @iitsr: IITSR register
+ * @titsr: TITSR registers
+ */
+struct rzg2l_irqc_reg_cache {
+	u32	iitsr;
+	u32	titsr[2];
+};
+
+/**
  * struct rzg2l_irqc_priv - IRQ controller private data structure
  * @base:	Controller's base address
  * @fwspec:	IRQ firmware specific data
  * @lock:	Lock to serialize access to hardware registers
+ * @cache:	Registers cache for suspend/resume
  */
-struct rzg2l_irqc_priv {
+static struct rzg2l_irqc_priv {
 	void __iomem			*base;
 	struct irq_fwspec		fwspec[IRQC_NUM_IRQ];
 	raw_spinlock_t			lock;
-};
+	struct rzg2l_irqc_reg_cache	cache;
+} *rzg2l_irqc_data;
 
 static struct rzg2l_irqc_priv *irq_data_to_priv(struct irq_data *data)
 {
@@ -246,6 +259,38 @@ static int rzg2l_irqc_set_type(struct irq_data *d, unsigned int type)
 	return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
 }
 
+static int rzg2l_irqc_irq_suspend(void)
+{
+	struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache;
+	void __iomem *base = rzg2l_irqc_data->base;
+
+	cache->iitsr = readl_relaxed(base + IITSR);
+	for (u8 i = 0; i < 2; i++)
+		cache->titsr[i] = readl_relaxed(base + TITSR(i));
+
+	return 0;
+}
+
+static void rzg2l_irqc_irq_resume(void)
+{
+	struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache;
+	void __iomem *base = rzg2l_irqc_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 + TITSR(i));
+	writel_relaxed(cache->iitsr, base + IITSR);
+}
+
+static struct syscore_ops rzg2l_irqc_syscore_ops = {
+	.suspend	= rzg2l_irqc_irq_suspend,
+	.resume		= rzg2l_irqc_irq_resume,
+};
+
 static const struct irq_chip irqc_chip = {
 	.name			= "rzg2l-irqc",
 	.irq_eoi		= rzg2l_irqc_eoi,
@@ -331,7 +376,6 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
 	struct irq_domain *irq_domain, *parent_domain;
 	struct platform_device *pdev;
 	struct reset_control *resetn;
-	struct rzg2l_irqc_priv *priv;
 	int ret;
 
 	pdev = of_find_device_by_node(node);
@@ -344,15 +388,15 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
 		return -ENODEV;
 	}
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
+	rzg2l_irqc_data = devm_kzalloc(&pdev->dev, sizeof(*rzg2l_irqc_data), GFP_KERNEL);
+	if (!rzg2l_irqc_data)
 		return -ENOMEM;
 
-	priv->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
-	if (IS_ERR(priv->base))
-		return PTR_ERR(priv->base);
+	rzg2l_irqc_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
+	if (IS_ERR(rzg2l_irqc_data->base))
+		return PTR_ERR(rzg2l_irqc_data->base);
 
-	ret = rzg2l_irqc_parse_interrupts(priv, node);
+	ret = rzg2l_irqc_parse_interrupts(rzg2l_irqc_data, node);
 	if (ret) {
 		dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret);
 		return ret;
@@ -375,17 +419,19 @@ static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
 		goto pm_disable;
 	}
 
-	raw_spin_lock_init(&priv->lock);
+	raw_spin_lock_init(&rzg2l_irqc_data->lock);
 
 	irq_domain = irq_domain_add_hierarchy(parent_domain, 0, IRQC_NUM_IRQ,
 					      node, &rzg2l_irqc_domain_ops,
-					      priv);
+					      rzg2l_irqc_data);
 	if (!irq_domain) {
 		dev_err(&pdev->dev, "failed to add irq domain\n");
 		ret = -ENOMEM;
 		goto pm_put;
 	}
 
+	register_syscore_ops(&rzg2l_irqc_syscore_ops);
+
 	return 0;
 
 pm_put:

  reply	other threads:[~2023-12-08 21:15 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-20 11:18 [PATCH v3 0/9] irqchip/renesas-rzg2l: add support for RZ/G3S SoC Claudiu
2023-11-20 11:18 ` [PATCH v3 1/9] clk: renesas: r9a08g045: Add IA55 pclk and its reset Claudiu
2023-11-21  9:59   ` Geert Uytterhoeven
2023-11-21 11:03     ` claudiu beznea
2023-12-13 14:11     ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-09 16:22     ` Geert Uytterhoeven
2023-11-20 11:18 ` [PATCH v3 2/9] irqchip/renesas-rzg2l: Use tabs instead of spaces Claudiu
2023-11-21 10:07   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 3/9] irqchip/renesas-rzg2l: Align struct member names to tabs Claudiu
2023-11-21 10:09   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 4/9] irqchip/renesas-rzg2l: Document structure members Claudiu
2023-11-21 10:10   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 5/9] irqchip/renesas-rzg2l: Implement restriction when writing ISCR register Claudiu
2023-11-21 10:17   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 6/9] irqchip/renesas-rzg2l: Add macro to retrieve TITSR register offset based on register's index Claudiu
2023-11-21 10:30   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 7/9] irqchip/renesas-rzg2l: Add support for suspend to RAM Claudiu
2023-12-08 21:14   ` tip-bot2 for Claudiu Beznea [this message]
2023-12-12 14:44   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 8/9] dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/G3S Claudiu
2023-11-21 10:44   ` Geert Uytterhoeven
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-12 14:44   ` tip-bot2 for Claudiu Beznea
2023-11-20 11:18 ` [PATCH v3 9/9] arm64: dts: renesas: r9108g045: Add IA55 interrupt controller node Claudiu
2023-12-08 21:14   ` [tip: irq/core] " tip-bot2 for Claudiu Beznea
2023-12-09 16:24     ` Geert Uytterhoeven
2023-12-12 14:41       ` Thomas Gleixner
2023-12-13 14:18   ` [PATCH v3 9/9] " Geert Uytterhoeven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=170207008017.398.9006634586293096788.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=claudiu.beznea.uj@bp.renesas.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.