From 082f43af91698a82583053679ec0d0be89b36b2d Mon Sep 17 00:00:00 2001 From: William Wu Date: Wed, 4 Jan 2017 16:05:21 +0800 Subject: [PATCH] mfd: fusb302: avoid sending notifier to USB/DP during PM suspend MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- drivers/mfd/fusb302.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) 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); - } } } -- 2.34.1