can: sun4i_can: Add acceptance register quirk
authorJohn Watts <contact@jookia.org>
Fri, 21 Jul 2023 22:15:52 +0000 (08:15 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Sep 2023 09:11:01 +0000 (11:11 +0200)
[ Upstream commit 8cda0c6dfd42ee6f2586e7dffb553aaf1fcb62ca ]

The Allwinner D1's CAN controllers have the ACPC and ACPM registers
moved down. Compensate for this by adding an offset quirk for the
acceptance registers.

Signed-off-by: John Watts <contact@jookia.org>
Link: https://lore.kernel.org/all/20230721221552.1973203-5-contact@jookia.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/can/sun4i_can.c

index 2b78f91..dd0c6cd 100644 (file)
  * struct sun4ican_quirks - Differences between SoC variants.
  *
  * @has_reset: SoC needs reset deasserted.
+ * @acp_offset: Offset of ACPC and ACPM registers
  */
 struct sun4ican_quirks {
        bool has_reset;
+       int acp_offset;
 };
 
 struct sun4ican_priv {
@@ -216,6 +218,7 @@ struct sun4ican_priv {
        struct clk *clk;
        struct reset_control *reset;
        spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */
+       int acp_offset;
 };
 
 static const struct can_bittiming_const sun4ican_bittiming_const = {
@@ -338,8 +341,8 @@ static int sun4i_can_start(struct net_device *dev)
        }
 
        /* set filters - we accept all */
-       writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR);
-       writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR);
+       writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset);
+       writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset);
 
        /* clear error counters and error code capture */
        writel(0, priv->base + SUN4I_REG_ERRC_ADDR);
@@ -768,10 +771,12 @@ static const struct ethtool_ops sun4ican_ethtool_ops = {
 
 static const struct sun4ican_quirks sun4ican_quirks_a10 = {
        .has_reset = false,
+       .acp_offset = 0,
 };
 
 static const struct sun4ican_quirks sun4ican_quirks_r40 = {
        .has_reset = true,
+       .acp_offset = 0,
 };
 
 static const struct of_device_id sun4ican_of_match[] = {
@@ -872,6 +877,7 @@ static int sun4ican_probe(struct platform_device *pdev)
        priv->base = addr;
        priv->clk = clk;
        priv->reset = reset;
+       priv->acp_offset = quirks->acp_offset;
        spin_lock_init(&priv->cmdreg_lock);
 
        platform_set_drvdata(pdev, dev);