Commit a43a0720 authored by Jakub Kicinski's avatar Jakub Kicinski

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.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 3a262c71 6a93ea38
......@@ -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>;
};
...
......@@ -511,6 +511,16 @@ pio: pinctrl@1c20800 {
#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 @@ i2c3: i2c@1c2b800 {
#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>;
......
......@@ -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;
......
......@@ -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_optional(&spi->dev, NULL);
if (IS_ERR(clk))
return dev_err_probe(dev, PTR_ERR(clk), "no CAN clock source defined\n");
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);
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");
}
freq = clk_get_rate(clk);
/* 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;
}
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);
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,8 +958,7 @@ 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);
clk_disable_unprepare(priv->clk);
free_candev(net);
......
......@@ -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);
......
......@@ -10,6 +10,7 @@
*/
#include <linux/kernel.h>
#include <linux/units.h>
#include <asm/unaligned.h>
#include "es58x_core.h"
......@@ -469,8 +470,8 @@ const struct es58x_parameters es581_4_param = {
.bittiming_const = &es581_4_bittiming_const,
.data_bittiming_const = NULL,
.tdc_const = NULL,
.bitrate_max = 1 * CAN_MBPS,
.clock = {.freq = 50 * CAN_MHZ},
.bitrate_max = 1 * MEGA /* BPS */,
.clock = {.freq = 50 * MEGA /* Hz */},
.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC,
.tx_start_of_frame = 0xAFAF,
.rx_start_of_frame = 0xFAFA,
......
......@@ -12,6 +12,7 @@
*/
#include <linux/kernel.h>
#include <linux/units.h>
#include <asm/unaligned.h>
#include "es58x_core.h"
......@@ -522,8 +523,8 @@ const struct es58x_parameters es58x_fd_param = {
* Mbps work in an optimal environment but are not recommended
* for production environment.
*/
.bitrate_max = 8 * CAN_MBPS,
.clock = {.freq = 80 * CAN_MHZ},
.bitrate_max = 8 * MEGA /* BPS */,
.clock = {.freq = 80 * MEGA /* Hz */},
.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO |
CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_TDC_AUTO,
......
......@@ -12,13 +12,6 @@
#define CAN_SYNC_SEG 1
/* Kilobits and Megabits per second */
#define CAN_KBPS 1000UL
#define CAN_MBPS 1000000UL
/* Megahertz */
#define CAN_MHZ 1000000UL
#define CAN_CTRLMODE_TDC_MASK \
(CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_TDC_MANUAL)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment