summaryrefslogtreecommitdiff
path: root/common/usbc/usb_tc_drp_acc_trysrc_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc/usb_tc_drp_acc_trysrc_sm.c')
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
index 041c3c7187..bf7d69bf13 100644
--- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c
+++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
@@ -1887,6 +1887,16 @@ __maybe_unused static void handle_new_power_state(int port)
}
/*
+ * If the sink port was sourcing Vconn, and can no longer, request a
+ * hard reset on this port to restore Vconn to the source.
+ */
+ if (IS_ENABLED(CONFIG_USB_PE_SM)) {
+ if (tc_is_vconn_src(port) && tc_is_attached_snk(port) &&
+ !pd_check_vconn_swap(port))
+ pd_dpm_request(port, DPM_REQUEST_HARD_RESET_SEND);
+ }
+
+ /*
* TC_FLAGS_UPDATE_USB_MUX is set on chipset startup and shutdown.
* Set the USB mux according to the new power state. If the chipset
* is transitioning to OFF, this disconnects USB and DP mux.
@@ -3995,6 +4005,27 @@ static void pd_chipset_shutdown(void)
}
DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pd_chipset_shutdown, HOOK_PRIO_DEFAULT);
+static void pd_set_power_change(void)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) {
+ task_set_event(PD_PORT_TO_TASK_ID(i),
+ PD_EVENT_POWER_STATE_CHANGE);
+ }
+}
+DECLARE_DEFERRED(pd_set_power_change);
+
+static void pd_chipset_hard_off(void)
+{
+ /*
+ * Wait 1 second to check our Vconn sourcing status, as the power rails
+ * which were supporting it may take some time to change after entering
+ * G3.
+ */
+ hook_call_deferred(&pd_set_power_change_data, 1 * SECOND);
+}
+DECLARE_HOOK(HOOK_CHIPSET_HARD_OFF, pd_chipset_hard_off, HOOK_PRIO_DEFAULT);
/*
* Type-C State Hierarchy (Sub-States are listed inside the boxes)