diff options
-rw-r--r-- | common/usbc/usb_pd_console.c | 2 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 16 | ||||
-rw-r--r-- | common/usbc/usb_pe_private.h | 5 | ||||
-rw-r--r-- | include/usb_pe_sm.h | 7 | ||||
-rw-r--r-- | test/usb_pd_console.c | 10 |
5 files changed, 37 insertions, 3 deletions
diff --git a/common/usbc/usb_pd_console.c b/common/usbc/usb_pd_console.c index d1c82bafda..ae6527b601 100644 --- a/common/usbc/usb_pd_console.c +++ b/common/usbc/usb_pd_console.c @@ -226,6 +226,8 @@ static req = DPM_REQUEST_EPR_MODE_ENTRY; } else if (!strcasecmp(argv[3], "exit")) { req = DPM_REQUEST_EPR_MODE_EXIT; + /* Prevent snk_ready from repeatedly entering EPR. */ + pe_snk_epr_explicit_exit(port); } else { return EC_ERROR_PARAM3; } diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 767fed302b..dba06dfbfb 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -1159,6 +1159,11 @@ bool pe_snk_in_epr_mode(int port) return PE_CHK_FLAG(port, PE_FLAGS_IN_EPR); } +void pe_snk_epr_explicit_exit(int port) +{ + PE_SET_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); +} + bool pe_snk_can_enter_epr_mode(int port) { /* @@ -3749,9 +3754,12 @@ static void pe_snk_ready_entry(int port) */ pe_update_wait_and_add_jitter_timer(port); - if (IS_ENABLED(CONFIG_USB_PD_EPR) && pe_snk_in_epr_mode(port)) { - pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE, - PD_T_SINK_EPR_KEEP_ALIVE); + if (IS_ENABLED(CONFIG_USB_PD_EPR)) { + if (pe_snk_in_epr_mode(port)) + pd_timer_enable(port, PE_TIMER_SINK_EPR_KEEP_ALIVE, + PD_T_SINK_EPR_KEEP_ALIVE); + else if (!PE_CHK_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT)) + pd_dpm_request(port, DPM_REQUEST_EPR_MODE_ENTRY); } } @@ -4138,6 +4146,7 @@ static void pe_send_soft_reset_entry(int port) print_current_state(port); PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); + PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); /* Reset Protocol Layer (softly) */ prl_reset_soft(port); @@ -7913,6 +7922,7 @@ static void pe_ddr_perform_data_reset_exit(int port) static void pe_enter_epr_mode(int port) { PE_CLR_FLAG(port, PE_FLAGS_ENTERING_EPR); + PE_CLR_FLAG(port, PE_FLAGS_EPR_EXPLICIT_EXIT); PE_SET_FLAG(port, PE_FLAGS_IN_EPR); CPRINTS("C%d: Entered EPR", port); } diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h index 5eafb7befd..b71cfced86 100644 --- a/common/usbc/usb_pe_private.h +++ b/common/usbc/usb_pe_private.h @@ -92,6 +92,11 @@ enum { PE_FLAGS_ENTERING_EPR_FN, /* In EPR mode */ PE_FLAGS_IN_EPR_FN, + /* + * Indicate the port exited EPR mode explicitly. If this is set, the + * port wouldn't enter EPR mode automatically. + */ + PE_FLAGS_EPR_EXPLICIT_EXIT_FN, /* Discovery disabled due to UFP/PD 2.0 constraint. */ PE_FLAGS_DISCOVERY_DISABLED_FN, /* Last element */ diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h index 9672c6b26b..21cc65d43d 100644 --- a/include/usb_pe_sm.h +++ b/include/usb_pe_sm.h @@ -210,6 +210,13 @@ void pe_clear_port_data(int port); bool pe_snk_in_epr_mode(int port); /** + * Make a sink exit EPR mode explicitly. + * + * @param port USB-C port number + */ +void pe_snk_epr_explicit_exit(int port); + +/** * Checks whether the port is ready for EPR entry. * * @param port USB-C port number diff --git a/test/usb_pd_console.c b/test/usb_pd_console.c index a835a643f8..119fe7131d 100644 --- a/test/usb_pd_console.c +++ b/test/usb_pd_console.c @@ -35,6 +35,7 @@ static bool pe_get_current_state_called; static bool pe_get_flags_called; static bool pe_is_explicit_contract_called; static bool pe_snk_in_epr_mode_called; +static bool pe_snk_epr_explicit_exit_called; static bool pd_get_dual_role_called; static bool board_get_usb_pd_port_count_called; static bool pd_srccaps_dump_called; @@ -86,6 +87,11 @@ bool pe_snk_in_epr_mode(int port) return true; } +void pe_snk_epr_explicit_exit(int port) +{ + pe_snk_epr_explicit_exit_called = true; +} + const char *pe_get_current_state(int port) { pe_get_current_state_called = true; @@ -726,18 +732,22 @@ static int test_command_pd_epr(void) request = 0; pd_get_power_role_called = false; pd_get_power_role_return = PD_ROLE_SINK; + pe_snk_epr_explicit_exit_called = false; TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); TEST_ASSERT(pd_get_power_role_called); TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_ENTRY); + TEST_ASSERT(!pe_snk_epr_explicit_exit_called); /* Return SUCCESS with request==DPM_REQUEST_EPR_MODE_EXIT. */ argv[3] = "exit"; request = 0; pd_get_power_role_called = false; pd_get_power_role_return = PD_ROLE_SINK; + pe_snk_epr_explicit_exit_called = false; TEST_ASSERT(command_pd(argc, argv) == EC_SUCCESS); TEST_ASSERT(pd_get_power_role_called); TEST_ASSERT(request == DPM_REQUEST_EPR_MODE_EXIT); + TEST_ASSERT(pe_snk_epr_explicit_exit_called); /* Return EC_ERROR_PARAM3 for invalid sub-command. */ argv[3] = "start"; |