[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250526062559.2061311-3-zhangqing@rock-chips.com>
Date: Mon, 26 May 2025 14:25:57 +0800
From: Elaine Zhang <zhangqing@...k-chips.com>
To: zhangqing@...k-chips.com,
mkl@...gutronix.de,
kernel@...gutronix.de,
mailhol.vincent@...adoo.fr,
robh@...nel.org,
krzk+dt@...nel.org,
conor+dt@...nel.org,
heiko@...ech.de,
cl@...k-chips.com,
kever.yang@...k-chips.com
Cc: linux-can@...r.kernel.org,
linux-arm-kernel@...ts.infradead.org,
linux-rockchip@...ts.infradead.org,
linux-kernel@...r.kernel.org,
devicetree@...r.kernel.org
Subject: [PATCH v6 2/4] net: can: rockchip: Refactor the rkcanfd_devtype_data structure
Add new function pointer:
Encapsulate some hardware operation functions into
rkcanfd_devtype_data to provide differentiated implementations for
different models (such as RK3568v2/v3).
Signed-off-by: Elaine Zhang <zhangqing@...k-chips.com>
---
.../net/can/rockchip/rockchip_canfd-core.c | 104 ++++++++++--------
drivers/net/can/rockchip/rockchip_canfd.h | 11 ++
2 files changed, 72 insertions(+), 43 deletions(-)
diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index c3fb3176ce42..c21ca4c1fb9a 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -24,32 +24,6 @@
#include "rockchip_canfd.h"
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
- .model = RKCANFD_MODEL_RK3568V2,
- .quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
- RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
- RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
- RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
- RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
- RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
- RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
-/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
- * states that only the rk3568v2 is affected by erratum 5, but tests
- * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
- * sometimes too high. In contrast to the errata sheet mark rk3568v3
- * as effected by erratum 5, too.
- */
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
- .model = RKCANFD_MODEL_RK3568V3,
- .quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
- RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
- RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
- RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
- RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
{
switch (model) {
@@ -212,7 +186,7 @@ static int rkcanfd_get_berr_counter(const struct net_device *ndev,
if (err)
return err;
- rkcanfd_get_berr_counter_corrected(priv, bec);
+ priv->devtype_data.get_berr_counter(priv, bec);
pm_runtime_put(ndev->dev.parent);
@@ -296,13 +270,13 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
memset(&priv->bec, 0x0, sizeof(priv->bec));
- rkcanfd_chip_fifo_setup(priv);
+ priv->devtype_data.fifo_setup(priv);
rkcanfd_timestamp_init(priv);
rkcanfd_timestamp_start(priv);
rkcanfd_set_bittiming(priv);
- rkcanfd_chip_interrupts_disable(priv);
+ priv->devtype_data.interrupts_disable(priv);
rkcanfd_chip_set_work_mode(priv);
priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -316,7 +290,7 @@ static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state
priv->can.state = state;
rkcanfd_chip_set_reset_mode(priv);
- rkcanfd_chip_interrupts_disable(priv);
+ priv->devtype_data.interrupts_disable(priv);
}
static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
@@ -342,8 +316,8 @@ static int rkcanfd_set_mode(struct net_device *ndev,
switch (mode) {
case CAN_MODE_START:
- rkcanfd_chip_start(priv);
- rkcanfd_chip_interrupts_enable(priv);
+ priv->devtype_data.chip_start(priv);
+ priv->devtype_data.interrupts_enable(priv);
netif_wake_queue(ndev);
break;
@@ -537,7 +511,7 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
if (cf) {
struct can_berr_counter bec;
- rkcanfd_get_berr_counter_corrected(priv, &bec);
+ priv->devtype_data.get_berr_counter(priv, &bec);
cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
cf->data[6] = bec.txerr;
cf->data[7] = bec.rxerr;
@@ -567,7 +541,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
u32 timestamp;
int err;
- rkcanfd_get_berr_counter_corrected(priv, &bec);
+ priv->devtype_data.get_berr_counter(priv, &bec);
can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
new_state = max(tx_state, rx_state);
@@ -581,7 +555,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
can_change_state(ndev, cf, tx_state, rx_state);
if (new_state == CAN_STATE_BUS_OFF) {
- rkcanfd_chip_stop(priv, CAN_STATE_BUS_OFF);
+ priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
can_bus_off(ndev);
}
@@ -620,7 +594,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
if (!skb)
return 0;
- rkcanfd_get_berr_counter_corrected(priv, &bec);
+ priv->devtype_data.get_berr_counter(priv, &bec);
cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
@@ -719,21 +693,21 @@ static int rkcanfd_open(struct net_device *ndev)
if (err)
goto out_close_candev;
- rkcanfd_chip_start(priv);
+ priv->devtype_data.chip_start(priv);
can_rx_offload_enable(&priv->offload);
- err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);
+ err = request_irq(ndev->irq, priv->devtype_data.irq, IRQF_SHARED, ndev->name, priv);
if (err)
goto out_rkcanfd_chip_stop;
- rkcanfd_chip_interrupts_enable(priv);
+ priv->devtype_data.interrupts_enable(priv);
netif_start_queue(ndev);
return 0;
out_rkcanfd_chip_stop:
- rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+ priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
pm_runtime_put(ndev->dev.parent);
out_close_candev:
close_candev(ndev);
@@ -746,10 +720,10 @@ static int rkcanfd_stop(struct net_device *ndev)
netif_stop_queue(ndev);
- rkcanfd_chip_interrupts_disable(priv);
+ priv->devtype_data.interrupts_disable(priv);
free_irq(ndev->irq, priv);
can_rx_offload_disable(&priv->offload);
- rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+ priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
close_candev(ndev);
pm_runtime_put(ndev->dev.parent);
@@ -818,7 +792,7 @@ static int rkcanfd_register(struct rkcanfd_priv *priv)
if (err)
goto out_pm_runtime_put_sync;
- rkcanfd_register_done(priv);
+ priv->devtype_data.register_done(priv);
pm_runtime_put(ndev->dev.parent);
@@ -840,6 +814,50 @@ static inline void rkcanfd_unregister(struct rkcanfd_priv *priv)
pm_runtime_disable(ndev->dev.parent);
}
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
+ .model = RKCANFD_MODEL_RK3568V2,
+ .quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+ RKCANFD_QUIRK_CANFD_BROKEN,
+ .get_berr_counter = rkcanfd_get_berr_counter_corrected,
+ .interrupts_enable = rkcanfd_chip_interrupts_enable,
+ .interrupts_disable = rkcanfd_chip_interrupts_disable,
+ .fifo_setup = rkcanfd_chip_fifo_setup,
+ .chip_start = rkcanfd_chip_start,
+ .chip_stop = rkcanfd_chip_stop,
+ .chip_stop_sync = rkcanfd_chip_stop_sync,
+ .irq = rkcanfd_irq,
+ .register_done = rkcanfd_register_done,
+};
+
+/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
+ * states that only the rk3568v2 is affected by erratum 5, but tests
+ * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
+ * sometimes too high. In contrast to the errata sheet mark rk3568v3
+ * as effected by erratum 5, too.
+ */
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
+ .model = RKCANFD_MODEL_RK3568V3,
+ .quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+ RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+ RKCANFD_QUIRK_CANFD_BROKEN,
+ .get_berr_counter = rkcanfd_get_berr_counter_corrected,
+ .interrupts_enable = rkcanfd_chip_interrupts_enable,
+ .interrupts_disable = rkcanfd_chip_interrupts_disable,
+ .fifo_setup = rkcanfd_chip_fifo_setup,
+ .chip_start = rkcanfd_chip_start,
+ .chip_stop = rkcanfd_chip_stop,
+ .chip_stop_sync = rkcanfd_chip_stop_sync,
+ .irq = rkcanfd_irq,
+ .register_done = rkcanfd_register_done,
+};
+
static const struct of_device_id rkcanfd_of_match[] = {
{
.compatible = "rockchip,rk3568v2-canfd",
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 93131c7d7f54..bcd26d23062b 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -436,9 +436,20 @@ enum rkcanfd_model {
RKCANFD_MODEL_RK3568V3 = 0x35683,
};
+struct rkcanfd_priv;
+
struct rkcanfd_devtype_data {
enum rkcanfd_model model;
u32 quirks;
+ void (*get_berr_counter)(struct rkcanfd_priv *priv, struct can_berr_counter *bec);
+ void (*interrupts_enable)(const struct rkcanfd_priv *priv);
+ void (*interrupts_disable)(const struct rkcanfd_priv *priv);
+ void (*fifo_setup)(struct rkcanfd_priv *priv);
+ void (*chip_start)(struct rkcanfd_priv *priv);
+ void (*chip_stop)(struct rkcanfd_priv *priv, const enum can_state state);
+ void (*chip_stop_sync)(struct rkcanfd_priv *priv, const enum can_state state);
+ irqreturn_t (*irq)(int irq, void *dev_id);
+ void (*register_done)(const struct rkcanfd_priv *priv);
};
struct rkcanfd_fifo_header {
--
2.34.1
Powered by blists - more mailing lists