summaryrefslogtreecommitdiff
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
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>
-rw-r--r--common/usb_pd_protocol.c23
-rw-r--r--include/usb_pd.h12
2 files changed, 33 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;
diff --git a/include/usb_pd.h b/include/usb_pd.h
index c5f6799a26..929b6d43ab 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1046,6 +1046,18 @@ int pd_is_max_request_allowed(void);
void pd_device_accessed(int port);
/**
+ * Prevents the TCPC from going back into low power mode. Invocations must be
+ * called in a pair from the same task, otherwise the TCPC will never re-enter
+ * low power mode.
+ *
+ * Note: This will not wake the device up if it is in LPM.
+ *
+ * @param port USB-C port number
+ * @param prevent 1 to prevent this port from entering LPM
+ */
+void pd_prevent_low_power_mode(int port, int prevent);
+
+/**
* Returns true if this TCPC is in low power mode and a failed i2c transaction
* should be retried after waiting for the device to wake up via
* pd_wait_for_wakeup()