diff --git a/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh b/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh index d19d1a77..90785c0d 100755 --- a/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh +++ b/Runner/suites/Kernel/Baseport/adsp_remoteproc/run.sh @@ -1,5 +1,4 @@ #!/bin/sh - # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. # SPDX-License-Identifier: BSD-3-Clause-Clear # Robustly find and source init_env @@ -39,42 +38,149 @@ log_info "---------------------------------------------------------------------- log_info "------------------- Starting $TESTNAME Testcase ----------------------------" log_info "=== Test Initialization ===" -# Tunables -STOP_TO="${STOP_TO:-10}" -START_TO="${START_TO:-10}" -POLL_I="${POLL_I:-1}" +# --- Tunables (override via env) ---------------------------------------------- +STOP_TO="${STOP_TO:-10}" # remoteproc stop timeout (s) +START_TO="${START_TO:-10}" # remoteproc start timeout (s) +POLL_I="${POLL_I:-1}" # state poll interval (s) +PRE_STOP_DELAY="${PRE_STOP_DELAY:-30}" # FIXED delay before stopping ADSP (seconds) +FATAL_ON_UNSUSPENDED="${FATAL_ON_UNSUSPENDED:-0}" # 1 = abort if audio not suspended/unsupported after delay + +log_info "Tunables: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I PRE_STOP_DELAY=$PRE_STOP_DELAY FATAL_ON_UNSUSPENDED=$FATAL_ON_UNSUSPENDED" + +# --- Audio readiness snapshot (no hardcoding, no long wait) ------------------- +# Discovers a bound snd*/snd-soc* driver, logs module once, collects nodes to check. +# Sets globals: +# CHECK_NODES="list of .../power/runtime_status files" +# AUDIO_PM_SNAPSHOT_OK=1/0 (current sample) +discover_audio_stack_and_snapshot() { + DRIVERS_BASE="/sys/bus/platform/drivers" + log_info "Validating audio stack readiness before ADSP test..." + log_info "Scanning for platform audio driver (module -> bound -> suspend snapshot)..." + + platform_drv="" + platform_mod="" + + for drvdir in "$DRIVERS_BASE"/snd-* "$DRIVERS_BASE"/snd-soc-*; do + [ -d "$drvdir" ] || continue + [ -L "$drvdir/sound" ] || continue + platform_drv="$(basename "$drvdir")" + if [ -L "$drvdir/module" ]; then + platform_mod="$(basename "$(readlink -f "$drvdir/module")")" + else + platform_mod="" + fi + break + done + + CHECK_NODES="" + if [ -z "$platform_drv" ]; then + log_warn "No suitable platform audio driver found (module+bound); skipping suspend snapshot" + AUDIO_PM_SNAPSHOT_OK=1 + return 0 + fi + + if [ -n "$platform_mod" ]; then + if check_driver_loaded "$platform_mod" >/dev/null 2>&1; then + log_pass "Driver/module '$platform_mod' is loaded" + elif [ -d "/sys/module/$platform_mod" ]; then + log_info "Module '$platform_mod' appears built-in" + else + log_warn "Module '$platform_mod' not present; proceeding (driver bound)" + fi + else + log_info "No 'module' symlink for $platform_drv; assuming built-in/platform driver" + fi + + log_info "Using bound audio driver: $platform_drv${platform_mod:+ (module: $platform_mod)}" + + TARGET_PATH="$DRIVERS_BASE/$platform_drv/sound" + + # 1) Platform sound root + immediate children (collect runtime_status files) + if [ -d "$TARGET_PATH" ]; then + _rt_nodes_list="$(mktemp)" + find "$TARGET_PATH" -maxdepth 2 -type f -path "*/power/runtime_status" \ + -exec printf '%s\n' {} \; 2>/dev/null > "$_rt_nodes_list" + while IFS= read -r f; do + [ -n "$f" ] && CHECK_NODES="$CHECK_NODES $f" + done < "$_rt_nodes_list" + rm -f "$_rt_nodes_list" + fi + + # 2) ALSA cards + for f in /sys/class/sound/card*/device/power/runtime_status; do + [ -f "$f" ] && CHECK_NODES="$CHECK_NODES $f" + done + + # 3) SoundWire slaves + for f in /sys/bus/soundwire/devices/*/power/runtime_status; do + [ -f "$f" ] && CHECK_NODES="$CHECK_NODES $f" + done -log_info "DEBUG: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I" + if [ -z "$CHECK_NODES" ]; then + log_warn "No runtime_status nodes found for audio stack; treating snapshot as OK" + AUDIO_PM_SNAPSHOT_OK=1 + return 0 + fi + + # Single snapshot: OK if all nodes are 'suspended' or 'unsupported' + AUDIO_PM_SNAPSHOT_OK=1 + for n in $CHECK_NODES; do + st="$(cat "$n" 2>/dev/null || echo "unknown")" + case "$st" in + suspended|unsupported) : ;; + *) AUDIO_PM_SNAPSHOT_OK=0 ;; + esac + [ "$AUDIO_PM_SNAPSHOT_OK" -eq 0 ] && break + done + + if [ "$AUDIO_PM_SNAPSHOT_OK" -eq 1 ]; then + log_info "Audio PM snapshot: OK (suspended/unsupported)" + else + log_warn "Audio PM snapshot: not fully suspended; proceeding to fixed pre-stop delay" + fi +} -# DT check for entries -if dt_has_remoteproc_fw "$FW"; then - log_info "DT indicates $FW is present" -else +# Re-check after fixed delay (if gating is enabled) +audio_pm_snapshot_ok() { + # Re-sample the same CHECK_NODES set; if empty, treat as OK. + if [ -z "$CHECK_NODES" ]; then + echo "1" + return + fi + for n in $CHECK_NODES; do + st="$(cat "$n" 2>/dev/null || echo "unknown")" + case "$st" in suspended|unsupported) : ;; *) echo "0"; return ;; esac + done + echo "1" +} + +discover_audio_stack_and_snapshot + +# --- Check DT presence for ADSP ----------------------------------------------- +if ! dt_has_remoteproc_fw "$FW"; then log_skip "$TESTNAME SKIP – $FW not described in DT" echo "$TESTNAME SKIP" >"$RES_FILE" exit 0 fi +log_info "DT indicates $FW is present" -# Enumerate ADSP remoteproc entries -# get_remoteproc_by_firmware prints: "path|state|firmware|name" -entries="$(get_remoteproc_by_firmware "$FW" "" all)" || entries="" +# --- Enumerate ADSP remoteproc entries ---------------------------------------- +entries="$(get_remoteproc_by_firmware "$FW" "" all 2>/dev/null)" || entries="" if [ -z "$entries" ]; then log_fail "$FW present in DT but no /sys/class/remoteproc entry found" + echo "$TESTNAME FAIL" >"$RES_FILE" exit 1 fi -count_instances=$(printf '%s\n' "$entries" | wc -l) +count_instances="$(printf '%s\n' "$entries" | wc -l)" log_info "Found $count_instances $FW instance(s)" inst_fail=0 RESULT_LINES="" -tmp_list="$(mktemp)" -printf '%s\n' "$entries" >"$tmp_list" - +# --- Iterate each instance via here-doc --------------------------------------- while IFS='|' read -r rpath rstate rfirm rname; do [ -n "$rpath" ] || continue - inst_id="$(basename "$rpath")" log_info "---- $inst_id: path=$rpath state=$rstate firmware=$rfirm name=$rname ----" @@ -83,7 +189,6 @@ while IFS='|' read -r rpath rstate rfirm rname; do start_res="NA" ping_res="SKIPPED" - # Boot check if [ "$rstate" = "running" ]; then log_pass "$inst_id: boot check PASS" else @@ -95,12 +200,28 @@ while IFS='|' read -r rpath rstate rfirm rname; do continue fi - # Stop + # ---- Fixed pre-stop delay (always wait PRE_STOP_DELAY seconds) ----------- + log_info "$inst_id: waiting ${PRE_STOP_DELAY}s before remoteproc stop (fixed delay)" + [ "$PRE_STOP_DELAY" -gt 0 ] && sleep "$PRE_STOP_DELAY" + + # Optional gating: after the fixed delay, ensure PM is OK before stopping + if [ "$FATAL_ON_UNSUSPENDED" -eq 1 ]; then + if [ "$(audio_pm_snapshot_ok)" -ne 1 ]; then + log_fail "Audio not in suspended/unsupported state after ${PRE_STOP_DELAY}s (FATAL_ON_UNSUSPENDED=1); aborting before stop" + echo "$TESTNAME FAIL" >"$RES_FILE" + exit 1 + fi + fi + + # Helpful dmesg snapshots + dmesg | tail -n 100 > "$test_path/dmesg_before_stop.log" dump_rproc_logs "$rpath" before-stop - t0=$(date +%s) + + # ---- Stop ADSP ----------------------------------------------------------- + t0="$(date +%s)" log_info "$inst_id: stopping" if stop_remoteproc "$rpath" && wait_remoteproc_state "$rpath" offline "$STOP_TO" "$POLL_I"; then - t1=$(date +%s) + t1="$(date +%s)" log_pass "$inst_id: stop PASS ($((t1 - t0))s)" stop_res="PASS" else @@ -112,14 +233,15 @@ while IFS='|' read -r rpath rstate rfirm rname; do $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" continue fi - dump_rproc_logs "$rpath" after-stop - # Start + dump_rproc_logs "$rpath" after-stop dump_rproc_logs "$rpath" before-start - t2=$(date +%s) + + # ---- Start ADSP ---------------------------------------------------------- + t2="$(date +%s)" log_info "$inst_id: starting" if start_remoteproc "$rpath" && wait_remoteproc_state "$rpath" running "$START_TO" "$POLL_I"; then - t3=$(date +%s) + t3="$(date +%s)" log_pass "$inst_id: start PASS ($((t3 - t2))s)" start_res="PASS" else @@ -131,10 +253,12 @@ while IFS='|' read -r rpath rstate rfirm rname; do $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" continue fi + dump_rproc_logs "$rpath" after-start + dmesg | tail -n 100 > "$test_path/dmesg_after_restart.log" - # Optional RPMsg ping - if CTRL_DEV=$(find_rpmsg_ctrl_for "$FW"); then + # ---- Optional RPMsg sanity ping ----------------------------------------- + if CTRL_DEV="$(find_rpmsg_ctrl_for "$FW")"; then log_info "$inst_id: RPMsg ctrl dev: $CTRL_DEV" if rpmsg_ping_generic "$CTRL_DEV"; then log_pass "$inst_id: rpmsg ping PASS" @@ -150,11 +274,11 @@ while IFS='|' read -r rpath rstate rfirm rname; do RESULT_LINES="$RESULT_LINES $inst_id: boot=$boot_res, stop=$stop_res, start=$start_res, ping=$ping_res" +done <<__RPROC_LIST__ +$entries +__RPROC_LIST__ -done <"$tmp_list" -rm -f "$tmp_list" - -# Summary +# --- Summary ------------------------------------------------------------------ log_info "Instance results:$RESULT_LINES" if [ "$inst_fail" -gt 0 ]; then diff --git a/Runner/utils/functestlib.sh b/Runner/utils/functestlib.sh index ab8ca48a..91c5869e 100755 --- a/Runner/utils/functestlib.sh +++ b/Runner/utils/functestlib.sh @@ -1200,7 +1200,7 @@ dump_rproc_logs() { logfile="rproc_${base}_${label}_${ts}.log" log_info "Dumping ${base} [${label}] → ${logfile}" [ -r "$rpath/trace" ] && cat "$rpath/trace" >"$logfile" - dmesg --ctime | grep -i "$base" >>"$logfile" 2>/dev/null || : + dmesg | grep -i "$base" >>"$logfile" 2>/dev/null || : } # find_rpmsg_ctrl_for