[PATCH net-next 20/37] can: rcar_canfd: Derive max_channels from the device tree
flat view
COOLING5d
REVIEWED: 2 (2M)
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: 2026-10-15 01:53:48
Also in:
linux-can
Subsystem:
can network drivers, the rest · Maintainers:
Marc Kleine-Budde, Vincent Mailhol, Linus Torvalds
2 review trailers.
From: Biju Das <biju.das.jz@bp.renesas.com> The maximum number of channels is currently hardcoded per SoC in struct rcar_canfd_hw_info. Since the DT describes the channels as child nodes of the controller, the count can be obtained at probe time with of_get_child_count() instead. Drop max_channels from struct rcar_canfd_hw_info and store the value in struct rcar_canfd_global, so it no longer needs to be maintained for each SoC variant. Update all for_each_set_bit() users over channels_mask to use gpriv->max_channels. No functional change. Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Link: https://patch.msgid.link/20261001075742.21961-3-biju.das.jz@bp.renesas.com (local) Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> --- drivers/net/can/rcar/rcar_canfd.c | 39 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index 74c3c3f20991..41c395118949 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c@@ -436,7 +436,6 @@ struct rcar_canfd_hw_info { u8 rnc_field_width; u8 max_aflpn; u8 max_cftml; - u8 max_channels; u8 postdiv; /* hardware features */ unsigned shared_global_irqs:1; /* Has shared global irqs */
@@ -478,6 +477,7 @@ struct rcar_canfd_global { struct reset_control *rstc1; struct reset_control *rstc2; const struct rcar_canfd_hw_info *info; + u8 max_channels; }; /* CAN FD mode nominal rate constants */
@@ -613,7 +613,6 @@ static const struct rcar_canfd_hw_info rcar_gen3_hw_info = { .rnc_field_width = 8, .max_aflpn = 31, .max_cftml = 15, - .max_channels = 2, .postdiv = 2, .shared_global_irqs = 1, .ch_interface_mode = 0,
@@ -632,7 +631,6 @@ static const struct rcar_canfd_hw_info rcar_gen4_hw_info = { .rnc_field_width = 16, .max_aflpn = 127, .max_cftml = 31, - .max_channels = 8, .postdiv = 2, .shared_global_irqs = 1, .ch_interface_mode = 1,
@@ -651,7 +649,6 @@ static const struct rcar_canfd_hw_info rzg2l_hw_info = { .rnc_field_width = 8, .max_aflpn = 31, .max_cftml = 15, - .max_channels = 2, .postdiv = 1, .multi_channel_irqs = 1, .ch_interface_mode = 0,
@@ -670,7 +667,6 @@ static const struct rcar_canfd_hw_info r9a08g045_hw_info = { .rnc_field_width = 16, .max_aflpn = 15, .max_cftml = 31, - .max_channels = 2, .postdiv = 2, .shared_global_irqs = 0, .multi_channel_irqs = 1,
@@ -690,7 +686,6 @@ static const struct rcar_canfd_hw_info r9a09g047_hw_info = { .rnc_field_width = 16, .max_aflpn = 63, .max_cftml = 31, - .max_channels = 6, .postdiv = 1, .multi_channel_irqs = 1, .ch_interface_mode = 1,
@@ -709,7 +704,6 @@ static const struct rcar_canfd_hw_info r9a09g077_hw_info = { .rnc_field_width = 16, .max_aflpn = 15, .max_cftml = 31, - .max_channels = 2, .postdiv = 1, .multi_channel_irqs = 1, .ch_interface_mode = 1,
@@ -854,7 +848,7 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) } /* Transition all Channels to reset mode */ - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { rcar_canfd_clear_bit(gpriv->base, RCANFD_CCTR(ch), RCANFD_CCTR_CSLPR);
@@ -922,7 +916,7 @@ static void rcar_canfd_configure_controller(struct rcar_canfd_global *gpriv) rcar_canfd_set_bit(gpriv->base, RCANFD_GCFG, cfg); /* Channel configuration settings */ - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { rcar_canfd_set_bit(gpriv->base, RCANFD_CCTR(ch), RCANFD_CCTR_ERRD); rcar_canfd_update_bit(gpriv->base, RCANFD_CCTR(ch),
@@ -1293,7 +1287,7 @@ static irqreturn_t rcar_canfd_global_err_interrupt(int irq, void *dev_id) struct rcar_canfd_global *gpriv = dev_id; u32 ch; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) rcar_canfd_handle_global_err(gpriv, ch); return IRQ_HANDLED;
@@ -1325,7 +1319,7 @@ static irqreturn_t rcar_canfd_global_receive_fifo_interrupt(int irq, void *dev_i struct rcar_canfd_global *gpriv = dev_id; u32 ch; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) rcar_canfd_handle_global_receive(gpriv, ch); return IRQ_HANDLED;
@@ -1339,7 +1333,7 @@ static irqreturn_t rcar_canfd_global_interrupt(int irq, void *dev_id) /* Global error interrupts still indicate a condition specific * to a channel. RxFIFO interrupt is a global interrupt. */ - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { rcar_canfd_handle_global_err(gpriv, ch); rcar_canfd_handle_global_receive(gpriv, ch); }
@@ -1435,7 +1429,7 @@ static irqreturn_t rcar_canfd_channel_interrupt(int irq, void *dev_id) u32 ch; /* Common FIFO is a per channel resource */ - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { rcar_canfd_handle_channel_err(gpriv, ch); rcar_canfd_handle_channel_tx(gpriv, ch); }
@@ -2072,7 +2066,7 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv) rcar_canfd_configure_controller(gpriv); /* Configure per channel attributes */ - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { /* Configure Channel's Rx fifo */ rcar_canfd_configure_rx(gpriv, ch);
@@ -2145,14 +2139,18 @@ static int rcar_canfd_probe(struct platform_device *pdev) bool fdmode = true; /* CAN FD only mode - default */ char name[9] = "channelX"; u32 ch, fcan_freq; + u8 max_channels; int i; info = of_device_get_match_data(dev); + max_channels = of_get_child_count(dev->of_node); + if (max_channels > RCANFD_NUM_CHANNELS) + return -EINVAL; if (of_property_read_bool(dev->of_node, "renesas,no-can-fd")) fdmode = false; /* Classical CAN only mode */ - for (i = 0; i < info->max_channels; ++i) { + for (i = 0; i < max_channels; ++i) { name[7] = '0' + i; of_child = of_get_available_child_by_name(dev->of_node, name); if (of_child) {
@@ -2199,6 +2197,7 @@ static int rcar_canfd_probe(struct platform_device *pdev) gpriv->pdev = pdev; gpriv->channels_mask = channels_mask; gpriv->fdmode = fdmode; + gpriv->max_channels = max_channels; gpriv->info = info; if (of_property_read_bool(dev->of_node, "renesas,fd-only"))
@@ -2300,7 +2299,7 @@ static int rcar_canfd_probe(struct platform_device *pdev) if (err) goto fail_mode; - for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { err = rcar_canfd_channel_probe(gpriv, ch, fcan_freq, transceivers[ch]); if (err)
@@ -2314,7 +2313,7 @@ static int rcar_canfd_probe(struct platform_device *pdev) return 0; fail_channel: - for_each_set_bit(ch, &gpriv->channels_mask, info->max_channels) + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) rcar_canfd_channel_remove(gpriv, ch); fail_mode: rcar_canfd_global_deinit(gpriv, false);
@@ -2327,7 +2326,7 @@ static void rcar_canfd_remove(struct platform_device *pdev) struct rcar_canfd_global *gpriv = platform_get_drvdata(pdev); u32 ch; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { rcar_canfd_disable_channel_interrupts(gpriv->ch[ch]); rcar_canfd_channel_remove(gpriv, ch); }
@@ -2341,7 +2340,7 @@ static int rcar_canfd_suspend(struct device *dev) int err; u32 ch; - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { struct rcar_canfd_channel *priv = gpriv->ch[ch]; struct net_device *ndev = priv->ndev;
@@ -2378,7 +2377,7 @@ static int rcar_canfd_resume(struct device *dev) return err; } - for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { + for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels) { struct rcar_canfd_channel *priv = gpriv->ch[ch]; struct net_device *ndev = priv->ndev;
--
2.53.0