From c6dcc2b321cccf1fc2a18480bb547956fdb2b2e0 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 8 Aug 2025 15:29:34 +0200 Subject: [PATCH 1/7] can: m_can: m_can_init_ram(): make static Since commit eaacfeaca7ad ("can: m_can: Call the RAM init directly from m_can_chip_config") m_can_init_ram() is not used outside of m_can.c. Mark as static and remove the EXPORT_SYMBOL_GPL(). Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-1-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 43 +++++++++++++++++------------------ drivers/net/can/m_can/m_can.h | 1 - 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 8569596ae830..9f4002f3481e 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1380,6 +1380,27 @@ static const struct can_bittiming_const m_can_data_bittiming_const_31X = { .brp_inc = 1, }; +static int m_can_init_ram(struct m_can_classdev *cdev) +{ + int end, i, start; + int err = 0; + + /* initialize the entire Message RAM in use to avoid possible + * ECC/parity checksum errors when reading an uninitialized buffer + */ + start = cdev->mcfg[MRAM_SIDF].off; + end = cdev->mcfg[MRAM_TXB].off + + cdev->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; + + for (i = start; i < end; i += 4) { + err = m_can_fifo_write_no_off(cdev, i, 0x0); + if (err) + break; + } + + return err; +} + static int m_can_set_bittiming(struct net_device *dev) { struct m_can_classdev *cdev = netdev_priv(dev); @@ -2374,28 +2395,6 @@ static void m_can_of_parse_mram(struct m_can_classdev *cdev, cdev->mcfg[MRAM_TXB].off, cdev->mcfg[MRAM_TXB].num); } -int m_can_init_ram(struct m_can_classdev *cdev) -{ - int end, i, start; - int err = 0; - - /* initialize the entire Message RAM in use to avoid possible - * ECC/parity checksum errors when reading an uninitialized buffer - */ - start = cdev->mcfg[MRAM_SIDF].off; - end = cdev->mcfg[MRAM_TXB].off + - cdev->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; - - for (i = start; i < end; i += 4) { - err = m_can_fifo_write_no_off(cdev, i, 0x0); - if (err) - break; - } - - return err; -} -EXPORT_SYMBOL_GPL(m_can_init_ram); - int m_can_class_get_clocks(struct m_can_classdev *cdev) { int ret = 0; diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index f2f89687bbd2..4743342b2fba 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -139,7 +139,6 @@ void m_can_class_free_dev(struct net_device *net); int m_can_class_register(struct m_can_classdev *cdev); void m_can_class_unregister(struct m_can_classdev *cdev); int m_can_class_get_clocks(struct m_can_classdev *cdev); -int m_can_init_ram(struct m_can_classdev *priv); int m_can_check_mram_cfg(struct m_can_classdev *cdev, u32 mram_max_size); int m_can_class_suspend(struct device *dev); From 60af9dbb63fb077cc71496cf5ada82261be0bb25 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 7 Aug 2025 20:14:55 +0200 Subject: [PATCH 2/7] can: m_can: hrtimer_callback(): rename to m_can_polling_timer() The original use of struct m_can_classdev::hrtimer was to support polling for devices without IRQ, with the timer function called hrtimer_callback(). Commit 07f25091ca02 ("can: m_can: Implement receive coalescing") uses the hrtimer for software-supported IRQ coalescence, with the timer function called m_can_coalescing_timer(). To improve the readability of the driver, rename hrtimer_callback() to m_can_polling_timer(), which better describes the functionality. Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-2-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 9f4002f3481e..110cfd54b669 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -2058,7 +2058,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, return ret; } -static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer) +static enum hrtimer_restart m_can_polling_timer(struct hrtimer *timer) { struct m_can_classdev *cdev = container_of(timer, struct m_can_classdev, hrtimer); @@ -2545,7 +2545,7 @@ int m_can_class_register(struct m_can_classdev *cdev) if (!cdev->net->irq) { dev_dbg(cdev->dev, "Polling enabled, initialize hrtimer"); - hrtimer_setup(&cdev->hrtimer, &hrtimer_callback, CLOCK_MONOTONIC, + hrtimer_setup(&cdev->hrtimer, m_can_polling_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); } else { hrtimer_setup(&cdev->hrtimer, m_can_coalescing_timer, CLOCK_MONOTONIC, From 293735053eaa7a15e0debacdcbe3cdcd006436be Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Fri, 8 Aug 2025 14:14:55 +0200 Subject: [PATCH 3/7] net: m_can: convert dev_{dbg,info,err} -> netdev_{dbg,info,err} To ease debugging use the netdev_{dbg,info,err}() functions instead of dev_{dbg,info,err}. Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-3-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 54 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 110cfd54b669..6aef5e771fc3 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -387,8 +387,8 @@ static int m_can_cccr_update_bits(struct m_can_classdev *cdev, u32 mask, u32 val size_t tries = 10; if (!(mask & CCCR_INIT) && !(val_before & CCCR_INIT)) { - dev_err(cdev->dev, - "refusing to configure device when in normal mode\n"); + netdev_err(cdev->net, + "refusing to configure device when in normal mode\n"); return -EBUSY; } @@ -470,7 +470,7 @@ static void m_can_coalescing_disable(struct m_can_classdev *cdev) static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev) { if (!cdev->net->irq) { - dev_dbg(cdev->dev, "Start hrtimer\n"); + netdev_dbg(cdev->net, "Start hrtimer\n"); hrtimer_start(&cdev->hrtimer, ms_to_ktime(HRTIMER_POLL_INTERVAL_MS), HRTIMER_MODE_REL_PINNED); @@ -486,7 +486,7 @@ static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev) m_can_write(cdev, M_CAN_ILE, 0x0); if (!cdev->net->irq) { - dev_dbg(cdev->dev, "Stop hrtimer\n"); + netdev_dbg(cdev->net, "Stop hrtimer\n"); hrtimer_try_to_cancel(&cdev->hrtimer); } } @@ -1486,7 +1486,7 @@ static int m_can_chip_config(struct net_device *dev) err = m_can_init_ram(cdev); if (err) { - dev_err(cdev->dev, "Message RAM configuration failed\n"); + netdev_err(dev, "Message RAM configuration failed\n"); return err; } @@ -1716,7 +1716,7 @@ static int m_can_niso_supported(struct m_can_classdev *cdev) /* Then clear the it again. */ ret = m_can_cccr_update_bits(cdev, CCCR_NISO, 0); if (ret) { - dev_err(cdev->dev, "failed to revert the NON-ISO bit in CCCR\n"); + netdev_err(cdev->net, "failed to revert the NON-ISO bit in CCCR\n"); return ret; } @@ -1735,8 +1735,8 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) m_can_version = m_can_check_core_release(cdev); /* return if unsupported version */ if (!m_can_version) { - dev_err(cdev->dev, "Unsupported version number: %2d", - m_can_version); + netdev_err(cdev->net, "Unsupported version number: %2d", + m_can_version); return -EINVAL; } @@ -1794,8 +1794,8 @@ static int m_can_dev_setup(struct m_can_classdev *cdev) cdev->can.ctrlmode_supported |= CAN_CTRLMODE_FD_NON_ISO; break; default: - dev_err(cdev->dev, "Unsupported version number: %2d", - cdev->version); + netdev_err(cdev->net, "Unsupported version number: %2d", + cdev->version); return -EINVAL; } @@ -2348,8 +2348,8 @@ int m_can_check_mram_cfg(struct m_can_classdev *cdev, u32 mram_max_size) total_size = cdev->mcfg[MRAM_TXB].off - cdev->mcfg[MRAM_SIDF].off + cdev->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE; if (total_size > mram_max_size) { - dev_err(cdev->dev, "Total size of mram config(%u) exceeds mram(%u)\n", - total_size, mram_max_size); + netdev_err(cdev->net, "Total size of mram config(%u) exceeds mram(%u)\n", + total_size, mram_max_size); return -EINVAL; } @@ -2384,15 +2384,15 @@ static void m_can_of_parse_mram(struct m_can_classdev *cdev, cdev->mcfg[MRAM_TXB].num = mram_config_vals[7] & FIELD_MAX(TXBC_NDTB_MASK); - dev_dbg(cdev->dev, - "sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", - cdev->mcfg[MRAM_SIDF].off, cdev->mcfg[MRAM_SIDF].num, - cdev->mcfg[MRAM_XIDF].off, cdev->mcfg[MRAM_XIDF].num, - cdev->mcfg[MRAM_RXF0].off, cdev->mcfg[MRAM_RXF0].num, - cdev->mcfg[MRAM_RXF1].off, cdev->mcfg[MRAM_RXF1].num, - cdev->mcfg[MRAM_RXB].off, cdev->mcfg[MRAM_RXB].num, - cdev->mcfg[MRAM_TXE].off, cdev->mcfg[MRAM_TXE].num, - cdev->mcfg[MRAM_TXB].off, cdev->mcfg[MRAM_TXB].num); + netdev_dbg(cdev->net, + "sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", + cdev->mcfg[MRAM_SIDF].off, cdev->mcfg[MRAM_SIDF].num, + cdev->mcfg[MRAM_XIDF].off, cdev->mcfg[MRAM_XIDF].num, + cdev->mcfg[MRAM_RXF0].off, cdev->mcfg[MRAM_RXF0].num, + cdev->mcfg[MRAM_RXF1].off, cdev->mcfg[MRAM_RXF1].num, + cdev->mcfg[MRAM_RXB].off, cdev->mcfg[MRAM_RXB].num, + cdev->mcfg[MRAM_TXE].off, cdev->mcfg[MRAM_TXE].num, + cdev->mcfg[MRAM_TXB].off, cdev->mcfg[MRAM_TXB].num); } int m_can_class_get_clocks(struct m_can_classdev *cdev) @@ -2403,7 +2403,7 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev) cdev->cclk = devm_clk_get(cdev->dev, "cclk"); if (IS_ERR(cdev->hclk) || IS_ERR(cdev->cclk)) { - dev_err(cdev->dev, "no clock found\n"); + netdev_err(cdev->net, "no clock found\n"); ret = -ENODEV; } @@ -2544,7 +2544,7 @@ int m_can_class_register(struct m_can_classdev *cdev) } if (!cdev->net->irq) { - dev_dbg(cdev->dev, "Polling enabled, initialize hrtimer"); + netdev_dbg(cdev->net, "Polling enabled, initialize hrtimer"); hrtimer_setup(&cdev->hrtimer, m_can_polling_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_PINNED); } else { @@ -2558,15 +2558,15 @@ int m_can_class_register(struct m_can_classdev *cdev) ret = register_m_can_dev(cdev); if (ret) { - dev_err(cdev->dev, "registering %s failed (err=%d)\n", - cdev->net->name, ret); + netdev_err(cdev->net, "registering %s failed (err=%d)\n", + cdev->net->name, ret); goto rx_offload_del; } of_can_transceiver(cdev->net); - dev_info(cdev->dev, "%s device registered (irq=%d, version=%d)\n", - KBUILD_MODNAME, cdev->net->irq, cdev->version); + netdev_info(cdev->net, "device registered (irq=%d, version=%d)\n", + cdev->net->irq, cdev->version); /* Probe finished * Assert reset and stop clocks. From c6cbd24f65f1bbdae15cf8450a8298255c231e2e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 7 Aug 2025 16:27:45 +0200 Subject: [PATCH 4/7] can: m_can: m_can_interrupt_enable(): use m_can_write() instead of open coding it As everywhere else in the driver, use m_can_write() instead of open coding it. Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-4-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 6aef5e771fc3..98e7ab612bba 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -452,7 +452,7 @@ static void m_can_interrupt_enable(struct m_can_classdev *cdev, u32 interrupts) { if (cdev->active_interrupts == interrupts) return; - cdev->ops->write_reg(cdev, M_CAN_IE, interrupts); + m_can_write(cdev, M_CAN_IE, interrupts); cdev->active_interrupts = interrupts; } From 6218391758b53e6cadf2aa80093457eeb485f06e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 7 Aug 2025 17:19:31 +0200 Subject: [PATCH 5/7] can: m_can: m_can_class_register(): remove error message in case devm_kzalloc() fails If devm_kzalloc() fails, it already outputs an error message. Remove the error message from m_can_class_register() accordingly. Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-5-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 98e7ab612bba..8013e8835027 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -2517,10 +2517,8 @@ int m_can_class_register(struct m_can_classdev *cdev) devm_kzalloc(cdev->dev, cdev->tx_fifo_size * sizeof(*cdev->tx_ops), GFP_KERNEL); - if (!cdev->tx_ops) { - dev_err(cdev->dev, "Failed to allocate tx_ops for workqueue\n"); + if (!cdev->tx_ops) return -ENOMEM; - } } cdev->rst = devm_reset_control_get_optional_shared(cdev->dev, NULL); From b24b43522eb33c32ca2348354e2555685c8c4644 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 7 Aug 2025 17:20:08 +0200 Subject: [PATCH 6/7] can: m_can: m_can_tx_submit(): remove unneeded sanity checks m_can_tx_submit() is only called for peripheral devices. So remove the sanity check. Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-6-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 8013e8835027..713d3df296df 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1973,11 +1973,6 @@ static netdev_tx_t m_can_tx_handler(struct m_can_classdev *cdev, static void m_can_tx_submit(struct m_can_classdev *cdev) { - if (cdev->version == 30) - return; - if (!cdev->is_peripheral) - return; - m_can_write(cdev, M_CAN_TXBAR, cdev->tx_peripheral_submit); cdev->tx_peripheral_submit = 0; } From 91a55c72a821d106a588af4c28aec129dcbea5af Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 6 Aug 2025 12:20:44 +0200 Subject: [PATCH 7/7] can: m_can: m_can_get_berr_counter(): don't wake up controller if interface is down If the interface is down, the CAN controller might be powered down, the clock disabled, and/or it's external reset asserted. Don't wake up the controller to read the CAN bus error counters, if the interface is down. Reviewed-by: Markus Schneider-Pargmann Link: https://patch.msgid.link/20251008-m_can-cleanups-v1-7-1784a18eaa84@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 713d3df296df..eb856547ae7d 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -791,6 +791,10 @@ static int m_can_get_berr_counter(const struct net_device *dev, struct m_can_classdev *cdev = netdev_priv(dev); int err; + /* Avoid waking up the controller if the interface is down */ + if (!(dev->flags & IFF_UP)) + return 0; + err = m_can_clk_start(cdev); if (err) return err;