[PATCH net v2 3/3] can: rockchip_canfd: cancel bus-off restart before closing the device
Cunhao Lu
1579567540 at qq.com
Tue Oct 13 19:54:24 PDT 2026
The close path cancels restart_work through close_candev() only after
freeing the IRQ, disabling RX offload and stopping the controller. A
running restart can re-enable the controller and its interrupts after
IRQ teardown, or restart timestamp work after it has been stopped and
before runtime suspend removes the controller clocks.
Call close_candev_cancel_restart_sync() at the start of ndo_stop(), while
the resources needed by a running restart are still available. The core
netif_running() check prevents a late restart from entering the driver,
while this cancellation waits for one that has already passed the check.
Keep close_candev() after IRQ teardown for the final cancellation and
echo cleanup, including work queued by an IRQ racing with the first
cancellation.
Exclude the IRQ handler while reinitializing hardware in the restart
callback: the handler continues processing after scheduling recovery,
and a shared interrupt can also invoke it while this controller's
interrupts are masked. Keep the shared IRQ enabled while the close path
waits for restart work to finish.
Fixes: ff60bfbaf67f ("can: rockchip_canfd: add driver for Rockchip CAN-FD controller")
Cc: stable at vger.kernel.org
Signed-off-by: Cunhao Lu <1579567540 at qq.com>
---
drivers/net/can/rockchip/rockchip_canfd-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 37c1c22c40c9..fb8f6b067502 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -356,8 +356,10 @@ static int rkcanfd_set_mode(struct net_device *ndev,
switch (mode) {
case CAN_MODE_START:
+ disable_irq(ndev->irq);
rkcanfd_chip_start(priv);
rkcanfd_chip_interrupts_enable(priv);
+ enable_irq(ndev->irq);
netif_wake_queue(ndev);
break;
@@ -758,6 +760,7 @@ static int rkcanfd_stop(struct net_device *ndev)
{
struct rkcanfd_priv *priv = netdev_priv(ndev);
+ close_candev_cancel_restart_sync(ndev);
netif_stop_queue(ndev);
rkcanfd_chip_interrupts_disable(priv);
--
2.34.1
More information about the linux-arm-kernel
mailing list