summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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()