summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2016-05-23 11:21:43 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-08 15:20:27 -0700
commitb5e86ec97a8fe07f6c53ca7e669317616e91ec82 (patch)
tree0cf71735d4c06b246f429860f6e8db2f6a1f554f /drivers
parent84f558918ff8eb0215f6afd4a18cf53e70a68657 (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.c20
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;