summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2018-10-04 12:37:33 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-10-05 19:37:58 -0700
commitb7288876ac2500d50a49d925833382be6f1eb5fc (patch)
tree1e4a929edfb1e04f72c5f8170ede7747f1f20218 /common
parent4170abd620557cddef031546ba0a249b834f7b38 (diff)
downloadchrome-ec-b7288876ac2500d50a49d925833382be6f1eb5fc.tar.gz
usb-pd: allow a task to prevent TCPC LPM
If a particularly low priority task (like hooks) wants to access the TCPC, then we do not want the LPM debounce to trigger in the middle of the communication sequence. This is especially a concern if the TCPC access is on debug registers that do not push out the LPM debounce deadline. BRANCH=none BUG=b:111406013 TEST=TCPC communication on meep is much more reliable with this change. TCPC will still go into low power mode after all tasks stop preventing LPM. Change-Id: I58cee8e202ced4085f131ff86dbda9d366e1dcca Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1262107 Reviewed-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/usb_pd_protocol.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 23c88d7a85..c5ab8ca9a2 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -191,6 +191,8 @@ static struct pd_protocol {
uint64_t low_power_time;
/* Tasks to notify after TCPC has been reset */
int tasks_waiting_on_reset;
+ /* Tasks preventing TCPC from entering low power mode */
+ int tasks_preventing_lpm;
#endif
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
@@ -491,6 +493,16 @@ void pd_wait_for_wakeup(int port)
}
}
+void pd_prevent_low_power_mode(int port, int prevent)
+{
+ const int current_task_mask = (1 << task_get_current());
+
+ if (prevent)
+ atomic_or(&pd[port].tasks_preventing_lpm, current_task_mask);
+ else
+ atomic_clear(&pd[port].tasks_preventing_lpm, current_task_mask);
+}
+
/* This is only called from the PD tasks that owns the port. */
static void exit_low_power_mode(int port)
{
@@ -3934,8 +3946,15 @@ void pd_task(void *u)
/* Determine if we need to put the TCPC in low power mode */
if (pd[port].flags & PD_FLAGS_LPM_REQUESTED &&
!(pd[port].flags & PD_FLAGS_LPM_ENGAGED)) {
- const int64_t time_left =
- pd[port].low_power_time - now.val;
+ int64_t time_left;
+
+ /* If any task prevents LPM, wait another debounce */
+ if (pd[port].tasks_preventing_lpm) {
+ pd[port].low_power_time =
+ PD_LPM_DEBOUNCE_US + now.val;
+ }
+
+ time_left = pd[port].low_power_time - now.val;
if (time_left <= 0) {
pd[port].flags |= PD_FLAGS_LPM_ENGAGED;
pd[port].flags |= PD_FLAGS_LPM_TRANSITION;