xref: /linux/tools/testing/selftests/cpufreq/cpufreq.sh (revision 2d2435e1c843ced85e55885282c866208ff9f676)
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# protect against multiple inclusion
5if [ $FILE_CPUFREQ ]; then
6	return 0
7else
8	FILE_CPUFREQ=DONE
9fi
10
11source cpu.sh
12
13
14# $1: cpu
15cpu_should_have_cpufreq_directory()
16{
17	if [ ! -d $CPUROOT/$1/cpufreq ]; then
18		printf "Warning: No cpufreq directory present for $1\n"
19	fi
20}
21
22cpu_should_not_have_cpufreq_directory()
23{
24	if [ -d $CPUROOT/$1/cpufreq ]; then
25		printf "Warning: cpufreq directory present for $1\n"
26	fi
27}
28
29for_each_policy()
30{
31	policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
32	for policy in $policies; do
33		$@ $policy
34	done
35}
36
37for_each_policy_concurrent()
38{
39	policies=$(ls $CPUFREQROOT| grep "policy[0-9].*")
40	for policy in $policies; do
41		$@ $policy &
42	done
43}
44
45# $1: Path
46read_cpufreq_files_in_dir()
47{
48	local files=`ls $1`
49
50	printf "Printing directory: $1\n\n"
51
52	for file in $files; do
53		if [ -f $1/$file ]; then
54			printf "$file:"
55			#file is readable ?
56			local rfile=$(ls -l $1/$file | awk '$1 ~ /^.*r.*/ { print $NF; }')
57
58			if [ ! -z $rfile ]; then
59				cat $1/$file
60			else
61				printf "$file is not readable\n"
62			fi
63		else
64			printf "\n"
65			read_cpufreq_files_in_dir "$1/$file"
66		fi
67	done
68	printf "\n"
69}
70
71
72read_all_cpufreq_files()
73{
74	printf "** Test: Running ${FUNCNAME[0]} **\n\n"
75
76	read_cpufreq_files_in_dir $CPUFREQROOT
77
78	printf "%s\n\n" "------------------------------------------------"
79}
80
81
82# UPDATE CPUFREQ FILES
83
84# $1: directory path
85update_cpufreq_files_in_dir()
86{
87	local files=`ls $1`
88
89	printf "Updating directory: $1\n\n"
90
91	for file in $files; do
92		if [ -f $1/$file ]; then
93			# file is readable and writable ?
94			local rwfile=$(ls -l $1/$file | awk '$1 ~ /^.*rw.*/ { print $NF; }')
95
96			if [ ! -z $rwfile ]; then
97				# scaling_setspeed is a special file and we
98				# should skip updating it
99				if [ $file != "scaling_setspeed" ]; then
100					local val=$(cat $1/$file)
101					printf "Writing $val to: $file\n"
102					echo $val > $1/$file
103				fi
104			fi
105		else
106			printf "\n"
107			update_cpufreq_files_in_dir "$1/$file"
108		fi
109	done
110
111	printf "\n"
112}
113
114# Update all writable files with their existing values
115update_all_cpufreq_files()
116{
117	printf "** Test: Running ${FUNCNAME[0]} **\n\n"
118
119	update_cpufreq_files_in_dir $CPUFREQROOT
120
121	printf "%s\n\n" "------------------------------------------------"
122}
123
124
125# CHANGE CPU FREQUENCIES
126
127# $1: policy
128find_current_freq()
129{
130	cat $CPUFREQROOT/$1/scaling_cur_freq
131}
132
133# $1: policy
134# $2: frequency
135set_cpu_frequency()
136{
137	printf "Change frequency for $1 to $2\n"
138	echo $2 > $CPUFREQROOT/$1/scaling_setspeed
139}
140
141# $1: policy
142test_all_frequencies()
143{
144	local filepath="$CPUFREQROOT/$1"
145
146	backup_governor $1
147
148	local found=$(switch_governor $1 "userspace")
149	if [ $found = 1 ]; then
150		printf "${FUNCNAME[0]}: userspace governor not available for: $1\n"
151		return;
152	fi
153
154	printf "Switched governor for $1 to userspace\n\n"
155
156	local freqs=$(cat $filepath/scaling_available_frequencies)
157	printf "Available frequencies for $1: $freqs\n\n"
158
159	# Set all frequencies one-by-one
160	for freq in $freqs; do
161		set_cpu_frequency $1 $freq
162	done
163
164	printf "\n"
165
166	restore_governor $1
167}
168
169# $1: loop count
170shuffle_frequency_for_all_cpus()
171{
172	printf "** Test: Running ${FUNCNAME[0]} for $1 loops **\n\n"
173
174	for i in `seq 1 $1`; do
175		for_each_policy test_all_frequencies
176	done
177	printf "\n%s\n\n" "------------------------------------------------"
178}
179
180# Basic cpufreq tests
181cpufreq_basic_tests()
182{
183	printf "*** RUNNING CPUFREQ SANITY TESTS ***\n"
184	printf "====================================\n\n"
185
186	count=$(count_cpufreq_managed_cpus)
187	if [ $count = 0 ]; then
188		ktap_exit_fail_msg "No cpu is managed by cpufreq core, exiting\n"
189	else
190		printf "CPUFreq manages: $count CPUs\n\n"
191	fi
192
193	# Detect & print which CPUs are not managed by cpufreq
194	print_unmanaged_cpus
195
196	# read/update all cpufreq files
197	read_all_cpufreq_files
198	update_all_cpufreq_files
199
200	# hotplug cpus
201	reboot_cpus 5
202
203	# Test all frequencies
204	shuffle_frequency_for_all_cpus 2
205
206	# Test all governors
207	shuffle_governors_for_all_cpus 1
208}
209
210# Suspend/resume
211# $1: "suspend" or "hibernate", $2: loop count
212do_suspend()
213{
214	printf "** Test: Running ${FUNCNAME[0]}: Trying $1 for $2 loops **\n\n"
215
216	# Is the directory available
217	if [ ! -d $SYSFS/power/ -o ! -f $SYSFS/power/state ]; then
218		printf "$SYSFS/power/state not available\n"
219		return 1
220	fi
221
222	if [ $1 = "suspend" ]; then
223		filename="mem"
224	elif [ $1 = "hibernate" ]; then
225		filename="disk"
226	else
227		printf "$1 is not a valid option\n"
228		return 1
229	fi
230
231	if [ -n $filename ]; then
232		present=$(cat $SYSFS/power/state | grep $filename)
233
234		if [ -z "$present" ]; then
235			printf "Tried to $1 but $filename isn't present in $SYSFS/power/state\n"
236			return 1;
237		fi
238
239		for i in `seq 1 $2`; do
240			printf "Starting $1\n"
241
242			if [ "$3" = "rtc" ]; then
243				if ! command -v rtcwake &> /dev/null; then
244					printf "rtcwake could not be found, please install it.\n"
245					return 1
246				fi
247
248				rtcwake -m $filename -s 15
249
250				if [ $? -ne 0 ]; then
251					printf "Failed to suspend using RTC wake alarm\n"
252					return 1
253				fi
254			else
255				echo $filename > $SYSFS/power/state
256			fi
257
258			printf "Came out of $1\n"
259
260			printf "Do basic tests after finishing $1 to verify cpufreq state\n\n"
261			cpufreq_basic_tests
262		done
263	fi
264}
265