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: V1->V2: *no change. V2->V3: *add error handling for pinctrl_pm_xx_xx_state() function. --- drivers/net/can/flexcan.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index c5e4b6928dee..3570ebe3b8f2 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" @@ -1700,7 +1701,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 @@ -1712,25 +1713,31 @@ static int __maybe_unused flexcan_suspend(struct device *device) if (err) return err; } else { - err = flexcan_chip_disable(priv); + err = flexcan_chip_stop(dev); if (err) return err; err = pm_runtime_force_suspend(device); + if (err) + return err; + + err = pinctrl_pm_select_sleep_state(device); + if (err) + return err; } 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)) { @@ -1742,15 +1749,21 @@ static int __maybe_unused flexcan_resume(struct device *device) if (err) return err; } else { + err = pinctrl_pm_select_default_state(device); + if (err) + return err; + 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