* [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver
@ 2026-08-05 11:07 Sean Nyekjaer
2026-08-05 11:23 ` sashiko-bot
2026-08-05 12:25 ` Marc Kleine-Budde
0 siblings, 2 replies; 3+ messages in thread
From: Sean Nyekjaer @ 2026-08-05 11:07 UTC (permalink / raw)
To: Markus Schneider-Pargmann, Marc Kleine-Budde, Vincent Mailhol
Cc: Sean Nyekjaer, linux-can, linux-kernel
Put the tcan4x5x transceiver into sleep mode when the driver is
removed, instead of leaving it in its current operating mode.
This reduces power consumption(3mA@12V) once the driver is
no longer bound to the device.
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
---
Changes since v1:
- Moved enter sleep mode into tcan4x5x_power_enable()
Changes since v2:
- Added comment about RST pin
- Fixed all calls to tcan4x5x_power_enable()
Changes since v3:
- When powering off, always put the device into sleep mode (if the RST pin is
present). This will ensure the device is in sleep mode even if the
power regulator is shared.
Changes since v4:
- Don't exit early if regmap_update_bits() fails in
tcan4x5x_power_enable()
drivers/net/can/m_can/tcan4x5x-core.c | 30 +++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
index 31cc9d0abd45..bdb266be6dd3 100644
--- a/drivers/net/can/m_can/tcan4x5x-core.c
+++ b/drivers/net/can/m_can/tcan4x5x-core.c
@@ -211,8 +211,30 @@ static int tcan4x5x_write_fifo(struct m_can_classdev *cdev,
return regmap_bulk_write(priv->regmap, TCAN4X5X_MRAM_START + addr_offset, val, val_count);
}
-static int tcan4x5x_power_enable(struct regulator *reg, int enable)
+static int tcan4x5x_power_enable(struct tcan4x5x_priv *priv, int enable)
{
+ struct regulator *reg = priv->power;
+ int ret;
+
+ /*
+ * Put the device into sleep mode if the RST pin is available,
+ * since a wake-up event, RST pin toggle, or power cycle are the only
+ * ways to exit sleep mode.
+ * Redundant if the regulator is exclusive to this device, but that
+ * can't be determined here.
+ *
+ * Datasheet: TCAN4550, section "8.4.3 Sleep Mode"
+ * https://www.ti.com/lit/gpn/tcan4550
+ */
+ if (priv->reset_gpio && !enable) {
+ ret = regmap_update_bits(priv->regmap, TCAN4X5X_CONFIG,
+ TCAN4X5X_MODE_SEL_MASK,
+ TCAN4X5X_MODE_SLEEP);
+ if (ret)
+ dev_err(&priv->spi->dev, "Setting sleep mode failed %pe\n",
+ ERR_PTR(ret));
+ }
+
if (IS_ERR_OR_NULL(reg))
return 0;
@@ -476,7 +498,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
goto out_m_can_class_free_dev;
}
- ret = tcan4x5x_power_enable(priv->power, 1);
+ ret = tcan4x5x_power_enable(priv, 1);
if (ret) {
dev_err(&spi->dev, "Enabling regulator failed %pe\n",
ERR_PTR(ret));
@@ -531,7 +553,7 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
return 0;
out_power:
- tcan4x5x_power_enable(priv->power, 0);
+ tcan4x5x_power_enable(priv, 0);
out_m_can_class_free_dev:
m_can_class_free_dev(mcan_class->net);
return ret;
@@ -543,7 +565,7 @@ static void tcan4x5x_can_remove(struct spi_device *spi)
m_can_class_unregister(&priv->cdev);
- tcan4x5x_power_enable(priv->power, 0);
+ tcan4x5x_power_enable(priv, 0);
m_can_class_free_dev(priv->cdev.net);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver
2026-08-05 11:07 [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver Sean Nyekjaer
@ 2026-08-05 11:23 ` sashiko-bot
2026-08-05 12:25 ` Marc Kleine-Budde
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-08-05 11:23 UTC (permalink / raw)
To: Sean Nyekjaer
Cc: Oleksij Rempel, linux-can, Vincent Mailhol, Marc Kleine-Budde,
Oliver Hartkopp
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Polling timer Use-After-Free during device shutdown when configured without an IRQ.
--
--- Patch [1]: [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver ---
commit 2a7917c5ce38fcbd43e02a99be03a839492ce7ee
Author: Sean Nyekjaer <sean@geanix.com>
can: tcan4x5x: put tcan into sleep when removing driver
This commit puts the tcan4x5x transceiver into sleep mode when the driver is
removed instead of leaving it in its operating mode. This reduces power
consumption once the driver is no longer bound to the device.
> diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
> index 31cc9d0abd453..bdb266be6dd37 100644
> --- a/drivers/net/can/m_can/tcan4x5x-core.c
> +++ b/drivers/net/can/m_can/tcan4x5x-core.c
[ ... ]
> @@ -543,7 +565,7 @@ static void tcan4x5x_can_remove(struct spi_device *spi)
>
> m_can_class_unregister(&priv->cdev);
>
> - tcan4x5x_power_enable(priv->power, 0);
> + tcan4x5x_power_enable(priv, 0);
>
> m_can_class_free_dev(priv->cdev.net);
[Severity: High]
This isn't a bug introduced by this patch, but could this lead to a
use-after-free of the m_can_classdev structure when the device is operating
in polling mode (without an IRQ)?
When the interface is shut down prior to driver removal, m_can_close()
eventually calls m_can_disable_all_interrupts() which attempts to stop the
polling timer:
drivers/net/can/m_can/m_can.c:m_can_disable_all_interrupts() {
...
if (!cdev->net->irq) {
...
hrtimer_try_to_cancel(&cdev->hrtimer);
}
...
}
Because hrtimer_try_to_cancel() does not block to wait for a concurrently
executing timer callback (m_can_polling_timer()) to complete, it returns -1
and allows the driver teardown sequence to proceed immediately.
If the driver unbinds and tcan4x5x_can_remove() calls m_can_class_free_dev()
while the timer callback is still executing on another CPU, won't the timer
callback access freed memory when it interacts with fields like
cdev->can.state?
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260805110708.3220251-1-sean@geanix.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver
2026-08-05 11:07 [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver Sean Nyekjaer
2026-08-05 11:23 ` sashiko-bot
@ 2026-08-05 12:25 ` Marc Kleine-Budde
1 sibling, 0 replies; 3+ messages in thread
From: Marc Kleine-Budde @ 2026-08-05 12:25 UTC (permalink / raw)
To: Sean Nyekjaer
Cc: Markus Schneider-Pargmann, Vincent Mailhol, linux-can,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 713 bytes --]
On 05.08.2026 13:07:07, Sean Nyekjaer wrote:
> Put the tcan4x5x transceiver into sleep mode when the driver is
> removed, instead of leaving it in its current operating mode.
> This reduces power consumption(3mA@12V) once the driver is
> no longer bound to the device.
>
> Signed-off-by: Sean Nyekjaer <sean@geanix.com>
Thank you for your persistence. sashiko is finally happy, and so am I,
added to linux-can-next.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Embedded Linux | https://www.pengutronix.de |
Vertretung Nürnberg | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-05 12:25 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 11:07 [PATCH v5] can: tcan4x5x: put tcan into sleep when removing driver Sean Nyekjaer
2026-08-05 11:23 ` sashiko-bot
2026-08-05 12:25 ` Marc Kleine-Budde
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.