All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] can: rcar_canfd: Add suspend/resume support
@ 2025-08-22  9:50 Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
                   ` (5 more replies)
  0 siblings, 6 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

	Hi all,

This patch series adds proper suspend/resume support to the Renesas
R-Car CAN-FD controller driver, after the customary cleanuops and fixes.
It aims to fix CAN-FD operation after resume from s2ram on systems where
PSCI powers down the SoC.

The last patch is marked RFC, as it causes a regression on R-Car Gen4.
More details can be found in that patch.

This has been tested on Ebisu-4D (R-Car E3) and White Hawk (R-Car V4H).

Thanks for your comments!

Geert Uytterhoeven (6):
  can: rcar_canfd: Invert reset assert order
  can: rcar_canfd: Invert global vs. channel teardown
  can: rcar_canfd: Extract rcar_canfd_global_{,de}init()
  can: rcar_canfd: Invert CAN clock and close_candev() order
  can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS()
  [RFC] can: rcar_canfd: Add suspend/resume support

 drivers/net/can/rcar/rcar_canfd.c | 225 ++++++++++++++++++++----------
 1 file changed, 152 insertions(+), 73 deletions(-)

-- 
2.43.0

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/6] can: rcar_canfd: Invert reset assert order
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22 14:24   ` Biju Das
  2025-09-09  6:36   ` Vincent Mailhol
  2025-08-22  9:50 ` [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown Geert Uytterhoeven
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

The two resets are asserted during cleanup in the same order as they
were deasserted during probe.  Invert the order to restore symmetry.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/net/can/rcar/rcar_canfd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index b3c8c592fb0e04ed..6f013f87f25c1494 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -2182,8 +2182,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
 fail_clk:
 	clk_disable_unprepare(gpriv->clkp);
 fail_reset:
-	reset_control_assert(gpriv->rstc1);
 	reset_control_assert(gpriv->rstc2);
+	reset_control_assert(gpriv->rstc1);
 fail_dev:
 	return err;
 }
@@ -2204,8 +2204,8 @@ static void rcar_canfd_remove(struct platform_device *pdev)
 	/* Enter global sleep mode */
 	rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
 	clk_disable_unprepare(gpriv->clkp);
-	reset_control_assert(gpriv->rstc1);
 	reset_control_assert(gpriv->rstc2);
+	reset_control_assert(gpriv->rstc1);
 }
 
 static int __maybe_unused rcar_canfd_suspend(struct device *dev)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22 14:21   ` Biju Das
  2025-09-09  6:38   ` Vincent Mailhol
  2025-08-22  9:50 ` [PATCH 3/6] can: rcar_canfd: Extract rcar_canfd_global_{,de}init() Geert Uytterhoeven
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

Global state is initialized and torn down before per-channel state.
Invert the order to restore symmetry.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/net/can/rcar/rcar_canfd.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 6f013f87f25c1494..341bc25df32a8973 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -2193,14 +2193,14 @@ static void rcar_canfd_remove(struct platform_device *pdev)
 	struct rcar_canfd_global *gpriv = platform_get_drvdata(pdev);
 	u32 ch;
 
-	rcar_canfd_reset_controller(gpriv);
-	rcar_canfd_disable_global_interrupts(gpriv);
-
 	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
 		rcar_canfd_disable_channel_interrupts(gpriv->ch[ch]);
 		rcar_canfd_channel_remove(gpriv, ch);
 	}
 
+	rcar_canfd_disable_global_interrupts(gpriv);
+	rcar_canfd_reset_controller(gpriv);
+
 	/* Enter global sleep mode */
 	rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
 	clk_disable_unprepare(gpriv->clkp);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 3/6] can: rcar_canfd: Extract rcar_canfd_global_{,de}init()
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order Geert Uytterhoeven
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

Extract the code to (de)initialize global state into separate functions,
for future reuse.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/net/can/rcar/rcar_canfd.c | 160 +++++++++++++++++-------------
 1 file changed, 93 insertions(+), 67 deletions(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 341bc25df32a8973..38c1b327f6b1d540 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1950,22 +1950,110 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch)
 	}
 }
 
+static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
+{
+	struct device *dev = &gpriv->pdev->dev;
+	u32 rule_entry = 0;
+	u32 ch, sts;
+	int err;
+
+	err = reset_control_reset(gpriv->rstc1);
+	if (err)
+		return err;
+
+	err = reset_control_reset(gpriv->rstc2);
+	if (err)
+		goto fail_reset1;
+
+	/* Enable peripheral clock for register access */
+	err = clk_prepare_enable(gpriv->clkp);
+	if (err) {
+		dev_err(dev, "failed to enable peripheral clock: %pe\n",
+			ERR_PTR(err));
+		goto fail_reset2;
+	}
+
+	err = rcar_canfd_reset_controller(gpriv);
+	if (err) {
+		dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
+		goto fail_clk;
+	}
+
+	/* Controller in Global reset & Channel reset mode */
+	rcar_canfd_configure_controller(gpriv);
+
+	/* Configure per channel attributes */
+	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
+		/* Configure Channel's Rx fifo */
+		rcar_canfd_configure_rx(gpriv, ch);
+
+		/* Configure Channel's Tx (Common) fifo */
+		rcar_canfd_configure_tx(gpriv, ch);
+
+		/* Configure receive rules */
+		rcar_canfd_configure_afl_rules(gpriv, ch, rule_entry);
+		rule_entry += RCANFD_CHANNEL_NUMRULES;
+	}
+
+	/* Configure common interrupts */
+	rcar_canfd_enable_global_interrupts(gpriv);
+
+	/* Start Global operation mode */
+	rcar_canfd_update_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GMDC_MASK,
+			      RCANFD_GCTR_GMDC_GOPM);
+
+	/* Verify mode change */
+	err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts,
+				 !(sts & RCANFD_GSTS_GNOPM), 2, 500000);
+	if (err) {
+		dev_err(dev, "global operational mode failed\n");
+		goto fail_mode;
+	}
+
+	return 0;
+
+fail_mode:
+	rcar_canfd_disable_global_interrupts(gpriv);
+fail_clk:
+	clk_disable_unprepare(gpriv->clkp);
+fail_reset2:
+	reset_control_assert(gpriv->rstc2);
+fail_reset1:
+	reset_control_assert(gpriv->rstc1);
+	return err;
+}
+
+static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool full)
+{
+	rcar_canfd_disable_global_interrupts(gpriv);
+
+	if (full) {
+		rcar_canfd_reset_controller(gpriv);
+
+		/* Enter global sleep mode */
+		rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
+	}
+
+	clk_disable_unprepare(gpriv->clkp);
+	reset_control_assert(gpriv->rstc2);
+	reset_control_assert(gpriv->rstc1);
+}
+
 static int rcar_canfd_probe(struct platform_device *pdev)
 {
 	struct phy *transceivers[RCANFD_NUM_CHANNELS] = { NULL, };
 	const struct rcar_canfd_hw_info *info;
 	struct device *dev = &pdev->dev;
 	void __iomem *addr;
-	u32 sts, ch, fcan_freq;
 	struct rcar_canfd_global *gpriv;
 	struct device_node *of_child;
 	unsigned long channels_mask = 0;
 	int err, ch_irq, g_irq;
 	int g_err_irq, g_recc_irq;
-	u32 rule_entry = 0;
 	bool fdmode = true;			/* CAN FD only mode - default */
 	char name[9] = "channelX";
 	struct clk *clk_ram;
+	u32 ch, fcan_freq;
 	int i;
 
 	info = of_device_get_match_data(dev);
@@ -2107,59 +2195,9 @@ static int rcar_canfd_probe(struct platform_device *pdev)
 		}
 	}
 
-	err = reset_control_reset(gpriv->rstc1);
+	err = rcar_canfd_global_init(gpriv);
 	if (err)
-		goto fail_dev;
-	err = reset_control_reset(gpriv->rstc2);
-	if (err) {
-		reset_control_assert(gpriv->rstc1);
-		goto fail_dev;
-	}
-
-	/* Enable peripheral clock for register access */
-	err = clk_prepare_enable(gpriv->clkp);
-	if (err) {
-		dev_err(dev, "failed to enable peripheral clock: %pe\n",
-			ERR_PTR(err));
-		goto fail_reset;
-	}
-
-	err = rcar_canfd_reset_controller(gpriv);
-	if (err) {
-		dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
-		goto fail_clk;
-	}
-
-	/* Controller in Global reset & Channel reset mode */
-	rcar_canfd_configure_controller(gpriv);
-
-	/* Configure per channel attributes */
-	for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) {
-		/* Configure Channel's Rx fifo */
-		rcar_canfd_configure_rx(gpriv, ch);
-
-		/* Configure Channel's Tx (Common) fifo */
-		rcar_canfd_configure_tx(gpriv, ch);
-
-		/* Configure receive rules */
-		rcar_canfd_configure_afl_rules(gpriv, ch, rule_entry);
-		rule_entry += RCANFD_CHANNEL_NUMRULES;
-	}
-
-	/* Configure common interrupts */
-	rcar_canfd_enable_global_interrupts(gpriv);
-
-	/* Start Global operation mode */
-	rcar_canfd_update_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GMDC_MASK,
-			      RCANFD_GCTR_GMDC_GOPM);
-
-	/* Verify mode change */
-	err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts,
-				 !(sts & RCANFD_GSTS_GNOPM), 2, 500000);
-	if (err) {
-		dev_err(dev, "global operational mode failed\n");
 		goto fail_mode;
-	}
 
 	for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) {
 		err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq,
@@ -2178,12 +2216,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
 	for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels)
 		rcar_canfd_channel_remove(gpriv, ch);
 fail_mode:
-	rcar_canfd_disable_global_interrupts(gpriv);
-fail_clk:
-	clk_disable_unprepare(gpriv->clkp);
-fail_reset:
-	reset_control_assert(gpriv->rstc2);
-	reset_control_assert(gpriv->rstc1);
+	rcar_canfd_global_deinit(gpriv, false);
 fail_dev:
 	return err;
 }
@@ -2198,14 +2231,7 @@ static void rcar_canfd_remove(struct platform_device *pdev)
 		rcar_canfd_channel_remove(gpriv, ch);
 	}
 
-	rcar_canfd_disable_global_interrupts(gpriv);
-	rcar_canfd_reset_controller(gpriv);
-
-	/* Enter global sleep mode */
-	rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
-	clk_disable_unprepare(gpriv->clkp);
-	reset_control_assert(gpriv->rstc2);
-	reset_control_assert(gpriv->rstc1);
+	rcar_canfd_global_deinit(gpriv, true);
 }
 
 static int __maybe_unused rcar_canfd_suspend(struct device *dev)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
                   ` (2 preceding siblings ...)
  2025-08-22  9:50 ` [PATCH 3/6] can: rcar_canfd: Extract rcar_canfd_global_{,de}init() Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22 14:26   ` Biju Das
  2025-08-22  9:50 ` [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Geert Uytterhoeven
  2025-08-22  9:50 ` [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
  5 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

The CAN clock is enabled before calling open_candev(), and disabled
before calling close_candev().  Invert the order of the latter, to
restore symmetry.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/net/can/rcar/rcar_canfd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 38c1b327f6b1d540..de5121efdabdb6ed 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1561,8 +1561,8 @@ static int rcar_canfd_close(struct net_device *ndev)
 	netif_stop_queue(ndev);
 	rcar_canfd_stop(ndev);
 	napi_disable(&priv->napi);
-	clk_disable_unprepare(gpriv->can_clk);
 	close_candev(ndev);
+	clk_disable_unprepare(gpriv->can_clk);
 	phy_power_off(priv->transceiver);
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS()
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
                   ` (3 preceding siblings ...)
  2025-08-22  9:50 ` [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22 14:27   ` Biju Das
  2025-08-22  9:50 ` [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
  5 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

Convert the Renesas R-Car CAN-FD driver from SIMPLE_DEV_PM_OPS() to
DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr().  This lets us drop the
__maybe_unused annotations from its suspend and resume callbacks, and
reduces kernel size in case CONFIG_PM or CONFIG_PM_SLEEP is disabled.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
 drivers/net/can/rcar/rcar_canfd.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index de5121efdabdb6ed..eedce83b91414c57 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -2234,18 +2234,18 @@ static void rcar_canfd_remove(struct platform_device *pdev)
 	rcar_canfd_global_deinit(gpriv, true);
 }
 
-static int __maybe_unused rcar_canfd_suspend(struct device *dev)
+static int rcar_canfd_suspend(struct device *dev)
 {
 	return 0;
 }
 
-static int __maybe_unused rcar_canfd_resume(struct device *dev)
+static int rcar_canfd_resume(struct device *dev)
 {
 	return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(rcar_canfd_pm_ops, rcar_canfd_suspend,
-			 rcar_canfd_resume);
+static DEFINE_SIMPLE_DEV_PM_OPS(rcar_canfd_pm_ops, rcar_canfd_suspend,
+				rcar_canfd_resume);
 
 static const __maybe_unused struct of_device_id rcar_canfd_of_table[] = {
 	{ .compatible = "renesas,r8a779a0-canfd", .data = &rcar_gen4_hw_info },
@@ -2262,7 +2262,7 @@ static struct platform_driver rcar_canfd_driver = {
 	.driver = {
 		.name = RCANFD_DRV_NAME,
 		.of_match_table = of_match_ptr(rcar_canfd_of_table),
-		.pm = &rcar_canfd_pm_ops,
+		.pm = pm_sleep_ptr(&rcar_canfd_pm_ops),
 	},
 	.probe = rcar_canfd_probe,
 	.remove = rcar_canfd_remove,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
                   ` (4 preceding siblings ...)
  2025-08-22  9:50 ` [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Geert Uytterhoeven
@ 2025-08-22  9:50 ` Geert Uytterhoeven
  2025-08-22 13:39   ` Biju Das
  2025-09-12  7:54   ` Biju Das
  5 siblings, 2 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-08-22  9:50 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol, Biju Das
  Cc: linux-can, linux-renesas-soc, Geert Uytterhoeven

On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume, the
CAN-FD interface no longer works.  Trying to bring it up again fails:

    # ip link set can0 up
    RTNETLINK answers: Connection timed out

    # dmesg
    ...
    channel 0 communication state failed

Fix this by populating the (currently empty) suspend and resume
callbacks, to stop/start the individual CAN-FD channels, and
(de)initialize the CAN-FD controller.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
While this fixes CAN-FD after resume from s2ram on R-Car E3 (Ebisu-4D),
it does introduce a regression on R-Car V4H (White Hawk): after resume
from s2idle (White Hawk does not support s2ram), CAN frames sent by
other devices are no longer received, and the other side sometimes
reports a "bus-off".

However, the underlying issue is pre-existing, and can be reproduced
without this patch: the CAN-FD controller fails in the same way after
driver unbind/rebind.  So something must be missing in the
(de)initialization sequence for the R-Car Gen4 CAN-FD register layout.
Note that it keeps on working after ifdown/ifup, which does not
reinitialize the full controller.
---
 drivers/net/can/rcar/rcar_canfd.c | 53 +++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index eedce83b91414c57..6b0c563e894f74b3 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -2236,11 +2236,64 @@ static void rcar_canfd_remove(struct platform_device *pdev)
 
 static int rcar_canfd_suspend(struct device *dev)
 {
+	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
+	int err;
+	u32 ch;
+
+	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
+		struct rcar_canfd_channel *priv = gpriv->ch[ch];
+		struct net_device *ndev = priv->ndev;
+
+		if (!netif_running(ndev))
+			continue;
+
+		netif_device_detach(ndev);
+
+		err = rcar_canfd_close(ndev);
+		if (err) {
+			netdev_err(ndev, "rcar_canfd_close() failed %pe\n",
+				   ERR_PTR(err));
+			return err;
+		}
+
+		priv->can.state = CAN_STATE_SLEEPING;
+	}
+
+	/* TODO Skip if wake-up (which is not yet supported) is enabled */
+	rcar_canfd_global_deinit(gpriv, false);
+
 	return 0;
 }
 
 static int rcar_canfd_resume(struct device *dev)
 {
+	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
+	int err;
+	u32 ch;
+
+	err = rcar_canfd_global_init(gpriv);
+	if (err) {
+		dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));
+		return err;
+	}
+
+	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
+		struct rcar_canfd_channel *priv = gpriv->ch[ch];
+		struct net_device *ndev = priv->ndev;
+
+		if (!netif_running(ndev))
+			continue;
+
+		err = rcar_canfd_open(ndev);
+		if (err) {
+			netdev_err(ndev, "rcar_canfd_open() failed %pe\n",
+				   ERR_PTR(err));
+			return err;
+		}
+
+		netif_device_attach(ndev);
+	}
+
 	return 0;
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-08-22  9:50 ` [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
@ 2025-08-22 13:39   ` Biju Das
  2025-08-22 16:19     ` Biju Das
  2025-09-12  7:54   ` Biju Das
  1 sibling, 1 reply; 25+ messages in thread
From: Biju Das @ 2025-08-22 13:39 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,


> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol <mailhol.vincent@wanadoo.fr>; Biju Das
> <biju.das.jz@bp.renesas.com>
> Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org; Geert Uytterhoeven
> <geert+renesas@glider.be>
> Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume, the CAN-FD interface no longer
> works.  Trying to bring it up again fails:
> 
>     # ip link set can0 up
>     RTNETLINK answers: Connection timed out
> 
>     # dmesg
>     ...
>     channel 0 communication state failed
> 
> Fix this by populating the (currently empty) suspend and resume callbacks, to stop/start the individual
> CAN-FD channels, and (de)initialize the CAN-FD controller.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> ---
> While this fixes CAN-FD after resume from s2ram on R-Car E3 (Ebisu-4D), it does introduce a regression
> on R-Car V4H (White Hawk): after resume from s2idle (White Hawk does not support s2ram), CAN frames
> sent by other devices are no longer received, and the other side sometimes reports a "bus-off".
> 
> However, the underlying issue is pre-existing, and can be reproduced without this patch: the CAN-FD
> controller fails in the same way after driver unbind/rebind.  So something must be missing in the
> (de)initialization sequence for the R-Car Gen4 CAN-FD register layout.
> Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> ---
>  drivers/net/can/rcar/rcar_canfd.c | 53 +++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
> 
> diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
> index eedce83b91414c57..6b0c563e894f74b3 100644
> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -2236,11 +2236,64 @@ static void rcar_canfd_remove(struct platform_device *pdev)
> 
>  static int rcar_canfd_suspend(struct device *dev)  {
> +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> +	int err;
> +	u32 ch;
> +
> +	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
> +		struct rcar_canfd_channel *priv = gpriv->ch[ch];
> +		struct net_device *ndev = priv->ndev;
> +
> +		if (!netif_running(ndev))
> +			continue;
> +
> +		netif_device_detach(ndev);
> +
> +		err = rcar_canfd_close(ndev);
> +		if (err) {
> +			netdev_err(ndev, "rcar_canfd_close() failed %pe\n",
> +				   ERR_PTR(err));
> +			return err;
> +		}
> +
> +		priv->can.state = CAN_STATE_SLEEPING;
> +	}
> +
> +	/* TODO Skip if wake-up (which is not yet supported) is enabled */
> +	rcar_canfd_global_deinit(gpriv, false);
> +
>  	return 0;
>  }
> 
>  static int rcar_canfd_resume(struct device *dev)  {
> +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> +	int err;
> +	u32 ch;
> +
> +	err = rcar_canfd_global_init(gpriv);
> +	if (err) {
> +		dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));
> +		return err;
> +	}
> +
> +	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
> +		struct rcar_canfd_channel *priv = gpriv->ch[ch];
> +		struct net_device *ndev = priv->ndev;
> +
> +		if (!netif_running(ndev))
> +			continue;
> +
> +		err = rcar_canfd_open(ndev);
> +		if (err) {
> +			netdev_err(ndev, "rcar_canfd_open() failed %pe\n",
> +				   ERR_PTR(err));
> +			return err;
> +		}
> +
> +		netif_device_attach(ndev);
> +	}
> +
>  	return 0;
>  }
> 

This patch does not work on RZ/G3E, please see the logs

Bind/Unbind:
-------------
root@smarc-rzg3e:/cip-test-scripts# cd /sys/bus/platform/drivers/rcar_canfd
n > unbindroot@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo 12440000.can > unbind
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo 12440000.can > bind
[   67.645615] rcar_canfd 12440000.can: can_clk rate is 80000000
[   67.655044] rcar_canfd 12440000.can: device registered (channel 1)
[   67.661788] rcar_canfd 12440000.can: can_clk rate is 80000000
[   67.671258] rcar_canfd 12440000.can: device registered (channel 4)
[   67.677603] rcar_canfd 12440000.can: global operational state (canfd clk, fd mode)

root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# /cip-test-scripts/canfd_t_003.sh
 [INFO] Testing can0<->can1 with bitrate 1000000 and dbitrate 4000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 500000 and dbitrate 2000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 250000 and dbitrate 1000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer

EXIT|PASS|canfd_t_003.sh|[00:00:25] ||

G3E S2Idle:
------------
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo s2idle > /sys/power/mem_sleep
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo mem > /sys/power/state
[  160.231921] PM: suspend entry (s2idle)
[  160.236099] Filesystems sync: 0.000 seconds
[  160.248409] Freezing user space processes
[  160.255200] Freezing user space processes completed (elapsed 0.002 seconds)
[  160.262354] OOM killer disabled.
[  160.265681] Freezing remaining freezable tasks
[  160.271723] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[  160.279253] printk: Suspending console(s) (use no_console_suspend to debug)
[  160.311505] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[  160.377382] renesas-gbeth 15c30000.ethernet end0: Link is Down
[  162.226309] dwmac4: Master AXI performs fixed burst length
[  162.227718] renesas-gbeth 15c30000.ethernet end0: No Safety Features support found
[  162.227788] renesas-gbeth 15c30000.ethernet end0: IEEE 1588-2008 Advanced Timestamp supported
[  162.232919] renesas-gbeth 15c30000.ethernet end0: configuring for phy/rgmii-id link mode
[  162.252982] dwmac4: Master AXI performs fixed burst length
[  162.254258] renesas-gbeth 15c40000.ethernet end1: No Safety Features support found
[  162.254321] renesas-gbeth 15c40000.ethernet end1: IEEE 1588-2008 Advanced Timestamp supported
[  162.259706] renesas-gbeth 15c40000.ethernet end1: configuring for phy/rgmii-id link mode
[  162.307564] usb usb1: root hub lost power or was reset
[  162.307607] usb usb2: root hub lost power or was reset
[  164.471610] usb 2-1: reset SuperSpeed Plus Gen 2x1 USB device number 2 using xhci-renesas-hcd
[  164.584382] OOM killer enabled.
[  164.587540] Restarting tasks: Starting
[  164.593757] Restarting tasks: Done
[  164.597263] random: crng reseeded on system resumption
[  164.602497] PM: suspend exit
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# [  164.959424] renesas-gbeth 15c30000.ethernet end0: Link is Up - 1Gbps/Full - flow control rx/tx

root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# /cip-test-scripts/canfd_t_003.sh
 [INFO] Testing can0<->can1 with bitrate 1000000 and dbitrate 4000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 500000 and dbitrate 2000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 250000 and dbitrate 1000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer

EXIT|PASS|canfd_t_003.sh|[00:00:25] ||

G3E STR:
--------

root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo deep > /sys/power/mem_sleep
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# echo mem > /sys/power/state
[  237.863858] PM: suspend entry (deep)
[  237.867860] Filesystems sync: 0.000 seconds
[  237.878623] Freezing user space processes
[  237.885330] Freezing user space processes completed (elapsed 0.002 seconds)
[  237.892455] OOM killer disabled.
[  237.895804] Freezing remaining freezable tasks
[  237.902064] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[  237.909648] printk: Suspending console(s) (use no_console_suspend to debug)
NOTICE:  BL2: v2.10.5(release):2.10.5/rz_soc_dev-169-g1410189b0
NOTICE:  BL2: Built : 12:53:12, Jul 15 2025
NOTICE:  BL2: SYS_LSI_MODE: 0x13e06
NOTICE:  BL2: SYS_LSI_DEVID: 0x8679447
NOTICE:  BL2: SYS_LSI_PRR: 0x0
NOTICE:  BL2: Booting BL31
[  237.943571] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[  237.992789] renesas-gbeth 15c30000.ethernet end0: Link is Down
[  238.006388] Disabling non-boot CPUs ...
[  238.011104] psci: CPU3 killed (polled 0 ms)
[  238.017799] psci: CPU2 killed (polled 0 ms)
[  238.023704] psci: CPU1 killed (polled 4 ms)
[  238.028259] Enabling non-boot CPUs ...
[  238.028474] Detected VIPT I-cache on CPU1
[  238.028521] GICv3: CPU1: found redistributor 100 region 0:0x0000000014960000
[  238.028558] CPU1: Booted secondary processor 0x0000000100 [0x412fd050]
[  238.029374] CPU1 is up
[  238.029470] Detected VIPT I-cache on CPU2
[  238.029492] GICv3: CPU2: found redistributor 200 region 0:0x0000000014980000
[  238.029513] CPU2: Booted secondary processor 0x0000000200 [0x412fd050]
[  238.030046] CPU2 is up
[  238.030145] Detected VIPT I-cache on CPU3
[  238.030167] GICv3: CPU3: found redistributor 300 region 0:0x00000000149a0000
[  238.030189] CPU3: Booted secondary processor 0x0000000300 [0x412fd050]
[  238.030873] CPU3 is up
[  238.047257] dwmac4: Master AXI performs fixed burst length
[  238.048165] renesas-gbeth 15c30000.ethernet end0: No Safety Features support found
[  238.048185] renesas-gbeth 15c30000.ethernet end0: IEEE 1588-2008 Advanced Timestamp supported
[  238.051680] renesas-gbeth 15c30000.ethernet end0: configuring for phy/rgmii-id link mode
[  238.069106] dwmac4: Master AXI performs fixed burst length
[  238.070002] renesas-gbeth 15c40000.ethernet end1: No Safety Features support found
[  238.070018] renesas-gbeth 15c40000.ethernet end1: IEEE 1588-2008 Advanced Timestamp supported
[  238.073613] renesas-gbeth 15c40000.ethernet end1: configuring for phy/rgmii-id link mode
[  238.119909] usb usb1: root hub lost power or was reset
[  238.119918] usb usb2: root hub lost power or was reset
[  240.279309] usb 2-1: reset SuperSpeed Plus Gen 2x1 USB device number 2 using xhci-renesas-hcd
[  240.468214] OOM killer enabled.
[  240.471358] Restarting tasks: Starting
[  240.475721] Restarting tasks: Done
[  240.479171] random: crng reseeded on system resumption
[  240.484426] PM: suspend exit
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# [  240.692426] renesas-gbeth 15c30000.ethernet end0: Link is Up - 1Gbps/Full - flow control rx/tx

root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd#
root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd# /cip-test-scripts/canfd_t_003.sh
 [INFO] Testing can0<->can1 with bitrate 1000000 and dbitrate 4000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer

EXIT|FAIL|canfd_t_003.sh|[00:00:04] Problems while producing data from can1 and consuming from can0||

root@smarc-rzg3e:/sys/bus/platform/drivers/rcar_canfd#

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown
  2025-08-22  9:50 ` [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown Geert Uytterhoeven
@ 2025-08-22 14:21   ` Biju Das
  2025-09-09  6:38   ` Vincent Mailhol
  1 sibling, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-08-22 14:21 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,

Thanks for the patch.

> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> Subject: [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown
> 
> Global state is initialized and torn down before per-channel state.
> Invert the order to restore symmetry.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>


Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>

Cheers,
Biju

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 1/6] can: rcar_canfd: Invert reset assert order
  2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
@ 2025-08-22 14:24   ` Biju Das
  2025-09-09  6:36   ` Vincent Mailhol
  1 sibling, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-08-22 14:24 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> Subject: [PATCH 1/6] can: rcar_canfd: Invert reset assert order
> 
> The two resets are asserted during cleanup in the same order as they were deasserted during probe.
> Invert the order to restore symmetry.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>

Cheers,
Biju


^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order
  2025-08-22  9:50 ` [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order Geert Uytterhoeven
@ 2025-08-22 14:26   ` Biju Das
  0 siblings, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-08-22 14:26 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> Subject: [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order
> 
> The CAN clock is enabled before calling open_candev(), and disabled before calling close_candev().
> Invert the order of the latter, to restore symmetry.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>

Cheers,
Biju


^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS()
  2025-08-22  9:50 ` [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Geert Uytterhoeven
@ 2025-08-22 14:27   ` Biju Das
  0 siblings, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-08-22 14:27 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,

Thanks for the patch.

> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol <mailhol.vincent@wanadoo.fr>; Biju Das
> <biju.das.jz@bp.renesas.com>
> Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org; Geert Uytterhoeven
> <geert+renesas@glider.be>
> Subject: [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS()
> 
> Convert the Renesas R-Car CAN-FD driver from SIMPLE_DEV_PM_OPS() to
> DEFINE_SIMPLE_DEV_PM_OPS() and pm_sleep_ptr().  This lets us drop the __maybe_unused annotations from
> its suspend and resume callbacks, and reduces kernel size in case CONFIG_PM or CONFIG_PM_SLEEP is
> disabled.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>

Cheers,
Biju

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-08-22 13:39   ` Biju Das
@ 2025-08-22 16:19     ` Biju Das
  2025-09-08 13:50       ` Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Biju Das @ 2025-08-22 16:19 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Biju Das
> Sent: 22 August 2025 14:40
> Subject: RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> Hi Geert,
> 
> 
> > -----Original Message-----
> > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > Sent: 22 August 2025 10:51
> > To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol
> > <mailhol.vincent@wanadoo.fr>; Biju Das <biju.das.jz@bp.renesas.com>
> > Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> > Geert Uytterhoeven <geert+renesas@glider.be>
> > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> >
> > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume,
> > the CAN-FD interface no longer works.  Trying to bring it up again fails:
> >
> >     # ip link set can0 up
> >     RTNETLINK answers: Connection timed out
> >
> >     # dmesg
> >     ...
> >     channel 0 communication state failed
> >
> > Fix this by populating the (currently empty) suspend and resume
> > callbacks, to stop/start the individual CAN-FD channels, and (de)initialize the CAN-FD controller.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > ---
> > While this fixes CAN-FD after resume from s2ram on R-Car E3
> > (Ebisu-4D), it does introduce a regression on R-Car V4H (White Hawk):
> > after resume from s2idle (White Hawk does not support s2ram), CAN frames sent by other devices are no
> longer received, and the other side sometimes reports a "bus-off".
> >
> > However, the underlying issue is pre-existing, and can be reproduced
> > without this patch: the CAN-FD controller fails in the same way after
> > driver unbind/rebind.  So something must be missing in the (de)initialization sequence for the R-Car
> Gen4 CAN-FD register layout.
> > Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> > ---
> >  drivers/net/can/rcar/rcar_canfd.c | 53
> > +++++++++++++++++++++++++++++++
> >  1 file changed, 53 insertions(+)
> >
> > diff --git a/drivers/net/can/rcar/rcar_canfd.c
> > b/drivers/net/can/rcar/rcar_canfd.c
> > index eedce83b91414c57..6b0c563e894f74b3 100644
> > --- a/drivers/net/can/rcar/rcar_canfd.c
> > +++ b/drivers/net/can/rcar/rcar_canfd.c
> > @@ -2236,11 +2236,64 @@ static void rcar_canfd_remove(struct
> > platform_device *pdev)
> >
> >  static int rcar_canfd_suspend(struct device *dev)  {
> > +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> > +	int err;
> > +	u32 ch;
> > +
> > +	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
> > +		struct rcar_canfd_channel *priv = gpriv->ch[ch];
> > +		struct net_device *ndev = priv->ndev;
> > +
> > +		if (!netif_running(ndev))
> > +			continue;
> > +
> > +		netif_device_detach(ndev);
> > +
> > +		err = rcar_canfd_close(ndev);
> > +		if (err) {
> > +			netdev_err(ndev, "rcar_canfd_close() failed %pe\n",
> > +				   ERR_PTR(err));
> > +			return err;
> > +		}
> > +
> > +		priv->can.state = CAN_STATE_SLEEPING;
> > +	}
> > +
> > +	/* TODO Skip if wake-up (which is not yet supported) is enabled */
> > +	rcar_canfd_global_deinit(gpriv, false);
> > +
> >  	return 0;
> >  }
> >
> >  static int rcar_canfd_resume(struct device *dev)  {
> > +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> > +	int err;
> > +	u32 ch;
> > +
> > +	err = rcar_canfd_global_init(gpriv);
> > +	if (err) {
> > +		dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));
> > +		return err;
> > +	}
> > +
> > +	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
> > +		struct rcar_canfd_channel *priv = gpriv->ch[ch];
> > +		struct net_device *ndev = priv->ndev;
> > +
> > +		if (!netif_running(ndev))
> > +			continue;
> > +
> > +		err = rcar_canfd_open(ndev);
> > +		if (err) {
> > +			netdev_err(ndev, "rcar_canfd_open() failed %pe\n",
> > +				   ERR_PTR(err));
> > +			return err;
> > +		}
> > +
> > +		netif_device_attach(ndev);
> > +	}
> > +
> >  	return 0;
> >  }
> >

STR is now working on G3E based on BSP code with the following modifications[1]


[1]
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index adf73d6238a1..89a1bc73c1af 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -469,6 +469,7 @@ struct rcar_canfd_global {
        struct platform_device *pdev;   /* Respective platform device */
        struct clk *clkp;               /* Peripheral clock */
        struct clk *can_clk;            /* fCAN clock */
+       struct clk *clk_ram;            /* Clock RAM */
        unsigned long channels_mask;    /* Enabled channels mask */
        bool extclk;                    /* CANFD or Ext clock */
        bool fdmode;                    /* CAN FD or Classical CAN only mode */
@@ -2158,7 +2159,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
                gpriv->extclk = gpriv->info->external_clk;
        }
 
-       clk_ram = devm_clk_get_optional_enabled(dev, "ram_clk");
+       gpriv->clk_ram = devm_clk_get_optional_enabled(dev, "ram_clk");
        if (IS_ERR(clk_ram))
                return dev_err_probe(dev, PTR_ERR(clk_ram),
                                     "cannot get enabled ram clock\n");
@@ -2262,20 +2263,15 @@ static int rcar_canfd_suspend(struct device *dev)
                if (!netif_running(ndev))
                        continue;
 
+               netif_stop_queue(ndev);
+               rcar_canfd_stop(ndev);
                netif_device_detach(ndev);
-
-               err = rcar_canfd_close(ndev);
-               if (err) {
-                       netdev_err(ndev, "rcar_canfd_close() failed %pe\n",
-                                  ERR_PTR(err));
-                       return err;
-               }
-
-               priv->can.state = CAN_STATE_SLEEPING;
        }
 
-       /* TODO Skip if wake-up (which is not yet supported) is enabled */
-       rcar_canfd_global_deinit(gpriv, false);
+       reset_control_assert(gpriv->rstc1);
+       reset_control_assert(gpriv->rstc2);
+       clk_disable_unprepare(gpriv->clkp);
+       clk_disable_unprepare(gpriv->clk_ram);
 
        return 0;
 }
@@ -2286,30 +2282,71 @@ static int rcar_canfd_resume(struct device *dev)
        int err;
        u32 ch;
 
+       err = reset_control_deassert(gpriv->rstc1);
+       if (err)
+               goto fail_dev;
+
+       err = reset_control_deassert(gpriv->rstc2);
+       if (err) {
+               reset_control_assert(gpriv->rstc1);
+               goto fail_dev;
+       }
+
+       /* Enable peripheral clock for register access */
+       err = clk_prepare_enable(gpriv->clkp);
+       if (err) {
+               dev_err(dev,
+                       "failed to enable peripheral clock, error %d\n", err);
+               goto fail_reset;
+       }
+
+       /* Enable RAM clock */
+       err = clk_prepare_enable(gpriv->clk_ram);
+       if (err) {
+               dev_err(dev,
+                       "failed to enable ram clock, error %d\n", err);
+               goto fail_reset;
+       }
+
+       err = rcar_canfd_reset_controller(gpriv);
+       if (err) {
+               dev_err(dev, "reset controller failed\n");
+               goto fail_clk;
+       }
+
        err = rcar_canfd_global_init(gpriv);
        if (err) {
-               dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));
-               return err;
+               dev_err(dev, "controller init failed\n");
+               goto fail_mode;
        }
 
-       for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
+       for_each_set_bit(ch, &gpriv->channels_mask, RCANFD_NUM_CHANNELS) {
                struct rcar_canfd_channel *priv = gpriv->ch[ch];
                struct net_device *ndev = priv->ndev;
 
                if (!netif_running(ndev))
                        continue;
 
-               err = rcar_canfd_open(ndev);
+               netif_device_attach(ndev);
+               err = rcar_canfd_start(ndev);
                if (err) {
-                       netdev_err(ndev, "rcar_canfd_open() failed %pe\n",
-                                  ERR_PTR(err));
+                       netif_device_detach(ndev);
                        return err;
                }
-
-               netif_device_attach(ndev);
+               netif_start_queue(ndev);
        }
 
        return 0;
+
+fail_mode:
+       rcar_canfd_disable_global_interrupts(gpriv);
+fail_clk:
+       clk_disable_unprepare(gpriv->clkp);
+fail_reset:
+       reset_control_assert(gpriv->rstc1);
+       reset_control_assert(gpriv->rstc2);
+fail_dev:
+       return err;
 }


[2] logs

root@smarc-rzg3e:/cip-test-scripts# [   36.691587] PM: suspend entry (deep)
[   36.695460] Filesystems sync: 0.000 seconds
[   36.704009] Freezing user space processes
[   36.709820] Freezing user space processes completed (elapsed 0.001 seconds)
[   36.716809] OOM killer disabled.
[   36.720049] Freezing remaining freezable tasks
[   36.725879] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[   36.733327] printk: Suspending console(s) (use no_console_suspend to debug)
NOTICE:  BL2: v2.10.5(release):2.10.5/rz_soc_dev-169-g1410189b0
NOTICE:  BL2: Built : 12:53:12, Jul 15 2025
NOTICE:  BL2: SYS_LSI_MODE: 0x13e06
NOTICE:  BL2: SYS_LSI_DEVID: 0x8679447
NOTICE:  BL2: SYS_LSI_PRR: 0x0
NOTICE:  BL2: Booting BL31
[   36.759719] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[   36.818341] renesas-gbeth 15c30000.ethernet end0: Link is Down
[   36.832139] Disabling non-boot CPUs ...
[   36.836762] psci: CPU3 killed (polled 0 ms)
[   36.843491] psci: CPU2 killed (polled 4 ms)
[   36.852615] psci: CPU1 killed (polled 0 ms)
[   36.855973] Enabling non-boot CPUs ...
[   36.856187] Detected VIPT I-cache on CPU1
[   36.856231] GICv3: CPU1: found redistributor 100 region 0:0x0000000014960000
[   36.856268] CPU1: Booted secondary processor 0x0000000100 [0x412fd050]
[   36.857067] CPU1 is up
[   36.857163] Detected VIPT I-cache on CPU2
[   36.857185] GICv3: CPU2: found redistributor 200 region 0:0x0000000014980000
[   36.857205] CPU2: Booted secondary processor 0x0000000200 [0x412fd050]
[   36.857783] CPU2 is up
[   36.857878] Detected VIPT I-cache on CPU3
[   36.857901] GICv3: CPU3: found redistributor 300 region 0:0x00000000149a0000
[   36.857923] CPU3: Booted secondary processor 0x0000000300 [0x412fd050]
[   36.858631] CPU3 is up
[   36.875320] dwmac4: Master AXI performs fixed burst length
[   36.876219] renesas-gbeth 15c30000.ethernet end0: No Safety Features support found
[   36.876241] renesas-gbeth 15c30000.ethernet end0: IEEE 1588-2008 Advanced Timestamp supported
[   36.879753] renesas-gbeth 15c30000.ethernet end0: configuring for phy/rgmii-id link mode
[   36.897118] dwmac4: Master AXI performs fixed burst length
[   36.898009] renesas-gbeth 15c40000.ethernet end1: No Safety Features support found
[   36.898026] renesas-gbeth 15c40000.ethernet end1: IEEE 1588-2008 Advanced Timestamp supported
[   36.901567] renesas-gbeth 15c40000.ethernet end1: configuring for phy/rgmii-id link mode
[   36.948005] usb usb1: root hub lost power or was reset
[   36.948012] usb usb2: root hub lost power or was reset
[   39.107397] usb 2-1: reset SuperSpeed Plus Gen 2x1 USB device number 2 using xhci-renesas-hcd
[   39.294764] OOM killer enabled.
[   39.297903] Restarting tasks: Starting
[   39.303378] Restarting tasks: Done
[   39.306841] random: crng reseeded on system resumption
[   39.312209] PM: suspend exit
[   39.502581] renesas-gbeth 15c30000.ethernet end0: Link is Up - 1Gbps/Full - flow control rx/tx

root@smarc-rzg3e:/cip-test-scripts# ./canfd_t_003.sh
 [INFO] Testing can0<->can1 with bitrate 1000000 and dbitrate 4000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
[   48.400817] can: controller area network core
[   48.405291] NET: Registered PF_CAN protocol family
[   48.445879] can: raw protocol
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 500000 and dbitrate 2000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
 [INFO] Testing can0<->can1 with bitrate 250000 and dbitrate 1000000
 [INFO] Bringing down can0 can1
 [INFO] Bringing up can0 can1
 [INFO] Testing can1 as producer and can0 as consumer
 [INFO] Testing can0 as producer and can1 as consumer
[   69.411870] kauditd_printk_skb: 5 callbacks suppressed
[   69.411883] audit: type=1334 audit(1755879165.759:22): prog-id=18 op=UNLOAD
[   69.423995] audit: type=1334 audit(1755879165.759:23): prog-id=17 op=UNLOAD
[   69.430946] audit: type=1334 audit(1755879165.759:24): prog-id=16 op=UNLOAD

EXIT|PASS|canfd_t_003.sh|[00:00:25] ||

root@smarc-rzg3e:/cip-test-scripts#

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-08-22 16:19     ` Biju Das
@ 2025-09-08 13:50       ` Geert Uytterhoeven
  2025-09-08 13:56         ` Biju Das
  0 siblings, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-08 13:50 UTC (permalink / raw)
  To: Biju Das
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Biju,

On Fri, 22 Aug 2025 at 18:19, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > From: Biju Das
> > > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > > Sent: 22 August 2025 10:51
> > > To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol
> > > <mailhol.vincent@wanadoo.fr>; Biju Das <biju.das.jz@bp.renesas.com>
> > > Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> > > Geert Uytterhoeven <geert+renesas@glider.be>
> > > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> > >
> > > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume,
> > > the CAN-FD interface no longer works.  Trying to bring it up again fails:
> > >
> > >     # ip link set can0 up
> > >     RTNETLINK answers: Connection timed out
> > >
> > >     # dmesg
> > >     ...
> > >     channel 0 communication state failed
> > >
> > > Fix this by populating the (currently empty) suspend and resume
> > > callbacks, to stop/start the individual CAN-FD channels, and (de)initialize the CAN-FD controller.
> > >
> > > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > > ---
> > > While this fixes CAN-FD after resume from s2ram on R-Car E3
> > > (Ebisu-4D), it does introduce a regression on R-Car V4H (White Hawk):
> > > after resume from s2idle (White Hawk does not support s2ram), CAN frames sent by other devices are no
> > longer received, and the other side sometimes reports a "bus-off".
> > >
> > > However, the underlying issue is pre-existing, and can be reproduced
> > > without this patch: the CAN-FD controller fails in the same way after
> > > driver unbind/rebind.  So something must be missing in the (de)initialization sequence for the R-Car
> > Gen4 CAN-FD register layout.
> > > Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> > > ---
> > >  drivers/net/can/rcar/rcar_canfd.c | 53

> STR is now working on G3E based on BSP code with the following modifications[1]

Thanks for looking into this!
Unfortunately your changes do not fix s2idle on R-Car V4H.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-08 13:50       ` Geert Uytterhoeven
@ 2025-09-08 13:56         ` Biju Das
  2025-09-08 14:06           ` Geert Uytterhoeven
  0 siblings, 1 reply; 25+ messages in thread
From: Biju Das @ 2025-09-08 13:56 UTC (permalink / raw)
  To: geert, Minh Le
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Geert,

Thanks for the report.

> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 08 September 2025 14:50
> Subject: Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> Hi Biju,
> 
> On Fri, 22 Aug 2025 at 18:19, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > From: Biju Das
> > > > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > > > Sent: 22 August 2025 10:51
> > > > To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol
> > > > <mailhol.vincent@wanadoo.fr>; Biju Das
> > > > <biju.das.jz@bp.renesas.com>
> > > > Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> > > > Geert Uytterhoeven <geert+renesas@glider.be>
> > > > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume
> > > > support
> > > >
> > > > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After
> > > > resume, the CAN-FD interface no longer works.  Trying to bring it up again fails:
> > > >
> > > >     # ip link set can0 up
> > > >     RTNETLINK answers: Connection timed out
> > > >
> > > >     # dmesg
> > > >     ...
> > > >     channel 0 communication state failed
> > > >
> > > > Fix this by populating the (currently empty) suspend and resume
> > > > callbacks, to stop/start the individual CAN-FD channels, and (de)initialize the CAN-FD
> controller.
> > > >
> > > > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > > > ---
> > > > While this fixes CAN-FD after resume from s2ram on R-Car E3
> > > > (Ebisu-4D), it does introduce a regression on R-Car V4H (White Hawk):
> > > > after resume from s2idle (White Hawk does not support s2ram), CAN
> > > > frames sent by other devices are no
> > > longer received, and the other side sometimes reports a "bus-off".
> > > >
> > > > However, the underlying issue is pre-existing, and can be
> > > > reproduced without this patch: the CAN-FD controller fails in the
> > > > same way after driver unbind/rebind.  So something must be missing
> > > > in the (de)initialization sequence for the R-Car
> > > Gen4 CAN-FD register layout.
> > > > Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> > > > ---
> > > >  drivers/net/can/rcar/rcar_canfd.c | 53
> 
> > STR is now working on G3E based on BSP code with the following
> > modifications[1]
> 
> Thanks for looking into this!
> Unfortunately your changes do not fix s2idle on R-Car V4H.

Is "bus-off" issue related to can transceiver, Maybe after s2idle transceiver may be down?

Cheers,
Biju


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-08 13:56         ` Biju Das
@ 2025-09-08 14:06           ` Geert Uytterhoeven
  0 siblings, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-08 14:06 UTC (permalink / raw)
  To: Biju Das
  Cc: Minh Le, Marc Kleine-Budde, Vincent Mailhol,
	linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Biju,

On Mon, 8 Sept 2025 at 15:56, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > From: Geert Uytterhoeven <geert@linux-m68k.org>
> > On Fri, 22 Aug 2025 at 18:19, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > > From: Biju Das
> > > > > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > > > > Sent: 22 August 2025 10:51
> > > > > To: Marc Kleine-Budde <mkl@pengutronix.de>; Vincent Mailhol
> > > > > <mailhol.vincent@wanadoo.fr>; Biju Das
> > > > > <biju.das.jz@bp.renesas.com>
> > > > > Cc: linux-can@vger.kernel.org; linux-renesas-soc@vger.kernel.org;
> > > > > Geert Uytterhoeven <geert+renesas@glider.be>
> > > > > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume
> > > > > support
> > > > >
> > > > > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After
> > > > > resume, the CAN-FD interface no longer works.  Trying to bring it up again fails:
> > > > >
> > > > >     # ip link set can0 up
> > > > >     RTNETLINK answers: Connection timed out
> > > > >
> > > > >     # dmesg
> > > > >     ...
> > > > >     channel 0 communication state failed
> > > > >
> > > > > Fix this by populating the (currently empty) suspend and resume
> > > > > callbacks, to stop/start the individual CAN-FD channels, and (de)initialize the CAN-FD
> > controller.
> > > > >
> > > > > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> > > > > ---
> > > > > While this fixes CAN-FD after resume from s2ram on R-Car E3
> > > > > (Ebisu-4D), it does introduce a regression on R-Car V4H (White Hawk):
> > > > > after resume from s2idle (White Hawk does not support s2ram), CAN
> > > > > frames sent by other devices are no
> > > > longer received, and the other side sometimes reports a "bus-off".
> > > > >
> > > > > However, the underlying issue is pre-existing, and can be
> > > > > reproduced without this patch: the CAN-FD controller fails in the
> > > > > same way after driver unbind/rebind.  So something must be missing
> > > > > in the (de)initialization sequence for the R-Car
> > > > Gen4 CAN-FD register layout.
> > > > > Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> > > > > ---
> > > > >  drivers/net/can/rcar/rcar_canfd.c | 53
> >
> > > STR is now working on G3E based on BSP code with the following
> > > modifications[1]
> >
> > Thanks for looking into this!
> > Unfortunately your changes do not fix s2idle on R-Car V4H.
>
> Is "bus-off" issue related to can transceiver, Maybe after s2idle transceiver may be down?

No, it also happens after unbind/rebind.
Both Ebisu and White Hawk ch3 use MCP2558FD transceivers, which
don't have standby lines (the silent signal is wired to reset).

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/6] can: rcar_canfd: Invert reset assert order
  2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
  2025-08-22 14:24   ` Biju Das
@ 2025-09-09  6:36   ` Vincent Mailhol
  2025-09-09  6:57     ` Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Vincent Mailhol @ 2025-09-09  6:36 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Biju Das
  Cc: linux-can, linux-renesas-soc

On 22/08/2025 at 18:50, Geert Uytterhoeven wrote:
> The two resets are asserted during cleanup in the same order as they
> were deasserted during probe.  Invert the order to restore symmetry.

Question: is this only a cosmetic change or does it fix any problem?

If this fixes an issue, please add the proper Fixes: tag.

> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Vincent Mailhol <mailhol@kernel.org>

(if the Fixes tag is needed, your are still welcome to add my Reviewed-by in the
v2).


Yours sincerely,
Vincent Mailhol


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown
  2025-08-22  9:50 ` [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown Geert Uytterhoeven
  2025-08-22 14:21   ` Biju Das
@ 2025-09-09  6:38   ` Vincent Mailhol
  2025-09-09  6:58     ` Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Vincent Mailhol @ 2025-09-09  6:38 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Biju Das
  Cc: linux-can, linux-renesas-soc

On 22/08/2025 at 18:50, Geert Uytterhoeven wrote:
> Global state is initialized and torn down before per-channel state.
> Invert the order to restore symmetry.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Same comment as before. I assume this is only cosmetic, if not, Fixes: tag please!

Reviewed-by: Vincent Mailhol <mailhol@kernel.org>


Yours sincerely,
Vincent Mailhol


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/6] can: rcar_canfd: Invert reset assert order
  2025-09-09  6:36   ` Vincent Mailhol
@ 2025-09-09  6:57     ` Geert Uytterhoeven
  0 siblings, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-09  6:57 UTC (permalink / raw)
  To: Vincent Mailhol; +Cc: Marc Kleine-Budde, Biju Das, linux-can, linux-renesas-soc

Hi Vincent,

On Tue, 9 Sept 2025 at 08:36, Vincent Mailhol <mailhol@kernel.org> wrote:
> On 22/08/2025 at 18:50, Geert Uytterhoeven wrote:
> > The two resets are asserted during cleanup in the same order as they
> > were deasserted during probe.  Invert the order to restore symmetry.
>
> Question: is this only a cosmetic change or does it fix any problem?

Cosmetic only, TTBOMK.

> Reviewed-by: Vincent Mailhol <mailhol@kernel.org>

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown
  2025-09-09  6:38   ` Vincent Mailhol
@ 2025-09-09  6:58     ` Geert Uytterhoeven
  0 siblings, 0 replies; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-09  6:58 UTC (permalink / raw)
  To: Vincent Mailhol; +Cc: Marc Kleine-Budde, Biju Das, linux-can, linux-renesas-soc

Hi Vincent,

On Tue, 9 Sept 2025 at 08:38, Vincent Mailhol <mailhol@kernel.org> wrote:
> On 22/08/2025 at 18:50, Geert Uytterhoeven wrote:
> > Global state is initialized and torn down before per-channel state.
> > Invert the order to restore symmetry.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> Same comment as before. I assume this is only cosmetic, if not, Fixes: tag please!

Cosmetic only, TTBOMK.

> Reviewed-by: Vincent Mailhol <mailhol@kernel.org>

Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-08-22  9:50 ` [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
  2025-08-22 13:39   ` Biju Das
@ 2025-09-12  7:54   ` Biju Das
  2025-09-12  8:27     ` Geert Uytterhoeven
  2025-09-12  8:43     ` Geert Uytterhoeven
  1 sibling, 2 replies; 25+ messages in thread
From: Biju Das @ 2025-09-12  7:54 UTC (permalink / raw)
  To: Geert Uytterhoeven, Marc Kleine-Budde, Vincent Mailhol
  Cc: linux-can@vger.kernel.org, linux-renesas-soc@vger.kernel.org

Hi Geert Uytterhoeven,

Thanks for the patch.

> -----Original Message-----
> From: Geert Uytterhoeven <geert+renesas@glider.be>
> Sent: 22 August 2025 10:51
> Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume, the CAN-FD interface no longer
> works.  Trying to bring it up again fails:
> 
>     # ip link set can0 up
>     RTNETLINK answers: Connection timed out
> 
>     # dmesg
>     ...
>     channel 0 communication state failed
> 
> Fix this by populating the (currently empty) suspend and resume callbacks, to stop/start the individual
> CAN-FD channels, and (de)initialize the CAN-FD controller.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>

Tested-by: Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>

With adaption to RZ/G3E for ram_clk [1]

> ---
> While this fixes CAN-FD after resume from s2ram on R-Car E3 (Ebisu-4D), it does introduce a regression
> on R-Car V4H (White Hawk): after resume from s2idle (White Hawk does not support s2ram), CAN frames
> sent by other devices are no longer received, and the other side sometimes reports a "bus-off".
> 
> However, the underlying issue is pre-existing, and can be reproduced without this patch: the CAN-FD
> controller fails in the same way after driver unbind/rebind.  So something must be missing in the
> (de)initialization sequence for the R-Car Gen4 CAN-FD register layout.
> Note that it keeps on working after ifdown/ifup, which does not reinitialize the full controller.
> ---
>  drivers/net/can/rcar/rcar_canfd.c | 53 +++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
> 
> diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
> index eedce83b91414c57..6b0c563e894f74b3 100644
> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -2236,11 +2236,64 @@ static void rcar_canfd_remove(struct platform_device *pdev)
> 
>  static int rcar_canfd_suspend(struct device *dev)  {
> +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> +	int err;
> +	u32 ch;
> +
> +	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) {
> +		struct rcar_canfd_channel *priv = gpriv->ch[ch];
> +		struct net_device *ndev = priv->ndev;
> +
> +		if (!netif_running(ndev))
> +			continue;
> +
> +		netif_device_detach(ndev);
> +
> +		err = rcar_canfd_close(ndev);
> +		if (err) {
> +			netdev_err(ndev, "rcar_canfd_close() failed %pe\n",
> +				   ERR_PTR(err));
> +			return err;
> +		}
> +
> +		priv->can.state = CAN_STATE_SLEEPING;
> +	}
> +
> +	/* TODO Skip if wake-up (which is not yet supported) is enabled */
> +	rcar_canfd_global_deinit(gpriv, false);
> +
>  	return 0;
>  }
> 
>  static int rcar_canfd_resume(struct device *dev)  {
> +	struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> +	int err;
> +	u32 ch;
> +
> +	err = rcar_canfd_global_init(gpriv);
> +	if (err) {
> +		dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));

Typo: rcar_canfd_global_init


> +		return err;
> +	}
> +


[1] 

biju@biju:~/linux-work/linux$ git diff
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 57ac90e57f11..cb358a4e49d0 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -468,6 +468,7 @@ struct rcar_canfd_global {
        struct platform_device *pdev;   /* Respective platform device */
        struct clk *clkp;               /* Peripheral clock */
        struct clk *can_clk;            /* fCAN clock */
+       struct clk *clk_ram;            /* Clock RAM */
        unsigned long channels_mask;    /* Enabled channels mask */
        bool extclk;                    /* CANFD or Ext clock */
        bool fdmode;                    /* CAN FD or Classical CAN only mode */
@@ -1983,10 +1984,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
                goto fail_reset2;
        }
 
+       /* Enable RAM clock */
+       err = clk_prepare_enable(gpriv->clk_ram);
+       if (err) {
+               dev_err(dev,
+                       "failed to enable ram clock, error %d\n", err);
+               goto fail_clk;
+       }
+
        err = rcar_canfd_reset_controller(gpriv);
        if (err) {
                dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
-               goto fail_clk;
+               goto fail_ram_clk;
        }
 
        /* Controller in Global reset & Channel reset mode */
@@ -2026,6 +2035,8 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
        rcar_canfd_disable_global_interrupts(gpriv);
 fail_clk:
        clk_disable_unprepare(gpriv->clkp);
+fail_ram_clk:
+       clk_disable_unprepare(gpriv->clk_ram);
 fail_reset2:
        reset_control_assert(gpriv->rstc2);
 fail_reset1:
@@ -2045,6 +2056,7 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool full)
        }
 
        clk_disable_unprepare(gpriv->clkp);
+       clk_disable_unprepare(gpriv->clk_ram);
        reset_control_assert(gpriv->rstc2);
        reset_control_assert(gpriv->rstc1);
 }
@@ -2153,10 +2165,10 @@ static int rcar_canfd_probe(struct platform_device *pdev)
                gpriv->extclk = gpriv->info->external_clk;
        }
 
-       clk_ram = devm_clk_get_optional_enabled(dev, "ram_clk");
+       gpriv->clk_ram = devm_clk_get_optional(dev, "ram_clk");
        if (IS_ERR(clk_ram))
                return dev_err_probe(dev, PTR_ERR(clk_ram),
-                                    "cannot get enabled ram clock\n");
+                                    "cannot get ram clock\n");


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-12  7:54   ` Biju Das
@ 2025-09-12  8:27     ` Geert Uytterhoeven
  2025-09-12  8:56       ` Biju Das
  2025-09-12  8:43     ` Geert Uytterhoeven
  1 sibling, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-12  8:27 UTC (permalink / raw)
  To: Biju Das
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Biju,

On Fri, 12 Sept 2025 at 09:54, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > -----Original Message-----
> > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > Sent: 22 August 2025 10:51
> > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> >
> > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume, the CAN-FD interface no longer
> > works.  Trying to bring it up again fails:
> >
> >     # ip link set can0 up
> >     RTNETLINK answers: Connection timed out
> >
> >     # dmesg
> >     ...
> >     channel 0 communication state failed
> >
> > Fix this by populating the (currently empty) suspend and resume callbacks, to stop/start the individual
> > CAN-FD channels, and (de)initialize the CAN-FD controller.
> >
> > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> Tested-by: Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
>
> With adaption to RZ/G3E for ram_clk [1]

Thanks!

> > --- a/drivers/net/can/rcar/rcar_canfd.c
> > +++ b/drivers/net/can/rcar/rcar_canfd.c

> >
> >  static int rcar_canfd_resume(struct device *dev)  {
> > +     struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> > +     int err;
> > +     u32 ch;
> > +
> > +     err = rcar_canfd_global_init(gpriv);
> > +     if (err) {
> > +             dev_err(dev, "rcar_canfd_open() failed %pe\n", ERR_PTR(err));
>
> Typo: rcar_canfd_global_init

Oops...

> [1]
>
> biju@biju:~/linux-work/linux$ git diff
> diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
> index 57ac90e57f11..cb358a4e49d0 100644
> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -468,6 +468,7 @@ struct rcar_canfd_global {
>         struct platform_device *pdev;   /* Respective platform device */
>         struct clk *clkp;               /* Peripheral clock */
>         struct clk *can_clk;            /* fCAN clock */
> +       struct clk *clk_ram;            /* Clock RAM */
>         unsigned long channels_mask;    /* Enabled channels mask */
>         bool extclk;                    /* CANFD or Ext clock */
>         bool fdmode;                    /* CAN FD or Classical CAN only mode */
> @@ -1983,10 +1984,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
>                 goto fail_reset2;
>         }
>
> +       /* Enable RAM clock */
> +       err = clk_prepare_enable(gpriv->clk_ram);
> +       if (err) {
> +               dev_err(dev,
> +                       "failed to enable ram clock, error %d\n", err);
> +               goto fail_clk;
> +       }
> +
>         err = rcar_canfd_reset_controller(gpriv);
>         if (err) {
>                 dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
> -               goto fail_clk;
> +               goto fail_ram_clk;
>         }
>
>         /* Controller in Global reset & Channel reset mode */
> @@ -2026,6 +2035,8 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
>         rcar_canfd_disable_global_interrupts(gpriv);
>  fail_clk:
>         clk_disable_unprepare(gpriv->clkp);
> +fail_ram_clk:
> +       clk_disable_unprepare(gpriv->clk_ram);
>  fail_reset2:
>         reset_control_assert(gpriv->rstc2);
>  fail_reset1:
> @@ -2045,6 +2056,7 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool full)
>         }
>
>         clk_disable_unprepare(gpriv->clkp);
> +       clk_disable_unprepare(gpriv->clk_ram);
>         reset_control_assert(gpriv->rstc2);
>         reset_control_assert(gpriv->rstc1);
>  }
> @@ -2153,10 +2165,10 @@ static int rcar_canfd_probe(struct platform_device *pdev)
>                 gpriv->extclk = gpriv->info->external_clk;
>         }
>
> -       clk_ram = devm_clk_get_optional_enabled(dev, "ram_clk");
> +       gpriv->clk_ram = devm_clk_get_optional(dev, "ram_clk");
>         if (IS_ERR(clk_ram))
>                 return dev_err_probe(dev, PTR_ERR(clk_ram),
> -                                    "cannot get enabled ram clock\n");
> +                                    "cannot get ram clock\n");

I guess this should be folded into "[PATCH 3/6] can: rcar_canfd:
Extract rcar_canfd_global_{,de}init()", or even better, inserted as
a new patch before that?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-12  7:54   ` Biju Das
  2025-09-12  8:27     ` Geert Uytterhoeven
@ 2025-09-12  8:43     ` Geert Uytterhoeven
  2025-09-12  8:49       ` Biju Das
  1 sibling, 1 reply; 25+ messages in thread
From: Geert Uytterhoeven @ 2025-09-12  8:43 UTC (permalink / raw)
  To: Biju Das
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Biju,

On Fri, 12 Sept 2025 at 09:54, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> With adaption to RZ/G3E for ram_clk [1]

> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -1983,10 +1984,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
>                 goto fail_reset2;
>         }
>
> +       /* Enable RAM clock */
> +       err = clk_prepare_enable(gpriv->clk_ram);
> +       if (err) {
> +               dev_err(dev,
> +                       "failed to enable ram clock, error %d\n", err);
> +               goto fail_clk;
> +       }
> +
>         err = rcar_canfd_reset_controller(gpriv);
>         if (err) {
>                 dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
> -               goto fail_clk;
> +               goto fail_ram_clk;
>         }
>
>         /* Controller in Global reset & Channel reset mode */
> @@ -2026,6 +2035,8 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
>         rcar_canfd_disable_global_interrupts(gpriv);
>  fail_clk:
>         clk_disable_unprepare(gpriv->clkp);
> +fail_ram_clk:
> +       clk_disable_unprepare(gpriv->clk_ram);

Should be inserted above fail_clk.

>  fail_reset2:
>         reset_control_assert(gpriv->rstc2);
>  fail_reset1:
> @@ -2045,6 +2056,7 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool full)
>         }
>
>         clk_disable_unprepare(gpriv->clkp);
> +       clk_disable_unprepare(gpriv->clk_ram);

Wrong order.

>         reset_control_assert(gpriv->rstc2);
>         reset_control_assert(gpriv->rstc1);
>  }

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-12  8:43     ` Geert Uytterhoeven
@ 2025-09-12  8:49       ` Biju Das
  0 siblings, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-09-12  8:49 UTC (permalink / raw)
  To: geert
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 12 September 2025 09:44
> Subject: Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> Hi Biju,
> 
> On Fri, 12 Sept 2025 at 09:54, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > With adaption to RZ/G3E for ram_clk [1]
> 
> > --- a/drivers/net/can/rcar/rcar_canfd.c
> > +++ b/drivers/net/can/rcar/rcar_canfd.c
> > @@ -1983,10 +1984,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> >                 goto fail_reset2;
> >         }
> >
> > +       /* Enable RAM clock */
> > +       err = clk_prepare_enable(gpriv->clk_ram);
> > +       if (err) {
> > +               dev_err(dev,
> > +                       "failed to enable ram clock, error %d\n", err);
> > +               goto fail_clk;
> > +       }
> > +
> >         err = rcar_canfd_reset_controller(gpriv);
> >         if (err) {
> >                 dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
> > -               goto fail_clk;
> > +               goto fail_ram_clk;
> >         }
> >
> >         /* Controller in Global reset & Channel reset mode */ @@
> > -2026,6 +2035,8 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> >         rcar_canfd_disable_global_interrupts(gpriv);
> >  fail_clk:
> >         clk_disable_unprepare(gpriv->clkp);
> > +fail_ram_clk:
> > +       clk_disable_unprepare(gpriv->clk_ram);
> 
> Should be inserted above fail_clk.

Oops. Will fix it

> 
> >  fail_reset2:
> >         reset_control_assert(gpriv->rstc2);
> >  fail_reset1:
> > @@ -2045,6 +2056,7 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool
> full)
> >         }
> >
> >         clk_disable_unprepare(gpriv->clkp);
> > +       clk_disable_unprepare(gpriv->clk_ram);
> 
> Wrong order.

OK.

Will take care in the proper patch.

Cheers,
Biju


^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
  2025-09-12  8:27     ` Geert Uytterhoeven
@ 2025-09-12  8:56       ` Biju Das
  0 siblings, 0 replies; 25+ messages in thread
From: Biju Das @ 2025-09-12  8:56 UTC (permalink / raw)
  To: geert
  Cc: Marc Kleine-Budde, Vincent Mailhol, linux-can@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org

Hi Geert,

> -----Original Message-----
> From: Geert Uytterhoeven <geert@linux-m68k.org>
> Sent: 12 September 2025 09:27
> Subject: Re: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> 
> Hi Biju,
> 
> On Fri, 12 Sept 2025 at 09:54, Biju Das <biju.das.jz@bp.renesas.com> wrote:
> > > -----Original Message-----
> > > From: Geert Uytterhoeven <geert+renesas@glider.be>
> > > Sent: 22 August 2025 10:51
> > > Subject: [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support
> > >
> > > On R-Car Gen3 using PSCI, s2ram powers down the SoC.  After resume,
> > > the CAN-FD interface no longer works.  Trying to bring it up again fails:
> > >
> > >     # ip link set can0 up
> > >     RTNETLINK answers: Connection timed out
> > >
> > >     # dmesg
> > >     ...
> > >     channel 0 communication state failed
> > >
> > > Fix this by populating the (currently empty) suspend and resume
> > > callbacks, to stop/start the individual CAN-FD channels, and (de)initialize the CAN-FD controller.
> > >
> > > Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> >
> > Tested-by: Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
> >
> > With adaption to RZ/G3E for ram_clk [1]
> 
> Thanks!
> 
> > > --- a/drivers/net/can/rcar/rcar_canfd.c
> > > +++ b/drivers/net/can/rcar/rcar_canfd.c
> 
> > >
> > >  static int rcar_canfd_resume(struct device *dev)  {
> > > +     struct rcar_canfd_global *gpriv = dev_get_drvdata(dev);
> > > +     int err;
> > > +     u32 ch;
> > > +
> > > +     err = rcar_canfd_global_init(gpriv);
> > > +     if (err) {
> > > +             dev_err(dev, "rcar_canfd_open() failed %pe\n",
> > > + ERR_PTR(err));
> >
> > Typo: rcar_canfd_global_init
> 
> Oops...
> 
> > [1]
> >
> > biju@biju:~/linux-work/linux$ git diff diff --git
> > a/drivers/net/can/rcar/rcar_canfd.c
> > b/drivers/net/can/rcar/rcar_canfd.c
> > index 57ac90e57f11..cb358a4e49d0 100644
> > --- a/drivers/net/can/rcar/rcar_canfd.c
> > +++ b/drivers/net/can/rcar/rcar_canfd.c
> > @@ -468,6 +468,7 @@ struct rcar_canfd_global {
> >         struct platform_device *pdev;   /* Respective platform device */
> >         struct clk *clkp;               /* Peripheral clock */
> >         struct clk *can_clk;            /* fCAN clock */
> > +       struct clk *clk_ram;            /* Clock RAM */
> >         unsigned long channels_mask;    /* Enabled channels mask */
> >         bool extclk;                    /* CANFD or Ext clock */
> >         bool fdmode;                    /* CAN FD or Classical CAN only mode */
> > @@ -1983,10 +1984,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> >                 goto fail_reset2;
> >         }
> >
> > +       /* Enable RAM clock */
> > +       err = clk_prepare_enable(gpriv->clk_ram);
> > +       if (err) {
> > +               dev_err(dev,
> > +                       "failed to enable ram clock, error %d\n", err);
> > +               goto fail_clk;
> > +       }
> > +
> >         err = rcar_canfd_reset_controller(gpriv);
> >         if (err) {
> >                 dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
> > -               goto fail_clk;
> > +               goto fail_ram_clk;
> >         }
> >
> >         /* Controller in Global reset & Channel reset mode */ @@
> > -2026,6 +2035,8 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> >         rcar_canfd_disable_global_interrupts(gpriv);
> >  fail_clk:
> >         clk_disable_unprepare(gpriv->clkp);
> > +fail_ram_clk:
> > +       clk_disable_unprepare(gpriv->clk_ram);
> >  fail_reset2:
> >         reset_control_assert(gpriv->rstc2);
> >  fail_reset1:
> > @@ -2045,6 +2056,7 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool
> full)
> >         }
> >
> >         clk_disable_unprepare(gpriv->clkp);
> > +       clk_disable_unprepare(gpriv->clk_ram);
> >         reset_control_assert(gpriv->rstc2);
> >         reset_control_assert(gpriv->rstc1);
> >  }
> > @@ -2153,10 +2165,10 @@ static int rcar_canfd_probe(struct platform_device *pdev)
> >                 gpriv->extclk = gpriv->info->external_clk;
> >         }
> >
> > -       clk_ram = devm_clk_get_optional_enabled(dev, "ram_clk");
> > +       gpriv->clk_ram = devm_clk_get_optional(dev, "ram_clk");
> >         if (IS_ERR(clk_ram))
> >                 return dev_err_probe(dev, PTR_ERR(clk_ram),
> > -                                    "cannot get enabled ram clock\n");
> > +                                    "cannot get ram clock\n");
> 
> I guess this should be folded into "[PATCH 3/6] can: rcar_canfd:
> Extract rcar_canfd_global_{,de}init()", or even better, inserted as a new patch before that?

I agree this has to be a new patch before this. I will send next series based on this.

Cheers,
Biju

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2025-09-12  8:56 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-22  9:50 [PATCH 0/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
2025-08-22  9:50 ` [PATCH 1/6] can: rcar_canfd: Invert reset assert order Geert Uytterhoeven
2025-08-22 14:24   ` Biju Das
2025-09-09  6:36   ` Vincent Mailhol
2025-09-09  6:57     ` Geert Uytterhoeven
2025-08-22  9:50 ` [PATCH 2/6] can: rcar_canfd: Invert global vs. channel teardown Geert Uytterhoeven
2025-08-22 14:21   ` Biju Das
2025-09-09  6:38   ` Vincent Mailhol
2025-09-09  6:58     ` Geert Uytterhoeven
2025-08-22  9:50 ` [PATCH 3/6] can: rcar_canfd: Extract rcar_canfd_global_{,de}init() Geert Uytterhoeven
2025-08-22  9:50 ` [PATCH 4/6] can: rcar_canfd: Invert CAN clock and close_candev() order Geert Uytterhoeven
2025-08-22 14:26   ` Biju Das
2025-08-22  9:50 ` [PATCH 5/6] can: rcar_canfd: Convert to DEFINE_SIMPLE_DEV_PM_OPS() Geert Uytterhoeven
2025-08-22 14:27   ` Biju Das
2025-08-22  9:50 ` [PATCH/RFC 6/6] can: rcar_canfd: Add suspend/resume support Geert Uytterhoeven
2025-08-22 13:39   ` Biju Das
2025-08-22 16:19     ` Biju Das
2025-09-08 13:50       ` Geert Uytterhoeven
2025-09-08 13:56         ` Biju Das
2025-09-08 14:06           ` Geert Uytterhoeven
2025-09-12  7:54   ` Biju Das
2025-09-12  8:27     ` Geert Uytterhoeven
2025-09-12  8:56       ` Biju Das
2025-09-12  8:43     ` Geert Uytterhoeven
2025-09-12  8:49       ` Biju Das

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.