From 00fce8bd20f48021588b49cc9b35c3a69f74c2d6 Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Fri, 25 Feb 2022 14:45:47 +0100 Subject: [PATCH] fix: ipc4: setdx: infinity loop This patch refactors the SetDX handler to avoid entering infinity loop. Secondary cores are enabled/disabled in loop iterating from 1 to CONFIG_CORE_COUNT. Primary core is disabled at the end, because it's required that all secondary cores to be already disabled. If all conditions are met, FW can enter the D3 state. Signed-off-by: Tomasz Leman --- src/ipc/ipc4/handler.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/ipc/ipc4/handler.c b/src/ipc/ipc4/handler.c index d505ebb6a..6fe1eb543 100644 --- a/src/ipc/ipc4/handler.c +++ b/src/ipc/ipc4/handler.c @@ -774,39 +774,34 @@ static int ipc4_module_process_dx(union ipc4_message_header *ipc4) return IPC4_BAD_STATE; } - /* Activate/deactivate requested cores. - * Start from highest id cores so in case of request to deactivate all active cores - * the core 0 will have a chance to be disabled as the last one. - */ - - for (core_id = CONFIG_CORE_COUNT - 1; core_id >= 0; core_id--) { + /* Activate/deactivate requested cores */ + for (core_id = 1; core_id < CONFIG_CORE_COUNT; core_id++) { if ((dx_info.core_mask & BIT(core_id)) == 0) continue; if (dx_info.dx_mask & BIT(core_id)) { ret = cpu_enable_core(core_id); if (ret != 0) { - tr_err(&ipc_tr, "Failed to enable core %d", core_id); + tr_err(&ipc_tr, "failed to enable core %d", core_id); return IPC4_FAILURE; } } else { - if (core_id == PLATFORM_PRIMARY_CORE_ID) { - if (cpu_enabled_cores() & ~BIT(PLATFORM_PRIMARY_CORE_ID)) { - /* primary core can't be deactivated */ - tr_err(&ipc_tr, "Secondary cores 0x%x still active", - cpu_enabled_cores()); - return IPC4_BUSY; - } - - ipc_get()->pm_prepare_D3 = 1; - /* TODO: prepare for D3 */ - return IPC4_SUCCESS; - } - cpu_disable_core(core_id); } } + /* Deactivating primary core if requested. */ + if (dx_info.core_mask & BIT(PLATFORM_PRIMARY_CORE_ID)) { + if (cpu_enabled_cores() & ~BIT(PLATFORM_PRIMARY_CORE_ID)) { + tr_err(&ipc_tr, "secondary cores 0x%x still active", + cpu_enabled_cores()); + return IPC4_BUSY; + } + + ipc_get()->pm_prepare_D3 = 1; + /* TODO: prepare for D3 */ + } + return IPC4_SUCCESS; }