Commit a43a0720 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-next-for-5.17-20211208' of...

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

Marc Kleine-Budde says:

====================
can-next 2021-12-08

The first patch is by Vincent Mailhol and replaces the custom CAN
units with generic one form linux/units.h.

The next 3 patches are by Evgeny Boger and add Allwinner R40 support
to the sun4i CAN driver.

Andy Shevchenko contributes 4 patches to the hi311x CAN driver,
consisting of cleanups and converting the driver to the device
property API.

* tag 'linux-can-next-for-5.17-20211208' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  can: hi311x: hi3110_can_probe(): convert to use dev_err_probe()
  can: hi311x: hi3110_can_probe(): make use of device property API
  can: hi311x: hi3110_can_probe(): try to get crystal clock rate from property
  can: hi311x: hi3110_can_probe(): use devm_clk_get_optional() to get the input clock
  ARM: dts: sun8i: r40: add node for CAN controller
  can: sun4i_can: add support for R40 CAN controller
  dt-bindings: net: can: add support for Allwinner R40 CAN controller
  can: bittiming: replace CAN units with the generic ones from linux/units.h
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3a262c71 6a93ea38
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ properties:
          - const: allwinner,sun7i-a20-can
          - const: allwinner,sun4i-a10-can
      - const: allwinner,sun4i-a10-can
      - const: allwinner,sun8i-r40-can

  reg:
    maxItems: 1
@@ -27,6 +28,19 @@ properties:
  clocks:
    maxItems: 1

  resets:
    maxItems: 1

if:
  properties:
    compatible:
      contains:
        const: allwinner,sun8i-r40-can

then:
  required:
    - resets

required:
  - compatible
  - reg
@@ -47,5 +61,15 @@ examples:
        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&ccu CLK_APB1_CAN>;
    };
  - |
    #define RST_BUS_CAN		68
    #define CLK_BUS_CAN		91
    can1: can@1c2bc00 {
        compatible = "allwinner,sun8i-r40-can";
        reg = <0x01c2bc00 0x400>;
        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&ccu CLK_BUS_CAN>;
        resets = <&ccu RST_BUS_CAN>;
    };

...
+19 −0
Original line number Diff line number Diff line
@@ -511,6 +511,16 @@
			#interrupt-cells = <3>;
			#gpio-cells = <3>;

			can_ph_pins: can-ph-pins {
				pins = "PH20", "PH21";
				function = "can";
			};

			can_pa_pins: can-pa-pins {
				pins = "PA16", "PA17";
				function = "can";
			};

			clk_out_a_pin: clk-out-a-pin {
				pins = "PI12";
				function = "clk_out_a";
@@ -926,6 +936,15 @@
			#size-cells = <0>;
		};

		can0: can@1c2bc00 {
			compatible = "allwinner,sun8i-r40-can";
			reg = <0x01c2bc00 0x400>;
			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
			clocks = <&ccu CLK_BUS_CAN>;
			resets = <&ccu RST_BUS_CAN>;
			status = "disabled";
		};

		i2c4: i2c@1c2c000 {
			compatible = "allwinner,sun6i-a31-i2c";
			reg = <0x01c2c000 0x400>;
+3 −2
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
 */

#include <linux/units.h>
#include <linux/can/dev.h>

#ifdef CONFIG_CAN_CALC_BITTIMING
@@ -81,9 +82,9 @@ int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt,
	if (bt->sample_point) {
		sample_point_nominal = bt->sample_point;
	} else {
		if (bt->bitrate > 800 * CAN_KBPS)
		if (bt->bitrate > 800 * KILO /* BPS */)
			sample_point_nominal = 750;
		else if (bt->bitrate > 500 * CAN_KBPS)
		else if (bt->bitrate > 500 * KILO /* BPS */)
			sample_point_nominal = 800;
		else
			sample_point_nominal = 875;
+26 −26
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
@@ -828,19 +828,25 @@ MODULE_DEVICE_TABLE(spi, hi3110_id_table);

static int hi3110_can_probe(struct spi_device *spi)
{
	const struct of_device_id *of_id = of_match_device(hi3110_of_match,
							   &spi->dev);
	struct device *dev = &spi->dev;
	struct net_device *net;
	struct hi3110_priv *priv;
	const void *match;
	struct clk *clk;
	int freq, ret;
	u32 freq;
	int ret;

	clk = devm_clk_get(&spi->dev, NULL);
	if (IS_ERR(clk)) {
		dev_err(&spi->dev, "no CAN clock source defined\n");
		return PTR_ERR(clk);
	}
	clk = devm_clk_get_optional(&spi->dev, NULL);
	if (IS_ERR(clk))
		return dev_err_probe(dev, PTR_ERR(clk), "no CAN clock source defined\n");

	if (clk) {
		freq = clk_get_rate(clk);
	} else {
		ret = device_property_read_u32(dev, "clock-frequency", &freq);
		if (ret)
			return dev_err_probe(dev, ret, "Failed to get clock-frequency!\n");
	}

	/* Sanity check */
	if (freq > 40000000)
@@ -851,11 +857,9 @@ static int hi3110_can_probe(struct spi_device *spi)
	if (!net)
		return -ENOMEM;

	if (!IS_ERR(clk)) {
	ret = clk_prepare_enable(clk);
	if (ret)
		goto out_free;
	}

	net->netdev_ops = &hi3110_netdev_ops;
	net->flags |= IFF_ECHO;
@@ -870,8 +874,9 @@ static int hi3110_can_probe(struct spi_device *spi)
		CAN_CTRLMODE_LISTENONLY |
		CAN_CTRLMODE_BERR_REPORTING;

	if (of_id)
		priv->model = (enum hi3110_model)(uintptr_t)of_id->data;
	match = device_get_match_data(dev);
	if (match)
		priv->model = (enum hi3110_model)(uintptr_t)match;
	else
		priv->model = spi_get_device_id(spi)->driver_data;
	priv->net = net;
@@ -918,9 +923,7 @@ static int hi3110_can_probe(struct spi_device *spi)

	ret = hi3110_hw_probe(spi);
	if (ret) {
		if (ret == -ENODEV)
			dev_err(&spi->dev, "Cannot initialize %x. Wrong wiring?\n",
				priv->model);
		dev_err_probe(dev, ret, "Cannot initialize %x. Wrong wiring?\n", priv->model);
		goto error_probe;
	}
	hi3110_hw_sleep(spi);
@@ -938,14 +941,12 @@ static int hi3110_can_probe(struct spi_device *spi)
	hi3110_power_enable(priv->power, 0);

 out_clk:
	if (!IS_ERR(clk))
	clk_disable_unprepare(clk);

 out_free:
	free_candev(net);

	dev_err(&spi->dev, "Probe failed, err=%d\n", -ret);
	return ret;
	return dev_err_probe(dev, ret, "Probe failed\n");
}

static int hi3110_can_remove(struct spi_device *spi)
@@ -957,7 +958,6 @@ static int hi3110_can_remove(struct spi_device *spi)

	hi3110_power_enable(priv->power, 0);

	if (!IS_ERR(priv->clk))
	clk_disable_unprepare(priv->clk);

	free_candev(net);
+60 −2
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reset.h>

#define DRV_NAME "sun4i_can"

@@ -200,10 +201,20 @@
#define SUN4I_CAN_MAX_IRQ	20
#define SUN4I_MODE_MAX_RETRIES	100

/**
 * struct sun4ican_quirks - Differences between SoC variants.
 *
 * @has_reset: SoC needs reset deasserted.
 */
struct sun4ican_quirks {
	bool has_reset;
};

struct sun4ican_priv {
	struct can_priv can;
	void __iomem *base;
	struct clk *clk;
	struct reset_control *reset;
	spinlock_t cmdreg_lock;	/* lock for concurrent cmd register writes */
};

@@ -702,6 +713,13 @@ static int sun4ican_open(struct net_device *dev)
		goto exit_irq;
	}

	/* software reset deassert */
	err = reset_control_deassert(priv->reset);
	if (err) {
		netdev_err(dev, "could not deassert CAN reset\n");
		goto exit_soft_reset;
	}

	/* turn on clocking for CAN peripheral block */
	err = clk_prepare_enable(priv->clk);
	if (err) {
@@ -723,6 +741,8 @@ static int sun4ican_open(struct net_device *dev)
exit_can_start:
	clk_disable_unprepare(priv->clk);
exit_clock:
	reset_control_assert(priv->reset);
exit_soft_reset:
	free_irq(dev->irq, dev);
exit_irq:
	close_candev(dev);
@@ -736,6 +756,7 @@ static int sun4ican_close(struct net_device *dev)
	netif_stop_queue(dev);
	sun4i_can_stop(dev);
	clk_disable_unprepare(priv->clk);
	reset_control_assert(priv->reset);

	free_irq(dev->irq, dev);
	close_candev(dev);
@@ -750,9 +771,27 @@ static const struct net_device_ops sun4ican_netdev_ops = {
	.ndo_start_xmit = sun4ican_start_xmit,
};

static const struct sun4ican_quirks sun4ican_quirks_a10 = {
	.has_reset = false,
};

static const struct sun4ican_quirks sun4ican_quirks_r40 = {
	.has_reset = true,
};

static const struct of_device_id sun4ican_of_match[] = {
	{.compatible = "allwinner,sun4i-a10-can"},
	{},
	{
		.compatible = "allwinner,sun4i-a10-can",
		.data = &sun4ican_quirks_a10
	}, {
		.compatible = "allwinner,sun7i-a20-can",
		.data = &sun4ican_quirks_a10
	}, {
		.compatible = "allwinner,sun8i-r40-can",
		.data = &sun4ican_quirks_r40
	}, {
		/* sentinel */
	},
};

MODULE_DEVICE_TABLE(of, sun4ican_of_match);
@@ -771,10 +810,28 @@ static int sun4ican_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct clk *clk;
	struct reset_control *reset = NULL;
	void __iomem *addr;
	int err, irq;
	struct net_device *dev;
	struct sun4ican_priv *priv;
	const struct sun4ican_quirks *quirks;

	quirks = of_device_get_match_data(&pdev->dev);
	if (!quirks) {
		dev_err(&pdev->dev, "failed to determine the quirks to use\n");
		err = -ENODEV;
		goto exit;
	}

	if (quirks->has_reset) {
		reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
		if (IS_ERR(reset)) {
			dev_err(&pdev->dev, "unable to request reset\n");
			err = PTR_ERR(reset);
			goto exit;
		}
	}

	clk = of_clk_get(np, 0);
	if (IS_ERR(clk)) {
@@ -818,6 +875,7 @@ static int sun4ican_probe(struct platform_device *pdev)
				       CAN_CTRLMODE_3_SAMPLES;
	priv->base = addr;
	priv->clk = clk;
	priv->reset = reset;
	spin_lock_init(&priv->cmdreg_lock);

	platform_set_drvdata(pdev, dev);
Loading