This test script try to do whitebox testing for gpio subsystem(
based on gpiolib). It manipulate gpio-mockup device through sysfs
provided and check the result from debugfs.

Test the following things:
1.  Add single, multi gpiochip with the checking of overlap.
2.  Test direction and output value for valid pin.
3.  Test dynamic allocation of gpio base.

Signed-off-by: Bamvor Jian Zhang <bamvor.zhangj...@linaro.org>
---
 tools/testing/selftests/Makefile     |   1 +
 tools/testing/selftests/gpio/gpio.sh | 238 +++++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
 create mode 100755 tools/testing/selftests/gpio/gpio.sh

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index cfe1213..df0b81d 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -5,6 +5,7 @@ TARGETS += exec
 TARGETS += firmware
 TARGETS += ftrace
 TARGETS += futex
+TARGETS += gpio
 TARGETS += kcmp
 TARGETS += membarrier
 TARGETS += memfd
diff --git a/tools/testing/selftests/gpio/gpio.sh 
b/tools/testing/selftests/gpio/gpio.sh
new file mode 100755
index 0000000..05e109e
--- /dev/null
+++ b/tools/testing/selftests/gpio/gpio.sh
@@ -0,0 +1,238 @@
+#!/bin/bash
+
+module="gpio-mockup"
+
+SYSFS=
+GPIO_SYSFS=
+GPIO_DRV_SYSFS=
+DEBUGFS=
+GPIO_DEBUGFS=
+
+prerequisite()
+{
+       msg="skip all tests:"
+
+       if [ $UID != 0 ]; then
+               echo $msg must be run as root >&2
+               exit 0
+       fi
+
+       SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
+       if [ ! -d "$SYSFS" ]; then
+               echo $msg sysfs is not mounted >&2
+               exit 0
+       fi
+       GPIO_SYSFS=`echo $SYSFS/class/gpio`
+       GPIO_DRV_SYSFS=`echo $SYSFS/devices/platform/$module/gpio`
+
+       DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+       if [ ! -d "$DEBUGFS" ]; then
+               echo $msg debugfs is not mounted >&2
+               exit 0
+       fi
+       GPIO_DEBUGFS=`echo $DEBUGFS/gpio`
+
+}
+
+insert_module()
+{
+       if modprobe -q $module $1; then
+               echo -n ""
+       else
+               echo $msg insmod $module failed >&2
+               exit 0
+       fi
+}
+
+remove_module()
+{
+       modprobe -r -q $module
+}
+
+die()
+{
+       remove_module
+       exit 1
+}
+
+gpio_test()
+{
+       param=$1
+       if [ X$2 != X ]; then
+               invalid_pin=$2
+       fi
+       if [ X$param = X ]; then
+               insert_module
+       else
+               insert_module "conf=$param"
+       fi
+
+       echo -n "GPIO $module test with base,ngpio configure<"
+       if [ X$param = X ]; then
+               echo "(default)>: ";
+       else
+               echo "$param>: "
+       fi
+       printf "%-10s %-5s %-5s\n" name base ngpio
+       gpiochip=`ls -d $GPIO_DRV_SYSFS/gpiochip* 2>/dev/null`
+       if [ X"$gpiochip" = X ]; then
+               echo "no gpiochip"
+       else
+               for chip in $gpiochip; do
+                       name=`basename $chip`
+                       base=`cat $chip/base`
+                       ngpio=`cat $chip/ngpio`
+                       printf "%-10s %-5s %-5s\n" $name $base $ngpio
+                       if [ $ngpio = "0" ]; then
+                               echo "number of gpio is zero is not allowed".
+                       fi
+                       test_one_pin $base
+                       test_one_pin $(($base + $ngpio - 1))
+                       test_one_pin $((( RANDOM % $ngpio )  + $base ))
+                       if [ X$invalid_pin != X ]; then
+                               test_one_pin_fail $invalid_pin
+                       fi
+               done
+       fi
+       remove_module
+}
+
+gpio_test_fail()
+{
+       param=$1
+
+       insert_module "conf=$param"
+       echo -n "GPIO $module fail test with base,ngpio configure<$param>: "
+       gpiochip=`ls -d $GPIO_DRV_SYSFS/gpiochip* 2>/dev/null`
+       if [ X"$gpiochip" = X ]; then
+               echo "successful"
+       else
+               echo "fail"
+               die
+       fi
+       remove_module
+}
+
+is_consistent()
+{
+       val=
+
+       active_low_sysfs=`cat $GPIO_SYSFS/gpio$nr/active_low`
+       val_sysfs=`cat $GPIO_SYSFS/gpio$nr/value`
+       dir_sysfs=`cat $GPIO_SYSFS/gpio$nr/direction`
+
+       gpio_this_debugfs=`cat $GPIO_DEBUGFS |grep "gpio-$nr" | sed "s/(.*)//g"`
+       dir_debugfs=`echo $gpio_this_debugfs | awk '{print $2}'`
+       val_debugfs=`echo $gpio_this_debugfs | awk '{print $3}'`
+       if [ $val_debugfs = "lo" ]; then
+               val=0
+       elif [ $val_debugfs = "hi" ]; then
+               val=1
+       fi
+
+       if [ $active_low_sysfs = "1" ]; then
+               if [ $val = "0" ]; then
+                       val="1"
+               else
+                       val="0"
+               fi
+       fi
+
+       if [ $val_sysfs = $val ] && [ $dir_sysfs = $dir_debugfs ]; then
+               echo -n "."
+       else
+               echo "test fail, exit"
+               die
+       fi
+}
+
+test_pin_logic()
+{
+       nr=$1
+       direction=$2
+       active_low=$3
+       value=$4
+
+       echo $direction > $GPIO_SYSFS/gpio$nr/direction
+       echo $active_low > $GPIO_SYSFS/gpio$nr/active_low
+       if [ $direction = "out" ]; then
+               echo $value > $GPIO_SYSFS/gpio$nr/value
+       fi
+       is_consistent $nr
+}
+
+test_one_pin()
+{
+       nr=$1
+
+       echo -n "test pin<$nr>"
+
+       echo $nr > $GPIO_SYSFS/export 2>/dev/null
+
+       if [ X$? != X0 ]; then
+               echo "test GPIO pin $nr failed"
+               die
+       fi
+
+       #"Checking if the sysfs is consistent with debugfs: "
+       is_consistent $nr
+
+       #"Checking the logic of active_low: "
+       test_pin_logic $nr out 1 1
+       test_pin_logic $nr out 1 0
+       test_pin_logic $nr out 0 1
+       test_pin_logic $nr out 0 0
+
+       #"Checking the logic of direction: "
+       test_pin_logic $nr in 1 1
+       test_pin_logic $nr out 1 0
+       test_pin_logic $nr low 0 1
+       test_pin_logic $nr high 0 0
+
+       echo $nr > $GPIO_SYSFS/unexport
+
+       echo "successful"
+}
+
+test_one_pin_fail()
+{
+       nr=$1
+
+       echo $nr > $GPIO_SYSFS/export 2>/dev/null
+
+       if [ X$? != X0 ]; then
+               echo "test invalid pin $nr successful"
+       else
+               echo "test invalid pin $nr failed"
+               echo $nr > $GPIO_SYSFS/unexport 2>/dev/null
+               die
+       fi
+}
+
+prerequisite
+
+#basically
+gpio_test
+gpio_test "0,32" 33
+gpio_test "0,32,32,16" 50
+gpio_test "0,32,40,16,32,5" 38
+#test dynamic allocation of gpio
+gpio_test "-1,32"
+gpio_test "-1,32,32,16" 31
+gpio_test "-1,32,40,16,-1,5" 38
+#error test
+#zero number of gpio
+gpio_test_fail "0,0"
+#base conflict
+gpio_test_fail "0,32,0,1"
+#range overlap
+gpio_test_fail "0,32,30,5"
+gpio_test_fail "0,32,1,5"
+gpio_test_fail "10,32,9,5"
+gpio_test_fail "10,32,30,5"
+gpio_test_fail "0,32,40,16,39,5"
+gpio_test_fail "0,32,40,16,30,5"
+gpio_test_fail "0,32,40,16,30,11"
+gpio_test_fail "0,32,40,16,20,1"
+
+echo GPIO test PASS
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to