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 <wulf@rock-chips.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user