Commit 8333c1c4 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-next-for-5.10-20200930' of...

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

Marc Kleine-Budde says:

====================
pull-request: can-next 2020-09-30

this is a pull request of 13 patches for net-next.

The first 10 target the mcp25xxfd driver (which is renamed to mcp251xfd during
this series).

The first two patches are by Thomas Kopp, which adds reference to the just
related errata and updates the documentation and log messages.

Dan Carpenter's patch fixes a resource leak during ifdown.

A patch by me adds the missing initialization of a variable.

Oleksij Rempel updates the DT binding documentation as requested by Rob
Herring.

The next 5 patches are by Thomas Kopp and me. During review Geert Uytterhoeven
suggested to use "microchip,mcp251xfd" instead of "microchip,mcp25xxfd" as the
DT autodetection compatible to avoid clashes with future but incompatible
devices. We decided not only to rename the compatible but the whole driver from
"mcp25xxfd" to "mcp251xfd". This is done in several patches.

Joakim Zhang contributes three patches for the flexcan driver. The first one
adds support for the ECC feature, which is implemented on some modern IP cores,
by initializing the controller's memory during ifup. The next patch adds
support for the i.MX8MP (which supports ECC) and the last patch properly
disables the runtime PM if device registration fails.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 11789fe7 5a9323f5
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2 %YAML 1.2
--- ---
$id: http://devicetree.org/schemas/net/can/microchip,mcp25xxfd.yaml# $id: http://devicetree.org/schemas/net/can/microchip,mcp251xfd.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml#
title: title:
...@@ -18,13 +18,13 @@ properties: ...@@ -18,13 +18,13 @@ properties:
description: for MCP2517FD description: for MCP2517FD
- const: microchip,mcp2518fd - const: microchip,mcp2518fd
description: for MCP2518FD description: for MCP2518FD
- const: microchip,mcp25xxfd - const: microchip,mcp251xfd
description: to autodetect chip variant description: to autodetect chip variant
reg: reg:
maxItems: 1 maxItems: 1
interrupts-extended: interrupts:
maxItems: 1 maxItems: 1
clocks: clocks:
...@@ -32,15 +32,13 @@ properties: ...@@ -32,15 +32,13 @@ properties:
vdd-supply: vdd-supply:
description: Regulator that powers the CAN controller. description: Regulator that powers the CAN controller.
maxItems: 1
xceiver-supply: xceiver-supply:
description: Regulator that powers the CAN transceiver. description: Regulator that powers the CAN transceiver.
maxItems: 1
microchip,rx-int-gpios: microchip,rx-int-gpios:
description: description:
GPIO phandle of GPIO connected to to INT1 pin of the MCP25XXFD, which GPIO phandle of GPIO connected to to INT1 pin of the MCP251XFD, which
signals a pending RX interrupt. signals a pending RX interrupt.
maxItems: 1 maxItems: 1
...@@ -52,9 +50,11 @@ properties: ...@@ -52,9 +50,11 @@ properties:
required: required:
- compatible - compatible
- reg - reg
- interrupts-extended - interrupts
- clocks - clocks
additionalProperties: false
examples: examples:
- | - |
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
...@@ -65,7 +65,7 @@ examples: ...@@ -65,7 +65,7 @@ examples:
#size-cells = <0>; #size-cells = <0>;
can@0 { can@0 {
compatible = "microchip,mcp25xxfd"; compatible = "microchip,mcp251xfd";
reg = <0>; reg = <0>;
clocks = <&can0_osc>; clocks = <&can0_osc>;
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -214,6 +214,7 @@ ...@@ -214,6 +214,7 @@
* MX53 FlexCAN2 03.00.00.00 yes no no no no no * MX53 FlexCAN2 03.00.00.00 yes no no no no no
* MX6s FlexCAN3 10.00.12.00 yes yes no no yes no * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no
* MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes
* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes
* VF610 FlexCAN3 ? no yes no yes yes? no * VF610 FlexCAN3 ? no yes no yes yes? no
* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no
* LX2160A FlexCAN3 03.00.23.00 no yes no no yes yes * LX2160A FlexCAN3 03.00.23.00 no yes no no yes yes
...@@ -239,6 +240,8 @@ ...@@ -239,6 +240,8 @@
#define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) #define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8)
/* Support CAN-FD mode */ /* Support CAN-FD mode */
#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) #define FLEXCAN_QUIRK_SUPPORT_FD BIT(9)
/* support memory detection and correction */
#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10)
/* Structure of the message buffer */ /* Structure of the message buffer */
struct flexcan_mb { struct flexcan_mb {
...@@ -292,7 +295,16 @@ struct flexcan_regs { ...@@ -292,7 +295,16 @@ struct flexcan_regs {
u32 rximr[64]; /* 0x880 - Not affected by Soft Reset */ u32 rximr[64]; /* 0x880 - Not affected by Soft Reset */
u32 _reserved5[24]; /* 0x980 */ u32 _reserved5[24]; /* 0x980 */
u32 gfwr_mx6; /* 0x9e0 - MX6 */ u32 gfwr_mx6; /* 0x9e0 - MX6 */
u32 _reserved6[63]; /* 0x9e4 */ u32 _reserved6[39]; /* 0x9e4 */
u32 _rxfir[6]; /* 0xa80 */
u32 _reserved8[2]; /* 0xa98 */
u32 _rxmgmask; /* 0xaa0 */
u32 _rxfgmask; /* 0xaa4 */
u32 _rx14mask; /* 0xaa8 */
u32 _rx15mask; /* 0xaac */
u32 tx_smb[4]; /* 0xab0 */
u32 rx_smb0[4]; /* 0xac0 */
u32 rx_smb1[4]; /* 0xad0 */
u32 mecr; /* 0xae0 */ u32 mecr; /* 0xae0 */
u32 erriar; /* 0xae4 */ u32 erriar; /* 0xae4 */
u32 erridpr; /* 0xae8 */ u32 erridpr; /* 0xae8 */
...@@ -305,9 +317,13 @@ struct flexcan_regs { ...@@ -305,9 +317,13 @@ struct flexcan_regs {
u32 fdctrl; /* 0xc00 - Not affected by Soft Reset */ u32 fdctrl; /* 0xc00 - Not affected by Soft Reset */
u32 fdcbt; /* 0xc04 - Not affected by Soft Reset */ u32 fdcbt; /* 0xc04 - Not affected by Soft Reset */
u32 fdcrc; /* 0xc08 */ u32 fdcrc; /* 0xc08 */
u32 _reserved9[199]; /* 0xc0c */
u32 tx_smb_fd[18]; /* 0xf28 */
u32 rx_smb0_fd[18]; /* 0xf70 */
u32 rx_smb1_fd[18]; /* 0xfb8 */
}; };
static_assert(sizeof(struct flexcan_regs) == 0x4 + 0xc08); static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8);
struct flexcan_devtype_data { struct flexcan_devtype_data {
u32 quirks; /* quirks needed for different IP cores */ u32 quirks; /* quirks needed for different IP cores */
...@@ -376,6 +392,13 @@ static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = { ...@@ -376,6 +392,13 @@ static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = {
FLEXCAN_QUIRK_SUPPORT_FD, FLEXCAN_QUIRK_SUPPORT_FD,
}; };
static struct flexcan_devtype_data fsl_imx8mp_devtype_data = {
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP |
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE |
FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC,
};
static const struct flexcan_devtype_data fsl_vf610_devtype_data = { static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP |
...@@ -1292,6 +1315,37 @@ static void flexcan_set_bittiming(struct net_device *dev) ...@@ -1292,6 +1315,37 @@ static void flexcan_set_bittiming(struct net_device *dev)
return flexcan_set_bittiming_ctrl(dev); return flexcan_set_bittiming_ctrl(dev);
} }
static void flexcan_ram_init(struct net_device *dev)
{
struct flexcan_priv *priv = netdev_priv(dev);
struct flexcan_regs __iomem *regs = priv->regs;
u32 reg_ctrl2;
/* 11.8.3.13 Detection and correction of memory errors:
* CTRL2[WRMFRZ] grants write access to all memory positions
* that require initialization, ranging from 0x080 to 0xADF
* and from 0xF28 to 0xFFF when the CAN FD feature is enabled.
* The RXMGMASK, RX14MASK, RX15MASK, and RXFGMASK registers
* need to be initialized as well. MCR[RFEN] must not be set
* during memory initialization.
*/
reg_ctrl2 = priv->read(&regs->ctrl2);
reg_ctrl2 |= FLEXCAN_CTRL2_WRMFRZ;
priv->write(reg_ctrl2, &regs->ctrl2);
memset_io(&regs->mb[0][0], 0,
offsetof(struct flexcan_regs, rx_smb1[3]) -
offsetof(struct flexcan_regs, mb[0][0]) + 0x4);
if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
memset_io(&regs->tx_smb_fd[0], 0,
offsetof(struct flexcan_regs, rx_smb1_fd[17]) -
offsetof(struct flexcan_regs, tx_smb_fd[0]) + 0x4);
reg_ctrl2 &= ~FLEXCAN_CTRL2_WRMFRZ;
priv->write(reg_ctrl2, &regs->ctrl2);
}
/* flexcan_chip_start /* flexcan_chip_start
* *
* this functions is entered with clocks enabled * this functions is entered with clocks enabled
...@@ -1316,6 +1370,9 @@ static int flexcan_chip_start(struct net_device *dev) ...@@ -1316,6 +1370,9 @@ static int flexcan_chip_start(struct net_device *dev)
if (err) if (err)
goto out_chip_disable; goto out_chip_disable;
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_ECC)
flexcan_ram_init(dev);
flexcan_set_bittiming(dev); flexcan_set_bittiming(dev);
/* MCR /* MCR
...@@ -1845,6 +1902,7 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev) ...@@ -1845,6 +1902,7 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
static const struct of_device_id flexcan_of_match[] = { static const struct of_device_id flexcan_of_match[] = {
{ .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, },
{ .compatible = "fsl,imx8mp-flexcan", .data = &fsl_imx8mp_devtype_data, },
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
{ .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, }, { .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, },
...@@ -1999,6 +2057,8 @@ static int flexcan_probe(struct platform_device *pdev) ...@@ -1999,6 +2057,8 @@ static int flexcan_probe(struct platform_device *pdev)
return 0; return 0;
failed_register: failed_register:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
free_candev(dev); free_candev(dev);
return err; return err;
} }
......
...@@ -13,6 +13,6 @@ config CAN_MCP251X ...@@ -13,6 +13,6 @@ config CAN_MCP251X
Driver for the Microchip MCP251x and MCP25625 SPI CAN Driver for the Microchip MCP251x and MCP25625 SPI CAN
controllers. controllers.
source "drivers/net/can/spi/mcp25xxfd/Kconfig" source "drivers/net/can/spi/mcp251xfd/Kconfig"
endmenu endmenu
...@@ -6,4 +6,4 @@ ...@@ -6,4 +6,4 @@
obj-$(CONFIG_CAN_HI311X) += hi311x.o obj-$(CONFIG_CAN_HI311X) += hi311x.o
obj-$(CONFIG_CAN_MCP251X) += mcp251x.o obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
obj-y += mcp25xxfd/ obj-y += mcp251xfd/
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
config CAN_MCP25XXFD config CAN_MCP251XFD
tristate "Microchip MCP25xxFD SPI CAN controllers" tristate "Microchip MCP251xFD SPI CAN controllers"
select REGMAP select REGMAP
help help
Driver for the Microchip MCP25XXFD SPI FD-CAN controller Driver for the Microchip MCP251XFD SPI FD-CAN controller
family. family.
config CAN_MCP25XXFD_SANITY config CAN_MCP251XFD_SANITY
depends on CAN_MCP25XXFD depends on CAN_MCP251XFD
bool "Additional Sanity Checks" bool "Additional Sanity Checks"
help help
This option enables additional sanity checks in the driver, This option enables additional sanity checks in the driver,
......
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CAN_MCP251XFD) += mcp251xfd.o
mcp251xfd-objs :=
mcp251xfd-objs += mcp251xfd-core.o
mcp251xfd-objs += mcp251xfd-crc16.o
mcp251xfd-objs += mcp251xfd-regmap.o
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
// //
// mcp25xxfd - Microchip MCP25xxFD Family CAN controller driver // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
// //
// Copyright (c) 2020 Pengutronix, // Copyright (c) 2020 Pengutronix,
// Marc Kleine-Budde <kernel@pengutronix.de> // Marc Kleine-Budde <kernel@pengutronix.de>
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
// //
#include "mcp25xxfd.h" #include "mcp251xfd.h"
/* The standard crc16 in linux/crc16.h is unfortunately not computing /* The standard crc16 in linux/crc16.h is unfortunately not computing
* the correct results (left shift vs. right shift). So here an * the correct results (left shift vs. right shift). So here an
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* *
* http://lkml.iu.edu/hypermail/linux/kernel/0508.1/1085.html * http://lkml.iu.edu/hypermail/linux/kernel/0508.1/1085.html
*/ */
static const u16 mcp25xxfd_crc16_table[] = { static const u16 mcp251xfd_crc16_table[] = {
0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
...@@ -55,35 +55,35 @@ static const u16 mcp25xxfd_crc16_table[] = { ...@@ -55,35 +55,35 @@ static const u16 mcp25xxfd_crc16_table[] = {
0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
}; };
static inline u16 mcp25xxfd_crc16_byte(u16 crc, const u8 data) static inline u16 mcp251xfd_crc16_byte(u16 crc, const u8 data)
{ {
u8 index = (crc >> 8) ^ data; u8 index = (crc >> 8) ^ data;
return (crc << 8) ^ mcp25xxfd_crc16_table[index]; return (crc << 8) ^ mcp251xfd_crc16_table[index];
} }
static u16 mcp25xxfd_crc16(u16 crc, u8 const *buffer, size_t len) static u16 mcp251xfd_crc16(u16 crc, u8 const *buffer, size_t len)
{ {
while (len--) while (len--)
crc = mcp25xxfd_crc16_byte(crc, *buffer++); crc = mcp251xfd_crc16_byte(crc, *buffer++);
return crc; return crc;
} }
u16 mcp25xxfd_crc16_compute(const void *data, size_t data_size) u16 mcp251xfd_crc16_compute(const void *data, size_t data_size)
{ {
u16 crc = 0xffff; u16 crc = 0xffff;
return mcp25xxfd_crc16(crc, data, data_size); return mcp251xfd_crc16(crc, data, data_size);
} }
u16 mcp25xxfd_crc16_compute2(const void *cmd, size_t cmd_size, u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size,
const void *data, size_t data_size) const void *data, size_t data_size)
{ {
u16 crc; u16 crc;
crc = mcp25xxfd_crc16_compute(cmd, cmd_size); crc = mcp251xfd_crc16_compute(cmd, cmd_size);
crc = mcp25xxfd_crc16(crc, data, data_size); crc = mcp251xfd_crc16(crc, data, data_size);
return crc; return crc;
} }
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CAN_MCP25XXFD) += mcp25xxfd.o
mcp25xxfd-objs :=
mcp25xxfd-objs += mcp25xxfd-core.o
mcp25xxfd-objs += mcp25xxfd-crc16.o
mcp25xxfd-objs += mcp25xxfd-regmap.o
This diff is collapsed.
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