diff options
-rw-r--r-- | common/usb_pd_protocol.c | 23 | ||||
-rw-r--r-- | include/usb_pd.h | 12 |
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() |