#!/bin/sh
#
# Copyright (C) 2011 Texas Instruments Incorporated
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation version 2.
#
# This program is distributed "as is" WITHOUT ANY WARRANTY of any
# kind, whether express or implied; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#

# Number of seconds before watchdog expires
HEARTBEAT=5

check_errs()
{
    if [ "${1}" -ne "0" ]
    then
	echo "Error: ${2}"
	exit ${1}
    fi
}

wait_for_file()
{
    # give file time to show up...
    for tries in 1 2 3 4 5; do
	if [ -e ${1} ]
	then
	    break
	fi
	sleep 1
    done
    [ -e ${1} ]
}

# load watchdog test helper
# this exposes a status value in /proc/sys/watchdog/status
#     0 => watchdog idle
#     1 => watchdog active and counting
#     2 => watchdog expired
#
modprobe wdt_test
check_errs $? "can't load watchdog test helper!"

wait_for_file /proc/sys/watchdog/status
check_errs $? "watchdog helper didn't create /proc/sys/watchdog/status!"

# load watchdog driver
modprobe davinci_wdt heartbeat=$HEARTBEAT
check_errs $? "can't load watchdog driver!"

wait_for_file /dev/watchdog
check_errs $? "watchdog driver didn't create /dev/watchdog!"

# start watchdog
echo >/dev/watchdog

WDSTAT=`cat /proc/sys/watchdog/status`
if ! [ "$WDSTAT" = "1" ]
then
    echo "Error: watchdog didn't start! Status: $WDSTAT"
    exit 1
fi

# first, make sure keepalive works
# if keepalive doesn't work, watchdog will fire before we
# time its heartbeat below.
for i in 1 2 3 4 5; do
    echo >/dev/watchdog
    sleep $(($HEARTBEAT / 2))
done
echo >/dev/watchdog

# uncomment to force failure (expiry too early)
# sleep $HEARTBEAT

START=`date`

while ! [ ${foo:=0} = 2 ]; do
    foo=`cat /proc/sys/watchdog/status`
    if ! [ "$foo" = "0" -o "$foo" = "1" -o "$foo" = "2" ]
    then
	echo "Error: Unknown watchdog status: $foo"
	exit 1
    fi
done

# uncomment to force failure (expiry too late)
# sleep $HEARTBEAT

END=`date`

echo "Watchdog start: $START, end: $END"

XSTART_MIN=`echo $START | sed -e 's/.*\([0-9]*\):\([0-9]*\):\([0-9]*\).*/\2/'`
XSTART_SEC=`echo $START | sed -e 's/.*\([0-9]*\):\([0-9]*\):\([0-9]*\).*/\3/'`
XEND_MIN=`echo $END | sed -e 's/.*\([0-9]*\):\([0-9]*\):\([0-9]*\).*/\2/'`
XEND_SEC=`echo $END | sed -e 's/.*\([0-9]*\):\([0-9]*\):\([0-9]*\).*/\3/'`

# strip leading zero so it doesn't look like an octal number
START_MIN=`echo $XSTART_MIN | sed -e 's/^0//'`
START_SEC=`echo $XSTART_SEC | sed -e 's/^0//'`
END_MIN=`echo $XEND_MIN | sed -e 's/^0//'`
END_SEC=`echo $XEND_SEC | sed -e 's/^0//'`

# handle minutes rollover
if [ $(($END_MIN < $START_MIN)) = 1 ]
then
    END_MIN=$(($END_MIN + 60))
fi
DELTA_MIN=$(($END_MIN - $START_MIN))
XSECS=$(($DELTA_MIN * 60))

# handle seconds rollover
if [ $(($END_SEC < $START_SEC)) = 1 ]
then
    END_SEC=$(($END_SEC + 60))
    XSECS=$(($XSECS - 60))
fi
END_SEC=$(($END_SEC + $XSECS))

DELTA=$(($END_SEC - $START_SEC))

MIN=$(($HEARTBEAT - 1))
MAX=$(($HEARTBEAT + 1))

if [ "$(($DELTA < $MIN))" = "1" -o "$(($DELTA > $MAX))" = "1" ]
then
    echo "Error: watchdog expiry out of range! Expected $HEARTBEAT, got $DELTA"
    exit 1
fi

echo "Success"
exit 0
