1 #!/bin/sh 2 # SPDX-License-Identifier: GPL-2.0 3 # Copyright (C) 2021 Bartosz Golaszewski <brgl@bgdev.pl> 4 5 BASE_DIR=`dirname $0` 6 CONFIGFS_DIR="/sys/kernel/config/gpio-sim" 7 MODULE="gpio-sim" 8 9 fail() { 10 echo "$*" >&2 11 echo "GPIO $MODULE test FAIL" 12 exit 1 13 } 14 15 skip() { 16 echo "$*" >&2 17 echo "GPIO $MODULE test SKIP" 18 exit 4 19 } 20 21 remove_chip() { 22 local CHIP=$1 23 24 for FILE in $CONFIGFS_DIR/$CHIP/*; do 25 BANK=`basename $FILE` 26 if [ "$BANK" = "live" -o "$BANK" = "dev_name" ]; then 27 continue 28 fi 29 30 LINES=`ls $CONFIGFS_DIR/$CHIP/$BANK/ | grep -E ^line` 31 if [ "$?" = 0 ]; then 32 for LINE in $LINES; do 33 if [ -e $CONFIGFS_DIR/$CHIP/$BANK/$LINE/hog ]; then 34 rmdir $CONFIGFS_DIR/$CHIP/$BANK/$LINE/hog || \ 35 fail "Unable to remove the hog" 36 fi 37 38 rmdir $CONFIGFS_DIR/$CHIP/$BANK/$LINE || \ 39 fail "Unable to remove the line" 40 done 41 fi 42 43 rmdir $CONFIGFS_DIR/$CHIP/$BANK 44 done 45 46 rmdir $CONFIGFS_DIR/$CHIP || fail "Unable to remove the chip" 47 } 48 49 configfs_cleanup() { 50 for CHIP in `ls $CONFIGFS_DIR/`; do 51 remove_chip $CHIP 52 done 53 } 54 55 create_chip() { 56 local CHIP=$1 57 58 mkdir $CONFIGFS_DIR/$CHIP 59 } 60 61 create_bank() { 62 local CHIP=$1 63 local BANK=$2 64 65 mkdir $CONFIGFS_DIR/$CHIP/$BANK 66 } 67 68 set_label() { 69 local CHIP=$1 70 local BANK=$2 71 local LABEL=$3 72 73 echo $LABEL > $CONFIGFS_DIR/$CHIP/$BANK/label || fail "Unable to set the chip label" 74 } 75 76 set_num_lines() { 77 local CHIP=$1 78 local BANK=$2 79 local NUM_LINES=$3 80 81 echo $NUM_LINES > $CONFIGFS_DIR/$CHIP/$BANK/num_lines || \ 82 fail "Unable to set the number of lines" 83 } 84 85 set_line_name() { 86 local CHIP=$1 87 local BANK=$2 88 local OFFSET=$3 89 local NAME=$4 90 local LINE_DIR=$CONFIGFS_DIR/$CHIP/$BANK/line$OFFSET 91 92 test -d $LINE_DIR || mkdir $LINE_DIR 93 echo $NAME > $LINE_DIR/name || fail "Unable to set the line name" 94 } 95 96 enable_chip() { 97 local CHIP=$1 98 99 echo 1 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to enable the chip" 100 } 101 102 disable_chip() { 103 local CHIP=$1 104 105 echo 0 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to disable the chip" 106 } 107 108 configfs_chip_name() { 109 local CHIP=$1 110 local BANK=$2 111 112 cat $CONFIGFS_DIR/$CHIP/$BANK/chip_name 2> /dev/null || \ 113 fail "unable to read the chip name from configfs" 114 } 115 116 configfs_dev_name() { 117 local CHIP=$1 118 119 cat $CONFIGFS_DIR/$CHIP/dev_name 2> /dev/null || \ 120 fail "unable to read the device name from configfs" 121 } 122 123 get_chip_num_lines() { 124 local CHIP=$1 125 local BANK=$2 126 127 $BASE_DIR/gpio-chip-info /dev/`configfs_chip_name $CHIP $BANK` num-lines || \ 128 fail "unable to read the number of lines from the character device" 129 } 130 131 get_chip_label() { 132 local CHIP=$1 133 local BANK=$2 134 135 $BASE_DIR/gpio-chip-info /dev/`configfs_chip_name $CHIP $BANK` label || \ 136 fail "unable to read the chip label from the character device" 137 } 138 139 get_line_name() { 140 local CHIP=$1 141 local BANK=$2 142 local OFFSET=$3 143 144 $BASE_DIR/gpio-line-name /dev/`configfs_chip_name $CHIP $BANK` $OFFSET || \ 145 fail "unable to read the line name from the character device" 146 } 147 148 sysfs_set_pull() { 149 local DEV=$1 150 local BANK=$2 151 local OFFSET=$3 152 local PULL=$4 153 local DEVNAME=`configfs_dev_name $DEV` 154 local CHIPNAME=`configfs_chip_name $DEV $BANK` 155 local SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio$OFFSET/pull" 156 157 echo $PULL > $SYSFS_PATH || fail "Unable to set line pull in sysfs" 158 } 159 160 # Load the gpio-sim module. This will pull in configfs if needed too. 161 modprobe gpio-sim || skip "unable to load the gpio-sim module" 162 # Make sure configfs is mounted at /sys/kernel/config. Wait a bit if needed. 163 for IDX in `seq 5`; do 164 if [ "$IDX" -eq "5" ]; then 165 skip "configfs not mounted at /sys/kernel/config" 166 fi 167 168 mountpoint -q /sys/kernel/config && break 169 sleep 0.1 170 done 171 # If the module was already loaded: remove all previous chips 172 configfs_cleanup 173 174 trap "exit 1" SIGTERM SIGINT 175 trap configfs_cleanup EXIT 176 177 echo "1. chip_name and dev_name attributes" 178 179 echo "1.1. Chip name is communicated to user" 180 create_chip chip 181 create_bank chip bank 182 enable_chip chip 183 test -n `cat $CONFIGFS_DIR/chip/bank/chip_name` || fail "chip_name doesn't work" 184 remove_chip chip 185 186 echo "1.2. chip_name returns 'none' if the chip is still pending" 187 create_chip chip 188 create_bank chip bank 189 test "`cat $CONFIGFS_DIR/chip/bank/chip_name`" = "none" || \ 190 fail "chip_name doesn't return 'none' for a pending chip" 191 remove_chip chip 192 193 echo "1.3. Device name is communicated to user" 194 create_chip chip 195 create_bank chip bank 196 enable_chip chip 197 test -n `cat $CONFIGFS_DIR/chip/dev_name` || fail "dev_name doesn't work" 198 remove_chip chip 199 200 echo "2. Creating and configuring simulated chips" 201 202 echo "2.1. Default number of lines is 1" 203 create_chip chip 204 create_bank chip bank 205 enable_chip chip 206 test "`get_chip_num_lines chip bank`" = "1" || fail "default number of lines is not 1" 207 remove_chip chip 208 209 echo "2.2. Number of lines can be specified" 210 create_chip chip 211 create_bank chip bank 212 set_num_lines chip bank 16 213 enable_chip chip 214 test "`get_chip_num_lines chip bank`" = "16" || fail "number of lines is not 16" 215 remove_chip chip 216 217 echo "2.3. Label can be set" 218 create_chip chip 219 create_bank chip bank 220 set_label chip bank foobar 221 enable_chip chip 222 test "`get_chip_label chip bank`" = "foobar" || fail "label is incorrect" 223 remove_chip chip 224 225 echo "2.4. Label can be left empty" 226 create_chip chip 227 create_bank chip bank 228 enable_chip chip 229 test -z "`cat $CONFIGFS_DIR/chip/bank/label`" || fail "label is not empty" 230 remove_chip chip 231 232 echo "2.5. Line names can be configured" 233 create_chip chip 234 create_bank chip bank 235 set_num_lines chip bank 16 236 set_line_name chip bank 0 foo 237 set_line_name chip bank 2 bar 238 enable_chip chip 239 test "`get_line_name chip bank 0`" = "foo" || fail "line name is incorrect" 240 test "`get_line_name chip bank 2`" = "bar" || fail "line name is incorrect" 241 remove_chip chip 242 243 echo "2.6. Line config can remain unused if offset is greater than number of lines" 244 create_chip chip 245 create_bank chip bank 246 set_num_lines chip bank 2 247 set_line_name chip bank 5 foobar 248 enable_chip chip 249 test "`get_line_name chip bank 0`" = "" || fail "line name is incorrect" 250 test "`get_line_name chip bank 1`" = "" || fail "line name is incorrect" 251 remove_chip chip 252 253 echo "2.7. Line configfs directory names are sanitized" 254 create_chip chip 255 create_bank chip bank 256 mkdir $CONFIGFS_DIR/chip/bank/line12foobar 2> /dev/null && \ 257 fail "invalid configfs line name accepted" 258 mkdir $CONFIGFS_DIR/chip/bank/line_no_offset 2> /dev/null && \ 259 fail "invalid configfs line name accepted" 260 remove_chip chip 261 262 echo "2.8. Multiple chips can be created" 263 CHIPS="chip0 chip1 chip2" 264 for CHIP in $CHIPS; do 265 create_chip $CHIP 266 create_bank $CHIP bank 267 enable_chip $CHIP 268 done 269 for CHIP in $CHIPS; do 270 remove_chip $CHIP 271 done 272 273 echo "2.9. Can't modify settings when chip is live" 274 create_chip chip 275 create_bank chip bank 276 enable_chip chip 277 echo foobar > $CONFIGFS_DIR/chip/bank/label 2> /dev/null && \ 278 fail "Setting label of a live chip should fail" 279 echo 8 > $CONFIGFS_DIR/chip/bank/num_lines 2> /dev/null && \ 280 fail "Setting number of lines of a live chip should fail" 281 remove_chip chip 282 283 echo "2.10. Can't create line items when chip is live" 284 create_chip chip 285 create_bank chip bank 286 enable_chip chip 287 mkdir $CONFIGFS_DIR/chip/bank/line0 2> /dev/null && fail "Creating line item should fail" 288 remove_chip chip 289 290 echo "2.11. Probe errors are propagated to user-space" 291 create_chip chip 292 create_bank chip bank 293 set_num_lines chip bank 99999 294 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Probe error was not propagated" 295 remove_chip chip 296 297 echo "2.12. Cannot enable a chip without any GPIO banks" 298 create_chip chip 299 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Chip enabled without any GPIO banks" 300 remove_chip chip 301 302 echo "2.13. Duplicate chip labels are not allowed" 303 create_chip chip 304 create_bank chip bank0 305 set_label chip bank0 foobar 306 create_bank chip bank1 307 set_label chip bank1 foobar 308 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Duplicate chip labels were not rejected" 309 remove_chip chip 310 311 echo "2.14. Lines can be hogged" 312 create_chip chip 313 create_bank chip bank 314 set_num_lines chip bank 8 315 mkdir -p $CONFIGFS_DIR/chip/bank/line4/hog 316 enable_chip chip 317 $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 4 2> /dev/null && \ 318 fail "Setting the value of a hogged line shouldn't succeed" 319 remove_chip chip 320 321 echo "3. Controlling simulated chips" 322 323 echo "3.1. Pull can be set over sysfs" 324 create_chip chip 325 create_bank chip bank 326 set_num_lines chip bank 8 327 enable_chip chip 328 sysfs_set_pull chip bank 0 pull-up 329 $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 0 330 test "$?" = "1" || fail "pull set incorrectly" 331 sysfs_set_pull chip bank 0 pull-down 332 $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 1 333 test "$?" = "0" || fail "pull set incorrectly" 334 remove_chip chip 335 336 echo "3.2. Pull can be read from sysfs" 337 create_chip chip 338 create_bank chip bank 339 set_num_lines chip bank 8 340 enable_chip chip 341 DEVNAME=`configfs_dev_name chip` 342 CHIPNAME=`configfs_chip_name chip bank` 343 SYSFS_PATH=/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull 344 test `cat $SYSFS_PATH` = "pull-down" || fail "reading the pull failed" 345 sysfs_set_pull chip bank 0 pull-up 346 test `cat $SYSFS_PATH` = "pull-up" || fail "reading the pull failed" 347 remove_chip chip 348 349 echo "3.3. Incorrect input in sysfs is rejected" 350 create_chip chip 351 create_bank chip bank 352 set_num_lines chip bank 8 353 enable_chip chip 354 DEVNAME=`configfs_dev_name chip` 355 CHIPNAME=`configfs_chip_name chip bank` 356 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull" 357 echo foobar > $SYSFS_PATH 2> /dev/null && fail "invalid input not detected" 358 remove_chip chip 359 360 echo "3.4. Can't write to value" 361 create_chip chip 362 create_bank chip bank 363 enable_chip chip 364 DEVNAME=`configfs_dev_name chip` 365 CHIPNAME=`configfs_chip_name chip bank` 366 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" 367 echo 1 > $SYSFS_PATH 2> /dev/null && fail "writing to 'value' succeeded unexpectedly" 368 remove_chip chip 369 370 echo "4. Simulated GPIO chips are functional" 371 372 echo "4.1. Values can be read from sysfs" 373 create_chip chip 374 create_bank chip bank 375 set_num_lines chip bank 8 376 enable_chip chip 377 DEVNAME=`configfs_dev_name chip` 378 CHIPNAME=`configfs_chip_name chip bank` 379 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" 380 test `cat $SYSFS_PATH` = "0" || fail "incorrect value read from sysfs" 381 $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 0 & 382 sleep 0.1 # FIXME Any better way? 383 test `cat $SYSFS_PATH` = "1" || fail "incorrect value read from sysfs" 384 kill $! 385 remove_chip chip 386 387 echo "4.2. Bias settings work correctly" 388 create_chip chip 389 create_bank chip bank 390 set_num_lines chip bank 8 391 enable_chip chip 392 DEVNAME=`configfs_dev_name chip` 393 CHIPNAME=`configfs_chip_name chip bank` 394 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value" 395 $BASE_DIR/gpio-mockup-cdev -b pull-up /dev/`configfs_chip_name chip bank` 0 396 test `cat $SYSFS_PATH` = "1" || fail "bias setting does not work" 397 remove_chip chip 398 399 echo "GPIO $MODULE test PASS"
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.