summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMarc Kleine-Budde <mkl@pengutronix.de>2023-05-15 22:26:39 +0200
committerMarc Kleine-Budde <mkl@pengutronix.de>2023-05-15 22:26:39 +0200
commitc08e24013aba49a593424715ffc04c928c84b9c9 (patch)
treee63c05791537b9136a3ae1c178dfa2e9b92146e1 /drivers
parent4920bded3ee077c99cd52666519cb50f9ee35b26 (diff)
parent0920ccdf41e3078a4dd2567eb905ea154bc826e6 (diff)
Merge patch series "can: bxcan: add support for single peripheral configuration"
Dario Binacchi <dario.binacchi@amarulasolutions.com> says: The series adds support for managing bxCAN controllers in single peripheral configuration. Unlike stm32f4 SOCs, where bxCAN controllers are only in dual peripheral configuration, stm32f7 SOCs contain three CAN peripherals, CAN1 and CAN2 in dual peripheral configuration and CAN3 in single peripheral configuration: - Dual CAN peripheral configuration: * CAN1: Primary bxCAN for managing the communication between a secondary bxCAN and the 512-byte SRAM memory. * CAN2: Secondary bxCAN with no direct access to the SRAM memory. This means that the two bxCAN cells share the 512-byte SRAM memory and CAN2 can't be used without enabling CAN1. - Single CAN peripheral configuration: * CAN3: Primary bxCAN with dedicated Memory Access Controller unit and 512-byte SRAM memory. The driver has been tested on the stm32f769i-discovery board with a kernel version 5.19.0-rc2 in loopback + silent mode: | ip link set can[0-2] type can bitrate 125000 loopback on listen-only on | ip link set up can[0-2] | candump can[0-2] -L & | cansend can[0-2] 300#AC.AB.AD.AE.75.49.AD.D1 Changes in v2: - s/fiter/filter/ in the commit message - Replace struct bxcan_mb::primary with struct bxcan_mb::cfg. - Move after the patch "can: bxcan: add support for single peripheral configuration". - Add node gcan3. - Rename gcan as gcan1. - Add property "st,can-secondary" to can2 node. - Drop patch "dt-bindings: mfd: stm32f7: add binding definition for CAN3" because it has been accepted. - Add patch "ARM: dts: stm32f429: put can2 in secondary mode". - Add patch "dt-bindings: net: can: add "st,can-secondary" property". v1: https://lore.kernel.org/all/20230423172528.1398158-1-dario.binacchi@amarulasolutions.com Link: https://lore.kernel.org/all/20230427204540.3126234-1-dario.binacchi@amarulasolutions.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/can/bxcan.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/net/can/bxcan.c b/drivers/net/can/bxcan.c
index e26ccd41e3cb..027a8a162fe4 100644
--- a/drivers/net/can/bxcan.c
+++ b/drivers/net/can/bxcan.c
@@ -118,7 +118,7 @@
#define BXCAN_FiR1_REG(b) (0x40 + (b) * 8)
#define BXCAN_FiR2_REG(b) (0x44 + (b) * 8)
-#define BXCAN_FILTER_ID(primary) (primary ? 0 : 14)
+#define BXCAN_FILTER_ID(cfg) ((cfg) == BXCAN_CFG_DUAL_SECONDARY ? 14 : 0)
/* Filter primary register (FMR) bits */
#define BXCAN_FMR_CANSB_MASK GENMASK(13, 8)
@@ -135,6 +135,12 @@ enum bxcan_lec_code {
BXCAN_LEC_UNUSED
};
+enum bxcan_cfg {
+ BXCAN_CFG_SINGLE = 0,
+ BXCAN_CFG_DUAL_PRIMARY,
+ BXCAN_CFG_DUAL_SECONDARY
+};
+
/* Structure of the message buffer */
struct bxcan_mb {
u32 id; /* can identifier */
@@ -167,7 +173,7 @@ struct bxcan_priv {
struct regmap *gcan;
int tx_irq;
int sce_irq;
- bool primary;
+ enum bxcan_cfg cfg;
struct clk *clk;
spinlock_t rmw_lock; /* lock for read-modify-write operations */
unsigned int tx_head;
@@ -202,17 +208,17 @@ static inline void bxcan_rmw(struct bxcan_priv *priv, void __iomem *addr,
spin_unlock_irqrestore(&priv->rmw_lock, flags);
}
-static void bxcan_disable_filters(struct bxcan_priv *priv, bool primary)
+static void bxcan_disable_filters(struct bxcan_priv *priv, enum bxcan_cfg cfg)
{
- unsigned int fid = BXCAN_FILTER_ID(primary);
+ unsigned int fid = BXCAN_FILTER_ID(cfg);
u32 fmask = BIT(fid);
regmap_update_bits(priv->gcan, BXCAN_FA1R_REG, fmask, 0);
}
-static void bxcan_enable_filters(struct bxcan_priv *priv, bool primary)
+static void bxcan_enable_filters(struct bxcan_priv *priv, enum bxcan_cfg cfg)
{
- unsigned int fid = BXCAN_FILTER_ID(primary);
+ unsigned int fid = BXCAN_FILTER_ID(cfg);
u32 fmask = BIT(fid);
/* Filter settings:
@@ -680,7 +686,7 @@ static int bxcan_chip_start(struct net_device *ndev)
BXCAN_BTR_BRP_MASK | BXCAN_BTR_TS1_MASK | BXCAN_BTR_TS2_MASK |
BXCAN_BTR_SJW_MASK, set);
- bxcan_enable_filters(priv, priv->primary);
+ bxcan_enable_filters(priv, priv->cfg);
/* Clear all internal status */
priv->tx_head = 0;
@@ -806,7 +812,7 @@ static void bxcan_chip_stop(struct net_device *ndev)
BXCAN_IER_EPVIE | BXCAN_IER_EWGIE | BXCAN_IER_FOVIE1 |
BXCAN_IER_FFIE1 | BXCAN_IER_FMPIE1 | BXCAN_IER_FOVIE0 |
BXCAN_IER_FFIE0 | BXCAN_IER_FMPIE0 | BXCAN_IER_TMEIE, 0);
- bxcan_disable_filters(priv, priv->primary);
+ bxcan_disable_filters(priv, priv->cfg);
bxcan_enter_sleep_mode(priv);
priv->can.state = CAN_STATE_STOPPED;
}
@@ -931,7 +937,7 @@ static int bxcan_probe(struct platform_device *pdev)
struct clk *clk = NULL;
void __iomem *regs;
struct regmap *gcan;
- bool primary;
+ enum bxcan_cfg cfg;
int err, rx_irq, tx_irq, sce_irq;
regs = devm_platform_ioremap_resource(pdev, 0);
@@ -946,7 +952,13 @@ static int bxcan_probe(struct platform_device *pdev)
return PTR_ERR(gcan);
}
- primary = of_property_read_bool(np, "st,can-primary");
+ if (of_property_read_bool(np, "st,can-primary"))
+ cfg = BXCAN_CFG_DUAL_PRIMARY;
+ else if (of_property_read_bool(np, "st,can-secondary"))
+ cfg = BXCAN_CFG_DUAL_SECONDARY;
+ else
+ cfg = BXCAN_CFG_SINGLE;
+
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "failed to get clock\n");
@@ -992,7 +1004,7 @@ static int bxcan_probe(struct platform_device *pdev)
priv->clk = clk;
priv->tx_irq = tx_irq;
priv->sce_irq = sce_irq;
- priv->primary = primary;
+ priv->cfg = cfg;
priv->can.clock.freq = clk_get_rate(clk);
spin_lock_init(&priv->rmw_lock);
priv->tx_head = 0;