From 36ca393bd32ea426f29c9c505ebb2a01b772a32e Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 4 Jun 2026 12:27:27 +0100 Subject: [PATCH 1/2] Revert "can: mcp251x: add error handling for power enable in open and resume" This reverts commit a06d3a9309733402aaad7ae0a848ea1afd0aac76. --- drivers/net/can/spi/mcp251x.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index b241953d2ef61d..74906aa98be3ec 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -1212,11 +1212,7 @@ static int mcp251x_open(struct net_device *net) } mutex_lock(&priv->mcp_lock); - ret = mcp251x_power_enable(priv->transceiver, 1); - if (ret) { - dev_err(&spi->dev, "failed to enable transceiver power: %pe\n", ERR_PTR(ret)); - goto out_close_candev; - } + mcp251x_power_enable(priv->transceiver, 1); priv->force_quit = 0; priv->tx_skb = NULL; @@ -1263,7 +1259,6 @@ static int mcp251x_open(struct net_device *net) mcp251x_hw_sleep(spi); out_close: mcp251x_power_enable(priv->transceiver, 0); -out_close_candev: close_candev(net); mutex_unlock(&priv->mcp_lock); if (release_irq) @@ -1499,25 +1494,11 @@ static int __maybe_unused mcp251x_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct mcp251x_priv *priv = spi_get_drvdata(spi); - int ret = 0; - if (priv->after_suspend & AFTER_SUSPEND_POWER) { - ret = mcp251x_power_enable(priv->power, 1); - if (ret) { - dev_err(dev, "failed to restore power: %pe\n", ERR_PTR(ret)); - return ret; - } - } - - if (priv->after_suspend & AFTER_SUSPEND_UP) { - ret = mcp251x_power_enable(priv->transceiver, 1); - if (ret) { - dev_err(dev, "failed to restore transceiver power: %pe\n", ERR_PTR(ret)); - if (priv->after_suspend & AFTER_SUSPEND_POWER) - mcp251x_power_enable(priv->power, 0); - return ret; - } - } + if (priv->after_suspend & AFTER_SUSPEND_POWER) + mcp251x_power_enable(priv->power, 1); + if (priv->after_suspend & AFTER_SUSPEND_UP) + mcp251x_power_enable(priv->transceiver, 1); if (priv->after_suspend & (AFTER_SUSPEND_POWER | AFTER_SUSPEND_UP)) queue_work(priv->wq, &priv->restart_work); From 1383f73ef78e6fae2c196dfcef5d215a4361760f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 4 Jun 2026 12:27:50 +0100 Subject: [PATCH 2/2] Revert "can: mcp251x: fix deadlock in error path of mcp251x_open" This reverts commit 38063cc435b69d56e76f947c10d336fcb2953508. --- drivers/net/can/spi/mcp251x.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index 74906aa98be3ec..ec5c64006a16f7 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -1201,7 +1201,6 @@ static int mcp251x_open(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); struct spi_device *spi = priv->spi; - bool release_irq = false; unsigned long flags = 0; int ret; @@ -1245,24 +1244,12 @@ static int mcp251x_open(struct net_device *net) return 0; out_free_irq: - /* The IRQ handler might be running, and if so it will be waiting - * for the lock. But free_irq() must wait for the handler to finish - * so calling it here would deadlock. - * - * Setting priv->force_quit will let the handler exit right away - * without any access to the hardware. This make it safe to call - * free_irq() after the lock is released. - */ - priv->force_quit = 1; - release_irq = true; - + free_irq(spi->irq, priv); mcp251x_hw_sleep(spi); out_close: mcp251x_power_enable(priv->transceiver, 0); close_candev(net); mutex_unlock(&priv->mcp_lock); - if (release_irq) - free_irq(spi->irq, priv); return ret; }