summaryrefslogtreecommitdiff
path: root/common/usb_pd_tcpc.c
diff options
context:
space:
mode:
authorJonathan Brandmeyer <jbrandmeyer@chromium.org>2018-10-03 09:16:33 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-10-04 17:09:01 -0700
commit31fe290061fdf9d1b0e8a634c77cb7a30b2f012b (patch)
tree4c86c978f86dce2e5868f71a0e756bb38cbaf7af /common/usb_pd_tcpc.c
parent356083b7f0b36ffd5b8d387e332ff488810ed47e (diff)
downloadchrome-ec-31fe290061fdf9d1b0e8a634c77cb7a30b2f012b.tar.gz
tcpc: Resume suspended ports after an interval
When it appears that the TCPC queue handling logic may be stuck in an infinite loop, the EC will break the loop by disabling the port in order to avoid task starvation. However, nothing attempts to resume the port, and it therefore remains disabled until the next EC reset. Wake back up after a reasonable interval in order to automatically retry. On port suspend, completely drain the TCPM message queue. BUG=chromium:891713 TEST=On Careena hardware, with analogix TCPC firmware v1.5 and an electronically marked cable that sends SOP' messages, verify that the EC auto-retries every second. After removing the offending cable, and PD power supply will work. BRANCH=grunt Change-Id: I563b763501333eb36ee1f76e6f484ebb3245c82a Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1258571 Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common/usb_pd_tcpc.c')
-rw-r--r--common/usb_pd_tcpc.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c
index 152775bbc0..11bc399b5e 100644
--- a/common/usb_pd_tcpc.c
+++ b/common/usb_pd_tcpc.c
@@ -261,7 +261,12 @@ static struct pd_port_controller {
static int rx_buf_is_full(int port)
{
- /* Buffer is full if the tail is 1 ahead of head */
+ /*
+ * TODO: Refactor these to use the incrementing-counter idiom instead of
+ * the wrapping-counter idiom to reclaim the last buffer entry.
+ *
+ * Buffer is full if the tail is 1 ahead of head.
+ */
int diff = pd[port].rx_buf_tail - pd[port].rx_buf_head;
return (diff == 1) || (diff == -RX_BUFFER_SIZE);
}
@@ -272,6 +277,11 @@ int rx_buf_is_empty(int port)
return pd[port].rx_buf_tail == pd[port].rx_buf_head;
}
+void rx_buf_clear(int port)
+{
+ pd[port].rx_buf_tail = pd[port].rx_buf_head;
+}
+
static void rx_buf_increment(int port, int *buf_ptr)
{
*buf_ptr = *buf_ptr == RX_BUFFER_SIZE ? 0 : *buf_ptr + 1;