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.zh...@nxp.com>
---
 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 c21b3507123e..228d07e84ddc 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"
@@ -1889,7 +1890,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
@@ -1899,25 +1900,27 @@ static int __maybe_unused flexcan_suspend(struct device 
*device)
                        enable_irq_wake(dev->irq);
                        flexcan_enter_stop_mode(priv);
                } 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)) {
@@ -1926,15 +1929,19 @@ static int __maybe_unused flexcan_resume(struct device 
*device)
                if (device_may_wakeup(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

Reply via email to