diff options
author | Jack Pham <jackp@codeaurora.org> | 2016-05-23 11:21:43 -0700 |
---|---|---|
committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-08 15:20:27 -0700 |
commit | b5e86ec97a8fe07f6c53ca7e669317616e91ec82 (patch) | |
tree | 0cf71735d4c06b246f429860f6e8db2f6a1f554f /drivers | |
parent | 84f558918ff8eb0215f6afd4a18cf53e70a68657 (diff) |
usb: pd: Handle disconnection immediately if SDP
Due to a known PMIC HW bug, hard reset or PR swap may result in
the charger notifying a CC disconnect event in sink mode, in which
case the handler ignores it given these conditions. However, this
closely resembles the case of a non-PD capable source getting
physically disconnected as well. Consisdering the most probable
case of this happening is disconnecting from an SDP while hard
reset was just issued (and will fail), this workaround is currently
racy if repeated plugin/plugout is performed as the timeout to
detect failed hard reset takes a few seconds.
For now, until a HW fix is available, optimize this legacy case
by allowing the disconnect to go through if the detected charger
type is SDP. Also fix the SINK_WAIT_CAP_TIME timeout as it was
incorrectly multiplied by 3 during testing and was not removed.
This will significantly reduce the amount of time for max failed
hard reset attempts for non-PD && non-SDP cases and should decrease
the window for racing with an actual disconnect.
Change-Id: Ic57a369ed1e194ab512b4b86ce4d216df46b5f46
Signed-off-by: Jack Pham <jackp@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/pd/policy_engine.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 8a1465a74ab3..b7b978b8d306 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -725,7 +725,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) queue_delayed_work(pd->wq, &pd->sm_work, 0); else queue_delayed_work(pd->wq, &pd->sm_work, - msecs_to_jiffies(SINK_WAIT_CAP_TIME * 3)); + msecs_to_jiffies(SINK_WAIT_CAP_TIME)); break; case PE_SNK_EVALUATE_CAPABILITY: @@ -1369,8 +1369,24 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) if (!pd_allowed && typec_mode != POWER_SUPPLY_TYPEC_NONE) return 0; + /* + * Workaround for PMIC HW bug. + * + * During hard reset or PR swap (sink to source) when VBUS goes to 0 + * the CC logic will report this as a disconnection. In those cases it + * can be ignored, however the downside is that pd->hard_reset can be + * momentarily true even when a non-PD capable source is attached, and + * can't be distinguished from a physical disconnect. In that case, + * allow for the common case of disconnecting from an SDP. + * + * The less common case is a PD-capable SDP which will result in a + * hard reset getting treated like a disconnect. We can live with this + * until the HW bug is fixed: in which disconnection won't be reported + * on VBUS loss alone unless pullup is also removed from CC. + */ if ((pd->hard_reset || pd->in_pr_swap) && - typec_mode == POWER_SUPPLY_TYPEC_NONE) { + typec_mode == POWER_SUPPLY_TYPEC_NONE && + pd->psy_type != POWER_SUPPLY_TYPE_USB) { usbpd_dbg(&pd->dev, "Ignoring disconnect due to %s\n", pd->hard_reset ? "hard reset" : "PR swap"); return 0; |