diff options
| author | Marc Kleine-Budde <mkl@pengutronix.de> | 2025-08-12 16:58:31 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-23 16:20:28 +0200 |
| commit | 7ed47a3207f59e3d9aec34323eea57020a9ef1c8 (patch) | |
| tree | 603bfc7b0dcb6fb9c3ed61d38e8defa89719be9a /drivers/net/can | |
| parent | b7f989b93836fbc4fe602e10dceaea6d60deaade (diff) | |
| download | linux-7ed47a3207f59e3d9aec34323eea57020a9ef1c8.tar.gz linux-7ed47a3207f59e3d9aec34323eea57020a9ef1c8.tar.bz2 linux-7ed47a3207f59e3d9aec34323eea57020a9ef1c8.zip | |
can: m_can: fix CAN state in system PM
[ Upstream commit a9e30a22d6f23a2684c248871cad4c3061181639 ]
A suspend/resume cycle on a down interface results in the interface
coming up in Error Active state. A suspend/resume cycle on an Up
interface will always result in Error Active state, regardless of the
actual CAN state.
During suspend, only set running interfaces to CAN_STATE_SLEEPING.
During resume only touch the CAN state of running interfaces. For
wakeup sources, set the CAN state depending on the Protocol Status
Regitser (PSR), for non wakeup source interfaces m_can_start() will do
the same.
Fixes: e0d1f4816f2a ("can: m_can: add Bosch M_CAN controller support")
Reviewed-by: Markus Schneider-Pargmann <msp@baylibre.com>
Link: https://patch.msgid.link/20250929-m_can-fix-state-handling-v4-4-682b49b49d9a@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net/can')
| -rw-r--r-- | drivers/net/can/m_can/m_can.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index bf7996c30242..f31a91ec7a6d 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -2506,12 +2506,11 @@ int m_can_class_suspend(struct device *dev) } m_can_clk_stop(cdev); + cdev->can.state = CAN_STATE_SLEEPING; } pinctrl_pm_select_sleep_state(dev); - cdev->can.state = CAN_STATE_SLEEPING; - return ret; } EXPORT_SYMBOL_GPL(m_can_class_suspend); @@ -2524,8 +2523,6 @@ int m_can_class_resume(struct device *dev) pinctrl_pm_select_default_state(dev); - cdev->can.state = CAN_STATE_ERROR_ACTIVE; - if (netif_running(ndev)) { ret = m_can_clk_start(cdev); if (ret) @@ -2543,6 +2540,8 @@ int m_can_class_resume(struct device *dev) if (cdev->ops->init) ret = cdev->ops->init(cdev); + cdev->can.state = m_can_state_get_by_psr(cdev); + m_can_write(cdev, M_CAN_IE, cdev->active_interrupts); } else { ret = m_can_start(ndev); |
