diff options
Diffstat (limited to 'drivers/net/can/spi/mcp251x.c')
| -rw-r--r-- | drivers/net/can/spi/mcp251x.c | 52 | 
1 files changed, 24 insertions, 28 deletions
diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index 44e99e3d7134..12358f06d194 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -664,17 +664,6 @@ static int mcp251x_power_enable(struct regulator *reg, int enable)  		return regulator_disable(reg);  } -static void mcp251x_open_clean(struct net_device *net) -{ -	struct mcp251x_priv *priv = netdev_priv(net); -	struct spi_device *spi = priv->spi; - -	free_irq(spi->irq, priv); -	mcp251x_hw_sleep(spi); -	mcp251x_power_enable(priv->transceiver, 0); -	close_candev(net); -} -  static int mcp251x_stop(struct net_device *net)  {  	struct mcp251x_priv *priv = netdev_priv(net); @@ -860,7 +849,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)  			if (new_state >= CAN_STATE_ERROR_WARNING &&  			    new_state <= CAN_STATE_BUS_OFF)  				priv->can.can_stats.error_warning++; -		case CAN_STATE_ERROR_WARNING:	/* fallthrough */ +			/* fall through */ +		case CAN_STATE_ERROR_WARNING:  			if (new_state >= CAN_STATE_ERROR_PASSIVE &&  			    new_state <= CAN_STATE_BUS_OFF)  				priv->can.can_stats.error_passive++; @@ -940,37 +930,43 @@ static int mcp251x_open(struct net_device *net)  				   flags | IRQF_ONESHOT, DEVICE_NAME, priv);  	if (ret) {  		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); -		mcp251x_power_enable(priv->transceiver, 0); -		close_candev(net); -		goto open_unlock; +		goto out_close;  	}  	priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,  				   0); +	if (!priv->wq) { +		ret = -ENOMEM; +		goto out_clean; +	}  	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);  	INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);  	ret = mcp251x_hw_reset(spi); -	if (ret) { -		mcp251x_open_clean(net); -		goto open_unlock; -	} +	if (ret) +		goto out_free_wq;  	ret = mcp251x_setup(net, spi); -	if (ret) { -		mcp251x_open_clean(net); -		goto open_unlock; -	} +	if (ret) +		goto out_free_wq;  	ret = mcp251x_set_normal_mode(spi); -	if (ret) { -		mcp251x_open_clean(net); -		goto open_unlock; -	} +	if (ret) +		goto out_free_wq;  	can_led_event(net, CAN_LED_EVENT_OPEN);  	netif_wake_queue(net); +	mutex_unlock(&priv->mcp_lock); -open_unlock: +	return 0; + +out_free_wq: +	destroy_workqueue(priv->wq); +out_clean: +	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);  	return ret;  }  | 
