Commit 4cee0fb9 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-next-for-6.4-20230327' of...

Merge tag 'linux-can-next-for-6.4-20230327' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2023-03-27

The first 2 patches by Geert Uytterhoeven add transceiver support and
improve the error messages in the rcar_canfd driver.

Cai Huoqing contributes 3 patches which remove a redundant call to
pci_clear_master() in the c_can, ctucanfd and kvaser_pciefd driver.

Frank Jungclaus's patch replaces the struct esd_usb_msg with a union
in the esd_usb driver to improve readability.

Markus Schneider-Pargmann contributes 5 patches to improve the
performance in the m_can driver, especially for SPI attached
controllers like the tcan4x5x.

* tag 'linux-can-next-for-6.4-20230327' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  can: m_can: Keep interrupts enabled during peripheral read
  can: m_can: Disable unused interrupts
  can: m_can: Remove double interrupt enable
  can: m_can: Always acknowledge all interrupts
  can: m_can: Remove repeated check for is_peripheral
  can: esd_usb: Improve code readability by means of replacing struct esd_usb_msg with a union
  can: kvaser_pciefd: Remove redundant pci_clear_master
  can: ctucanfd: Remove redundant pci_clear_master
  can: c_can: Remove redundant pci_clear_master
  can: rcar_canfd: Improve error messages
  can: rcar_canfd: Add transceiver support
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents da954ae1 db88681c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -227,7 +227,6 @@ static int c_can_pci_probe(struct pci_dev *pdev,
	pci_iounmap(pdev, addr);
out_release_regions:
	pci_disable_msi(pdev);
	pci_clear_master(pdev);
	pci_release_regions(pdev);
out_disable_device:
	pci_disable_device(pdev);
@@ -247,7 +246,6 @@ static void c_can_pci_remove(struct pci_dev *pdev)

	pci_iounmap(pdev, addr);
	pci_disable_msi(pdev);
	pci_clear_master(pdev);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
}
+2 −6
Original line number Diff line number Diff line
@@ -206,10 +206,8 @@ static int ctucan_pci_probe(struct pci_dev *pdev,
err_pci_iounmap_bar1:
	pci_iounmap(pdev, addr);
err_release_regions:
	if (msi_ok) {
	if (msi_ok)
		pci_disable_msi(pdev);
		pci_clear_master(pdev);
	}
	pci_release_regions(pdev);
err_disable_device:
	pci_disable_device(pdev);
@@ -257,10 +255,8 @@ static void ctucan_pci_remove(struct pci_dev *pdev)

	pci_iounmap(pdev, bdata->bar1_base);

	if (bdata->use_msi) {
	if (bdata->use_msi)
		pci_disable_msi(pdev);
		pci_clear_master(pdev);
	}

	pci_release_regions(pdev);
	pci_disable_device(pdev);
+0 −1
Original line number Diff line number Diff line
@@ -1907,7 +1907,6 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev)

	free_irq(pcie->pci->irq, pcie);

	pci_clear_master(pdev);
	pci_iounmap(pdev, pcie->reg_base);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
+19 −18
Original line number Diff line number Diff line
@@ -972,8 +972,8 @@ static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus)
	/* Don't re-enable interrupts if the driver had a fatal error
	 * (e.g., FIFO read failure).
	 */
	if (work_done >= 0)
		m_can_enable_all_interrupts(cdev);
	if (work_done < 0)
		m_can_disable_all_interrupts(cdev);

	return work_done;
}
@@ -1083,7 +1083,6 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
		return IRQ_NONE;

	/* ACK all irqs */
	if (ir & IR_ALL_INT)
	m_can_write(cdev, M_CAN_IR, ir);

	if (cdev->ops->clear_interrupts)
@@ -1096,12 +1095,13 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
	 */
	if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) {
		cdev->irqstatus = ir;
		if (!cdev->is_peripheral) {
			m_can_disable_all_interrupts(cdev);
		if (!cdev->is_peripheral)
			napi_schedule(&cdev->napi);
		else if (m_can_rx_peripheral(dev, ir) < 0)
		} else if (m_can_rx_peripheral(dev, ir) < 0) {
			goto out_fail;
		}
	}

	if (cdev->version == 30) {
		if (ir & IR_TC) {
@@ -1262,6 +1262,7 @@ static int m_can_set_bittiming(struct net_device *dev)
static int m_can_chip_config(struct net_device *dev)
{
	struct m_can_classdev *cdev = netdev_priv(dev);
	u32 interrupts = IR_ALL_INT;
	u32 cccr, test;
	int err;

@@ -1271,6 +1272,11 @@ static int m_can_chip_config(struct net_device *dev)
		return err;
	}

	/* Disable unused interrupts */
	interrupts &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TEFW | IR_TFE |
			IR_TCF | IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N |
			IR_RF0F | IR_RF0W);

	m_can_config_endisable(cdev, true);

	/* RX Buffer/FIFO Element Size 64 bytes data field */
@@ -1365,16 +1371,13 @@ static int m_can_chip_config(struct net_device *dev)
	m_can_write(cdev, M_CAN_TEST, test);

	/* Enable interrupts */
	m_can_write(cdev, M_CAN_IR, IR_ALL_INT);
	if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
	if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
		if (cdev->version == 30)
			m_can_write(cdev, M_CAN_IE, IR_ALL_INT &
				    ~(IR_ERR_LEC_30X));
		else
			m_can_write(cdev, M_CAN_IE, IR_ALL_INT &
				    ~(IR_ERR_LEC_31X));
			interrupts &= ~(IR_ERR_LEC_30X);
		else
		m_can_write(cdev, M_CAN_IE, IR_ALL_INT);
			interrupts &= ~(IR_ERR_LEC_31X);
	}
	m_can_write(cdev, M_CAN_IE, interrupts);

	/* route all interrupts to INT0 */
	m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0);
@@ -1592,10 +1595,8 @@ static int m_can_close(struct net_device *dev)
		cdev->tx_skb = NULL;
		destroy_workqueue(cdev->tx_wq);
		cdev->tx_wq = NULL;
	}

	if (cdev->is_peripheral)
		can_rx_offload_disable(&cdev->offload);
	}

	close_candev(dev);

+45 −26
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/types.h>
@@ -530,6 +531,7 @@ struct rcar_canfd_channel {
	struct net_device *ndev;
	struct rcar_canfd_global *gpriv;	/* Controller reference */
	void __iomem *base;			/* Register base address */
	struct phy *transceiver;		/* Optional transceiver */
	struct napi_struct napi;
	u32 tx_head;				/* Incremented on xmit */
	u32 tx_tail;				/* Incremented on xmit done */
@@ -1413,16 +1415,22 @@ static int rcar_canfd_open(struct net_device *ndev)
	struct rcar_canfd_global *gpriv = priv->gpriv;
	int err;

	err = phy_power_on(priv->transceiver);
	if (err) {
		netdev_err(ndev, "failed to power on PHY: %pe\n", ERR_PTR(err));
		return err;
	}

	/* Peripheral clock is already enabled in probe */
	err = clk_prepare_enable(gpriv->can_clk);
	if (err) {
		netdev_err(ndev, "failed to enable CAN clock, error %d\n", err);
		goto out_clock;
		netdev_err(ndev, "failed to enable CAN clock: %pe\n", ERR_PTR(err));
		goto out_phy;
	}

	err = open_candev(ndev);
	if (err) {
		netdev_err(ndev, "open_candev() failed, error %d\n", err);
		netdev_err(ndev, "open_candev() failed: %pe\n", ERR_PTR(err));
		goto out_can_clock;
	}

@@ -1437,7 +1445,8 @@ static int rcar_canfd_open(struct net_device *ndev)
	close_candev(ndev);
out_can_clock:
	clk_disable_unprepare(gpriv->can_clk);
out_clock:
out_phy:
	phy_power_off(priv->transceiver);
	return err;
}

@@ -1480,6 +1489,7 @@ static int rcar_canfd_close(struct net_device *ndev)
	napi_disable(&priv->napi);
	clk_disable_unprepare(gpriv->can_clk);
	close_candev(ndev);
	phy_power_off(priv->transceiver);
	return 0;
}

@@ -1711,7 +1721,7 @@ static const struct ethtool_ops rcar_canfd_ethtool_ops = {
};

static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
				    u32 fcan_freq)
				    u32 fcan_freq, struct phy *transceiver)
{
	const struct rcar_canfd_hw_info *info = gpriv->info;
	struct platform_device *pdev = gpriv->pdev;
@@ -1721,10 +1731,9 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
	int err = -ENODEV;

	ndev = alloc_candev(sizeof(*priv), RCANFD_FIFO_DEPTH);
	if (!ndev) {
		dev_err(dev, "alloc_candev() failed\n");
	if (!ndev)
		return -ENOMEM;
	}

	priv = netdev_priv(ndev);

	ndev->netdev_ops = &rcar_canfd_netdev_ops;
@@ -1732,8 +1741,11 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
	ndev->flags |= IFF_ECHO;
	priv->ndev = ndev;
	priv->base = gpriv->base;
	priv->transceiver = transceiver;
	priv->channel = ch;
	priv->gpriv = gpriv;
	if (transceiver)
		priv->can.bitrate_max = transceiver->attrs.max_link_rate;
	priv->can.clock.freq = fcan_freq;
	dev_info(dev, "can_clk rate is %u\n", priv->can.clock.freq);

@@ -1764,8 +1776,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
				       rcar_canfd_channel_err_interrupt, 0,
				       irq_name, priv);
		if (err) {
			dev_err(dev, "devm_request_irq CH Err(%d) failed, error %d\n",
				err_irq, err);
			dev_err(dev, "devm_request_irq CH Err %d failed: %pe\n",
				err_irq, ERR_PTR(err));
			goto fail;
		}
		irq_name = devm_kasprintf(dev, GFP_KERNEL, "canfd.ch%d_trx",
@@ -1778,8 +1790,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
				       rcar_canfd_channel_tx_interrupt, 0,
				       irq_name, priv);
		if (err) {
			dev_err(dev, "devm_request_irq Tx (%d) failed, error %d\n",
				tx_irq, err);
			dev_err(dev, "devm_request_irq Tx %d failed: %pe\n",
				tx_irq, ERR_PTR(err));
			goto fail;
		}
	}
@@ -1810,7 +1822,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
	gpriv->ch[priv->channel] = priv;
	err = register_candev(ndev);
	if (err) {
		dev_err(dev, "register_candev() failed, error %d\n", err);
		dev_err(dev, "register_candev() failed: %pe\n", ERR_PTR(err));
		goto fail_candev;
	}
	dev_info(dev, "device registered (channel %u)\n", priv->channel);
@@ -1836,6 +1848,7 @@ static void rcar_canfd_channel_remove(struct rcar_canfd_global *gpriv, u32 ch)

static int rcar_canfd_probe(struct platform_device *pdev)
{
	struct phy *transceivers[RCANFD_NUM_CHANNELS] = { 0, };
	const struct rcar_canfd_hw_info *info;
	struct device *dev = &pdev->dev;
	void __iomem *addr;
@@ -1857,9 +1870,14 @@ static int rcar_canfd_probe(struct platform_device *pdev)
	for (i = 0; i < info->max_channels; ++i) {
		name[7] = '0' + i;
		of_child = of_get_child_by_name(dev->of_node, name);
		if (of_child && of_device_is_available(of_child))
		if (of_child && of_device_is_available(of_child)) {
			channels_mask |= BIT(i);
			transceivers[i] = devm_of_phy_optional_get(dev,
							of_child, NULL);
		}
		of_node_put(of_child);
		if (IS_ERR(transceivers[i]))
			return PTR_ERR(transceivers[i]);
	}

	if (info->shared_global_irqs) {
@@ -1948,16 +1966,16 @@ static int rcar_canfd_probe(struct platform_device *pdev)
				       rcar_canfd_channel_interrupt, 0,
				       "canfd.ch_int", gpriv);
		if (err) {
			dev_err(dev, "devm_request_irq(%d) failed, error %d\n",
				ch_irq, err);
			dev_err(dev, "devm_request_irq %d failed: %pe\n",
				ch_irq, ERR_PTR(err));
			goto fail_dev;
		}

		err = devm_request_irq(dev, g_irq, rcar_canfd_global_interrupt,
				       0, "canfd.g_int", gpriv);
		if (err) {
			dev_err(dev, "devm_request_irq(%d) failed, error %d\n",
				g_irq, err);
			dev_err(dev, "devm_request_irq %d failed: %pe\n",
				g_irq, ERR_PTR(err));
			goto fail_dev;
		}
	} else {
@@ -1966,8 +1984,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
				       "canfd.g_recc", gpriv);

		if (err) {
			dev_err(dev, "devm_request_irq(%d) failed, error %d\n",
				g_recc_irq, err);
			dev_err(dev, "devm_request_irq %d failed: %pe\n",
				g_recc_irq, ERR_PTR(err));
			goto fail_dev;
		}

@@ -1975,8 +1993,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
				       rcar_canfd_global_err_interrupt, 0,
				       "canfd.g_err", gpriv);
		if (err) {
			dev_err(dev, "devm_request_irq(%d) failed, error %d\n",
				g_err_irq, err);
			dev_err(dev, "devm_request_irq %d failed: %pe\n",
				g_err_irq, ERR_PTR(err));
			goto fail_dev;
		}
	}
@@ -1993,14 +2011,14 @@ static int rcar_canfd_probe(struct platform_device *pdev)
	/* Enable peripheral clock for register access */
	err = clk_prepare_enable(gpriv->clkp);
	if (err) {
		dev_err(dev, "failed to enable peripheral clock, error %d\n",
			err);
		dev_err(dev, "failed to enable peripheral clock: %pe\n",
			ERR_PTR(err));
		goto fail_reset;
	}

	err = rcar_canfd_reset_controller(gpriv);
	if (err) {
		dev_err(dev, "reset controller failed\n");
		dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
		goto fail_clk;
	}

@@ -2035,7 +2053,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
	}

	for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) {
		err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq);
		err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq,
					       transceivers[ch]);
		if (err)
			goto fail_channel;
	}
Loading