linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 0/4] CAST Controller Area Network driver support
@ 2024-01-29  3:12 William Qiu
  2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: William Qiu @ 2024-01-29  3:12 UTC (permalink / raw)
  To: devicetree, linux-kernel, linux-riscv, linux-can
  Cc: Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Hi,

This patchset adds initial rudimentary support for the CAST Controller
Area Network driver. And we registered cast in kernel as well. This
driver will be applied in JH7110 SoC first, so add relevant
compatibility support.

William Qiu (4):
  dt-bindings: vendor-prefixes: Add cast vendor prefix
  dt-bindings: can: Add bindings for CAST CAN Controller
  can: cast: add driver for CAST CAN controller
  riscv: dts: starfive: jh7110: Add CAN node

 .../devicetree/bindings/net/can/cast,can.yaml |   95 ++
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    7 +
 arch/riscv/boot/dts/starfive/jh7110.dtsi      |   32 +
 drivers/net/can/Kconfig                       |    7 +
 drivers/net/can/Makefile                      |    1 +
 drivers/net/can/cast_can.c                    | 1215 +++++++++++++++++
 7 files changed, 1359 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/can/cast,can.yaml
 create mode 100644 drivers/net/can/cast_can.c

--
2.34.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix
  2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
@ 2024-01-29  3:12 ` William Qiu
  2024-01-29 14:59   ` Conor Dooley
  2024-01-30 16:44   ` Rob Herring
  2024-01-29  3:12 ` [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller William Qiu
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 19+ messages in thread
From: William Qiu @ 2024-01-29  3:12 UTC (permalink / raw)
  To: devicetree, linux-kernel, linux-riscv, linux-can
  Cc: Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Add prefix for Computer-Aided Software Technologies, Inc.

Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 1a0dc04f1db4..b9c6ce99d24d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -242,6 +242,8 @@ patternProperties:
     description: Capella Microsystems, Inc
   "^cascoda,.*":
     description: Cascoda, Ltd.
+  "^cast,.*":
+    description: Computer-Aided Software Technologies, Inc.
   "^catalyst,.*":
     description: Catalyst Semiconductor, Inc.
   "^cavium,.*":
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller
  2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
  2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
@ 2024-01-29  3:12 ` William Qiu
  2024-01-29 15:37   ` Conor Dooley
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 19+ messages in thread
From: William Qiu @ 2024-01-29  3:12 UTC (permalink / raw)
  To: devicetree, linux-kernel, linux-riscv, linux-can
  Cc: Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Add bindings for CAST CAN Controller

Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
 .../devicetree/bindings/net/can/cast,can.yaml | 95 +++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/can/cast,can.yaml

diff --git a/Documentation/devicetree/bindings/net/can/cast,can.yaml b/Documentation/devicetree/bindings/net/can/cast,can.yaml
new file mode 100644
index 000000000000..ea52132d9b1c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/cast,can.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/can/cast,can.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CAST CAN controller
+
+maintainers:
+  - William Qiu <william.qiu@starfivetech.com>
+
+allOf:
+  - $ref: can-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: starfive,can
+    then:
+      required:
+        - starfive,syscon
+
+properties:
+  compatible:
+    enum:
+      - cast,can
+      - cast,canfd
+      - starfive,can
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+
+  clock-names:
+    items:
+      - const: apb_clk
+      - const: timer_clk
+      - const: can_clk
+
+  resets:
+    minItems: 3
+
+  reset-names:
+    items:
+      - const: rst_apb
+      - const: rst_core
+      - const: rst_timer
+
+  starfive,syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to System Register Controller syscon node
+          - description: offset of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller
+          - description: shift of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller
+          - description: mask of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller
+    description:
+      Should be four parameters, the phandle to System Register Controller
+      syscon node and the offset/shift/mask of SYS_SYSCON_NE__SAIF__SYSCFG register
+      for CAN controller.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+    can@130d0000{
+        compatible = "starfive,can";
+        reg = <0x130d0000 0x1000>;
+        interrupts = <112>;
+        clocks = <&syscrg 115>,
+                 <&syscrg 116>,
+                 <&syscrg 117>;
+        clock-names = "apb_clk", "timer_clk", "can_clk";
+        resets = <&syscrg 111>,
+                 <&syscrg 112>,
+                 <&syscrg 113>;
+        reset-names = "rst_apb", "rst_core", "rst_timer";
+        starfive,syscon = <&sys_syscon 0x10 0x3 0x8>;
+    };
+
+...
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
  2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
  2024-01-29  3:12 ` [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller William Qiu
@ 2024-01-29  3:12 ` William Qiu
  2024-01-29  8:26   ` Marc Kleine-Budde
                     ` (3 more replies)
  2024-01-29  3:12 ` [PATCH v1 4/4] riscv: dts: starfive: jh7110: Add CAN node William Qiu
  2024-01-29  7:57 ` [PATCH v1 0/4] CAST Controller Area Network driver support Marc Kleine-Budde
  4 siblings, 4 replies; 19+ messages in thread
From: William Qiu @ 2024-01-29  3:12 UTC (permalink / raw)
  To: devicetree, linux-kernel, linux-riscv, linux-can
  Cc: Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Add driver for CAST CAN Controller. And add compatibility code which
based on StarFive JH7110 SoC.

Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
 MAINTAINERS                |    7 +
 drivers/net/can/Kconfig    |    7 +
 drivers/net/can/Makefile   |    1 +
 drivers/net/can/cast_can.c | 1215 ++++++++++++++++++++++++++++++++++++
 4 files changed, 1230 insertions(+)
 create mode 100644 drivers/net/can/cast_can.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 8d1052fa6a69..daa3af8b4f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4723,6 +4723,13 @@ S:	Maintained
 W:	https://wireless.wiki.kernel.org/en/users/Drivers/carl9170
 F:	drivers/net/wireless/ath/carl9170/
 
+CAST CAN DRIVER
+M:	William Qiu <william.qiu@starfivetech.com>
+L:	linux-can@vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/net/can/cast,can.yaml
+F:	drivers/net/can/cast_can.c
+
 CAVIUM I2C DRIVER
 M:	Robert Richter <rric@kernel.org>
 S:	Odd Fixes
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index eb410714afc2..d98ad06c8ff3 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -124,6 +124,13 @@ config CAN_CAN327
 
 	  If this driver is built as a module, it will be called can327.
 
+config CAN_CASTCAN
+	tristate "CAST CAN"
+	depends on ARCH_STARFIVE || COMPILE_TEST
+	depends on COMMON_CLK && HAS_IOMEM
+	help
+	  CAST CAN driver. This driver supports both CAN and CANFD IP.
+
 config CAN_FLEXCAN
 	tristate "Support for Freescale FLEXCAN based chips"
 	depends on OF || COLDFIRE || COMPILE_TEST
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index ff8f76295d13..d6fa47278859 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -16,6 +16,7 @@ obj-y				+= softing/
 obj-$(CONFIG_CAN_AT91)		+= at91_can.o
 obj-$(CONFIG_CAN_BXCAN)		+= bxcan.o
 obj-$(CONFIG_CAN_CAN327)	+= can327.o
+obj-$(CONFIG_CAN_CASTCAN)	+= cast_can.o
 obj-$(CONFIG_CAN_CC770)		+= cc770/
 obj-$(CONFIG_CAN_C_CAN)		+= c_can/
 obj-$(CONFIG_CAN_CTUCANFD)	+= ctucanfd/
diff --git a/drivers/net/can/cast_can.c b/drivers/net/can/cast_can.c
new file mode 100644
index 000000000000..404e050e41a0
--- /dev/null
+++ b/drivers/net/can/cast_can.c
@@ -0,0 +1,1215 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CAST Controller Area Network Host Controller Driver
+ *
+ * Copyright (c) 2022-2023 StarFive Technology Co., Ltd.
+ */
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define DRIVER_NAME "cast_can"
+
+/* CAN registers set */
+enum ccan_device_reg {
+	CCAN_RUBF_OFFSET           =   0x00,	/* Receive Buffer Registers 0x00-0x4f */
+	CCAN_RUBF_ID_OFFSET        =   0x00,
+	CCAN_RBUF_CTL_OFFSET       =   0x04,
+	CCAN_RBUF_DATA_OFFSET      =   0x08,
+	CCAN_TBUF_OFFSET           =   0x50,	/* Transmit Buffer Registers 0x50-0x97 */
+	CCAN_TBUF_ID_OFFSET        =   0x50,
+	CCAN_TBUF_CTL_OFFSET       =   0x54,
+	CCAN_TBUF_DATA_OFFSET      =   0x58,
+	CCAN_TTS_OFFSET            =   0x98,	/* Transmission Time Stamp 0x98-0x9f */
+	CCAN_CFG_STAT_OFFSET       =   0xa0,
+	CCAN_TCMD_OFFSET           =   0xa1,
+	CCAN_TCTRL_OFFSET          =   0xa2,
+	CCAN_RCTRL_OFFSET          =   0xa3,
+	CCAN_RTIE_OFFSET           =   0xa4,
+	CCAN_RTIF_OFFSET           =   0xa5,
+	CCAN_ERRINT_OFFSET         =   0xa6,
+	CCAN_LIMIT_OFFSET          =   0xa7,
+	CCAN_S_SEG_1_OFFSET        =   0xa8,
+	CCAN_S_SEG_2_OFFSET        =   0xa9,
+	CCAN_S_SJW_OFFSET          =   0xaa,
+	CCAN_S_PRESC_OFFSET        =   0xab,
+	CCAN_F_SEG_1_OFFSET        =   0xac,
+	CCAN_F_SEG_2_OFFSET        =   0xad,
+	CCAN_F_SJW_OFFSET          =   0xae,
+	CCAN_F_PRESC_OFFSET        =   0xaf,
+	CCAN_EALCAP_OFFSET         =   0xb0,
+	CCAN_RECNT_OFFSET          =   0xb2,
+	CCAN_TECNT_OFFSET          =   0xb3,
+};
+
+enum ccan_reg_bitchange {
+	CCAN_SET_RST_MASK         =   0x80,	/* Set Reset Bit */
+	CCAN_OFF_RST_MASK         =   0x7f,	/* Reset Off Bit */
+	CCAN_SET_FULLCAN_MASK     =   0x10,	/* set TTTBM as 1->full TTCAN mode */
+	CCAN_OFF_FULLCAN_MASK     =   0xef,	/* set TTTBM as 0->separate PTB and STB mode */
+	CCAN_SET_FIFO_MASK        =   0x20,	/* set TSMODE as 1->FIFO mode */
+	CCAN_OFF_FIFO_MASK        =   0xdf,	/* set TSMODE as 0->Priority mode */
+	CCAN_SET_TSONE_MASK       =   0x04,
+	CCAN_OFF_TSONE_MASK       =   0xfb,
+	CCAN_SET_TSALL_MASK       =   0x02,
+	CCAN_OFF_TSALL_MASK       =   0xfd,
+	CCAN_LBMEMOD_MASK         =   0x40,	/* set loop back mode, external */
+	CCAN_LBMIMOD_MASK         =   0x20,	/* set loopback internal mode */
+	CCAN_SET_BUSOFF_MASK      =   0x01,
+	CCAN_OFF_BUSOFF_MASK      =   0xfe,
+	CCAN_SET_TTSEN_MASK       =   0x80,	/* set ttsen, tts update enable */
+	CCAN_SET_BRS_MASK         =   0x10,	/* can fd Bit Rate Switch mask */
+	CCAN_OFF_BRS_MASK         =   0xef,
+	CCAN_SET_EDL_MASK         =   0x20,	/* Extended Data Length */
+	CCAN_OFF_EDL_MASK         =   0xdf,
+	CCAN_SET_DLC_MASK         =   0x0f,
+	CCAN_SET_TENEXT_MASK      =   0x40,
+	CCAN_SET_IDE_MASK         =   0x80,
+	CCAN_OFF_IDE_MASK         =   0x7f,
+	CCAN_SET_RTR_MASK         =   0x40,
+	CCAN_OFF_RTR_MASK         =   0xbf,
+	CCAN_INTR_ALL_MASK        =   0xff,	/* all interrupts enable mask */
+	CCAN_SET_RIE_MASK         =   0x80,
+	CCAN_OFF_RIE_MASK         =   0x7f,
+	CCAN_SET_RFIE_MASK        =   0x20,
+	CCAN_OFF_RFIE_MASK        =   0xdf,
+	CCAN_SET_RAFIE_MASK       =   0x10,
+	CCAN_OFF_RAFIE_MASK       =   0xef,
+	CCAN_SET_EIE_MASK         =   0x02,
+	CCAN_OFF_EIE_MASK         =   0xfd,
+	CCAN_TASCTIVE_MASK        =   0x02,
+	CCAN_RASCTIVE_MASK        =   0x04,
+	CCAN_SET_TBSEL_MASK       =   0x80,	/* message writen in STB */
+	CCAN_OFF_TBSEL_MASK       =   0x7f,	/* message writen in PTB */
+	CCAN_SET_STBY_MASK        =   0x20,
+	CCAN_OFF_STBY_MASK        =   0xdf,
+	CCAN_SET_TPE_MASK         =   0x10,	/* Transmit primary enable */
+	CCAN_SET_TPA_MASK         =   0x08,
+	CCAN_SET_SACK_MASK        =   0x80,
+	CCAN_SET_RREL_MASK        =   0x10,
+	CCAN_RSTAT_NOT_EMPTY_MASK =   0x03,
+	CCAN_SET_RIF_MASK         =   0x80,
+	CCAN_OFF_RIF_MASK         =   0x7f,
+	CCAN_SET_RAFIF_MASK       =   0x10,
+	CCAN_SET_RFIF_MASK        =   0x20,
+	CCAN_SET_TPIF_MASK        =   0x08,	/* Transmission Primary Interrupt Flag */
+	CCAN_SET_TSIF_MASK        =   0x04,
+	CCAN_SET_EIF_MASK         =   0x02,
+	CCAN_SET_AIF_MASK         =   0x01,
+	CCAN_SET_EWARN_MASK       =   0x80,
+	CCAN_SET_EPASS_MASK       =   0x40,
+	CCAN_SET_EPIE_MASK        =   0x20,
+	CCAN_SET_EPIF_MASK        =   0x10,
+	CCAN_SET_ALIE_MASK        =   0x08,
+	CCAN_SET_ALIF_MASK        =   0x04,
+	CCAN_SET_BEIE_MASK        =   0x02,
+	CCAN_SET_BEIF_MASK        =   0x01,
+	CCAN_OFF_EPIE_MASK        =   0xdf,
+	CCAN_OFF_BEIE_MASK        =   0xfd,
+	CCAN_SET_AFWL_MASK        =   0x40,
+	CCAN_SET_EWL_MASK         =   0x0b,
+	CCAN_SET_KOER_MASK        =   0xe0,
+	CCAN_SET_BIT_ERROR_MASK   =   0x20,
+	CCAN_SET_FORM_ERROR_MASK  =   0x40,
+	CCAN_SET_STUFF_ERROR_MASK =   0x60,
+	CCAN_SET_ACK_ERROR_MASK   =   0x80,
+	CCAN_SET_CRC_ERROR_MASK   =   0xa0,
+	CCAN_SET_OTH_ERROR_MASK   =   0xc0,
+};
+
+/* seg1,seg2,sjw,prescaler all have 8 bits */
+#define BITS_OF_BITTIMING_REG		8
+
+/* in can_bittiming strucure every field has 32 bits---->u32 */
+#define FBITS_IN_BITTIMING_STR		32
+#define SEG_1_SHIFT			0
+#define SEG_2_SHIFT			8
+#define SJW_SHIFT			16
+#define PRESC_SHIFT			24
+
+/* TTSEN bit used for 32 bit register read or write */
+#define TTSEN_8_32_SHIFT		24
+#define RTR_32_8_SHIFT			24
+
+/* transmit mode */
+#define XMIT_FULL			0
+#define XMIT_SEP_FIFO			1
+#define XMIT_SEP_PRIO			2
+#define XMIT_PTB_MODE			3
+
+enum cast_can_type {
+	CAST_CAN_TYPE_CAN = 0,
+	CAST_CAN_TYPE_CANFD,
+};
+
+struct ccan_priv {
+	struct can_priv can;
+	struct napi_struct napi;
+	struct device *dev;
+	struct regmap *reg_syscon;
+	void __iomem *reg_base;
+	u32 (*read_reg)(const struct ccan_priv *priv, enum ccan_device_reg reg);
+	void (*write_reg)(const struct ccan_priv *priv, enum ccan_device_reg reg, u32 val);
+	struct clk *can_clk;
+	struct clk *host_clk;
+	struct clk *timer_clk;
+	u32 tx_mode;
+	struct reset_control *resets;
+	u32 cantype;
+	bool is_starfive;
+};
+
+struct cast_can_data {
+	enum cast_can_type cantype;
+	const struct can_bittiming_const *bittime_const;
+	int (*starfive_parse_dt)(struct ccan_priv *priv);
+};
+
+static struct can_bittiming_const ccan_bittiming_const = {
+	.name = DRIVER_NAME,
+	.tseg1_min = 2,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 1,
+};
+
+static struct can_bittiming_const ccan_bittiming_const_canfd = {
+	.name = DRIVER_NAME,
+	.tseg1_min = 2,
+	.tseg1_max = 64,
+	.tseg2_min = 2,
+	.tseg2_max = 16,
+	.sjw_max = 16,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 1,
+};
+
+static struct can_bittiming_const ccan_data_bittiming_const_canfd = {
+	.name = DRIVER_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 2,
+	.tseg2_max = 8,
+	.sjw_max = 8,
+	.brp_min = 1,
+	.brp_max = 256,
+	.brp_inc = 1,
+};
+
+static void ccan_write_reg_le(const struct ccan_priv *priv,
+			      enum ccan_device_reg reg, u32 val)
+{
+	iowrite32(val, priv->reg_base + reg);
+}
+
+static u32 ccan_read_reg_le(const struct ccan_priv *priv,
+			    enum ccan_device_reg reg)
+{
+	return ioread32(priv->reg_base + reg);
+}
+
+static inline unsigned char ccan_ioread8(const void  *addr)
+{
+	void  *addr_down;
+	union val {
+		u8 val_8[4];
+		u32 val_32;
+	} val;
+	u32 offset = 0;
+
+	addr_down = (void  *)ALIGN_DOWN((unsigned long)addr, 4);
+	offset = addr - addr_down;
+	val.val_32 = ioread32(addr_down);
+
+	return val.val_8[offset];
+}
+
+static inline void ccan_iowrite8(unsigned char value, void  *addr)
+{
+	void  *addr_down;
+	union val {
+		u8 val_8[4];
+		u32 val_32;
+	} val;
+	u8 offset = 0;
+
+	addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
+	offset = addr - addr_down;
+	val.val_32 = ioread32(addr_down);
+	val.val_8[offset] = value;
+	iowrite32(val.val_32, addr_down);
+}
+
+static void ccan_reigister_set_bit(const struct ccan_priv *priv,
+				   enum ccan_device_reg reg,
+				   enum ccan_reg_bitchange mask)
+{
+	void  *addr_down;
+	union val {
+		u8 val_8[4];
+		u32 val_32;
+	} val;
+	u8 offset = 0;
+
+	addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
+	offset = (priv->reg_base + reg) - addr_down;
+	val.val_32 = ioread32(addr_down);
+	val.val_8[offset] |= mask;
+	iowrite32(val.val_32, addr_down);
+}
+
+static void ccan_reigister_off_bit(const struct ccan_priv *priv,
+				   enum ccan_device_reg reg,
+				   enum ccan_reg_bitchange mask)
+{
+	void  *addr_down;
+	union val {
+		u8 val_8[4];
+		u32 val_32;
+	} val;
+	u8 offset = 0;
+
+	addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
+	offset = (priv->reg_base + reg) - addr_down;
+	val.val_32 = ioread32(addr_down);
+	val.val_8[offset] &= mask;
+	iowrite32(val.val_32, addr_down);
+}
+
+static int ccan_device_driver_bittime_configuration(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	struct can_bittiming *bt = &priv->can.bittiming;
+	struct can_bittiming *dbt = &priv->can.data_bittiming;
+	u32 reset_test, bittiming_temp, data_bittiming;
+
+	reset_test = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
+
+	if (!(reset_test & CCAN_SET_RST_MASK)) {
+		netdev_alert(ndev, "Not in reset mode, cannot set bit timing\n");
+		return -EPERM;
+	}
+
+	bittiming_temp = ((bt->phase_seg1 + bt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
+			 ((bt->phase_seg2 - 1) << SEG_2_SHIFT) |
+			 ((bt->sjw - 1) << SJW_SHIFT) |
+			 ((bt->brp - 1) << PRESC_SHIFT);
+
+	/* Check the bittime parameter */
+	if ((((int)(bt->phase_seg1 + bt->prop_seg + 1) - 2) < 0) ||
+	    (((int)(bt->phase_seg2) - 1) < 0) ||
+	    (((int)(bt->sjw) - 1) < 0) ||
+	    (((int)(bt->brp) - 1) < 0))
+		return -EINVAL;
+
+	priv->write_reg(priv, CCAN_S_SEG_1_OFFSET, bittiming_temp);
+
+	if (priv->cantype == CAST_CAN_TYPE_CANFD) {
+		data_bittiming = ((dbt->phase_seg1 + dbt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
+				 ((dbt->phase_seg2 - 1) << SEG_2_SHIFT) |
+				 ((dbt->sjw - 1) << SJW_SHIFT) |
+				 ((dbt->brp - 1) << PRESC_SHIFT);
+
+		if ((((int)(dbt->phase_seg1 + dbt->prop_seg + 1) - 2) < 0) ||
+		    (((int)(dbt->phase_seg2) - 1) < 0) ||
+		    (((int)(dbt->sjw) - 1) < 0) ||
+		    (((int)(dbt->brp) - 1) < 0))
+			return -EINVAL;
+
+		priv->write_reg(priv, CCAN_F_SEG_1_OFFSET, data_bittiming);
+	}
+
+	ccan_reigister_off_bit(priv, CCAN_CFG_STAT_OFFSET, CCAN_OFF_RST_MASK);
+
+	netdev_dbg(ndev, "Slow bit rate: %08x\n", priv->read_reg(priv, CCAN_S_SEG_1_OFFSET));
+	netdev_dbg(ndev, "Fast bit rate: %08x\n", priv->read_reg(priv, CCAN_F_SEG_1_OFFSET));
+
+	return 0;
+}
+
+int ccan_get_freebuffer(struct ccan_priv *priv)
+{
+	/* Get next transmit buffer */
+	ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_TENEXT_MASK);
+
+	if (ccan_ioread8(priv->reg_base + CCAN_TCTRL_OFFSET) & CCAN_SET_TENEXT_MASK)
+		return -EPERM;
+
+	return 0;
+}
+
+static void ccan_tx_interrupt(struct net_device *ndev, u8 isr)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+
+	/* wait till transmission of the PTB or STB finished */
+	while (isr & (CCAN_SET_TPIF_MASK | CCAN_SET_TSIF_MASK)) {
+		if (isr & CCAN_SET_TPIF_MASK)
+			ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_TPIF_MASK);
+
+		if (isr & CCAN_SET_TSIF_MASK)
+			ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_TSIF_MASK);
+
+		isr = ccan_ioread8(priv->reg_base + CCAN_RTIF_OFFSET);
+	}
+	netif_wake_queue(ndev);
+}
+
+static int ccan_rx(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u32 can_id;
+	u8  dlc, control, rx_status;
+
+	rx_status = ccan_ioread8(priv->reg_base + CCAN_RCTRL_OFFSET);
+
+	if (!(rx_status & CCAN_RSTAT_NOT_EMPTY_MASK))
+		return 0;
+
+	control = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET);
+	can_id = priv->read_reg(priv, CCAN_RUBF_ID_OFFSET);
+	dlc = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET) & CCAN_SET_DLC_MASK;
+
+	skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
+	if (!skb) {
+		stats->rx_dropped++;
+		return 0;
+	}
+	cf->can_dlc = can_cc_dlc2len(dlc);
+
+	/* change the CANFD id into socketcan id format */
+	cf->can_id = can_id;
+	if (control & CCAN_SET_IDE_MASK)
+		cf->can_id |= CAN_EFF_FLAG;
+	else
+		cf->can_id &= ~CAN_EFF_FLAG;
+
+	if (control & CCAN_SET_RTR_MASK)
+		cf->can_id |= CAN_RTR_FLAG;
+
+	if (!(control & CCAN_SET_RTR_MASK)) {
+		*((u32 *)(cf->data + 0)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET);
+		*((u32 *)(cf->data + 4)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET + 4);
+	}
+
+	ccan_reigister_set_bit(priv, CCAN_RCTRL_OFFSET, CCAN_SET_RREL_MASK);
+	stats->rx_bytes += can_fd_dlc2len(cf->can_dlc);
+	stats->rx_packets++;
+	netif_receive_skb(skb);
+
+	return 1;
+}
+
+static int ccanfd_rx(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct canfd_frame *cf;
+	struct sk_buff *skb;
+	u32 can_id;
+	u8  dlc, control, rx_status;
+	int i;
+
+	rx_status = ccan_ioread8(priv->reg_base + CCAN_RCTRL_OFFSET);
+
+	if (!(rx_status & CCAN_RSTAT_NOT_EMPTY_MASK))
+		return 0;
+
+	control = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET);
+	can_id = priv->read_reg(priv, CCAN_RUBF_ID_OFFSET);
+	dlc = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET) & CCAN_SET_DLC_MASK;
+
+	if (control & CCAN_SET_EDL_MASK)
+		/* allocate sk_buffer for canfd frame */
+		skb = alloc_canfd_skb(ndev, &cf);
+	else
+		/* allocate sk_buffer for can frame */
+		skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
+
+	if (!skb) {
+		stats->rx_dropped++;
+		return 0;
+	}
+
+	/* change the CANFD or CAN2.0 data into socketcan data format */
+	if (control & CCAN_SET_EDL_MASK)
+		cf->len = can_fd_dlc2len(dlc);
+	else
+		cf->len = can_cc_dlc2len(dlc);
+
+	/* change the CANFD id into socketcan id format */
+	cf->can_id = can_id;
+	if (control & CCAN_SET_IDE_MASK)
+		cf->can_id |= CAN_EFF_FLAG;
+	else
+		cf->can_id &= ~CAN_EFF_FLAG;
+
+	if (!(control & CCAN_SET_EDL_MASK))
+		if (control & CCAN_SET_RTR_MASK)
+			cf->can_id |= CAN_RTR_FLAG;
+
+	/* CANFD frames handed over to SKB */
+	if (control & CCAN_SET_EDL_MASK) {
+		for (i = 0; i < cf->len; i += 4)
+			*((u32 *)(cf->data + i)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET + i);
+	} else {
+		/* skb reads the received datas, if the RTR bit not set */
+		if (!(control & CCAN_SET_RTR_MASK)) {
+			*((u32 *)(cf->data + 0)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET);
+			*((u32 *)(cf->data + 4)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET + 4);
+		}
+	}
+
+	ccan_reigister_set_bit(priv, CCAN_RCTRL_OFFSET, CCAN_SET_RREL_MASK);
+
+	stats->rx_bytes += cf->len;
+	stats->rx_packets++;
+	netif_receive_skb(skb);
+
+	return 1;
+}
+
+static int ccan_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct net_device *ndev = napi->dev;
+	struct ccan_priv *priv = netdev_priv(ndev);
+	int work_done = 0;
+	u8 rx_status = 0, control = 0;
+
+	control = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET);
+	rx_status = ccan_ioread8(priv->reg_base + CCAN_RCTRL_OFFSET);
+
+	/* clear receive interrupt and deal with all the received frames */
+	while ((rx_status & CCAN_RSTAT_NOT_EMPTY_MASK) && (work_done < quota)) {
+		if (control & CCAN_SET_EDL_MASK)
+			work_done += ccanfd_rx(ndev);
+		else
+			work_done += ccan_rx(ndev);
+
+		control = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET);
+		rx_status = ccan_ioread8(priv->reg_base + CCAN_RCTRL_OFFSET);
+	}
+
+	napi_complete(napi);
+	ccan_reigister_set_bit(priv, CCAN_RTIE_OFFSET, CCAN_SET_RIE_MASK);
+
+	return work_done;
+}
+
+static void ccan_rxfull_interrupt(struct net_device *ndev, u8 isr)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+
+	if (isr & CCAN_SET_RAFIF_MASK)
+		ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_RAFIF_MASK);
+
+	if (isr & (CCAN_SET_RAFIF_MASK | CCAN_SET_RFIF_MASK))
+		ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET,
+				       (CCAN_SET_RAFIF_MASK | CCAN_SET_RFIF_MASK));
+}
+
+static int set_ccan_xmit_mode(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+
+	switch (priv->tx_mode) {
+	case XMIT_FULL:
+		ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_FULLCAN_MASK);
+		break;
+	case XMIT_SEP_FIFO:
+		ccan_reigister_off_bit(priv, CCAN_TCTRL_OFFSET, CCAN_OFF_FULLCAN_MASK);
+		ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_FIFO_MASK);
+		ccan_reigister_off_bit(priv, CCAN_TCMD_OFFSET, CCAN_SET_TBSEL_MASK);
+		break;
+	case XMIT_SEP_PRIO:
+		ccan_reigister_off_bit(priv, CCAN_TCTRL_OFFSET, CCAN_OFF_FULLCAN_MASK);
+		ccan_reigister_off_bit(priv, CCAN_TCTRL_OFFSET, CCAN_OFF_FIFO_MASK);
+		ccan_reigister_off_bit(priv, CCAN_TCMD_OFFSET, CCAN_SET_TBSEL_MASK);
+		break;
+	case XMIT_PTB_MODE:
+		ccan_reigister_off_bit(priv, CCAN_TCMD_OFFSET, CCAN_OFF_TBSEL_MASK);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static netdev_tx_t ccan_driver_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+	struct net_device_stats *stats = &ndev->stats;
+	u32 ttsen, id, ctl, addr_off;
+	int i;
+
+	priv->tx_mode = XMIT_PTB_MODE;
+
+	if (can_dropped_invalid_skb(ndev, skb))
+		return NETDEV_TX_OK;
+
+	switch (priv->tx_mode) {
+	case XMIT_FULL:
+		return NETDEV_TX_BUSY;
+	case XMIT_PTB_MODE:
+		set_ccan_xmit_mode(ndev);
+		ccan_reigister_off_bit(priv, CCAN_TCMD_OFFSET, CCAN_OFF_STBY_MASK);
+
+		if (cf->can_id & CAN_EFF_FLAG) {
+			id = cf->can_id & CAN_EFF_MASK;
+			ttsen = 0 << TTSEN_8_32_SHIFT;
+			id |= ttsen;
+		} else {
+			id = cf->can_id & CAN_SFF_MASK;
+			ttsen = 0 << TTSEN_8_32_SHIFT;
+			id |= ttsen;
+		}
+
+		ctl = can_fd_len2dlc(cf->len);
+
+		/* transmit can fd frame */
+		if (priv->cantype == CAST_CAN_TYPE_CANFD) {
+			if (can_is_canfd_skb(skb)) {
+				if (cf->can_id & CAN_EFF_FLAG)
+					ctl |= CCAN_SET_IDE_MASK;
+				else
+					ctl &= CCAN_OFF_IDE_MASK;
+
+				if (cf->flags & CANFD_BRS)
+					ctl |= CCAN_SET_BRS_MASK;
+
+				ctl |= CCAN_SET_EDL_MASK;
+
+				addr_off = CCAN_TBUF_DATA_OFFSET;
+
+				for (i = 0; i < cf->len; i += 4) {
+					priv->write_reg(priv, addr_off,
+							*((u32 *)(cf->data + i)));
+					addr_off += 4;
+				}
+			} else {
+				ctl &= (CCAN_OFF_EDL_MASK | CCAN_OFF_BRS_MASK);
+
+				if (cf->can_id & CAN_EFF_FLAG)
+					ctl |= CCAN_SET_IDE_MASK;
+				else
+					ctl &= CCAN_OFF_IDE_MASK;
+
+				if (cf->can_id & CAN_RTR_FLAG) {
+					ctl |= CCAN_SET_RTR_MASK;
+					priv->write_reg(priv,
+						CCAN_TBUF_ID_OFFSET, id);
+					priv->write_reg(priv,
+						CCAN_TBUF_CTL_OFFSET, ctl);
+				} else {
+					ctl &= CCAN_OFF_RTR_MASK;
+					addr_off = CCAN_TBUF_DATA_OFFSET;
+					priv->write_reg(priv, addr_off,
+							*((u32 *)(cf->data + 0)));
+					priv->write_reg(priv, addr_off + 4,
+							*((u32 *)(cf->data + 4)));
+				}
+			}
+			priv->write_reg(priv, CCAN_TBUF_ID_OFFSET, id);
+			priv->write_reg(priv, CCAN_TBUF_CTL_OFFSET, ctl);
+			addr_off = CCAN_TBUF_DATA_OFFSET;
+		} else {
+			ctl &= (CCAN_OFF_EDL_MASK | CCAN_OFF_BRS_MASK);
+
+			if (cf->can_id & CAN_EFF_FLAG)
+				ctl |= CCAN_SET_IDE_MASK;
+			else
+				ctl &= CCAN_OFF_IDE_MASK;
+
+			if (cf->can_id & CAN_RTR_FLAG) {
+				ctl |= CCAN_SET_RTR_MASK;
+				priv->write_reg(priv, CCAN_TBUF_ID_OFFSET, id);
+				priv->write_reg(priv, CCAN_TBUF_CTL_OFFSET, ctl);
+			} else {
+				ctl &= CCAN_OFF_RTR_MASK;
+				priv->write_reg(priv, CCAN_TBUF_ID_OFFSET, id);
+				priv->write_reg(priv, CCAN_TBUF_CTL_OFFSET, ctl);
+				addr_off = CCAN_TBUF_DATA_OFFSET;
+				priv->write_reg(priv, addr_off,
+						*((u32 *)(cf->data + 0)));
+				priv->write_reg(priv, addr_off + 4,
+						*((u32 *)(cf->data + 4)));
+			}
+		}
+		ccan_reigister_set_bit(priv, CCAN_TCMD_OFFSET, CCAN_SET_TPE_MASK);
+		stats->tx_bytes += cf->len;
+		break;
+	default:
+		break;
+	}
+
+	if (!(ndev->flags & IFF_ECHO) || (skb->protocol != htons(ETH_P_CAN) &&
+					  skb->protocol != htons(ETH_P_CANFD))) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	skb = can_create_echo_skb(skb);
+	if (!skb)
+		return -ENOMEM;
+
+	/* make settings for echo to reduce code in irq context */
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->dev = ndev;
+
+	skb_tx_timestamp(skb);
+
+	return NETDEV_TX_OK;
+}
+
+static int set_reset_mode(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	u8 ret;
+
+	ret = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
+	ret |= CCAN_SET_RST_MASK;
+	ccan_iowrite8(ret, priv->reg_base + CCAN_CFG_STAT_OFFSET);
+
+	return 0;
+}
+
+static void ccan_driver_stop(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	ret = set_reset_mode(ndev);
+	if (ret)
+		netdev_err(ndev, "Mode resetting failed!\n");
+
+	priv->can.state = CAN_STATE_STOPPED;
+}
+
+static int ccan_driver_close(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+
+	netif_stop_queue(ndev);
+	napi_disable(&priv->napi);
+	ccan_driver_stop(ndev);
+
+	close_candev(ndev);
+
+	return 0;
+}
+
+static enum can_state get_of_chip_status(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	u8 can_stat, eir;
+
+	can_stat = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
+	eir = ccan_ioread8(priv->reg_base + CCAN_ERRINT_OFFSET);
+
+	if (can_stat & CCAN_SET_BUSOFF_MASK)
+		return CAN_STATE_BUS_OFF;
+
+	if ((eir & CCAN_SET_EPASS_MASK) && ~(can_stat & CCAN_SET_BUSOFF_MASK))
+		return CAN_STATE_ERROR_PASSIVE;
+
+	if (eir & CCAN_SET_EWARN_MASK && ~(eir & CCAN_SET_EPASS_MASK))
+		return CAN_STATE_ERROR_WARNING;
+
+	if (~(eir & CCAN_SET_EPASS_MASK))
+		return CAN_STATE_ERROR_ACTIVE;
+
+	return CAN_STATE_ERROR_ACTIVE;
+}
+
+static void ccan_error_interrupt(struct net_device *ndev, u8 isr, u8 eir)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	struct net_device_stats *stats = &ndev->stats;
+	struct can_frame *cf;
+	struct sk_buff *skb;
+	u8 koer, recnt = 0, tecnt = 0, can_stat = 0;
+
+	skb = alloc_can_err_skb(ndev, &cf);
+
+	koer = ccan_ioread8(priv->reg_base + CCAN_EALCAP_OFFSET) & CCAN_SET_KOER_MASK;
+	recnt = ccan_ioread8(priv->reg_base + CCAN_RECNT_OFFSET);
+	tecnt = ccan_ioread8(priv->reg_base + CCAN_TECNT_OFFSET);
+
+	/*Read can status*/
+	can_stat = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
+
+	/* Bus off --->active error mode */
+	if ((isr & CCAN_SET_EIF_MASK) && priv->can.state == CAN_STATE_BUS_OFF)
+		priv->can.state = get_of_chip_status(ndev);
+
+	/* State selection */
+	if (can_stat & CCAN_SET_BUSOFF_MASK) {
+		priv->can.state = get_of_chip_status(ndev);
+		priv->can.can_stats.bus_off++;
+		ccan_reigister_set_bit(priv, CCAN_CFG_STAT_OFFSET, CCAN_SET_BUSOFF_MASK);
+		can_bus_off(ndev);
+		if (skb)
+			cf->can_id |= CAN_ERR_BUSOFF;
+
+	} else if ((eir & CCAN_SET_EPASS_MASK) && ~(can_stat & CCAN_SET_BUSOFF_MASK)) {
+		priv->can.state = get_of_chip_status(ndev);
+		priv->can.can_stats.error_passive++;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] |= (recnt > 127) ? CAN_ERR_CRTL_RX_PASSIVE : 0;
+			cf->data[1] |= (tecnt > 127) ? CAN_ERR_CRTL_TX_PASSIVE : 0;
+			cf->data[6] = tecnt;
+			cf->data[7] = recnt;
+		}
+	} else if (eir & CCAN_SET_EWARN_MASK && ~(eir & CCAN_SET_EPASS_MASK)) {
+		priv->can.state = get_of_chip_status(ndev);
+		priv->can.can_stats.error_warning++;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] |= (recnt > 95) ? CAN_ERR_CRTL_RX_WARNING : 0;
+			cf->data[1] |= (tecnt > 95) ? CAN_ERR_CRTL_TX_WARNING : 0;
+			cf->data[6] = tecnt;
+			cf->data[7] = recnt;
+		}
+	}
+
+	/* Check for in protocol defined error interrupt */
+	if (eir & CCAN_SET_BEIF_MASK) {
+		if (skb)
+			cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+
+		if (koer == CCAN_SET_BIT_ERROR_MASK) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] = CAN_ERR_PROT_BIT;
+		} else if (koer == CCAN_SET_FORM_ERROR_MASK) {
+			stats->rx_errors++;
+			if (skb)
+				cf->data[2] = CAN_ERR_PROT_FORM;
+		} else if (koer == CCAN_SET_STUFF_ERROR_MASK) {
+			stats->rx_errors++;
+			if (skb)
+				cf->data[3] = CAN_ERR_PROT_STUFF;
+		} else if (koer == CCAN_SET_ACK_ERROR_MASK) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] = CAN_ERR_PROT_LOC_ACK;
+		} else if (koer == CCAN_SET_CRC_ERROR_MASK) {
+			stats->rx_errors++;
+			if (skb)
+				cf->data[2] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		}
+		priv->can.can_stats.bus_error++;
+	}
+
+	if (skb) {
+		stats->rx_packets++;
+		stats->rx_bytes += cf->can_dlc;
+		netif_rx(skb);
+	}
+
+	netdev_dbg(ndev, "Recnt is 0x%02x", ccan_ioread8(priv->reg_base + CCAN_RECNT_OFFSET));
+	netdev_dbg(ndev, "Tecnt is 0x%02x", ccan_ioread8(priv->reg_base + CCAN_TECNT_OFFSET));
+}
+
+static irqreturn_t ccan_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = (struct net_device *)dev_id;
+	struct ccan_priv *priv = netdev_priv(ndev);
+	u8 isr, eir;
+	u8 isr_handled = 0, eir_handled = 0;
+
+	/* read the value of interrupt status register */
+	isr = ccan_ioread8(priv->reg_base + CCAN_RTIF_OFFSET);
+
+	/* read the value of error interrupt register */
+	eir = ccan_ioread8(priv->reg_base + CCAN_ERRINT_OFFSET);
+
+	/* Check for Tx interrupt and Processing it */
+	if (isr & (CCAN_SET_TPIF_MASK | CCAN_SET_TSIF_MASK)) {
+		ccan_tx_interrupt(ndev, isr);
+		isr_handled |= (CCAN_SET_TPIF_MASK | CCAN_SET_TSIF_MASK);
+	}
+
+	if (isr & (CCAN_SET_RAFIF_MASK | CCAN_SET_RFIF_MASK)) {
+		ccan_rxfull_interrupt(ndev, isr);
+		isr_handled |= (CCAN_SET_RAFIF_MASK | CCAN_SET_RFIF_MASK);
+	}
+
+	/* Check Rx interrupt and Processing the receive interrupt routine */
+	if (isr & CCAN_SET_RIF_MASK) {
+		ccan_reigister_off_bit(priv, CCAN_RTIE_OFFSET, CCAN_OFF_RIE_MASK);
+		ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_RIF_MASK);
+
+		napi_schedule(&priv->napi);
+		isr_handled |= CCAN_SET_RIF_MASK;
+	}
+
+	if ((isr & CCAN_SET_EIF_MASK) |
+	    (eir & (CCAN_SET_EPIF_MASK | CCAN_SET_BEIF_MASK))) {
+		/* reset EPIF and BEIF. Reset EIF */
+		ccan_reigister_set_bit(priv, CCAN_ERRINT_OFFSET,
+				       eir & (CCAN_SET_EPIF_MASK | CCAN_SET_BEIF_MASK));
+		ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET,
+				       isr & CCAN_SET_EIF_MASK);
+
+		ccan_error_interrupt(ndev, isr, eir);
+
+		isr_handled |= CCAN_SET_EIF_MASK;
+		eir_handled |= (CCAN_SET_EPIF_MASK | CCAN_SET_BEIF_MASK);
+	}
+
+	if (isr_handled == 0 && eir_handled == 0) {
+		netdev_err(ndev, "Unhandled interrupt!\n");
+		return IRQ_NONE;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int ccan_chip_start(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	int err;
+	u8 ret;
+
+	err = set_reset_mode(ndev);
+	if (err) {
+		netdev_err(ndev, "Mode resetting failed!\n");
+		return err;
+	}
+
+	err = ccan_device_driver_bittime_configuration(ndev);
+	if (err) {
+		netdev_err(ndev, "Bittime setting failed!\n");
+		return err;
+	}
+
+	/* Set Almost Full Warning Limit */
+	ccan_reigister_set_bit(priv, CCAN_LIMIT_OFFSET, CCAN_SET_AFWL_MASK);
+
+	/* Programmable Error Warning Limit = (EWL+1)*8. Set EWL=11->Error Warning=96 */
+	ccan_reigister_set_bit(priv, CCAN_LIMIT_OFFSET, CCAN_SET_EWL_MASK);
+
+	/* Interrupts enable */
+	ccan_iowrite8(CCAN_INTR_ALL_MASK, priv->reg_base + CCAN_RTIE_OFFSET);
+
+	/* Error Interrupts enable(Error Passive and Bus Error) */
+	ccan_reigister_set_bit(priv, CCAN_ERRINT_OFFSET, CCAN_SET_EPIE_MASK);
+
+	ret = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
+
+	/* Check whether it is loopback mode or normal mode */
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
+		ret |= CCAN_LBMIMOD_MASK;
+	else
+		ret &= ~(CCAN_LBMEMOD_MASK | CCAN_LBMIMOD_MASK);
+
+	ccan_iowrite8(ret, priv->reg_base + CCAN_CFG_STAT_OFFSET);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	return 0;
+}
+
+static int  ccan_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+	int ret;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		ret = ccan_chip_start(ndev);
+		if (ret) {
+			netdev_err(ndev, "Could not start CAN device !\n");
+			return ret;
+		}
+		netif_wake_queue(ndev);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+
+static int ccan_driver_open(struct net_device *ndev)
+{
+	struct ccan_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	/* Set chip into reset mode */
+	ret = set_reset_mode(ndev);
+	if (ret) {
+		netdev_err(ndev, "Mode resetting failed!\n");
+		return ret;
+	}
+
+	/* Common open */
+	ret = open_candev(ndev);
+	if (ret)
+		return ret;
+
+	/* Register interrupt handler */
+	ret = devm_request_irq(priv->dev, ndev->irq, ccan_interrupt, IRQF_SHARED,
+			       ndev->name, ndev);
+	if (ret) {
+		netdev_err(ndev, "Request_irq err: %d\n", ret);
+		goto err;
+	}
+
+	ret = ccan_chip_start(ndev);
+	if (ret) {
+		netdev_err(ndev, "Could not start CAN device !\n");
+		goto err;
+	}
+
+	napi_enable(&priv->napi);
+	netif_start_queue(ndev);
+
+	return 0;
+
+err:
+	close_candev(ndev);
+	return ret;
+}
+
+static int ccan_starfive_parse_dt(struct ccan_priv *priv)
+{
+	struct of_phandle_args args;
+	u32 syscon_mask, syscon_shift;
+	u32 syscon_offset, regval;
+	int ret;
+
+	ret = of_parse_phandle_with_fixed_args(priv->dev->of_node,
+					       "starfive,sys-syscon", 3, 0, &args);
+	if (ret) {
+		dev_err(priv->dev, "Failed to parse starfive,sys-syscon\n");
+		return -EINVAL;
+	}
+
+	priv->reg_syscon = syscon_node_to_regmap(args.np);
+	of_node_put(args.np);
+	if (IS_ERR(priv->reg_syscon))
+		return PTR_ERR(priv->reg_syscon);
+
+	syscon_offset = args.args[0];
+	syscon_shift  = args.args[1];
+	syscon_mask   = args.args[2];
+
+	/* enable can2.0/canfd function */
+	regval = priv->cantype << syscon_shift;
+	ret = regmap_update_bits(priv->reg_syscon, syscon_offset, syscon_mask, regval);
+	if (ret)
+		return ret;
+
+	priv->is_starfive = true;
+
+	return 0;
+}
+
+static const struct net_device_ops ccan_netdev_ops = {
+	.ndo_open = ccan_driver_open,
+	.ndo_stop = ccan_driver_close,
+	.ndo_start_xmit = ccan_driver_start_xmit,
+	.ndo_change_mtu = can_change_mtu,
+};
+
+static const struct cast_can_data ccan_can_data = {
+	.cantype = CAST_CAN_TYPE_CAN,
+	.bittime_const = &ccan_bittiming_const,
+};
+
+static const struct cast_can_data ccan_canfd_data = {
+	.cantype = CAST_CAN_TYPE_CANFD,
+	.bittime_const = &ccan_bittiming_const_canfd,
+};
+
+static const struct cast_can_data sfcan_can_data = {
+	.cantype = CAST_CAN_TYPE_CAN,
+	.bittime_const = &ccan_bittiming_const,
+	.starfive_parse_dt = ccan_starfive_parse_dt,
+};
+
+static const struct of_device_id ccan_of_match[] = {
+	{ .compatible = "cast,can", .data = &ccan_can_data },
+	{ .compatible = "cast,canfd", .data = &ccan_canfd_data },
+	{ .compatible = "starfive,can", .data = &sfcan_can_data },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, ccan_of_match);
+
+static int ccan_driver_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+	struct ccan_priv *priv;
+	const struct of_device_id *id;
+	const struct cast_can_data *ddata;
+	void __iomem *addr;
+	int ret;
+
+	addr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(addr)) {
+		ret = PTR_ERR(addr);
+		goto exit;
+	}
+
+	id = of_match_device(ccan_of_match, &pdev->dev);
+	if (id && id->data)
+		ddata = id->data;
+
+	ndev = alloc_candev(sizeof(struct ccan_priv), 1);
+	if (!ndev) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	priv = netdev_priv(ndev);
+	priv->dev = &pdev->dev;
+	priv->is_starfive = false;
+
+	if (ddata) {
+		if (ddata->starfive_parse_dt) {
+			ret = ccan_starfive_parse_dt(priv);
+			if (ret)
+				goto free_exit;
+		}
+	}
+
+	priv->can_clk = devm_clk_get_enabled(&pdev->dev, "can_clk");
+	if (IS_ERR(priv->can_clk)) {
+		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->can_clk),
+				    "Device clock not found\n");
+		goto free_exit;
+	}
+
+	priv->host_clk = devm_clk_get_enabled(&pdev->dev, "apb_clk");
+	if (IS_ERR(priv->host_clk)) {
+		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->host_clk),
+				    "Host clock not found\n");
+		goto free_exit;
+	}
+
+	priv->timer_clk = devm_clk_get_enabled(&pdev->dev, "timer_clk");
+	if (IS_ERR(priv->timer_clk)) {
+		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->timer_clk),
+				    "Timer clock not found\n");
+		goto free_exit;
+	}
+
+	priv->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
+	if (IS_ERR(priv->resets)) {
+		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->resets),
+				    "Failed to get CAN resets");
+		goto clk_exit;
+	}
+
+	ret = reset_control_deassert(priv->resets);
+	if (ret)
+		goto clk_exit;
+
+	priv->can.do_set_mode = ccan_do_set_mode;
+	priv->can.bittiming_const = ddata->bittime_const;
+	priv->cantype = ddata->cantype;
+
+	if (priv->cantype == CAST_CAN_TYPE_CANFD) {
+		priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_FD;
+		priv->can.data_bittiming_const = &ccan_data_bittiming_const_canfd;
+	} else {
+		priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK;
+	}
+
+	priv->reg_base = addr;
+	priv->write_reg = ccan_write_reg_le;
+	priv->read_reg = ccan_read_reg_le;
+	priv->can.clock.freq = clk_get_rate(priv->can_clk);
+	ndev->irq = platform_get_irq(pdev, 0);
+
+	/* we support local echo */
+	ndev->flags |= IFF_ECHO;
+	ndev->netdev_ops = &ccan_netdev_ops;
+
+	platform_set_drvdata(pdev, ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	netif_napi_add_tx_weight(ndev, &priv->napi, ccan_rx_poll, 16);
+	ret = register_candev(ndev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register (err=%d)\n", ret);
+		goto reset_exit;
+	}
+
+	dev_dbg(&pdev->dev, "Driver registered: regs=%p, irp=%d, clock=%d\n",
+		priv->reg_base, ndev->irq, priv->can.clock.freq);
+
+	return 0;
+
+reset_exit:
+	reset_control_assert(priv->resets);
+clk_exit:
+	clk_disable_unprepare(priv->can_clk);
+	clk_disable_unprepare(priv->host_clk);
+	clk_disable_unprepare(priv->timer_clk);
+free_exit:
+	free_candev(ndev);
+exit:
+	return ret;
+}
+
+static int ccan_driver_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct ccan_priv *priv = netdev_priv(ndev);
+
+	reset_control_assert(priv->resets);
+	clk_disable_unprepare(priv->can_clk);
+	clk_disable_unprepare(priv->host_clk);
+	clk_disable_unprepare(priv->timer_clk);
+
+	unregister_candev(ndev);
+	netif_napi_del(&priv->napi);
+	free_candev(ndev);
+
+	return 0;
+}
+
+static struct platform_driver ccan_driver = {
+	.probe          = ccan_driver_probe,
+	.remove         = ccan_driver_remove,
+	.driver = {
+		.name  = DRIVER_NAME,
+		.of_match_table = ccan_of_match,
+	},
+};
+
+module_platform_driver(ccan_driver);
+
+MODULE_DESCRIPTION("CAST CAN Controller Driver");
+MODULE_AUTHOR("William Qiu<william.qiu@starfivetech.com");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 4/4] riscv: dts: starfive: jh7110: Add CAN node
  2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
                   ` (2 preceding siblings ...)
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
@ 2024-01-29  3:12 ` William Qiu
  2024-01-29  7:57 ` [PATCH v1 0/4] CAST Controller Area Network driver support Marc Kleine-Budde
  4 siblings, 0 replies; 19+ messages in thread
From: William Qiu @ 2024-01-29  3:12 UTC (permalink / raw)
  To: devicetree, linux-kernel, linux-riscv, linux-can
  Cc: Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Add CAST CAN controller node in JH7110 SoC.

Signed-off-by: William Qiu <william.qiu@starfivetech.com>
---
 arch/riscv/boot/dts/starfive/jh7110.dtsi | 32 ++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi
index 45213cdf50dc..4d0469cb8ca9 100644
--- a/arch/riscv/boot/dts/starfive/jh7110.dtsi
+++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -914,6 +914,38 @@ watchdog@13070000 {
 				 <&syscrg JH7110_SYSRST_WDT_CORE>;
 		};
 
+		can0: can@130d0000 {
+			compatible = "starfive,can";
+			reg = <0x0 0x130d0000 0x0 0x1000>;
+			interrupts = <112>;
+			clocks = <&syscrg JH7110_SYSCLK_CAN0_APB>,
+				 <&syscrg JH7110_SYSCLK_CAN0_TIMER>,
+				 <&syscrg JH7110_SYSCLK_CAN0_CAN>;
+			clock-names = "apb_clk", "timer_clk", "can_clk";
+			resets = <&syscrg JH7110_SYSRST_CAN0_APB>,
+				 <&syscrg JH7110_SYSRST_CAN0_CORE>,
+				 <&syscrg JH7110_SYSRST_CAN0_TIMER>;
+			reset-names = "rst_apb", "rst_core", "rst_timer";
+			starfive,syscon = <&sys_syscon 0x10 0x3 0x8>;
+			status = "disabled";
+		};
+
+		can1: can@130e0000 {
+			compatible = "starfive,can";
+			reg = <0x0 0x130e0000 0x0 0x1000>;
+			interrupts = <113>;
+			clocks = <&syscrg JH7110_SYSCLK_CAN1_APB>,
+				 <&syscrg JH7110_SYSCLK_CAN1_TIMER>,
+				 <&syscrg JH7110_SYSCLK_CAN1_CAN>;
+			clock-names = "apb_clk", "timer_clk", "can_clk";
+			resets = <&syscrg JH7110_SYSRST_CAN1_APB>,
+				 <&syscrg JH7110_SYSRST_CAN1_CORE>,
+				 <&syscrg JH7110_SYSRST_CAN1_TIMER>;
+			reset-names = "rst_apb", "rst_core", "rst_timer";
+			starfive,syscon = <&sys_syscon 0x88 0x12 0x40000>;
+			status = "disabled";
+		};
+
 		crypto: crypto@16000000 {
 			compatible = "starfive,jh7110-crypto";
 			reg = <0x0 0x16000000 0x0 0x4000>;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 0/4] CAST Controller Area Network driver support
  2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
                   ` (3 preceding siblings ...)
  2024-01-29  3:12 ` [PATCH v1 4/4] riscv: dts: starfive: jh7110: Add CAN node William Qiu
@ 2024-01-29  7:57 ` Marc Kleine-Budde
  2024-01-29  8:07   ` William Qiu
  4 siblings, 1 reply; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-01-29  7:57 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

On 29.01.2024 11:12:35, William Qiu wrote:
> Hi,
> 
> This patchset adds initial rudimentary support for the CAST Controller
> Area Network driver. And we registered cast in kernel as well. This
> driver will be applied in JH7110 SoC first, so add relevant
> compatibility support.

Is there a public available data sheet for the IP core?

Marc

> 
> William Qiu (4):
>   dt-bindings: vendor-prefixes: Add cast vendor prefix
>   dt-bindings: can: Add bindings for CAST CAN Controller
>   can: cast: add driver for CAST CAN controller
>   riscv: dts: starfive: jh7110: Add CAN node
> 
>  .../devicetree/bindings/net/can/cast,can.yaml |   95 ++
>  .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
>  MAINTAINERS                                   |    7 +
>  arch/riscv/boot/dts/starfive/jh7110.dtsi      |   32 +
>  drivers/net/can/Kconfig                       |    7 +
>  drivers/net/can/Makefile                      |    1 +
>  drivers/net/can/cast_can.c                    | 1215 +++++++++++++++++
>  7 files changed, 1359 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/can/cast,can.yaml
>  create mode 100644 drivers/net/can/cast_can.c
> 
> --
> 2.34.1
> 
> 
> 

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v1 0/4] CAST Controller Area Network driver support
  2024-01-29  7:57 ` [PATCH v1 0/4] CAST Controller Area Network driver support Marc Kleine-Budde
@ 2024-01-29  8:07   ` William Qiu
  2024-01-29 11:31     ` Marc Kleine-Budde
  0 siblings, 1 reply; 19+ messages in thread
From: William Qiu @ 2024-01-29  8:07 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou


> -----Original Message-----
> From: Marc Kleine-Budde <mkl@pengutronix.de>
> Sent: 2024年1月29日 15:58
> To: William Qiu <william.qiu@starfivetech.com>
> Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-riscv@lists.infradead.org; linux-can@vger.kernel.org; Emil Renner
> Berthing <kernel@esmil.dk>; Rob Herring <robh+dt@kernel.org>; Wolfgang
> Grandegger <wg@grandegger.com>; Philipp Zabel <p.zabel@pengutronix.de>;
> Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley
> <conor+dt@kernel.org>; David S . Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; Paul Walmsley <paul.walmsley@sifive.com>;
> Palmer Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: [PATCH v1 0/4] CAST Controller Area Network driver support
> 
> On 29.01.2024 11:12:35, William Qiu wrote:
> > Hi,
> >
> > This patchset adds initial rudimentary support for the CAST Controller
> > Area Network driver. And we registered cast in kernel as well. This
> > driver will be applied in JH7110 SoC first, so add relevant
> > compatibility support.
> 
> Is there a public available data sheet for the IP core?
> 
> Marc
> 

We do have the data sheet, but I'm not sure if CAST is willing to make it
public. I need to contact them first and then reply to you.
Or you can contact them on their website, which is https://www.cast-inc.com/.

Thanks,
William
> >
> > William Qiu (4):
> >   dt-bindings: vendor-prefixes: Add cast vendor prefix
> >   dt-bindings: can: Add bindings for CAST CAN Controller
> >   can: cast: add driver for CAST CAN controller
> >   riscv: dts: starfive: jh7110: Add CAN node
> >
> >  .../devicetree/bindings/net/can/cast,can.yaml |   95 ++
> >  .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
> >  MAINTAINERS                                   |    7 +
> >  arch/riscv/boot/dts/starfive/jh7110.dtsi      |   32 +
> >  drivers/net/can/Kconfig                       |    7 +
> >  drivers/net/can/Makefile                      |    1 +
> >  drivers/net/can/cast_can.c                    | 1215
> +++++++++++++++++
> >  7 files changed, 1359 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/net/can/cast,can.yaml
> >  create mode 100644 drivers/net/can/cast_can.c
> >
> > --
> > 2.34.1
> >
> >
> >
> 
> --
> Pengutronix e.K.                 | Marc Kleine-Budde          |
> Embedded Linux                   | https://www.pengutronix.de |
> Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
@ 2024-01-29  8:26   ` Marc Kleine-Budde
  2024-01-29  8:42     ` William Qiu
  2024-01-29 19:51   ` kernel test robot
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-01-29  8:26 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou

[-- Attachment #1: Type: text/plain, Size: 1885 bytes --]

Hello William Qiu,

thank you for your contribution. I've some quick notes about your
driver.

On 29.01.2024 11:12:38, William Qiu wrote:
> Add driver for CAST CAN Controller. And add compatibility code which
> based on StarFive JH7110 SoC.

Please add yourself or someone else at starfivetech to the Maintainers
file.

Please use BIT() and/or GEN_MASK() to create the _MASK enums. Please use
FIELD_GET(), FIELD_PREP.

Please replace the ccan_ioread8() by a proper 32 bit read and use
FIELD_GET to access any non 32 bit value. Instead of ccan_iowrite8() use
FIELD_PREP and a proper 32 bit write.

The enum ccan_reg_bitchange looks very strange, why do you have OFF and
SET values?

The ccan_reigister_set_bit() and ccan_reigister_off_bit() functions
looks very strange, too. I suggest to use a 32 bit read, set, clear the
bits followed by a 32 bit write. Having set_bit() clear_bit() functions
may lead to more register accesses than needed, if not handled with care.

If you think the driver absolutely needs bit set/clear functions, please
follow the name and signature of the regmap_update_bits(),
regmap_set_bits() and regmap_clear_bits().

Please use can_put_echo_skb(), can_get_echo_skb().

Please implement proper TX-flow control. Stop the TX queue, if you HW
queue is full, start the TX queue once the HW queue has space again.

Consider using the rx_offload helper

You claim you IRQ handler works with shared interrupts, but you return
an error if there are no interrupts by your IP core.

Please enable the clocks during open() and disabled during close()

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  8:26   ` Marc Kleine-Budde
@ 2024-01-29  8:42     ` William Qiu
  0 siblings, 0 replies; 19+ messages in thread
From: William Qiu @ 2024-01-29  8:42 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou

> -----Original Message-----
> From: Marc Kleine-Budde <mkl@pengutronix.de>
> Sent: 2024年1月29日 16:26
> To: William Qiu <william.qiu@starfivetech.com>
> Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-riscv@lists.infradead.org; linux-can@vger.kernel.org; Emil Renner
> Berthing <kernel@esmil.dk>; Rob Herring <robh+dt@kernel.org>; Wolfgang
> Grandegger <wg@grandegger.com>; Philipp Zabel <p.zabel@pengutronix.de>;
> Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley
> <conor+dt@kernel.org>; David S . Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; Paul Walmsley <paul.walmsley@sifive.com>;
> Palmer Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
> 
> Hello William Qiu,
> 
> thank you for your contribution. I've some quick notes about your driver.
> 
> On 29.01.2024 11:12:38, William Qiu wrote:
> > Add driver for CAST CAN Controller. And add compatibility code which
> > based on StarFive JH7110 SoC.
> 
> Please add yourself or someone else at starfivetech to the Maintainers file.
> 
> Please use BIT() and/or GEN_MASK() to create the _MASK enums. Please use
> FIELD_GET(), FIELD_PREP.
> 
> Please replace the ccan_ioread8() by a proper 32 bit read and use FIELD_GET to
> access any non 32 bit value. Instead of ccan_iowrite8() use FIELD_PREP and a
> proper 32 bit write.
> 
> The enum ccan_reg_bitchange looks very strange, why do you have OFF and SET
> values?
> 
> The ccan_reigister_set_bit() and ccan_reigister_off_bit() functions looks very
> strange, too. I suggest to use a 32 bit read, set, clear the bits followed by a 32 bit
> write. Having set_bit() clear_bit() functions may lead to more register accesses
> than needed, if not handled with care.
> 
> If you think the driver absolutely needs bit set/clear functions, please follow the
> name and signature of the regmap_update_bits(),
> regmap_set_bits() and regmap_clear_bits().
> 
> Please use can_put_echo_skb(), can_get_echo_skb().
> 
> Please implement proper TX-flow control. Stop the TX queue, if you HW queue is
> full, start the TX queue once the HW queue has space again.
> 
> Consider using the rx_offload helper
> 
> You claim you IRQ handler works with shared interrupts, but you return an error
> if there are no interrupts by your IP core.
> 
> Please enable the clocks during open() and disabled during close()
> 
> Marc
> 

Thank you for your notes. I will modify my driver one by one according to your notes。

Thanks,
William
> --
> Pengutronix e.K.                 | Marc Kleine-Budde          |
> Embedded Linux                   | https://www.pengutronix.de |
> Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: RE: [PATCH v1 0/4] CAST Controller Area Network driver support
  2024-01-29  8:07   ` William Qiu
@ 2024-01-29 11:31     ` Marc Kleine-Budde
  2024-01-30  6:41       ` William Qiu
  0 siblings, 1 reply; 19+ messages in thread
From: Marc Kleine-Budde @ 2024-01-29 11:31 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou

[-- Attachment #1: Type: text/plain, Size: 744 bytes --]

On 29.01.2024 08:07:49, William Qiu wrote:
> > Is there a public available data sheet for the IP core?
> 
> We do have the data sheet, but I'm not sure if CAST is willing to make it
> public. I need to contact them first and then reply to you.
> Or you can contact them on their website, which is https://www.cast-inc.com/.

I'll contact them via the website, but please ask them as well, as you
have probably a better, more direct contact to them.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix
  2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
@ 2024-01-29 14:59   ` Conor Dooley
  2024-01-30 16:44   ` Rob Herring
  1 sibling, 0 replies; 19+ messages in thread
From: Conor Dooley @ 2024-01-29 14:59 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou

[-- Attachment #1: Type: text/plain, Size: 1193 bytes --]

On Mon, Jan 29, 2024 at 11:12:36AM +0800, William Qiu wrote:
> Add prefix for Computer-Aided Software Technologies, Inc.
> 
> Signed-off-by: William Qiu <william.qiu@starfivetech.com>

Acked-by: Conor Dooley <conor.dooley@microchip.com>

Cheers,
Conor.

> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 1a0dc04f1db4..b9c6ce99d24d 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -242,6 +242,8 @@ patternProperties:
>      description: Capella Microsystems, Inc
>    "^cascoda,.*":
>      description: Cascoda, Ltd.
> +  "^cast,.*":
> +    description: Computer-Aided Software Technologies, Inc.
>    "^catalyst,.*":
>      description: Catalyst Semiconductor, Inc.
>    "^cavium,.*":
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller
  2024-01-29  3:12 ` [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller William Qiu
@ 2024-01-29 15:37   ` Conor Dooley
  2024-01-30  6:30     ` William Qiu
  0 siblings, 1 reply; 19+ messages in thread
From: Conor Dooley @ 2024-01-29 15:37 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou

[-- Attachment #1: Type: text/plain, Size: 3443 bytes --]

Hey William,

On Mon, Jan 29, 2024 at 11:12:37AM +0800, William Qiu wrote:
> Add bindings for CAST CAN Controller
> 
> Signed-off-by: William Qiu <william.qiu@starfivetech.com>
> ---
>  .../devicetree/bindings/net/can/cast,can.yaml | 95 +++++++++++++++++++
>  1 file changed, 95 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/can/cast,can.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/can/cast,can.yaml b/Documentation/devicetree/bindings/net/can/cast,can.yaml
> new file mode 100644
> index 000000000000..ea52132d9b1c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/can/cast,can.yaml
> @@ -0,0 +1,95 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/can/cast,can.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: CAST CAN controller
> +
> +maintainers:
> +  - William Qiu <william.qiu@starfivetech.com>
> +
> +allOf:
> +  - $ref: can-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: starfive,can
> +    then:
> +      required:
> +        - starfive,syscon

If you've got property related stuff in the allOf, move it down after
the property definitions.

> +properties:
> +  compatible:
> +    enum:
> +      - cast,can
> +      - cast,canfd

I don't like these uber generic compatibles that have no users as a
fallback. Allowing them in the binding only really discourages people
from creating device specific compatibles.
Secondly, this is some purchased IP that I am sure has a versioning
scheme and the compatibles that you have created do not reflect that.
If they were being used as a fallback, I would request some versioning.
That's not going to really work though since the canfd features on the
jh7110 require setting u0_can_ctrl_can_fd_enable, so neither of these
compatibles really has a use right now.

> +      - starfive,can

Just "starfive,can"? Can you please add device specific compatibles for
the SoCs on which this is used?

> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 3
> +
> +  clock-names:
> +    items:
> +      - const: apb_clk
> +      - const: timer_clk
> +      - const: can_clk

Drop _clk, they're all clocks!

> +
> +  resets:
> +    minItems: 3
> +
> +  reset-names:
> +    items:
> +      - const: rst_apb
> +      - const: rst_core
> +      - const: rst_timer

Same here, drop rst_

> +
> +  starfive,syscon:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to System Register Controller syscon node
> +          - description: offset of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller

The docs I have call this register "SYS_SYSCONSAIF__SYSCFG". Did the
names change since the TRM I have was written?

> +          - description: shift of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller
> +          - description: mask of SYS_SYSCON_NE__SAIF__SYSCFG register for CAN controller
> +    description:
> +      Should be four parameters, the phandle to System Register Controller
> +      syscon node and the offset/shift/mask of SYS_SYSCON_NE__SAIF__SYSCFG register
> +      for CAN controller.

Cheers,
Conor.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
  2024-01-29  8:26   ` Marc Kleine-Budde
@ 2024-01-29 19:51   ` kernel test robot
  2024-01-29 22:58   ` kernel test robot
  2024-01-31  1:23   ` kernel test robot
  3 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-01-29 19:51 UTC (permalink / raw)
  To: William Qiu, devicetree, linux-kernel, linux-riscv, linux-can
  Cc: llvm, oe-kbuild-all, Emil Renner Berthing, Rob Herring,
	Wolfgang Grandegger, Philipp Zabel, Krzysztof Kozlowski,
	Conor Dooley, Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Hi William,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on linus/master mkl-can-next/testing v6.8-rc2 next-20240129]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/William-Qiu/dt-bindings-vendor-prefixes-Add-cast-vendor-prefix/20240129-114752
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240129031239.17037-4-william.qiu%40starfivetech.com
patch subject: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20240130/202401300313.9DPa2nuW-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 4a39d08908942b2d415db405844cbe4af73e75d4)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240130/202401300313.9DPa2nuW-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401300313.9DPa2nuW-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/net/can/cast_can.c:352:5: warning: no previous prototype for function 'ccan_get_freebuffer' [-Wmissing-prototypes]
     352 | int ccan_get_freebuffer(struct ccan_priv *priv)
         |     ^
   drivers/net/can/cast_can.c:352:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
     352 | int ccan_get_freebuffer(struct ccan_priv *priv)
         | ^
         | static 
   1 warning generated.


vim +/ccan_get_freebuffer +352 drivers/net/can/cast_can.c

   351	
 > 352	int ccan_get_freebuffer(struct ccan_priv *priv)
   353	{
   354		/* Get next transmit buffer */
   355		ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_TENEXT_MASK);
   356	
   357		if (ccan_ioread8(priv->reg_base + CCAN_TCTRL_OFFSET) & CCAN_SET_TENEXT_MASK)
   358			return -EPERM;
   359	
   360		return 0;
   361	}
   362	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
  2024-01-29  8:26   ` Marc Kleine-Budde
  2024-01-29 19:51   ` kernel test robot
@ 2024-01-29 22:58   ` kernel test robot
  2024-01-31  1:23   ` kernel test robot
  3 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-01-29 22:58 UTC (permalink / raw)
  To: William Qiu, devicetree, linux-kernel, linux-riscv, linux-can
  Cc: oe-kbuild-all, Emil Renner Berthing, Rob Herring,
	Wolfgang Grandegger, Philipp Zabel, Krzysztof Kozlowski,
	Conor Dooley, Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Hi William,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on linus/master mkl-can-next/testing v6.8-rc2 next-20240129]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/William-Qiu/dt-bindings-vendor-prefixes-Add-cast-vendor-prefix/20240129-114752
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240129031239.17037-4-william.qiu%40starfivetech.com
patch subject: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
config: openrisc-allmodconfig (https://download.01.org/0day-ci/archive/20240130/202401300618.Sp2FQ2Z7-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240130/202401300618.Sp2FQ2Z7-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401300618.Sp2FQ2Z7-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/net/can/cast_can.c:352:5: warning: no previous prototype for 'ccan_get_freebuffer' [-Wmissing-prototypes]
     352 | int ccan_get_freebuffer(struct ccan_priv *priv)
         |     ^~~~~~~~~~~~~~~~~~~


vim +/ccan_get_freebuffer +352 drivers/net/can/cast_can.c

   351	
 > 352	int ccan_get_freebuffer(struct ccan_priv *priv)
   353	{
   354		/* Get next transmit buffer */
   355		ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_TENEXT_MASK);
   356	
   357		if (ccan_ioread8(priv->reg_base + CCAN_TCTRL_OFFSET) & CCAN_SET_TENEXT_MASK)
   358			return -EPERM;
   359	
   360		return 0;
   361	}
   362	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller
  2024-01-29 15:37   ` Conor Dooley
@ 2024-01-30  6:30     ` William Qiu
  2024-01-30 17:02       ` Conor Dooley
  0 siblings, 1 reply; 19+ messages in thread
From: William Qiu @ 2024-01-30  6:30 UTC (permalink / raw)
  To: Conor Dooley
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou

> -----Original Message-----
> From: Conor Dooley <conor@kernel.org>
> Sent: 2024年1月29日 23:37
> To: William Qiu <william.qiu@starfivetech.com>
> Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-riscv@lists.infradead.org; linux-can@vger.kernel.org; Emil Renner
> Berthing <kernel@esmil.dk>; Rob Herring <robh+dt@kernel.org>; Wolfgang
> Grandegger <wg@grandegger.com>; Philipp Zabel <p.zabel@pengutronix.de>;
> Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley
> <conor+dt@kernel.org>; Marc Kleine-Budde <mkl@pengutronix.de>; David S .
> Miller <davem@davemloft.net>; Eric Dumazet <edumazet@google.com>;
> Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; Paul
> Walmsley <paul.walmsley@sifive.com>; Palmer Dabbelt
> <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN
> Controller
> 
> Hey William,
> 
> On Mon, Jan 29, 2024 at 11:12:37AM +0800, William Qiu wrote:
> > Add bindings for CAST CAN Controller
> >
> > Signed-off-by: William Qiu <william.qiu@starfivetech.com>
> > ---
> >  .../devicetree/bindings/net/can/cast,can.yaml | 95
> > +++++++++++++++++++
> >  1 file changed, 95 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/net/can/cast,can.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/net/can/cast,can.yaml
> > b/Documentation/devicetree/bindings/net/can/cast,can.yaml
> > new file mode 100644
> > index 000000000000..ea52132d9b1c
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/can/cast,can.yaml
> > @@ -0,0 +1,95 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/can/cast,can.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: CAST CAN controller
> > +
> > +maintainers:
> > +  - William Qiu <william.qiu@starfivetech.com>
> > +
> > +allOf:
> > +  - $ref: can-controller.yaml#
> > +  - if:
> > +      properties:
> > +        compatible:
> > +          contains:
> > +            const: starfive,can
> > +    then:
> > +      required:
> > +        - starfive,syscon
> 
> If you've got property related stuff in the allOf, move it down after the property
> definitions.
> 
Will update
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - cast,can
> > +      - cast,canfd
> 
> I don't like these uber generic compatibles that have no users as a fallback.
> Allowing them in the binding only really discourages people from creating device
> specific compatibles.
> Secondly, this is some purchased IP that I am sure has a versioning scheme and
> the compatibles that you have created do not reflect that.
> If they were being used as a fallback, I would request some versioning.
> That's not going to really work though since the canfd features on the
> jh7110 require setting u0_can_ctrl_can_fd_enable, so neither of these
> compatibles really has a use right now.
> 
I'll add some tag to do versioning.
> > +      - starfive,can
> 
> Just "starfive,can"? Can you please add device specific compatibles for the SoCs
> on which this is used?
> 
Will add.
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    minItems: 3
> > +
> > +  clock-names:
> > +    items:
> > +      - const: apb_clk
> > +      - const: timer_clk
> > +      - const: can_clk
> 
> Drop _clk, they're all clocks!
> 
Will drop.
> > +
> > +  resets:
> > +    minItems: 3
> > +
> > +  reset-names:
> > +    items:
> > +      - const: rst_apb
> > +      - const: rst_core
> > +      - const: rst_timer
> 
> Same here, drop rst_
>Will drop.
> > +
> > +  starfive,syscon:
> > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > +    items:
> > +      - items:
> > +          - description: phandle to System Register Controller syscon node
> > +          - description: offset of SYS_SYSCON_NE__SAIF__SYSCFG
> > + register for CAN controller
> 
> The docs I have call this register "SYS_SYSCONSAIF__SYSCFG". Did the names
> change since the TRM I have was written?
> 
They do change on the 8100 SoC.
Other descriptions may be needed for compatibility. I'll think about it.

Thanks,
William
> > +          - description: shift of SYS_SYSCON_NE__SAIF__SYSCFG register
> for CAN controller
> > +          - description: mask of SYS_SYSCON_NE__SAIF__SYSCFG register
> for CAN controller
> > +    description:
> > +      Should be four parameters, the phandle to System Register Controller
> > +      syscon node and the offset/shift/mask of
> SYS_SYSCON_NE__SAIF__SYSCFG register
> > +      for CAN controller.
> 
> Cheers,
> Conor.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: RE: [PATCH v1 0/4] CAST Controller Area Network driver support
  2024-01-29 11:31     ` Marc Kleine-Budde
@ 2024-01-30  6:41       ` William Qiu
  0 siblings, 0 replies; 19+ messages in thread
From: William Qiu @ 2024-01-30  6:41 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou



> -----Original Message-----
> From: Marc Kleine-Budde <mkl@pengutronix.de>
> Sent: 2024年1月29日 19:31
> To: William Qiu <william.qiu@starfivetech.com>
> Cc: devicetree@vger.kernel.org; linux-kernel@vger.kernel.org;
> linux-riscv@lists.infradead.org; linux-can@vger.kernel.org; Emil Renner
> Berthing <kernel@esmil.dk>; Rob Herring <robh+dt@kernel.org>; Wolfgang
> Grandegger <wg@grandegger.com>; Philipp Zabel <p.zabel@pengutronix.de>;
> Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>; Conor Dooley
> <conor+dt@kernel.org>; David S . Miller <davem@davemloft.net>; Eric
> Dumazet <edumazet@google.com>; Jakub Kicinski <kuba@kernel.org>; Paolo
> Abeni <pabeni@redhat.com>; Paul Walmsley <paul.walmsley@sifive.com>;
> Palmer Dabbelt <palmer@dabbelt.com>; Albert Ou <aou@eecs.berkeley.edu>
> Subject: Re: RE: [PATCH v1 0/4] CAST Controller Area Network driver support
> 
> On 29.01.2024 08:07:49, William Qiu wrote:
> > > Is there a public available data sheet for the IP core?
> >
> > We do have the data sheet, but I'm not sure if CAST is willing to make
> > it public. I need to contact them first and then reply to you.
> > Or you can contact them on their website, which is
> https://www.cast-inc.com/.
> 
> I'll contact them via the website, but please ask them as well, as you have
> probably a better, more direct contact to them.
> 
> regards,
> Marc
> 
I see. I'll do it .

Thanks,
William
> --
> Pengutronix e.K.                 | Marc Kleine-Budde          |
> Embedded Linux                   | https://www.pengutronix.de |
> Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix
  2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
  2024-01-29 14:59   ` Conor Dooley
@ 2024-01-30 16:44   ` Rob Herring
  1 sibling, 0 replies; 19+ messages in thread
From: Rob Herring @ 2024-01-30 16:44 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Wolfgang Grandegger, Philipp Zabel,
	Krzysztof Kozlowski, Conor Dooley, Marc Kleine-Budde,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Paul Walmsley, Palmer Dabbelt, Albert Ou

On Mon, Jan 29, 2024 at 11:12:36AM +0800, William Qiu wrote:
> Add prefix for Computer-Aided Software Technologies, Inc.

The diff tells me this. The commit message should say who Computer-Aided 
Software Technologies, Inc. is. What do they make? Website? etc.

> 
> Signed-off-by: William Qiu <william.qiu@starfivetech.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 1a0dc04f1db4..b9c6ce99d24d 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -242,6 +242,8 @@ patternProperties:
>      description: Capella Microsystems, Inc
>    "^cascoda,.*":
>      description: Cascoda, Ltd.
> +  "^cast,.*":
> +    description: Computer-Aided Software Technologies, Inc.
>    "^catalyst,.*":
>      description: Catalyst Semiconductor, Inc.
>    "^cavium,.*":
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller
  2024-01-30  6:30     ` William Qiu
@ 2024-01-30 17:02       ` Conor Dooley
  0 siblings, 0 replies; 19+ messages in thread
From: Conor Dooley @ 2024-01-30 17:02 UTC (permalink / raw)
  To: William Qiu
  Cc: devicetree, linux-kernel, linux-riscv, linux-can,
	Emil Renner Berthing, Rob Herring, Wolfgang Grandegger,
	Philipp Zabel, Krzysztof Kozlowski, Conor Dooley,
	Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

On Tue, Jan 30, 2024 at 06:30:54AM +0000, William Qiu wrote:
> > From: Conor Dooley <conor@kernel.org>
> > On Mon, Jan 29, 2024 at 11:12:37AM +0800, William Qiu wrote:

> > > +properties:
> > > +  compatible:
> > > +    enum:
> > > +      - cast,can
> > > +      - cast,canfd
> > 
> > I don't like these uber generic compatibles that have no users as a fallback.
> > Allowing them in the binding only really discourages people from creating device
> > specific compatibles.
> > Secondly, this is some purchased IP that I am sure has a versioning scheme and
> > the compatibles that you have created do not reflect that.
> > If they were being used as a fallback, I would request some versioning.
> > That's not going to really work though since the canfd features on the
> > jh7110 require setting u0_can_ctrl_can_fd_enable, so neither of these
> > compatibles really has a use right now.
> > 
> I'll add some tag to do versioning.

I don't want to see a "cast,can-<something>" compatible allowed in
isolation either as there is no user for it.
The generic compatibles like that should only be permitted in
combination with a device specific one - particularly since there are
bits in implementation defined registers that control whether or not
canfd is enabled.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
  2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
                     ` (2 preceding siblings ...)
  2024-01-29 22:58   ` kernel test robot
@ 2024-01-31  1:23   ` kernel test robot
  3 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2024-01-31  1:23 UTC (permalink / raw)
  To: William Qiu, devicetree, linux-kernel, linux-riscv, linux-can
  Cc: oe-kbuild-all, Emil Renner Berthing, Rob Herring,
	Wolfgang Grandegger, Philipp Zabel, Krzysztof Kozlowski,
	Conor Dooley, Marc Kleine-Budde, David S . Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, William Qiu

Hi William,

kernel test robot noticed the following build warnings:

[auto build test WARNING on robh/for-next]
[also build test WARNING on linus/master mkl-can-next/testing v6.8-rc2 next-20240130]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/William-Qiu/dt-bindings-vendor-prefixes-Add-cast-vendor-prefix/20240129-114752
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/20240129031239.17037-4-william.qiu%40starfivetech.com
patch subject: [PATCH v1 3/4] can: cast: add driver for CAST CAN controller
config: arm-randconfig-r131-20240131 (https://download.01.org/0day-ci/archive/20240131/202401310909.4bnaezTF-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project fdac7d0b6f74f919d319b31a0680c77f66732586)
reproduce: (https://download.01.org/0day-ci/archive/20240131/202401310909.4bnaezTF-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202401310909.4bnaezTF-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/net/can/cast_can.c:277:41: sparse: sparse: subtraction of different types can't work (different address spaces)
   drivers/net/can/cast_can.c:295:41: sparse: sparse: subtraction of different types can't work (different address spaces)
>> drivers/net/can/cast_can.c:308:50: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:357:41: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
>> drivers/net/can/cast_can.c:352:5: sparse: sparse: symbol 'ccan_get_freebuffer' was not declared. Should it be static?
   drivers/net/can/cast_can.c:375:51: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:389:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:394:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:396:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:438:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:443:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:445:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:504:47: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:505:49: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:514:55: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:515:57: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:695:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
>> drivers/net/can/cast_can.c:697:43: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:732:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:733:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:760:44: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:761:45: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:762:45: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:765:48: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:837:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:838:9: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:849:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:852:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:921:58: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:926:43: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const *addr @@     got void [noderef] __iomem * @@
   drivers/net/can/cast_can.c:934:43: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void *addr @@     got void [noderef] __iomem * @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
   drivers/net/can/cast_can.c:260:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:262:31: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
   drivers/net/can/cast_can.c:260:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:262:31: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:244:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
   drivers/net/can/cast_can.c:260:31: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@
>> drivers/net/can/cast_can.c:262:31: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got void *[assigned] addr_down @@

vim +277 drivers/net/can/cast_can.c

   232	
   233	static inline unsigned char ccan_ioread8(const void  *addr)
   234	{
   235		void  *addr_down;
   236		union val {
   237			u8 val_8[4];
   238			u32 val_32;
   239		} val;
   240		u32 offset = 0;
   241	
   242		addr_down = (void  *)ALIGN_DOWN((unsigned long)addr, 4);
   243		offset = addr - addr_down;
 > 244		val.val_32 = ioread32(addr_down);
   245	
   246		return val.val_8[offset];
   247	}
   248	
   249	static inline void ccan_iowrite8(unsigned char value, void  *addr)
   250	{
   251		void  *addr_down;
   252		union val {
   253			u8 val_8[4];
   254			u32 val_32;
   255		} val;
   256		u8 offset = 0;
   257	
   258		addr_down = (void *)ALIGN_DOWN((unsigned long)addr, 4);
   259		offset = addr - addr_down;
   260		val.val_32 = ioread32(addr_down);
   261		val.val_8[offset] = value;
 > 262		iowrite32(val.val_32, addr_down);
   263	}
   264	
   265	static void ccan_reigister_set_bit(const struct ccan_priv *priv,
   266					   enum ccan_device_reg reg,
   267					   enum ccan_reg_bitchange mask)
   268	{
   269		void  *addr_down;
   270		union val {
   271			u8 val_8[4];
   272			u32 val_32;
   273		} val;
   274		u8 offset = 0;
   275	
   276		addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
 > 277		offset = (priv->reg_base + reg) - addr_down;
   278		val.val_32 = ioread32(addr_down);
   279		val.val_8[offset] |= mask;
   280		iowrite32(val.val_32, addr_down);
   281	}
   282	
   283	static void ccan_reigister_off_bit(const struct ccan_priv *priv,
   284					   enum ccan_device_reg reg,
   285					   enum ccan_reg_bitchange mask)
   286	{
   287		void  *addr_down;
   288		union val {
   289			u8 val_8[4];
   290			u32 val_32;
   291		} val;
   292		u8 offset = 0;
   293	
   294		addr_down = (void *)ALIGN_DOWN((unsigned long)(priv->reg_base + reg), 4);
   295		offset = (priv->reg_base + reg) - addr_down;
   296		val.val_32 = ioread32(addr_down);
   297		val.val_8[offset] &= mask;
   298		iowrite32(val.val_32, addr_down);
   299	}
   300	
   301	static int ccan_device_driver_bittime_configuration(struct net_device *ndev)
   302	{
   303		struct ccan_priv *priv = netdev_priv(ndev);
   304		struct can_bittiming *bt = &priv->can.bittiming;
   305		struct can_bittiming *dbt = &priv->can.data_bittiming;
   306		u32 reset_test, bittiming_temp, data_bittiming;
   307	
 > 308		reset_test = ccan_ioread8(priv->reg_base + CCAN_CFG_STAT_OFFSET);
   309	
   310		if (!(reset_test & CCAN_SET_RST_MASK)) {
   311			netdev_alert(ndev, "Not in reset mode, cannot set bit timing\n");
   312			return -EPERM;
   313		}
   314	
   315		bittiming_temp = ((bt->phase_seg1 + bt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
   316				 ((bt->phase_seg2 - 1) << SEG_2_SHIFT) |
   317				 ((bt->sjw - 1) << SJW_SHIFT) |
   318				 ((bt->brp - 1) << PRESC_SHIFT);
   319	
   320		/* Check the bittime parameter */
   321		if ((((int)(bt->phase_seg1 + bt->prop_seg + 1) - 2) < 0) ||
   322		    (((int)(bt->phase_seg2) - 1) < 0) ||
   323		    (((int)(bt->sjw) - 1) < 0) ||
   324		    (((int)(bt->brp) - 1) < 0))
   325			return -EINVAL;
   326	
   327		priv->write_reg(priv, CCAN_S_SEG_1_OFFSET, bittiming_temp);
   328	
   329		if (priv->cantype == CAST_CAN_TYPE_CANFD) {
   330			data_bittiming = ((dbt->phase_seg1 + dbt->prop_seg + 1 - 2) << SEG_1_SHIFT) |
   331					 ((dbt->phase_seg2 - 1) << SEG_2_SHIFT) |
   332					 ((dbt->sjw - 1) << SJW_SHIFT) |
   333					 ((dbt->brp - 1) << PRESC_SHIFT);
   334	
   335			if ((((int)(dbt->phase_seg1 + dbt->prop_seg + 1) - 2) < 0) ||
   336			    (((int)(dbt->phase_seg2) - 1) < 0) ||
   337			    (((int)(dbt->sjw) - 1) < 0) ||
   338			    (((int)(dbt->brp) - 1) < 0))
   339				return -EINVAL;
   340	
   341			priv->write_reg(priv, CCAN_F_SEG_1_OFFSET, data_bittiming);
   342		}
   343	
   344		ccan_reigister_off_bit(priv, CCAN_CFG_STAT_OFFSET, CCAN_OFF_RST_MASK);
   345	
   346		netdev_dbg(ndev, "Slow bit rate: %08x\n", priv->read_reg(priv, CCAN_S_SEG_1_OFFSET));
   347		netdev_dbg(ndev, "Fast bit rate: %08x\n", priv->read_reg(priv, CCAN_F_SEG_1_OFFSET));
   348	
   349		return 0;
   350	}
   351	
 > 352	int ccan_get_freebuffer(struct ccan_priv *priv)
   353	{
   354		/* Get next transmit buffer */
   355		ccan_reigister_set_bit(priv, CCAN_TCTRL_OFFSET, CCAN_SET_TENEXT_MASK);
   356	
   357		if (ccan_ioread8(priv->reg_base + CCAN_TCTRL_OFFSET) & CCAN_SET_TENEXT_MASK)
   358			return -EPERM;
   359	
   360		return 0;
   361	}
   362	
   363	static void ccan_tx_interrupt(struct net_device *ndev, u8 isr)
   364	{
   365		struct ccan_priv *priv = netdev_priv(ndev);
   366	
   367		/* wait till transmission of the PTB or STB finished */
   368		while (isr & (CCAN_SET_TPIF_MASK | CCAN_SET_TSIF_MASK)) {
   369			if (isr & CCAN_SET_TPIF_MASK)
   370				ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_TPIF_MASK);
   371	
   372			if (isr & CCAN_SET_TSIF_MASK)
   373				ccan_reigister_set_bit(priv, CCAN_RTIF_OFFSET, CCAN_SET_TSIF_MASK);
   374	
   375			isr = ccan_ioread8(priv->reg_base + CCAN_RTIF_OFFSET);
   376		}
   377		netif_wake_queue(ndev);
   378	}
   379	
   380	static int ccan_rx(struct net_device *ndev)
   381	{
   382		struct ccan_priv *priv = netdev_priv(ndev);
   383		struct net_device_stats *stats = &ndev->stats;
   384		struct can_frame *cf;
   385		struct sk_buff *skb;
   386		u32 can_id;
   387		u8  dlc, control, rx_status;
   388	
   389		rx_status = ccan_ioread8(priv->reg_base + CCAN_RCTRL_OFFSET);
   390	
   391		if (!(rx_status & CCAN_RSTAT_NOT_EMPTY_MASK))
   392			return 0;
   393	
   394		control = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET);
   395		can_id = priv->read_reg(priv, CCAN_RUBF_ID_OFFSET);
 > 396		dlc = ccan_ioread8(priv->reg_base + CCAN_RBUF_CTL_OFFSET) & CCAN_SET_DLC_MASK;
   397	
   398		skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
   399		if (!skb) {
   400			stats->rx_dropped++;
   401			return 0;
   402		}
   403		cf->can_dlc = can_cc_dlc2len(dlc);
   404	
   405		/* change the CANFD id into socketcan id format */
   406		cf->can_id = can_id;
   407		if (control & CCAN_SET_IDE_MASK)
   408			cf->can_id |= CAN_EFF_FLAG;
   409		else
   410			cf->can_id &= ~CAN_EFF_FLAG;
   411	
   412		if (control & CCAN_SET_RTR_MASK)
   413			cf->can_id |= CAN_RTR_FLAG;
   414	
   415		if (!(control & CCAN_SET_RTR_MASK)) {
   416			*((u32 *)(cf->data + 0)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET);
   417			*((u32 *)(cf->data + 4)) = priv->read_reg(priv, CCAN_RBUF_DATA_OFFSET + 4);
   418		}
   419	
   420		ccan_reigister_set_bit(priv, CCAN_RCTRL_OFFSET, CCAN_SET_RREL_MASK);
   421		stats->rx_bytes += can_fd_dlc2len(cf->can_dlc);
   422		stats->rx_packets++;
   423		netif_receive_skb(skb);
   424	
   425		return 1;
   426	}
   427	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-01-31  1:24 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-29  3:12 [PATCH v1 0/4] CAST Controller Area Network driver support William Qiu
2024-01-29  3:12 ` [PATCH v1 1/4] dt-bindings: vendor-prefixes: Add cast vendor prefix William Qiu
2024-01-29 14:59   ` Conor Dooley
2024-01-30 16:44   ` Rob Herring
2024-01-29  3:12 ` [PATCH v1 2/4] dt-bindings: can: Add bindings for CAST CAN Controller William Qiu
2024-01-29 15:37   ` Conor Dooley
2024-01-30  6:30     ` William Qiu
2024-01-30 17:02       ` Conor Dooley
2024-01-29  3:12 ` [PATCH v1 3/4] can: cast: add driver for CAST CAN controller William Qiu
2024-01-29  8:26   ` Marc Kleine-Budde
2024-01-29  8:42     ` William Qiu
2024-01-29 19:51   ` kernel test robot
2024-01-29 22:58   ` kernel test robot
2024-01-31  1:23   ` kernel test robot
2024-01-29  3:12 ` [PATCH v1 4/4] riscv: dts: starfive: jh7110: Add CAN node William Qiu
2024-01-29  7:57 ` [PATCH v1 0/4] CAST Controller Area Network driver support Marc Kleine-Budde
2024-01-29  8:07   ` William Qiu
2024-01-29 11:31     ` Marc Kleine-Budde
2024-01-30  6:41       ` William Qiu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).