Message ID | 20240729074135.3850634-3-msp@baylibre.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | can: m_can: Add am62 wakeup support | expand |
On Mon, Jul 29, 2024 at 09:41:30AM +0200, Markus Schneider-Pargmann wrote: > In some devices the pins of the m_can module can act as a wakeup source. > This patch helps do that by connecting the PHY_WAKE WoL option to > device_set_wakeup_enable. By marking this device as being wakeup > enabled, this setting can be used by platform code to decide which > sleep or poweroff mode to use. > > Also this prepares the driver for the next patch in which the pinctrl > settings are changed depending on the desired wakeup source. > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > --- > drivers/net/can/m_can/m_can.c | 37 +++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > index 81e05746d7d4..2e4ccf05e162 100644 > --- a/drivers/net/can/m_can/m_can.c > +++ b/drivers/net/can/m_can/m_can.c > @@ -2182,6 +2182,36 @@ 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; > +} It is nice to see Ethernet WoL mapped to CAN :-) So will any activity on the CAN BUS wake the device? Or does it need to be addresses to this device? Andrew
On 29.07.2024 21:27:04, Andrew Lunn wrote: > On Mon, Jul 29, 2024 at 09:41:30AM +0200, Markus Schneider-Pargmann wrote: > > In some devices the pins of the m_can module can act as a wakeup source. > > This patch helps do that by connecting the PHY_WAKE WoL option to > > device_set_wakeup_enable. By marking this device as being wakeup > > enabled, this setting can be used by platform code to decide which > > sleep or poweroff mode to use. > > > > Also this prepares the driver for the next patch in which the pinctrl > > settings are changed depending on the desired wakeup source. > > > > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> > > --- > > drivers/net/can/m_can/m_can.c | 37 +++++++++++++++++++++++++++++++++++ > > 1 file changed, 37 insertions(+) > > > > diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c > > index 81e05746d7d4..2e4ccf05e162 100644 > > --- a/drivers/net/can/m_can/m_can.c > > +++ b/drivers/net/can/m_can/m_can.c > > @@ -2182,6 +2182,36 @@ 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; > > +} > > It is nice to see Ethernet WoL mapped to CAN :-) > > So will any activity on the CAN BUS wake the device? Or does it need > to be addresses to this device? Unless you have a special filtering transceiver, which is the CAN equivalent of a PHY, CAN interfaces usually wake up on the first message on the bus. That message is usually lost. Note: The details of the m_can IP core might be different. regards, Marc
> > > +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; > > > +} > > > > It is nice to see Ethernet WoL mapped to CAN :-) > > > > So will any activity on the CAN BUS wake the device? Or does it need > > to be addresses to this device? > > Unless you have a special filtering transceiver, which is the CAN > equivalent of a PHY, CAN interfaces usually wake up on the first > message on the bus. That message is usually lost. Thanks for the info. WAKE_PHY does seem the most appropriate then. Reviewed-by: Andrew Lunn <andrew@lunn.ch> Andrew
Hi, On Mon, Jul 29, 2024 at 09:37:56PM GMT, Andrew Lunn wrote: > > > > +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; > > > > +} > > > > > > It is nice to see Ethernet WoL mapped to CAN :-) > > > > > > So will any activity on the CAN BUS wake the device? Or does it need > > > to be addresses to this device? > > > > Unless you have a special filtering transceiver, which is the CAN > > equivalent of a PHY, CAN interfaces usually wake up on the first > > message on the bus. That message is usually lost. > > Thanks for the info. WAKE_PHY does seem the most appropriate then. > > Reviewed-by: Andrew Lunn <andrew@lunn.ch> Thank you. Just to extend on Marc's explanation specifically for m_can: For this very low power mode 'Partial-IO' the m_can IP is not active. The m_can pins will trigger a wakeup for any activity. Also as the SoC needs to do a normal boot, I would guess there are more messages lost when waking up from Partial-IO. Other low power modes that will be upstreamed in the future will not need as much time to be able to receive CAN messages again. Best Markus
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 81e05746d7d4..2e4ccf05e162 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -2182,6 +2182,36 @@ 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) != wol->wolopts) + 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; + } + + return 0; +} + static const struct ethtool_ops m_can_ethtool_ops_coalescing = { .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS_IRQ | ETHTOOL_COALESCE_RX_MAX_FRAMES_IRQ | @@ -2191,10 +2221,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) @@ -2321,6 +2355,9 @@ struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, goto out; } + 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 */
In some devices the pins of the m_can module can act as a wakeup source. This patch helps do that by connecting the PHY_WAKE WoL option to device_set_wakeup_enable. By marking this device as being wakeup enabled, this setting can be used by platform code to decide which sleep or poweroff mode to use. Also this prepares the driver for the next patch in which the pinctrl settings are changed depending on the desired wakeup source. Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> --- drivers/net/can/m_can/m_can.c | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)