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 <tomasz.m.leman@intel.com>
This commit is contained in:
Tomasz Leman 2022-02-25 14:45:47 +01:00 committed by Liam Girdwood
parent 4ea628e118
commit 00fce8bd20
1 changed files with 15 additions and 20 deletions

View File

@ -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;
}