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