Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / tools / testing / selftests / gpio / gpio-mockup.sh
blobfc2dd4c24d069fb359319f01f6c58def5a614408
1 #!/bin/bash -efu
2 # SPDX-License-Identifier: GPL-2.0
4 #exit status
5 #0: success
6 #1: fail
7 #4: skip test - including run as non-root user
9 BASE=${0%/*}
10 DEBUGFS=
11 GPIO_DEBUGFS=
12 dev_type="cdev"
13 module="gpio-mockup"
14 verbose=
15 full_test=
16 random=
17 uapi_opt=
18 active_opt=
19 bias_opt=
20 line_set_pid=
22 # Kselftest return codes
23 ksft_fail=1
24 ksft_skip=4
26 usage()
28 echo "Usage:"
29 echo "$0 [-frv] [-t type]"
30 echo "-f: full test (minimal set run by default)"
31 echo "-r: test random lines as well as fence posts"
32 echo "-t: interface type:"
33 echo " cdev (character device ABI) - default"
34 echo " cdev_v1 (deprecated character device ABI)"
35 echo " sysfs (deprecated SYSFS ABI)"
36 echo "-v: verbose progress reporting"
37 exit $ksft_fail
40 skip()
42 echo "$*" >&2
43 echo "GPIO $module test SKIP"
44 exit $ksft_skip
47 prerequisite()
49 [ $(id -u) -eq 0 ] || skip "must be run as root"
51 DEBUGFS=$(grep -w debugfs /proc/mounts | cut -f2 -d' ')
52 [ -d "$DEBUGFS" ] || skip "debugfs is not mounted"
54 GPIO_DEBUGFS=$DEBUGFS/$module
57 remove_module()
59 modprobe -r -q $module
62 cleanup()
64 set +e
65 release_line
66 remove_module
67 jobs -p | xargs -r kill > /dev/null 2>&1
70 fail()
72 echo "test failed: $*" >&2
73 echo "GPIO $module test FAIL"
74 exit $ksft_fail
77 try_insert_module()
79 modprobe -q $module "$1" || fail "insert $module failed with error $?"
82 log()
84 [ -z "$verbose" ] || echo "$*"
87 # The following line helpers, release_Line, get_line and set_line, all
88 # make use of the global $chip and $offset variables.
90 # This implementation drives the GPIO character device (cdev) uAPI.
91 # Other implementations may override these to test different uAPIs.
93 # Release any resources related to the line
94 release_line()
96 [ "$line_set_pid" ] && kill $line_set_pid && wait $line_set_pid || true
97 line_set_pid=
100 # Read the current value of the line
101 get_line()
103 release_line
105 local cdev_opts=${uapi_opt}${active_opt}
106 $BASE/gpio-mockup-cdev $cdev_opts /dev/$chip $offset
107 echo $?
110 # Set the state of the line
112 # Changes to line configuration are provided as parameters.
113 # The line is assumed to be an output if the line value 0 or 1 is
114 # specified, else an input.
115 set_line()
117 local val=
119 release_line
121 # parse config options...
122 for option in $*; do
123 case $option in
124 active-low)
125 active_opt="-l "
127 active-high)
128 active_opt=
130 bias-none)
131 bias_opt=
133 pull-down)
134 bias_opt="-bpull-down "
136 pull-up)
137 bias_opt="-bpull-up "
140 val=0
143 val=1
145 esac
146 done
148 local cdev_opts=${uapi_opt}${active_opt}
149 if [ "$val" ]; then
150 $BASE/gpio-mockup-cdev $cdev_opts -s$val /dev/$chip $offset &
151 # failure to set is detected by reading mockup and toggling values
152 line_set_pid=$!
153 # allow for gpio-mockup-cdev to launch and request line
154 # (there is limited value in checking if line has been requested)
155 sleep 0.01
156 elif [ "$bias_opt" ]; then
157 cdev_opts=${cdev_opts}${bias_opt}
158 $BASE/gpio-mockup-cdev $cdev_opts /dev/$chip $offset || true
162 assert_line()
164 local val
165 # don't need any retry here as set_mock allows for propagation
166 val=$(get_line)
167 [ "$val" = "$1" ] || fail "line value is ${val:-empty} when $1 was expected"
170 # The following mockup helpers all make use of the $mock_line
171 assert_mock()
173 local backoff_wait=10
174 local retry=0
175 local val
176 # retry allows for set propagation from uAPI to mockup
177 while true; do
178 val=$(< $mock_line)
179 [ "$val" = "$1" ] && break
180 retry=$((retry + 1))
181 [ $retry -lt 5 ] || fail "mockup $mock_line value ${val:-empty} when $1 expected"
182 sleep $(printf "%0.2f" $((backoff_wait))e-3)
183 backoff_wait=$((backoff_wait * 2))
184 done
187 set_mock()
189 echo "$1" > $mock_line
190 # allow for set propagation - so we won't be in a race with set_line
191 assert_mock "$1"
194 # test the functionality of a line
196 # The line is set from the mockup side and is read from the userspace side
197 # (input), and is set from the userspace side and is read from the mockup side
198 # (output).
200 # Setting the mockup pull using the userspace interface bias settings is
201 # tested where supported by the userspace interface (cdev).
202 test_line()
204 chip=$1
205 offset=$2
206 log "test_line $chip $offset"
207 mock_line=$GPIO_DEBUGFS/$chip/$offset
208 [ -e "$mock_line" ] || fail "missing line $chip:$offset"
210 # test input active-high
211 set_mock 1
212 set_line input active-high
213 assert_line 1
214 set_mock 0
215 assert_line 0
216 set_mock 1
217 assert_line 1
219 if [ "$full_test" ]; then
220 if [ "$dev_type" != "sysfs" ]; then
221 # test pulls
222 set_mock 0
223 set_line input pull-up
224 assert_line 1
225 set_mock 0
226 assert_line 0
228 set_mock 1
229 set_line input pull-down
230 assert_line 0
231 set_mock 1
232 assert_line 1
234 set_line bias-none
237 # test input active-low
238 set_mock 0
239 set_line active-low
240 assert_line 1
241 set_mock 1
242 assert_line 0
243 set_mock 0
244 assert_line 1
246 # test output active-high
247 set_mock 1
248 set_line active-high 0
249 assert_mock 0
250 set_line 1
251 assert_mock 1
252 set_line 0
253 assert_mock 0
256 # test output active-low
257 set_mock 0
258 set_line active-low 0
259 assert_mock 1
260 set_line 1
261 assert_mock 0
262 set_line 0
263 assert_mock 1
265 release_line
268 test_no_line()
270 log test_no_line "$*"
271 [ ! -e "$GPIO_DEBUGFS/$1/$2" ] || fail "unexpected line $1:$2"
274 # Load the module and check that the expected number of gpiochips, with the
275 # expected number of lines, are created and are functional.
277 # $1 is the gpio_mockup_ranges parameter for the module
278 # The remaining parameters are the number of lines, n, expected for each of
279 # the gpiochips expected to be created.
281 # For each gpiochip the fence post lines, 0 and n-1, are tested, and the
282 # line on the far side of the fence post, n, is tested to not exist.
284 # If the $random flag is set then a random line in the middle of the
285 # gpiochip is tested as well.
286 insmod_test()
288 local ranges=
289 local gc=
290 local width=
292 [ "${1:-}" ] || fail "missing ranges"
293 ranges=$1 ; shift
294 try_insert_module "gpio_mockup_ranges=$ranges"
295 log "GPIO $module test with ranges: <$ranges>:"
296 # e.g. /sys/kernel/debug/gpio-mockup/gpiochip1
297 gpiochip=$(find "$DEBUGFS/$module/" -name gpiochip* -type d | sort)
298 for chip in $gpiochip; do
299 gc=${chip##*/}
300 [ "${1:-}" ] || fail "unexpected chip - $gc"
301 width=$1 ; shift
302 test_line $gc 0
303 if [ "$random" -a $width -gt 2 ]; then
304 test_line $gc $((RANDOM % ($width - 2) + 1))
306 test_line $gc $(($width - 1))
307 test_no_line $gc $width
308 done
309 [ "${1:-}" ] && fail "missing expected chip of width $1"
310 remove_module || fail "failed to remove module with error $?"
313 while getopts ":frvt:" opt; do
314 case $opt in
316 full_test=true
319 random=true
322 dev_type=$OPTARG
325 verbose=true
328 usage
330 esac
331 done
332 shift $((OPTIND - 1))
334 [ "${1:-}" ] && fail "unknown argument '$1'"
336 prerequisite
338 trap 'exit $ksft_fail' SIGTERM SIGINT
339 trap cleanup EXIT
341 case "$dev_type" in
342 sysfs)
343 source $BASE/gpio-mockup-sysfs.sh
344 echo "WARNING: gpio sysfs ABI is deprecated."
346 cdev_v1)
347 echo "WARNING: gpio cdev ABI v1 is deprecated."
348 uapi_opt="-u1 "
350 cdev)
353 fail "unknown interface type: $dev_type"
355 esac
357 remove_module || fail "can't remove existing $module module"
359 # manual gpio allocation tests fail if a physical chip already exists
360 [ "$full_test" -a -e "/dev/gpiochip0" ] && skip "full tests conflict with gpiochip0"
362 echo "1. Module load tests"
363 echo "1.1. dynamic allocation of gpio"
364 insmod_test "-1,32" 32
365 insmod_test "-1,23,-1,32" 23 32
366 insmod_test "-1,23,-1,26,-1,32" 23 26 32
367 if [ "$full_test" ]; then
368 echo "1.2. manual allocation of gpio"
369 insmod_test "0,32" 32
370 insmod_test "0,32,32,60" 32 28
371 insmod_test "0,32,40,64,64,96" 32 24 32
372 echo "1.3. dynamic and manual allocation of gpio"
373 insmod_test "-1,32,32,62" 32 30
374 insmod_test "-1,22,-1,23,0,24,32,64" 22 23 24 32
375 insmod_test "-1,32,32,60,-1,29" 32 28 29
376 insmod_test "-1,32,40,64,-1,5" 32 24 5
377 insmod_test "0,32,32,44,-1,22,-1,31" 32 12 22 31
379 echo "2. Module load error tests"
380 echo "2.1 no lines defined"
381 insmod_test "0,0"
382 if [ "$full_test" ]; then
383 echo "2.2 ignore range overlap"
384 insmod_test "0,32,0,1" 32
385 insmod_test "0,32,1,5" 32
386 insmod_test "0,32,30,35" 32
387 insmod_test "0,32,31,32" 32
388 insmod_test "10,32,30,35" 22
389 insmod_test "10,32,9,14" 22
390 insmod_test "0,32,20,21,40,56" 32 16
391 insmod_test "0,32,32,64,32,40" 32 32
392 insmod_test "0,32,32,64,36,37" 32 32
393 insmod_test "0,32,35,64,34,36" 32 29
394 insmod_test "0,30,35,64,35,45" 30 29
395 insmod_test "0,32,40,56,30,33" 32 16
396 insmod_test "0,32,40,56,30,41" 32 16
397 insmod_test "0,32,40,56,39,45" 32 16
400 echo "GPIO $module test PASS"