Commit 9f3c3b42 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-fixes-for-5.13-20210506' of...

Merge tag 'linux-can-fixes-for-5.13-20210506' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2021-05-06

The first two patches target the mcp251xfd driver. Dan Carpenter's
patch fixes a NULL pointer dereference in the probe function's error
path. A patch by me adds the missing can_rx_offload_del() in error
path of the probe function.

Frieder Schrempf contributes a patch for the mcp251x driver, the patch
fixes the resume from sleep before interface was brought up.

The last patch is by me and fixes a race condition in the TX path of
the m_can driver for peripheral (SPI) based m_can cores.

* tag 'linux-can-fixes-for-5.13-20210506' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: m_can: m_can_tx_work_queue(): fix tx_skb race condition
  can: mcp251x: fix resume from sleep before interface was brought up
  can: mcp251xfd: mcp251xfd_probe(): add missing can_rx_offload_del() in error path
  can: mcp251xfd: mcp251xfd_probe(): fix an error pointer dereference in probe
====================

Link: https://lore.kernel.org/r/20210506074015.1300591-1-mkl@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 86214366 e04b2cfe
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1562,6 +1562,8 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev)
	int i;
	int putidx;

	cdev->tx_skb = NULL;

	/* Generate ID field for TX buffer Element */
	/* Common to all supported M_CAN versions */
	if (cf->can_id & CAN_EFF_FLAG) {
@@ -1678,7 +1680,6 @@ static void m_can_tx_work_queue(struct work_struct *ws)
						   tx_work);

	m_can_tx_handler(cdev);
	cdev->tx_skb = NULL;
}

static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
+18 −17
Original line number Diff line number Diff line
@@ -956,8 +956,6 @@ static int mcp251x_stop(struct net_device *net)

	priv->force_quit = 1;
	free_irq(spi->irq, priv);
	destroy_workqueue(priv->wq);
	priv->wq = NULL;

	mutex_lock(&priv->mcp_lock);

@@ -1224,24 +1222,15 @@ static int mcp251x_open(struct net_device *net)
		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_wake(spi);
	if (ret)
		goto out_free_wq;
		goto out_free_irq;
	ret = mcp251x_setup(net, spi);
	if (ret)
		goto out_free_wq;
		goto out_free_irq;
	ret = mcp251x_set_normal_mode(spi);
	if (ret)
		goto out_free_wq;
		goto out_free_irq;

	can_led_event(net, CAN_LED_EVENT_OPEN);

@@ -1250,9 +1239,7 @@ static int mcp251x_open(struct net_device *net)

	return 0;

out_free_wq:
	destroy_workqueue(priv->wq);
out_clean:
out_free_irq:
	free_irq(spi->irq, priv);
	mcp251x_hw_sleep(spi);
out_close:
@@ -1373,6 +1360,15 @@ static int mcp251x_can_probe(struct spi_device *spi)
	if (ret)
		goto out_clk;

	priv->wq = alloc_workqueue("mcp251x_wq", WQ_FREEZABLE | WQ_MEM_RECLAIM,
				   0);
	if (!priv->wq) {
		ret = -ENOMEM;
		goto out_clk;
	}
	INIT_WORK(&priv->tx_work, mcp251x_tx_work_handler);
	INIT_WORK(&priv->restart_work, mcp251x_restart_work_handler);

	priv->spi = spi;
	mutex_init(&priv->mcp_lock);

@@ -1417,6 +1413,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
	return 0;

error_probe:
	destroy_workqueue(priv->wq);
	priv->wq = NULL;
	mcp251x_power_enable(priv->power, 0);

out_clk:
@@ -1438,6 +1436,9 @@ static int mcp251x_can_remove(struct spi_device *spi)

	mcp251x_power_enable(priv->power, 0);

	destroy_workqueue(priv->wq);
	priv->wq = NULL;

	clk_disable_unprepare(priv->clk);

	free_candev(net);
+5 −3
Original line number Diff line number Diff line
@@ -2885,7 +2885,7 @@ static int mcp251xfd_probe(struct spi_device *spi)

	clk = devm_clk_get(&spi->dev, NULL);
	if (IS_ERR(clk))
		dev_err_probe(&spi->dev, PTR_ERR(clk),
		return dev_err_probe(&spi->dev, PTR_ERR(clk),
				     "Failed to get Oscillator (clock)!\n");
	freq = clk_get_rate(clk);

@@ -2986,10 +2986,12 @@ static int mcp251xfd_probe(struct spi_device *spi)

	err = mcp251xfd_register(priv);
	if (err)
		goto out_free_candev;
		goto out_can_rx_offload_del;

	return 0;

 out_can_rx_offload_del:
	can_rx_offload_del(&priv->offload);
 out_free_candev:
	spi->max_speed_hz = priv->spi_max_speed_hz_orig;