diff options
author | Jett Rink <jettrink@chromium.org> | 2018-10-04 12:37:33 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-05 19:37:58 -0700 |
commit | b7288876ac2500d50a49d925833382be6f1eb5fc (patch) | |
tree | 1e4a929edfb1e04f72c5f8170ede7747f1f20218 /common | |
parent | 4170abd620557cddef031546ba0a249b834f7b38 (diff) | |
download | chrome-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.c | 23 |
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; |