lib: utils/suspend: wait for the secondary Andes harts to sleep

A secondary hart may not have reached the target sleep state by the time
the primary checks, so the one-shot check could fail spuriously. Poll
each PCS status instead and give up after HART_SLEEP_TIMEOUT_MS.

Rework atcsmu_pcs_is_sleep() into the atcsmu_hart_is_sleep() predicate so
sbi_timer_waitms_until() can drive it.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260728081041.2724668-7-ben717@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Ben Zong-You Xie
2026-09-01 10:46:23 +05:30
committed by Anup Patel
parent e01bd7926b
commit 0fb4799307
3 changed files with 35 additions and 21 deletions
+8 -14
View File
@@ -94,23 +94,17 @@ u32 atcsmu_read_scratch(void)
return readl_relaxed((char *)atcsmu_base + SCRATCH_PAD_OFFSET);
}
bool atcsmu_pcs_is_sleep(u32 hartid, bool deep_sleep)
bool atcsmu_hart_is_sleep(void *opaque)
{
u32 pcs_status = readl_relaxed((char *)atcsmu_base + PCSm_STATUS_OFFSET(hartid));
u32 pd_status = deep_sleep ? PD_STATUS_DEEP_SLEEP : PD_STATUS_LIGHT_SLEEP;
struct atcsmu_sleep_arg *arg = opaque;
if (EXTRACT_FIELD(pcs_status, PD_TYPE_MASK) != PD_TYPE_SLEEP) {
sbi_printf("ATCSMU: hart%d (PCS%d): failed to sleep\n", hartid, hartid + 3);
return false;
}
u32 pcs_status = readl_relaxed((char *)atcsmu_base +
PCSm_STATUS_OFFSET(arg->hartid));
u32 pd_status = arg->deep_sleep ? PD_STATUS_DEEP_SLEEP :
PD_STATUS_LIGHT_SLEEP;
if (EXTRACT_FIELD(pcs_status, PD_STATUS_MASK) != pd_status) {
sbi_printf("ATCSMU: hart%d (PCS%d): failed to enter %s sleep\n",
hartid, hartid + 3, deep_sleep ? "deep" : "light");
return false;
}
return true;
return EXTRACT_FIELD(pcs_status, PD_TYPE_MASK) == PD_TYPE_SLEEP &&
EXTRACT_FIELD(pcs_status, PD_STATUS_MASK) == pd_status;
}
static int ae350_hart_start(u32 hartid, ulong saddr)