Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 6 additions & 38 deletions drivers/net/can/spi/mcp251x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -1212,11 +1211,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;
Expand Down Expand Up @@ -1249,25 +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);
out_close_candev:
close_candev(net);
mutex_unlock(&priv->mcp_lock);
if (release_irq)
free_irq(spi->irq, priv);
return ret;
}

Expand Down Expand Up @@ -1499,25 +1481,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);
Expand Down
Loading