From 3b399a415c4d438f8d093b35c34c2fe08871c2e7 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Thu, 20 Jul 2017 11:30:33 -0700 Subject: [PATCH 1/2] usb: pd: avoid missed connection notification In the disconnect handler of usbpd_sm(), pd->current_pr is already set to PR_NONE, so there is no reason to set it again. This helps for cases where a quick reconnection notification just arrived and sets the variable to either PR_SRC or PR_SINK but the disconnect handling clears it resulting in nothing to be done the next time work is scheduled. Change-Id: Ia88520149905989a3b3efb94361670760b79c0bd Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 0cbe95304417..ea24e02ff44e 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -1617,7 +1617,6 @@ static void usbpd_sm(struct work_struct *w) else if (pd->current_dr == DR_DFP) stop_usb_host(pd); - pd->current_pr = PR_NONE; pd->current_dr = DR_NONE; reset_vdm_state(pd); From 4a32817fda1cd284f944b92878d44de43f203024 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Mon, 24 Jul 2017 10:05:05 -0700 Subject: [PATCH 2/2] usb: pd: force disconnect upon unexpected SRC->SNK transition While in Source mode, a notification that a source is attached is unexpected. In this case, force a disconnect in order to clean up state and turn off VBUS and Vconn. Change-Id: Ie576feeb7622376e8cb0dd8454b626b3b24b190b Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index ea24e02ff44e..d5653e908cec 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -2479,6 +2479,16 @@ static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) if (pd->current_pr == PR_SINK) return 0; + /* + * Unexpected if not in PR swap; need to force disconnect from + * source so we can turn off VBUS, Vconn, PD PHY etc. + */ + if (pd->current_pr == PR_SRC) { + usbpd_info(&pd->dev, "Forcing disconnect from source mode\n"); + pd->current_pr = PR_NONE; + break; + } + pd->current_pr = PR_SINK; break;