11#! /bin/sh
2-
32# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
43# SPDX-License-Identifier: BSD-3-Clause-Clear
54# Robustly find and source init_env
@@ -39,42 +38,149 @@ log_info "----------------------------------------------------------------------
3938log_info " ------------------- Starting $TESTNAME Testcase ----------------------------"
4039log_info " === Test Initialization ==="
4140
42- # Tunables
43- STOP_TO=" ${STOP_TO:- 10} "
44- START_TO=" ${START_TO:- 10} "
45- POLL_I=" ${POLL_I:- 1} "
41+ # --- Tunables (override via env) ----------------------------------------------
42+ STOP_TO=" ${STOP_TO:- 10} " # remoteproc stop timeout (s)
43+ START_TO=" ${START_TO:- 10} " # remoteproc start timeout (s)
44+ POLL_I=" ${POLL_I:- 1} " # state poll interval (s)
45+ PRE_STOP_DELAY=" ${PRE_STOP_DELAY:- 30} " # FIXED delay before stopping ADSP (seconds)
46+ FATAL_ON_UNSUSPENDED=" ${FATAL_ON_UNSUSPENDED:- 0} " # 1 = abort if audio not suspended/unsupported after delay
47+
48+ 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 "
49+
50+ # --- Audio readiness snapshot (no hardcoding, no long wait) -------------------
51+ # Discovers a bound snd*/snd-soc* driver, logs module once, collects nodes to check.
52+ # Sets globals:
53+ # CHECK_NODES="list of .../power/runtime_status files"
54+ # AUDIO_PM_SNAPSHOT_OK=1/0 (current sample)
55+ discover_audio_stack_and_snapshot () {
56+ DRIVERS_BASE=" /sys/bus/platform/drivers"
57+ log_info " Validating audio stack readiness before ADSP test..."
58+ log_info " Scanning for platform audio driver (module -> bound -> suspend snapshot)..."
59+
60+ platform_drv=" "
61+ platform_mod=" "
62+
63+ for drvdir in " $DRIVERS_BASE " /snd-* " $DRIVERS_BASE " /snd-soc-* ; do
64+ [ -d " $drvdir " ] || continue
65+ [ -L " $drvdir /sound" ] || continue
66+ platform_drv=" $( basename " $drvdir " ) "
67+ if [ -L " $drvdir /module" ]; then
68+ platform_mod=" $( basename " $( readlink -f " $drvdir /module" ) " ) "
69+ else
70+ platform_mod=" "
71+ fi
72+ break
73+ done
74+
75+ CHECK_NODES=" "
76+ if [ -z " $platform_drv " ]; then
77+ log_warn " No suitable platform audio driver found (module+bound); skipping suspend snapshot"
78+ AUDIO_PM_SNAPSHOT_OK=1
79+ return 0
80+ fi
81+
82+ if [ -n " $platform_mod " ]; then
83+ if check_driver_loaded " $platform_mod " > /dev/null 2>&1 ; then
84+ log_pass " Driver/module '$platform_mod ' is loaded"
85+ elif [ -d " /sys/module/$platform_mod " ]; then
86+ log_info " Module '$platform_mod ' appears built-in"
87+ else
88+ log_warn " Module '$platform_mod ' not present; proceeding (driver bound)"
89+ fi
90+ else
91+ log_info " No 'module' symlink for $platform_drv ; assuming built-in/platform driver"
92+ fi
93+
94+ log_info " Using bound audio driver: $platform_drv ${platform_mod: + (module: $platform_mod )} "
95+
96+ TARGET_PATH=" $DRIVERS_BASE /$platform_drv /sound"
97+
98+ # 1) Platform sound root + immediate children (collect runtime_status files)
99+ if [ -d " $TARGET_PATH " ]; then
100+ _rt_nodes_list=" $( mktemp) "
101+ find " $TARGET_PATH " -maxdepth 2 -type f -path " */power/runtime_status" \
102+ -exec printf ' %s\n' {} \; 2> /dev/null > " $_rt_nodes_list "
103+ while IFS= read -r f; do
104+ [ -n " $f " ] && CHECK_NODES=" $CHECK_NODES $f "
105+ done < " $_rt_nodes_list "
106+ rm -f " $_rt_nodes_list "
107+ fi
108+
109+ # 2) ALSA cards
110+ for f in /sys/class/sound/card* /device/power/runtime_status; do
111+ [ -f " $f " ] && CHECK_NODES=" $CHECK_NODES $f "
112+ done
113+
114+ # 3) SoundWire slaves
115+ for f in /sys/bus/soundwire/devices/* /power/runtime_status; do
116+ [ -f " $f " ] && CHECK_NODES=" $CHECK_NODES $f "
117+ done
46118
47- log_info " DEBUG: STOP_TO=$STOP_TO START_TO=$START_TO POLL_I=$POLL_I "
119+ if [ -z " $CHECK_NODES " ]; then
120+ log_warn " No runtime_status nodes found for audio stack; treating snapshot as OK"
121+ AUDIO_PM_SNAPSHOT_OK=1
122+ return 0
123+ fi
124+
125+ # Single snapshot: OK if all nodes are 'suspended' or 'unsupported'
126+ AUDIO_PM_SNAPSHOT_OK=1
127+ for n in $CHECK_NODES ; do
128+ st=" $( cat " $n " 2> /dev/null || echo " unknown" ) "
129+ case " $st " in
130+ suspended|unsupported) : ;;
131+ * ) AUDIO_PM_SNAPSHOT_OK=0 ;;
132+ esac
133+ [ " $AUDIO_PM_SNAPSHOT_OK " -eq 0 ] && break
134+ done
135+
136+ if [ " $AUDIO_PM_SNAPSHOT_OK " -eq 1 ]; then
137+ log_info " Audio PM snapshot: OK (suspended/unsupported)"
138+ else
139+ log_warn " Audio PM snapshot: not fully suspended; proceeding to fixed pre-stop delay"
140+ fi
141+ }
48142
49- # DT check for entries
50- if dt_has_remoteproc_fw " $FW " ; then
51- log_info " DT indicates $FW is present"
52- else
143+ # Re-check after fixed delay (if gating is enabled)
144+ audio_pm_snapshot_ok () {
145+ # Re-sample the same CHECK_NODES set; if empty, treat as OK.
146+ if [ -z " $CHECK_NODES " ]; then
147+ echo " 1"
148+ return
149+ fi
150+ for n in $CHECK_NODES ; do
151+ st=" $( cat " $n " 2> /dev/null || echo " unknown" ) "
152+ case " $st " in suspended|unsupported) : ;; * ) echo " 0" ; return ;; esac
153+ done
154+ echo " 1"
155+ }
156+
157+ discover_audio_stack_and_snapshot
158+
159+ # --- Check DT presence for ADSP -----------------------------------------------
160+ if ! dt_has_remoteproc_fw " $FW " ; then
53161 log_skip " $TESTNAME SKIP – $FW not described in DT"
54162 echo " $TESTNAME SKIP" > " $RES_FILE "
55163 exit 0
56164fi
165+ log_info " DT indicates $FW is present"
57166
58- # Enumerate ADSP remoteproc entries
59- # get_remoteproc_by_firmware prints: "path|state|firmware|name"
60- entries=" $( get_remoteproc_by_firmware " $FW " " " all) " || entries=" "
167+ # --- Enumerate ADSP remoteproc entries ----------------------------------------
168+ entries=" $( get_remoteproc_by_firmware " $FW " " " all 2> /dev/null) " || entries=" "
61169if [ -z " $entries " ]; then
62170 log_fail " $FW present in DT but no /sys/class/remoteproc entry found"
171+ echo " $TESTNAME FAIL" > " $RES_FILE "
63172 exit 1
64173fi
65174
66- count_instances=$( printf ' %s\n' " $entries " | wc -l)
175+ count_instances=" $( printf ' %s\n' " $entries " | wc -l) "
67176log_info " Found $count_instances $FW instance(s)"
68177
69178inst_fail=0
70179RESULT_LINES=" "
71180
72- tmp_list=" $( mktemp) "
73- printf ' %s\n' " $entries " > " $tmp_list "
74-
181+ # --- Iterate each instance via here-doc ---------------------------------------
75182while IFS=' |' read -r rpath rstate rfirm rname; do
76183 [ -n " $rpath " ] || continue
77-
78184 inst_id=" $( basename " $rpath " ) "
79185 log_info " ---- $inst_id : path=$rpath state=$rstate firmware=$rfirm name=$rname ----"
80186
@@ -83,7 +189,6 @@ while IFS='|' read -r rpath rstate rfirm rname; do
83189 start_res=" NA"
84190 ping_res=" SKIPPED"
85191
86- # Boot check
87192 if [ " $rstate " = " running" ]; then
88193 log_pass " $inst_id : boot check PASS"
89194 else
@@ -95,12 +200,28 @@ while IFS='|' read -r rpath rstate rfirm rname; do
95200 continue
96201 fi
97202
98- # Stop
203+ # ---- Fixed pre-stop delay (always wait PRE_STOP_DELAY seconds) -----------
204+ log_info " $inst_id : waiting ${PRE_STOP_DELAY} s before remoteproc stop (fixed delay)"
205+ [ " $PRE_STOP_DELAY " -gt 0 ] && sleep " $PRE_STOP_DELAY "
206+
207+ # Optional gating: after the fixed delay, ensure PM is OK before stopping
208+ if [ " $FATAL_ON_UNSUSPENDED " -eq 1 ]; then
209+ if [ " $( audio_pm_snapshot_ok) " -ne 1 ]; then
210+ log_fail " Audio not in suspended/unsupported state after ${PRE_STOP_DELAY} s (FATAL_ON_UNSUSPENDED=1); aborting before stop"
211+ echo " $TESTNAME FAIL" > " $RES_FILE "
212+ exit 1
213+ fi
214+ fi
215+
216+ # Helpful dmesg snapshots
217+ dmesg | tail -n 100 > " $test_path /dmesg_before_stop.log"
99218 dump_rproc_logs " $rpath " before-stop
100- t0=$( date +%s)
219+
220+ # ---- Stop ADSP -----------------------------------------------------------
221+ t0=" $( date +%s) "
101222 log_info " $inst_id : stopping"
102223 if stop_remoteproc " $rpath " && wait_remoteproc_state " $rpath " offline " $STOP_TO " " $POLL_I " ; then
103- t1=$( date +%s)
224+ t1=" $( date +%s) "
104225 log_pass " $inst_id : stop PASS ($(( t1 - t0 )) s)"
105226 stop_res=" PASS"
106227 else
@@ -112,14 +233,15 @@ while IFS='|' read -r rpath rstate rfirm rname; do
112233 $inst_id : boot=$boot_res , stop=$stop_res , start=$start_res , ping=$ping_res "
113234 continue
114235 fi
115- dump_rproc_logs " $rpath " after-stop
116236
117- # Start
237+ dump_rproc_logs " $rpath " after-stop
118238 dump_rproc_logs " $rpath " before-start
119- t2=$( date +%s)
239+
240+ # ---- Start ADSP ----------------------------------------------------------
241+ t2=" $( date +%s) "
120242 log_info " $inst_id : starting"
121243 if start_remoteproc " $rpath " && wait_remoteproc_state " $rpath " running " $START_TO " " $POLL_I " ; then
122- t3=$( date +%s)
244+ t3=" $( date +%s) "
123245 log_pass " $inst_id : start PASS ($(( t3 - t2 )) s)"
124246 start_res=" PASS"
125247 else
@@ -131,10 +253,12 @@ while IFS='|' read -r rpath rstate rfirm rname; do
131253 $inst_id : boot=$boot_res , stop=$stop_res , start=$start_res , ping=$ping_res "
132254 continue
133255 fi
256+
134257 dump_rproc_logs " $rpath " after-start
258+ dmesg | tail -n 100 > " $test_path /dmesg_after_restart.log"
135259
136- # Optional RPMsg ping
137- if CTRL_DEV=$( find_rpmsg_ctrl_for " $FW " ) ; then
260+ # ---- Optional RPMsg sanity ping -----------------------------------------
261+ if CTRL_DEV=" $( find_rpmsg_ctrl_for " $FW " ) " ; then
138262 log_info " $inst_id : RPMsg ctrl dev: $CTRL_DEV "
139263 if rpmsg_ping_generic " $CTRL_DEV " ; then
140264 log_pass " $inst_id : rpmsg ping PASS"
@@ -150,11 +274,11 @@ while IFS='|' read -r rpath rstate rfirm rname; do
150274
151275 RESULT_LINES=" $RESULT_LINES
152276 $inst_id : boot=$boot_res , stop=$stop_res , start=$start_res , ping=$ping_res "
277+ done << __RPROC_LIST__
278+ $entries
279+ __RPROC_LIST__
153280
154- done < " $tmp_list "
155- rm -f " $tmp_list "
156-
157- # Summary
281+ # --- Summary ------------------------------------------------------------------
158282log_info " Instance results:$RESULT_LINES "
159283
160284if [ " $inst_fail " -gt 0 ]; then
0 commit comments