mfd: fusb302: avoid sending notifier to USB/DP during PM suspend
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / fusb302.c
index 6f07904718e48721ef4e3ef9d19b0ddd70b5c9d4..3201a17fa53d7d92525315b59005f4a22cc013f9 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/delay.h>
 #include <linux/extcon.h>
+#include <linux/freezer.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
@@ -248,6 +249,32 @@ static void platform_fusb_notify(struct fusb30x_chip *chip)
                        usb_ss = 1;
                }
 
+               if (chip->notify.power_role == 0 &&
+                   chip->notify.is_pd_connected &&
+                   chip->pd_output_vol > 0 && chip->pd_output_cur > 0) {
+                       extcon_set_state(chip->extcon, EXTCON_CHG_USB_FAST,
+                                        true);
+                       property.intval =
+                               (chip->pd_output_cur << 15 |
+                                chip->pd_output_vol);
+                       extcon_set_property(chip->extcon, EXTCON_CHG_USB_FAST,
+                                           EXTCON_PROP_USB_TYPEC_POLARITY,
+                                           property);
+                       extcon_sync(chip->extcon, EXTCON_CHG_USB_FAST);
+               }
+
+#ifdef CONFIG_FREEZER
+               /*
+                * If system enter PM suspend, we need to wait until
+                * PM resume all of devices completion, then the flag
+                * pm_freezing will be set to false, and we can send
+                * notifier to USB/DP module safety, it make sure that
+                * USB/DP can enable power domain successfully.
+                */
+               while (pm_freezing)
+                       usleep_range(10000, 11000);
+#endif
+
                property.intval = flip;
                extcon_set_property(chip->extcon, EXTCON_USB,
                                    EXTCON_PROP_USB_TYPEC_POLARITY, property);
@@ -269,18 +296,6 @@ static void platform_fusb_notify(struct fusb30x_chip *chip)
                extcon_sync(chip->extcon, EXTCON_USB);
                extcon_sync(chip->extcon, EXTCON_USB_HOST);
                extcon_sync(chip->extcon, EXTCON_DISP_DP);
-               if (chip->notify.power_role == 0 &&
-                   chip->notify.is_pd_connected &&
-                   chip->pd_output_vol > 0 && chip->pd_output_cur > 0) {
-                       extcon_set_state(chip->extcon, EXTCON_CHG_USB_FAST, true);
-                       property.intval =
-                               (chip->pd_output_cur << 15 |
-                                chip->pd_output_vol);
-                       extcon_set_property(chip->extcon, EXTCON_CHG_USB_FAST,
-                                           EXTCON_PROP_USB_TYPEC_POLARITY,
-                                           property);
-                       extcon_sync(chip->extcon, EXTCON_CHG_USB_FAST);
-               }
        }
 }