From: William Wu Date: Wed, 4 Jan 2017 08:05:21 +0000 (+0800) Subject: mfd: fusb302: avoid sending notifier to USB/DP during PM suspend X-Git-Tag: firefly_0821_release~801 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=082f43af91698a82583053679ec0d0be89b36b2d;p=firefly-linux-kernel-4.4.55.git mfd: fusb302: avoid sending notifier to USB/DP during PM suspend When system enter PM suspend, it will use a flag genpd->suspend_ power_off to disable device power domain operations, and device can't enable its power domain until complete PM resume, or rather, until call pm_genpd_complete() to clear suspend_power_off flag. In some case, e.g. plug in Type-C PD adapter during system suspend, and then wakeup system, the fusb302 may send notifier to USB/DP before USB/DP complete PM resume, this may cause USB/DP fail to enable their power domain. I don't find a way to make sure USB/DP PM resume, fortunately, the PM framework provides a flag pm_freezing to indicate that complete PM resume all of devices. Change-Id: I5c9a467691956250c1fa99b7a83f5fe306c0730a Signed-off-by: William Wu --- diff --git a/drivers/mfd/fusb302.c b/drivers/mfd/fusb302.c index 6f07904718e4..3201a17fa53d 100644 --- a/drivers/mfd/fusb302.c +++ b/drivers/mfd/fusb302.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -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); - } } }