summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2015-01-22 18:30:09 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-01-23 19:56:42 +0000
commit35c00bf3d9a9dd5da6e797a189598ed4862626f5 (patch)
treefabee62bf5be80a5e02c92d83509a6f4c591f5a1
parentad0306862031b4422958c1b7fc0b5399825f6d37 (diff)
downloadchrome-ec-35c00bf3d9a9dd5da6e797a189598ed4862626f5.tar.gz
pd: fix power swap to sink could get wedged if missing PS_RDY
Fix bug if we are executing a power swap to a sink, and we don't get PS_RDY from port partner, then we transition to SNK_DISCONNECTED without switching our power role to sink, which could cause us to get wedged in the wrong state if we also receive a hard reset a little later because we will have Rd asserted but are will transition to source role and can never get out of it. BUG=none BRANCH=samus TEST=load onto two samus' and executing a bunch of power swaps. load custom code on one samus to never send PS_RDY when switching from sink to source and make sure when power swap occurs the state machine does not get wedged with the wrong role. Change-Id: I7eb2bd4d48f32770b8d7a754fee8ac8da35fa949 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/242760 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--common/usb_pd_protocol.c14
1 files changed, 3 insertions, 11 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 234f024624..b7c190d173 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -833,12 +833,6 @@ static void execute_hard_reset(int port)
pd_set_host_mode(port, 0);
pd_power_supply_reset(port);
}
- /*
- * If we are swapping to a sink and have changed to Rd, change role to
- * sink to match the CC pull resistor.
- */
- if (pd[port].task_state == PD_STATE_SRC_SWAP_STANDBY)
- pd[port].power_role = PD_ROLE_SINK;
if (pd[port].power_role == PD_ROLE_SINK) {
/* Clear the input current limit */
@@ -2251,8 +2245,9 @@ void pd_task(void)
PD_STATE_SRC_DISCONNECTED);
break;
}
- /* Switch to Rd */
+ /* Switch to Rd and swap roles to sink */
pd_set_host_mode(port, 0);
+ pd[port].power_role = PD_ROLE_SINK;
/* Wait for PS_RDY from new source */
set_state_timeout(port,
get_time().val +
@@ -2698,10 +2693,7 @@ void pd_task(void)
* If hard reset while in the last stages of power
* swap, then we need to restore our CC resistor.
*/
- if (pd[port].last_state == PD_STATE_SRC_SWAP_STANDBY)
- pd_set_host_mode(port, 1);
- else if (pd[port].last_state ==
- PD_STATE_SNK_SWAP_STANDBY)
+ if (pd[port].last_state == PD_STATE_SNK_SWAP_STANDBY)
pd_set_host_mode(port, 0);
#endif