Skip to content

Commit a06d3a9

Browse files
vanyuan599gregkh
authored andcommitted
can: mcp251x: add error handling for power enable in open and resume
[ Upstream commit 7a57354 ] Add missing error handling for mcp251x_power_enable() calls in both mcp251x_open() and mcp251x_can_resume() functions. In mcp251x_open(), if power enable fails, jump to error path to close candev without attempting to disable power again. In mcp251x_can_resume(), properly check return values of power enable calls for both power and transceiver regulators. If any fails, return the error code to the PM framework and log the failure. This ensures the driver properly handles power control failures and maintains correct device state. Signed-off-by: Wenyuan Li <2063309626@qq.com> Link: https://patch.msgid.link/tencent_F3EFC5D7738AC548857B91657715E2D3AA06@qq.com [mkl: fix patch description] [mkl: mcp251x_can_resume(): replace goto by return] Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 06d4938 commit a06d3a9

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

drivers/net/can/spi/mcp251x.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,11 @@ static int mcp251x_open(struct net_device *net)
12121212
}
12131213

12141214
mutex_lock(&priv->mcp_lock);
1215-
mcp251x_power_enable(priv->transceiver, 1);
1215+
ret = mcp251x_power_enable(priv->transceiver, 1);
1216+
if (ret) {
1217+
dev_err(&spi->dev, "failed to enable transceiver power: %pe\n", ERR_PTR(ret));
1218+
goto out_close_candev;
1219+
}
12161220

12171221
priv->force_quit = 0;
12181222
priv->tx_skb = NULL;
@@ -1259,6 +1263,7 @@ static int mcp251x_open(struct net_device *net)
12591263
mcp251x_hw_sleep(spi);
12601264
out_close:
12611265
mcp251x_power_enable(priv->transceiver, 0);
1266+
out_close_candev:
12621267
close_candev(net);
12631268
mutex_unlock(&priv->mcp_lock);
12641269
if (release_irq)
@@ -1494,11 +1499,25 @@ static int __maybe_unused mcp251x_can_resume(struct device *dev)
14941499
{
14951500
struct spi_device *spi = to_spi_device(dev);
14961501
struct mcp251x_priv *priv = spi_get_drvdata(spi);
1502+
int ret = 0;
14971503

1498-
if (priv->after_suspend & AFTER_SUSPEND_POWER)
1499-
mcp251x_power_enable(priv->power, 1);
1500-
if (priv->after_suspend & AFTER_SUSPEND_UP)
1501-
mcp251x_power_enable(priv->transceiver, 1);
1504+
if (priv->after_suspend & AFTER_SUSPEND_POWER) {
1505+
ret = mcp251x_power_enable(priv->power, 1);
1506+
if (ret) {
1507+
dev_err(dev, "failed to restore power: %pe\n", ERR_PTR(ret));
1508+
return ret;
1509+
}
1510+
}
1511+
1512+
if (priv->after_suspend & AFTER_SUSPEND_UP) {
1513+
ret = mcp251x_power_enable(priv->transceiver, 1);
1514+
if (ret) {
1515+
dev_err(dev, "failed to restore transceiver power: %pe\n", ERR_PTR(ret));
1516+
if (priv->after_suspend & AFTER_SUSPEND_POWER)
1517+
mcp251x_power_enable(priv->power, 0);
1518+
return ret;
1519+
}
1520+
}
15021521

15031522
if (priv->after_suspend & (AFTER_SUSPEND_POWER | AFTER_SUSPEND_UP))
15041523
queue_work(priv->wq, &priv->restart_work);

0 commit comments

Comments
 (0)