For i.MX7D LPSR mode, the controller will lost power and got the configuration state lost after system resume back. (coming i.MX8QM/QXP will also completely power off the domain, the controller state will be lost and needs restore). So we need to set pinctrl state again and re-start chip to do re-configuration after resume. For wakeup case, it should not set pinctrl to sleep state by pinctrl_pm_select_sleep_state. For interface is not up before suspend case, we don't need re-configure as it will be configured by user later by interface up. Signed-off-by: Joakim Zhang <qiangqing.zhang@xxxxxxx> ChangeLog: V2->V3: * rebase on linux-can/testing. * change into patch set. V3->V4: * rebase on linux-can/testing. --- drivers/net/can/flexcan.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 24cc386c4bce..e2bc5078615f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -26,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> +#include <linux/pinctrl/consumer.h> #include <linux/regmap.h> #define DRV_NAME "flexcan" @@ -1660,7 +1661,7 @@ static int __maybe_unused flexcan_suspend(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); - int err = 0; + int err; if (netif_running(dev)) { /* if wakeup is enabled, enter stop mode @@ -1674,25 +1675,27 @@ static int __maybe_unused flexcan_suspend(struct device *device) priv->in_stop_mode = true; } else { - err = flexcan_chip_disable(priv); + flexcan_chip_stop(dev); + + err = pm_runtime_force_suspend(device); if (err) return err; - err = pm_runtime_force_suspend(device); + pinctrl_pm_select_sleep_state(device); } netif_stop_queue(dev); netif_device_detach(dev); } priv->can.state = CAN_STATE_SLEEPING; - return err; + return 0; } static int __maybe_unused flexcan_resume(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); - int err = 0; + int err; priv->can.state = CAN_STATE_ERROR_ACTIVE; if (netif_running(dev)) { @@ -1710,15 +1713,19 @@ static int __maybe_unused flexcan_resume(struct device *device) disable_irq_wake(dev->irq); } else { + pinctrl_pm_select_default_state(device); + err = pm_runtime_force_resume(device); if (err) return err; - err = flexcan_chip_enable(priv); + err = flexcan_chip_start(dev); + if (err) + return err; } } - return err; + return 0; } static int __maybe_unused flexcan_runtime_suspend(struct device *device) -- 2.17.1