Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/sh
0002 # SPDX-License-Identifier: GPL-2.0
0003 # Copyright (C) 2021 Bartosz Golaszewski <brgl@bgdev.pl>
0004 
0005 BASE_DIR=`dirname $0`
0006 CONFIGFS_DIR="/sys/kernel/config/gpio-sim"
0007 MODULE="gpio-sim"
0008 
0009 fail() {
0010         echo "$*" >&2
0011         echo "GPIO $MODULE test FAIL"
0012         exit 1
0013 }
0014 
0015 skip() {
0016         echo "$*" >&2
0017         echo "GPIO $MODULE test SKIP"
0018         exit 4
0019 }
0020 
0021 remove_chip() {
0022         local CHIP=$1
0023 
0024         for FILE in $CONFIGFS_DIR/$CHIP/*; do
0025                 BANK=`basename $FILE`
0026                 if [ "$BANK" = "live" -o "$BANK" = "dev_name" ]; then
0027                         continue
0028                 fi
0029 
0030                 LINES=`ls $CONFIGFS_DIR/$CHIP/$BANK/ | egrep ^line`
0031                 if [ "$?" = 0 ]; then
0032                         for LINE in $LINES; do
0033                                 if [ -e $CONFIGFS_DIR/$CHIP/$BANK/$LINE/hog ]; then
0034                                         rmdir $CONFIGFS_DIR/$CHIP/$BANK/$LINE/hog || \
0035                                                 fail "Unable to remove the hog"
0036                                 fi
0037 
0038                                 rmdir $CONFIGFS_DIR/$CHIP/$BANK/$LINE || \
0039                                         fail "Unable to remove the line"
0040                         done
0041                 fi
0042 
0043                 rmdir $CONFIGFS_DIR/$CHIP/$BANK
0044         done
0045 
0046         rmdir $CONFIGFS_DIR/$CHIP || fail "Unable to remove the chip"
0047 }
0048 
0049 configfs_cleanup() {
0050         for CHIP in `ls $CONFIGFS_DIR/`; do
0051                 remove_chip $CHIP
0052         done
0053 }
0054 
0055 create_chip() {
0056         local CHIP=$1
0057 
0058         mkdir $CONFIGFS_DIR/$CHIP
0059 }
0060 
0061 create_bank() {
0062         local CHIP=$1
0063         local BANK=$2
0064 
0065         mkdir $CONFIGFS_DIR/$CHIP/$BANK
0066 }
0067 
0068 set_label() {
0069         local CHIP=$1
0070         local BANK=$2
0071         local LABEL=$3
0072 
0073         echo $LABEL > $CONFIGFS_DIR/$CHIP/$BANK/label || fail "Unable to set the chip label"
0074 }
0075 
0076 set_num_lines() {
0077         local CHIP=$1
0078         local BANK=$2
0079         local NUM_LINES=$3
0080 
0081         echo $NUM_LINES > $CONFIGFS_DIR/$CHIP/$BANK/num_lines || \
0082                 fail "Unable to set the number of lines"
0083 }
0084 
0085 set_line_name() {
0086         local CHIP=$1
0087         local BANK=$2
0088         local OFFSET=$3
0089         local NAME=$4
0090         local LINE_DIR=$CONFIGFS_DIR/$CHIP/$BANK/line$OFFSET
0091 
0092         test -d $LINE_DIR || mkdir $LINE_DIR
0093         echo $NAME > $LINE_DIR/name || fail "Unable to set the line name"
0094 }
0095 
0096 enable_chip() {
0097         local CHIP=$1
0098 
0099         echo 1 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to enable the chip"
0100 }
0101 
0102 disable_chip() {
0103         local CHIP=$1
0104 
0105         echo 0 > $CONFIGFS_DIR/$CHIP/live || fail "Unable to disable the chip"
0106 }
0107 
0108 configfs_chip_name() {
0109         local CHIP=$1
0110         local BANK=$2
0111 
0112         cat $CONFIGFS_DIR/$CHIP/$BANK/chip_name 2> /dev/null || \
0113                 fail "unable to read the chip name from configfs"
0114 }
0115 
0116 configfs_dev_name() {
0117         local CHIP=$1
0118 
0119         cat $CONFIGFS_DIR/$CHIP/dev_name 2> /dev/null || \
0120                 fail "unable to read the device name from configfs"
0121 }
0122 
0123 get_chip_num_lines() {
0124         local CHIP=$1
0125         local BANK=$2
0126 
0127         $BASE_DIR/gpio-chip-info /dev/`configfs_chip_name $CHIP $BANK` num-lines || \
0128                 fail "unable to read the number of lines from the character device"
0129 }
0130 
0131 get_chip_label() {
0132         local CHIP=$1
0133         local BANK=$2
0134 
0135         $BASE_DIR/gpio-chip-info /dev/`configfs_chip_name $CHIP $BANK` label || \
0136                 fail "unable to read the chip label from the character device"
0137 }
0138 
0139 get_line_name() {
0140         local CHIP=$1
0141         local BANK=$2
0142         local OFFSET=$3
0143 
0144         $BASE_DIR/gpio-line-name /dev/`configfs_chip_name $CHIP $BANK` $OFFSET || \
0145                 fail "unable to read the line name from the character device"
0146 }
0147 
0148 sysfs_set_pull() {
0149         local DEV=$1
0150         local BANK=$2
0151         local OFFSET=$3
0152         local PULL=$4
0153         local DEVNAME=`configfs_dev_name $DEV`
0154         local CHIPNAME=`configfs_chip_name $DEV $BANK`
0155         local SYSFSPATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio$OFFSET/pull"
0156 
0157         echo $PULL > $SYSFSPATH || fail "Unable to set line pull in sysfs"
0158 }
0159 
0160 # Load the gpio-sim module. This will pull in configfs if needed too.
0161 modprobe gpio-sim || skip "unable to load the gpio-sim module"
0162 # Make sure configfs is mounted at /sys/kernel/config. Wait a bit if needed.
0163 for IDX in `seq 5`; do
0164         if [ "$IDX" -eq "5" ]; then
0165                 skip "configfs not mounted at /sys/kernel/config"
0166         fi
0167 
0168         mountpoint -q /sys/kernel/config && break
0169         sleep 0.1
0170 done
0171 # If the module was already loaded: remove all previous chips
0172 configfs_cleanup
0173 
0174 trap "exit 1" SIGTERM SIGINT
0175 trap configfs_cleanup EXIT
0176 
0177 echo "1. chip_name and dev_name attributes"
0178 
0179 echo "1.1. Chip name is communicated to user"
0180 create_chip chip
0181 create_bank chip bank
0182 enable_chip chip
0183 test -n `cat $CONFIGFS_DIR/chip/bank/chip_name` || fail "chip_name doesn't work"
0184 remove_chip chip
0185 
0186 echo "1.2. chip_name returns 'none' if the chip is still pending"
0187 create_chip chip
0188 create_bank chip bank
0189 test "`cat $CONFIGFS_DIR/chip/bank/chip_name`" = "none" || \
0190         fail "chip_name doesn't return 'none' for a pending chip"
0191 remove_chip chip
0192 
0193 echo "1.3. Device name is communicated to user"
0194 create_chip chip
0195 create_bank chip bank
0196 enable_chip chip
0197 test -n `cat $CONFIGFS_DIR/chip/dev_name` || fail "dev_name doesn't work"
0198 remove_chip chip
0199 
0200 echo "2. Creating and configuring simulated chips"
0201 
0202 echo "2.1. Default number of lines is 1"
0203 create_chip chip
0204 create_bank chip bank
0205 enable_chip chip
0206 test "`get_chip_num_lines chip bank`" = "1" || fail "default number of lines is not 1"
0207 remove_chip chip
0208 
0209 echo "2.2. Number of lines can be specified"
0210 create_chip chip
0211 create_bank chip bank
0212 set_num_lines chip bank 16
0213 enable_chip chip
0214 test "`get_chip_num_lines chip bank`" = "16" || fail "number of lines is not 16"
0215 remove_chip chip
0216 
0217 echo "2.3. Label can be set"
0218 create_chip chip
0219 create_bank chip bank
0220 set_label chip bank foobar
0221 enable_chip chip
0222 test "`get_chip_label chip bank`" = "foobar" || fail "label is incorrect"
0223 remove_chip chip
0224 
0225 echo "2.4. Label can be left empty"
0226 create_chip chip
0227 create_bank chip bank
0228 enable_chip chip
0229 test -z "`cat $CONFIGFS_DIR/chip/bank/label`" || fail "label is not empty"
0230 remove_chip chip
0231 
0232 echo "2.5. Line names can be configured"
0233 create_chip chip
0234 create_bank chip bank
0235 set_num_lines chip bank 16
0236 set_line_name chip bank 0 foo
0237 set_line_name chip bank 2 bar
0238 enable_chip chip
0239 test "`get_line_name chip bank 0`" = "foo" || fail "line name is incorrect"
0240 test "`get_line_name chip bank 2`" = "bar" || fail "line name is incorrect"
0241 remove_chip chip
0242 
0243 echo "2.6. Line config can remain unused if offset is greater than number of lines"
0244 create_chip chip
0245 create_bank chip bank
0246 set_num_lines chip bank 2
0247 set_line_name chip bank 5 foobar
0248 enable_chip chip
0249 test "`get_line_name chip bank 0`" = "" || fail "line name is incorrect"
0250 test "`get_line_name chip bank 1`" = "" || fail "line name is incorrect"
0251 remove_chip chip
0252 
0253 echo "2.7. Line configfs directory names are sanitized"
0254 create_chip chip
0255 create_bank chip bank
0256 mkdir $CONFIGFS_DIR/chip/bank/line12foobar 2> /dev/null && \
0257         fail "invalid configfs line name accepted"
0258 mkdir $CONFIGFS_DIR/chip/bank/line_no_offset 2> /dev/null && \
0259         fail "invalid configfs line name accepted"
0260 remove_chip chip
0261 
0262 echo "2.8. Multiple chips can be created"
0263 CHIPS="chip0 chip1 chip2"
0264 for CHIP in $CHIPS; do
0265         create_chip $CHIP
0266         create_bank $CHIP bank
0267         enable_chip $CHIP
0268 done
0269 for CHIP in $CHIPS; do
0270         remove_chip $CHIP
0271 done
0272 
0273 echo "2.9. Can't modify settings when chip is live"
0274 create_chip chip
0275 create_bank chip bank
0276 enable_chip chip
0277 echo foobar > $CONFIGFS_DIR/chip/bank/label 2> /dev/null && \
0278         fail "Setting label of a live chip should fail"
0279 echo 8 > $CONFIGFS_DIR/chip/bank/num_lines 2> /dev/null && \
0280         fail "Setting number of lines of a live chip should fail"
0281 remove_chip chip
0282 
0283 echo "2.10. Can't create line items when chip is live"
0284 create_chip chip
0285 create_bank chip bank
0286 enable_chip chip
0287 mkdir $CONFIGFS_DIR/chip/bank/line0 2> /dev/null && fail "Creating line item should fail"
0288 remove_chip chip
0289 
0290 echo "2.11. Probe errors are propagated to user-space"
0291 create_chip chip
0292 create_bank chip bank
0293 set_num_lines chip bank 99999
0294 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Probe error was not propagated"
0295 remove_chip chip
0296 
0297 echo "2.12. Cannot enable a chip without any GPIO banks"
0298 create_chip chip
0299 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Chip enabled without any GPIO banks"
0300 remove_chip chip
0301 
0302 echo "2.13. Duplicate chip labels are not allowed"
0303 create_chip chip
0304 create_bank chip bank0
0305 set_label chip bank0 foobar
0306 create_bank chip bank1
0307 set_label chip bank1 foobar
0308 echo 1 > $CONFIGFS_DIR/chip/live 2> /dev/null && fail "Duplicate chip labels were not rejected"
0309 remove_chip chip
0310 
0311 echo "2.14. Lines can be hogged"
0312 create_chip chip
0313 create_bank chip bank
0314 set_num_lines chip bank 8
0315 mkdir -p $CONFIGFS_DIR/chip/bank/line4/hog
0316 enable_chip chip
0317 $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 4 2> /dev/null && \
0318         fail "Setting the value of a hogged line shouldn't succeed"
0319 remove_chip chip
0320 
0321 echo "3. Controlling simulated chips"
0322 
0323 echo "3.1. Pull can be set over sysfs"
0324 create_chip chip
0325 create_bank chip bank
0326 set_num_lines chip bank 8
0327 enable_chip chip
0328 sysfs_set_pull chip bank 0 pull-up
0329 $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 0
0330 test "$?" = "1" || fail "pull set incorrectly"
0331 sysfs_set_pull chip bank 0 pull-down
0332 $BASE_DIR/gpio-mockup-cdev /dev/`configfs_chip_name chip bank` 1
0333 test "$?" = "0" || fail "pull set incorrectly"
0334 remove_chip chip
0335 
0336 echo "3.2. Pull can be read from sysfs"
0337 create_chip chip
0338 create_bank chip bank
0339 set_num_lines chip bank 8
0340 enable_chip chip
0341 DEVNAME=`configfs_dev_name chip`
0342 CHIPNAME=`configfs_chip_name chip bank`
0343 SYSFS_PATH=/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull
0344 test `cat $SYSFS_PATH` = "pull-down" || fail "reading the pull failed"
0345 sysfs_set_pull chip bank 0 pull-up
0346 test `cat $SYSFS_PATH` = "pull-up" || fail "reading the pull failed"
0347 remove_chip chip
0348 
0349 echo "3.3. Incorrect input in sysfs is rejected"
0350 create_chip chip
0351 create_bank chip bank
0352 set_num_lines chip bank 8
0353 enable_chip chip
0354 DEVNAME=`configfs_dev_name chip`
0355 CHIPNAME=`configfs_chip_name chip bank`
0356 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/pull"
0357 echo foobar > $SYSFS_PATH 2> /dev/null && fail "invalid input not detected"
0358 remove_chip chip
0359 
0360 echo "3.4. Can't write to value"
0361 create_chip chip
0362 create_bank chip bank
0363 enable_chip chip
0364 DEVNAME=`configfs_dev_name chip`
0365 CHIPNAME=`configfs_chip_name chip bank`
0366 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value"
0367 echo 1 > $SYSFS_PATH 2> /dev/null && fail "writing to 'value' succeeded unexpectedly"
0368 remove_chip chip
0369 
0370 echo "4. Simulated GPIO chips are functional"
0371 
0372 echo "4.1. Values can be read from sysfs"
0373 create_chip chip
0374 create_bank chip bank
0375 set_num_lines chip bank 8
0376 enable_chip chip
0377 DEVNAME=`configfs_dev_name chip`
0378 CHIPNAME=`configfs_chip_name chip bank`
0379 SYSFS_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio0/value"
0380 test `cat $SYSFS_PATH` = "0" || fail "incorrect value read from sysfs"
0381 $BASE_DIR/gpio-mockup-cdev -s 1 /dev/`configfs_chip_name chip bank` 0 &
0382 sleep 0.1 # FIXME Any better way?
0383 test `cat $SYSFS_PATH` = "1" || fail "incorrect value read from sysfs"
0384 kill $!
0385 remove_chip chip
0386 
0387 echo "4.2. Bias settings work correctly"
0388 create_chip chip
0389 create_bank chip bank
0390 set_num_lines chip bank 8
0391 enable_chip chip
0392 $BASE_DIR/gpio-mockup-cdev -b pull-up /dev/`configfs_chip_name chip bank` 0
0393 test `cat $SYSFS_PATH` = "1" || fail "bias setting does not work"
0394 remove_chip chip
0395 
0396 echo "GPIO $MODULE test PASS"