linux-can-next-for-6.19-20251017

-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEn/sM2K9nqF/8FWzzDHRl3/mQkZwFAmjyWiQTHG1rbEBwZW5n
 dXRyb25peC5kZQAKCRAMdGXf+ZCRnDm6CACW1LjNTfKAFEytuGK/LnR38bIaZI6V
 nIHxzQSHlZs8tN9AWJR3ucF7so7FK07eiWBpVP5HXnEBkrC+8EUPsCXWGOkQBVcC
 s8BCdRLJfl+OnSFtSNk2LqTLpmN3o1rly7HrdJEyZyqKsoX0bLQmF/dGQIgn5JI+
 2v9ibQSuj0fOQCKR9vyPf3UflJmrsFqJqsHfsbq/2Ld28mGuaqX0+LxSbdFVosnh
 KxL1S8jK8j8vD+FN5eMWI0KkehztMIQHfNVLgcr+neyqjqiX1qIqNjm8enQanMI4
 pGzroH7OdYQ8/a0DBmYG4lmDRMQ46T/PurgA0H9TgGaxoesTV0NhkADb
 =Bu+P
 -----END PGP SIGNATURE-----

Merge tag 'linux-can-next-for-6.19-20251017' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2025-10-17

The first patch is by me and adds support for an optional reset to the
m_can drivers.

Vincent Mailhol's patch targets all drivers and removes the
can_change_mtu() function, since the netdev's min and max MTU are
populated.

Markus Schneider-Pargmann contributes 4 patches to the m_can driver to
add am62 wakeup support.

The last 7 patches are by me and provide various cleanups to the m_can
driver.

* tag 'linux-can-next-for-6.19-20251017' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
  can: m_can: m_can_get_berr_counter(): don't wake up controller if interface is down
  can: m_can: m_can_tx_submit(): remove unneeded sanity checks
  can: m_can: m_can_class_register(): remove error message in case devm_kzalloc() fails
  can: m_can: m_can_interrupt_enable(): use m_can_write() instead of open coding it
  net: m_can: convert dev_{dbg,info,err} -> netdev_{dbg,info,err}
  can: m_can: hrtimer_callback(): rename to m_can_polling_timer()
  can: m_can: m_can_init_ram(): make static
  can: m_can: Support pinctrl wakeup state
  can: m_can: Return ERR_PTR on error in allocation
  can: m_can: Map WoL to device_set_wakeup_enable
  dt-bindings: can: m_can: Add wakeup properties
  can: treewide: remove can_change_mtu()
  can: m_can: add support for optional reset
====================

Link: https://patch.msgid.link/20251017150819.1415685-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-10-20 18:36:17 -07:00
commit ebc742edc9
45 changed files with 222 additions and 152 deletions

View file

@ -109,6 +109,26 @@ properties:
maximum: 32
minItems: 1
pinctrl-0:
description: Default pinctrl state
pinctrl-1:
description: Can be "sleep" or "wakeup" pinctrl state
pinctrl-2:
description: Can be "sleep" or "wakeup" pinctrl state
pinctrl-names:
description:
When present should contain at least "default" describing the default pin
states. Other states are "sleep" which describes the pinstate when
sleeping and "wakeup" describing the pins if wakeup is enabled.
minItems: 1
items:
- const: default
- enum: [ sleep, wakeup ]
- const: wakeup
power-domains:
description:
Power domain provider node and an args specifier containing
@ -125,6 +145,11 @@ properties:
minItems: 1
maxItems: 2
wakeup-source:
$ref: /schemas/types.yaml#/definitions/phandle-array
description:
List of phandles to system idle states in which mcan can wakeup the system.
required:
- compatible
- reg

View file

@ -948,7 +948,6 @@ static const struct net_device_ops at91_netdev_ops = {
.ndo_open = at91_open,
.ndo_stop = at91_close,
.ndo_start_xmit = at91_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops at91_ethtool_ops = {

View file

@ -881,7 +881,6 @@ static const struct net_device_ops bxcan_netdev_ops = {
.ndo_open = bxcan_open,
.ndo_stop = bxcan_stop,
.ndo_start_xmit = bxcan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops bxcan_ethtool_ops = {

View file

@ -1362,7 +1362,6 @@ static const struct net_device_ops c_can_netdev_ops = {
.ndo_open = c_can_open,
.ndo_stop = c_can_close,
.ndo_start_xmit = c_can_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
int register_c_can_dev(struct net_device *dev)

View file

@ -849,7 +849,6 @@ static const struct net_device_ops can327_netdev_ops = {
.ndo_open = can327_netdev_open,
.ndo_stop = can327_netdev_close,
.ndo_start_xmit = can327_netdev_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops can327_ethtool_ops = {

View file

@ -834,7 +834,6 @@ static const struct net_device_ops cc770_netdev_ops = {
.ndo_open = cc770_open,
.ndo_stop = cc770_close,
.ndo_start_xmit = cc770_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops cc770_ethtool_ops = {

View file

@ -1301,7 +1301,6 @@ static const struct net_device_ops ctucan_netdev_ops = {
.ndo_open = ctucan_open,
.ndo_stop = ctucan_close,
.ndo_start_xmit = ctucan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ctucan_ethtool_ops = {

View file

@ -359,44 +359,6 @@ void can_set_default_mtu(struct net_device *dev)
}
}
/* changing MTU and control mode for CAN/CANFD devices */
int can_change_mtu(struct net_device *dev, int new_mtu)
{
struct can_priv *priv = netdev_priv(dev);
u32 ctrlmode_static = can_get_static_ctrlmode(priv);
/* Do not allow changing the MTU while running */
if (dev->flags & IFF_UP)
return -EBUSY;
/* allow change of MTU according to the CANFD ability of the device */
switch (new_mtu) {
case CAN_MTU:
/* 'CANFD-only' controllers can not switch to CAN_MTU */
if (ctrlmode_static & CAN_CTRLMODE_FD)
return -EINVAL;
priv->ctrlmode &= ~CAN_CTRLMODE_FD;
break;
case CANFD_MTU:
/* check for potential CANFD ability */
if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) &&
!(ctrlmode_static & CAN_CTRLMODE_FD))
return -EINVAL;
priv->ctrlmode |= CAN_CTRLMODE_FD;
break;
default:
return -EINVAL;
}
WRITE_ONCE(dev->mtu, new_mtu);
return 0;
}
EXPORT_SYMBOL_GPL(can_change_mtu);
/* helper to define static CAN controller features at device creation time */
int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
{

View file

@ -86,7 +86,6 @@ static const struct net_device_ops pci402_acc_netdev_ops = {
.ndo_open = acc_open,
.ndo_stop = acc_close,
.ndo_start_xmit = acc_start_xmit,
.ndo_change_mtu = can_change_mtu,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
};

View file

@ -1867,7 +1867,6 @@ static const struct net_device_ops flexcan_netdev_ops = {
.ndo_open = flexcan_open,
.ndo_stop = flexcan_close,
.ndo_start_xmit = flexcan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static int register_flexcandev(struct net_device *dev)

View file

@ -1561,7 +1561,6 @@ static const struct net_device_ops grcan_netdev_ops = {
.ndo_open = grcan_open,
.ndo_stop = grcan_close,
.ndo_start_xmit = grcan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops grcan_ethtool_ops = {

View file

@ -944,7 +944,6 @@ static const struct net_device_ops ifi_canfd_netdev_ops = {
.ndo_open = ifi_canfd_open,
.ndo_stop = ifi_canfd_close,
.ndo_start_xmit = ifi_canfd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ifi_canfd_ethtool_ops = {

View file

@ -1752,7 +1752,6 @@ static const struct net_device_ops ican3_netdev_ops = {
.ndo_open = ican3_open,
.ndo_stop = ican3_stop,
.ndo_start_xmit = ican3_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ican3_ethtool_ops = {

View file

@ -904,7 +904,6 @@ static const struct net_device_ops kvaser_pciefd_netdev_ops = {
.ndo_stop = kvaser_pciefd_stop,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
.ndo_start_xmit = kvaser_pciefd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static int kvaser_pciefd_set_phys_id(struct net_device *netdev,

View file

@ -23,6 +23,7 @@
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include "m_can.h"
@ -386,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;
}
@ -451,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;
}
@ -469,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);
@ -485,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);
}
}
@ -790,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;
@ -1379,6 +1384,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);
@ -1464,7 +1490,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;
}
@ -1694,7 +1720,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;
}
@ -1713,8 +1739,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;
}
@ -1772,8 +1798,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;
}
@ -1827,6 +1853,7 @@ static int m_can_close(struct net_device *dev)
close_candev(dev);
reset_control_assert(cdev->rst);
m_can_clk_stop(cdev);
phy_power_off(cdev->transceiver);
@ -1950,11 +1977,6 @@ out_fail:
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;
}
@ -2035,7 +2057,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);
@ -2069,11 +2091,15 @@ static int m_can_open(struct net_device *dev)
if (err)
goto out_phy_power_off;
err = reset_control_deassert(cdev->rst);
if (err)
goto exit_disable_clks;
/* open the can device */
err = open_candev(dev);
if (err) {
netdev_err(dev, "failed to open can device\n");
goto exit_disable_clks;
goto out_reset_control_assert;
}
if (cdev->is_peripheral)
@ -2129,6 +2155,8 @@ out_wq_fail:
else
napi_disable(&cdev->napi);
close_candev(dev);
out_reset_control_assert:
reset_control_assert(cdev->rst);
exit_disable_clks:
m_can_clk_stop(cdev);
out_phy_power_off:
@ -2140,7 +2168,6 @@ static const struct net_device_ops m_can_netdev_ops = {
.ndo_open = m_can_open,
.ndo_stop = m_can_close,
.ndo_start_xmit = m_can_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static int m_can_get_coalesce(struct net_device *dev,
@ -2231,6 +2258,55 @@ static int m_can_set_coalesce(struct net_device *dev,
return 0;
}
static void m_can_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct m_can_classdev *cdev = netdev_priv(dev);
wol->supported = device_can_wakeup(cdev->dev) ? WAKE_PHY : 0;
wol->wolopts = device_may_wakeup(cdev->dev) ? WAKE_PHY : 0;
}
static int m_can_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct m_can_classdev *cdev = netdev_priv(dev);
bool wol_enable = !!(wol->wolopts & WAKE_PHY);
int ret;
if (wol->wolopts & ~WAKE_PHY)
return -EINVAL;
if (wol_enable == device_may_wakeup(cdev->dev))
return 0;
ret = device_set_wakeup_enable(cdev->dev, wol_enable);
if (ret) {
netdev_err(cdev->net, "Failed to set wakeup enable %pE\n",
ERR_PTR(ret));
return ret;
}
if (!IS_ERR_OR_NULL(cdev->pinctrl_state_wakeup)) {
if (wol_enable)
ret = pinctrl_select_state(cdev->pinctrl, cdev->pinctrl_state_wakeup);
else
ret = pinctrl_pm_select_default_state(cdev->dev);
if (ret) {
netdev_err(cdev->net, "Failed to select pinctrl state %pE\n",
ERR_PTR(ret));
goto err_wakeup_enable;
}
}
return 0;
err_wakeup_enable:
/* Revert wakeup enable */
device_set_wakeup_enable(cdev->dev, !wol_enable);
return ret;
}
static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ |
ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ |
@ -2240,10 +2316,14 @@ static const struct ethtool_ops m_can_ethtool_ops_coalescing = {
.get_ts_info = ethtool_op_get_ts_info,
.get_coalesce = m_can_get_coalesce,
.set_coalesce = m_can_set_coalesce,
.get_wol = m_can_get_wol,
.set_wol = m_can_set_wol,
};
static const struct ethtool_ops m_can_ethtool_ops = {
.get_ts_info = ethtool_op_get_ts_info,
.get_wol = m_can_get_wol,
.set_wol = m_can_set_wol,
};
static int register_m_can_dev(struct m_can_classdev *cdev)
@ -2267,8 +2347,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;
}
@ -2303,39 +2383,17 @@ 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_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;
@ -2344,7 +2402,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;
}
@ -2352,6 +2410,42 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev)
}
EXPORT_SYMBOL_GPL(m_can_class_get_clocks);
static bool m_can_class_wakeup_pinctrl_enabled(struct m_can_classdev *class_dev)
{
return device_may_wakeup(class_dev->dev) && class_dev->pinctrl_state_wakeup;
}
static int m_can_class_parse_pinctrl(struct m_can_classdev *class_dev)
{
struct device *dev = class_dev->dev;
int ret;
class_dev->pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(class_dev->pinctrl)) {
ret = PTR_ERR(class_dev->pinctrl);
class_dev->pinctrl = NULL;
if (ret == -ENODEV)
return 0;
return dev_err_probe(dev, ret, "Failed to get pinctrl\n");
}
class_dev->pinctrl_state_wakeup =
pinctrl_lookup_state(class_dev->pinctrl, "wakeup");
if (IS_ERR(class_dev->pinctrl_state_wakeup)) {
ret = PTR_ERR(class_dev->pinctrl_state_wakeup);
class_dev->pinctrl_state_wakeup = NULL;
if (ret == -ENODEV)
return 0;
return dev_err_probe(dev, ret, "Failed to lookup pinctrl wakeup state\n");
}
return 0;
}
struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
int sizeof_priv)
{
@ -2367,9 +2461,12 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
sizeof(mram_config_vals) / 4);
if (ret) {
dev_err(dev, "Could not get Message RAM configuration.");
goto out;
return ERR_PTR(ret);
}
if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source"))
device_set_wakeup_capable(dev, true);
/* Get TX FIFO size
* Defines the total amount of echo buffers for loopback
*/
@ -2379,7 +2476,7 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
net_dev = alloc_candev(sizeof_priv, tx_fifo_size);
if (!net_dev) {
dev_err(dev, "Failed to allocate CAN device");
goto out;
return ERR_PTR(-ENOMEM);
}
class_dev = netdev_priv(net_dev);
@ -2389,8 +2486,16 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev,
m_can_of_parse_mram(class_dev, mram_config_vals);
spin_lock_init(&class_dev->tx_handling_spinlock);
out:
ret = m_can_class_parse_pinctrl(class_dev);
if (ret)
goto err_free_candev;
return class_dev;
err_free_candev:
free_candev(net_dev);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(m_can_class_allocate_dev);
@ -2411,26 +2516,33 @@ 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);
if (IS_ERR(cdev->rst))
return dev_err_probe(cdev->dev, PTR_ERR(cdev->rst),
"Failed to get reset line\n");
ret = m_can_clk_start(cdev);
if (ret)
return ret;
ret = reset_control_deassert(cdev->rst);
if (ret)
goto clk_disable;
if (cdev->is_peripheral) {
ret = can_rx_offload_add_manual(cdev->net, &cdev->offload,
NAPI_POLL_WEIGHT);
if (ret)
goto clk_disable;
goto out_reset_control_assert;
}
if (!cdev->net->irq) {
dev_dbg(cdev->dev, "Polling enabled, initialize hrtimer");
hrtimer_setup(&cdev->hrtimer, &hrtimer_callback, CLOCK_MONOTONIC,
netdev_dbg(cdev->net, "Polling enabled, initialize hrtimer");
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,
@ -2443,19 +2555,21 @@ 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
* Stop clocks. They will be reactivated once the M_CAN device is opened
* Assert reset and stop clocks.
* They will be reactivated once the M_CAN device is opened
*/
reset_control_assert(cdev->rst);
m_can_clk_stop(cdev);
return 0;
@ -2463,6 +2577,8 @@ int m_can_class_register(struct m_can_classdev *cdev)
rx_offload_del:
if (cdev->is_peripheral)
can_rx_offload_del(&cdev->offload);
out_reset_control_assert:
reset_control_assert(cdev->rst);
clk_disable:
m_can_clk_stop(cdev);
@ -2506,7 +2622,8 @@ int m_can_class_suspend(struct device *dev)
cdev->can.state = CAN_STATE_SLEEPING;
}
pinctrl_pm_select_sleep_state(dev);
if (!m_can_class_wakeup_pinctrl_enabled(cdev))
pinctrl_pm_select_sleep_state(dev);
return ret;
}
@ -2518,7 +2635,8 @@ int m_can_class_resume(struct device *dev)
struct net_device *ndev = cdev->net;
int ret = 0;
pinctrl_pm_select_default_state(dev);
if (!m_can_class_wakeup_pinctrl_enabled(cdev))
pinctrl_pm_select_default_state(dev);
if (netif_running(ndev)) {
ret = m_can_clk_start(cdev);

View file

@ -86,6 +86,7 @@ struct m_can_classdev {
struct device *dev;
struct clk *hclk;
struct clk *cclk;
struct reset_control *rst;
struct workqueue_struct *tx_wq;
struct phy *transceiver;
@ -128,6 +129,9 @@ struct m_can_classdev {
struct mram_cfg mcfg[MRAM_CFG_NUM];
struct hrtimer hrtimer;
struct pinctrl *pinctrl;
struct pinctrl_state *pinctrl_state_wakeup;
};
struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, int sizeof_priv);
@ -135,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);

View file

@ -111,8 +111,8 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
mcan_class = m_can_class_allocate_dev(&pci->dev,
sizeof(struct m_can_pci_priv));
if (!mcan_class)
return -ENOMEM;
if (IS_ERR(mcan_class))
return PTR_ERR(mcan_class);
priv = cdev_to_priv(mcan_class);

View file

@ -87,8 +87,8 @@ static int m_can_plat_probe(struct platform_device *pdev)
mcan_class = m_can_class_allocate_dev(&pdev->dev,
sizeof(struct m_can_plat_priv));
if (!mcan_class)
return -ENOMEM;
if (IS_ERR(mcan_class))
return PTR_ERR(mcan_class);
priv = cdev_to_priv(mcan_class);

View file

@ -416,8 +416,8 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
mcan_class = m_can_class_allocate_dev(&spi->dev,
sizeof(struct tcan4x5x_priv));
if (!mcan_class)
return -ENOMEM;
if (IS_ERR(mcan_class))
return PTR_ERR(mcan_class);
ret = m_can_check_mram_cfg(mcan_class, TCAN4X5X_MRAM_SIZE);
if (ret)

View file

@ -607,7 +607,6 @@ static const struct net_device_ops mscan_netdev_ops = {
.ndo_open = mscan_open,
.ndo_stop = mscan_close,
.ndo_start_xmit = mscan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops mscan_ethtool_ops = {

View file

@ -773,7 +773,6 @@ static const struct net_device_ops peak_canfd_netdev_ops = {
.ndo_stop = peak_canfd_close,
.ndo_eth_ioctl = peak_eth_ioctl,
.ndo_start_xmit = peak_canfd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static int peak_get_ts_info(struct net_device *dev,

View file

@ -635,7 +635,6 @@ static const struct net_device_ops rcar_can_netdev_ops = {
.ndo_open = rcar_can_open,
.ndo_stop = rcar_can_close,
.ndo_start_xmit = rcar_can_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops rcar_can_ethtool_ops = {

View file

@ -1818,7 +1818,6 @@ static const struct net_device_ops rcar_canfd_netdev_ops = {
.ndo_open = rcar_canfd_open,
.ndo_stop = rcar_canfd_close,
.ndo_start_xmit = rcar_canfd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops rcar_canfd_ethtool_ops = {

View file

@ -761,7 +761,6 @@ static const struct net_device_ops rkcanfd_netdev_ops = {
.ndo_open = rkcanfd_open,
.ndo_stop = rkcanfd_stop,
.ndo_start_xmit = rkcanfd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static int __maybe_unused rkcanfd_runtime_suspend(struct device *dev)

View file

@ -697,7 +697,6 @@ static const struct net_device_ops sja1000_netdev_ops = {
.ndo_open = sja1000_open,
.ndo_stop = sja1000_close,
.ndo_start_xmit = sja1000_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops sja1000_ethtool_ops = {

View file

@ -774,7 +774,6 @@ static const struct net_device_ops slcan_netdev_ops = {
.ndo_open = slcan_netdev_open,
.ndo_stop = slcan_netdev_close,
.ndo_start_xmit = slcan_netdev_xmit,
.ndo_change_mtu = can_change_mtu,
};
/******************************************

View file

@ -609,7 +609,6 @@ static const struct net_device_ops softing_netdev_ops = {
.ndo_open = softing_netdev_open,
.ndo_stop = softing_netdev_stop,
.ndo_start_xmit = softing_netdev_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops softing_ethtool_ops = {

View file

@ -799,7 +799,6 @@ static const struct net_device_ops hi3110_netdev_ops = {
.ndo_open = hi3110_open,
.ndo_stop = hi3110_stop,
.ndo_start_xmit = hi3110_hard_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops hi3110_ethtool_ops = {

View file

@ -1270,7 +1270,6 @@ static const struct net_device_ops mcp251x_netdev_ops = {
.ndo_open = mcp251x_open,
.ndo_stop = mcp251x_stop,
.ndo_start_xmit = mcp251x_hard_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops mcp251x_ethtool_ops = {

View file

@ -1715,7 +1715,6 @@ static const struct net_device_ops mcp251xfd_netdev_ops = {
.ndo_stop = mcp251xfd_stop,
.ndo_start_xmit = mcp251xfd_start_xmit,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
.ndo_change_mtu = can_change_mtu,
};
static void

View file

@ -768,7 +768,6 @@ static const struct net_device_ops sun4ican_netdev_ops = {
.ndo_open = sun4ican_open,
.ndo_stop = sun4ican_close,
.ndo_start_xmit = sun4ican_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops sun4ican_ethtool_ops = {

View file

@ -829,7 +829,6 @@ static const struct net_device_ops ti_hecc_netdev_ops = {
.ndo_open = ti_hecc_open,
.ndo_stop = ti_hecc_close,
.ndo_start_xmit = ti_hecc_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ti_hecc_ethtool_ops = {

View file

@ -885,7 +885,6 @@ static const struct net_device_ops ems_usb_netdev_ops = {
.ndo_open = ems_usb_open,
.ndo_stop = ems_usb_close,
.ndo_start_xmit = ems_usb_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ems_usb_ethtool_ops = {

View file

@ -1011,7 +1011,6 @@ static const struct net_device_ops esd_usb_netdev_ops = {
.ndo_open = esd_usb_open,
.ndo_stop = esd_usb_close,
.ndo_start_xmit = esd_usb_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops esd_usb_ethtool_ops = {

View file

@ -1977,7 +1977,6 @@ static const struct net_device_ops es58x_netdev_ops = {
.ndo_stop = es58x_stop,
.ndo_start_xmit = es58x_start_xmit,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops es58x_ethtool_ops = {

View file

@ -1052,7 +1052,6 @@ static const struct net_device_ops f81604_netdev_ops = {
.ndo_open = f81604_open,
.ndo_stop = f81604_close,
.ndo_start_xmit = f81604_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct can_bittiming_const f81604_bittiming_const = {

View file

@ -1101,7 +1101,6 @@ static const struct net_device_ops gs_usb_netdev_ops = {
.ndo_open = gs_can_open,
.ndo_stop = gs_can_close,
.ndo_start_xmit = gs_can_start_xmit,
.ndo_change_mtu = can_change_mtu,
.ndo_eth_ioctl = gs_can_eth_ioctl,
};

View file

@ -786,7 +786,6 @@ static const struct net_device_ops kvaser_usb_netdev_ops = {
.ndo_stop = kvaser_usb_close,
.ndo_eth_ioctl = can_eth_ioctl_hwts,
.ndo_start_xmit = kvaser_usb_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops kvaser_usb_ethtool_ops = {

View file

@ -761,7 +761,6 @@ static const struct net_device_ops mcba_netdev_ops = {
.ndo_open = mcba_usb_open,
.ndo_stop = mcba_usb_close,
.ndo_start_xmit = mcba_usb_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops mcba_ethtool_ops = {

View file

@ -690,7 +690,6 @@ static const struct net_device_ops nct6694_canfd_netdev_ops = {
.ndo_open = nct6694_canfd_open,
.ndo_stop = nct6694_canfd_close,
.ndo_start_xmit = nct6694_canfd_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops nct6694_canfd_ethtool_ops = {

View file

@ -814,7 +814,6 @@ static const struct net_device_ops peak_usb_netdev_ops = {
.ndo_stop = peak_usb_ndo_stop,
.ndo_eth_ioctl = peak_eth_ioctl,
.ndo_start_xmit = peak_usb_ndo_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
/* CAN-USB devices generally handle 32-bit CAN channel IDs.

View file

@ -1233,7 +1233,6 @@ static const struct net_device_ops ucan_netdev_ops = {
.ndo_open = ucan_open,
.ndo_stop = ucan_close,
.ndo_start_xmit = ucan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops ucan_ethtool_ops = {

View file

@ -868,7 +868,6 @@ static const struct net_device_ops usb_8dev_netdev_ops = {
.ndo_open = usb_8dev_open,
.ndo_stop = usb_8dev_close,
.ndo_start_xmit = usb_8dev_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops usb_8dev_ethtool_ops = {

View file

@ -1702,7 +1702,6 @@ static const struct net_device_ops xcan_netdev_ops = {
.ndo_open = xcan_open,
.ndo_stop = xcan_close,
.ndo_start_xmit = xcan_start_xmit,
.ndo_change_mtu = can_change_mtu,
};
static const struct ethtool_ops xcan_ethtool_ops = {

View file

@ -127,7 +127,6 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
int open_candev(struct net_device *dev);
void close_candev(struct net_device *dev);
void can_set_default_mtu(struct net_device *dev);
int can_change_mtu(struct net_device *dev, int new_mtu);
int __must_check can_set_static_ctrlmode(struct net_device *dev,
u32 static_mode);
int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd);