243 lines
5.5 KiB
Bash
Executable File
243 lines
5.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# shellcheck disable=SC2046
|
|
# shellcheck source=meta-ampere/meta-mitchell/recipes-ampere/platform/ampere-platform-init/gpio-lib.sh
|
|
source /usr/sbin/gpio-lib.sh
|
|
|
|
spi_address="1e630000.spi"
|
|
spi_bind="/sys/bus/platform/drivers/spi-aspeed-smc/bind"
|
|
spi_unbind="/sys/bus/platform/drivers/spi-aspeed-smc/unbind"
|
|
spi_lock="/run/platform/spi.lock"
|
|
spi_lock_dir="/run/platform"
|
|
|
|
bind_aspeed_smc_driver() {
|
|
if [ -f "${spi_lock}" ]; then
|
|
pid=$1
|
|
pid_lock=$(cat "${spi_lock}")
|
|
if [[ "${pid}" != "${pid_lock}" ]]; then
|
|
echo "SPI-NOR resoure is lock by process $pid_lock"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# BMC access SPI-NOR resource
|
|
gpio_name_set spi0-program-sel 1
|
|
sleep 0.1
|
|
echo "Bind the ASpeed SMC driver"
|
|
echo "${spi_address}" > "${spi_bind}" 2>/dev/null
|
|
# Check the HNOR partition available
|
|
HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
|
|
if [ -z "$HOST_MTD" ]; then
|
|
echo "${spi_address}" > "${spi_unbind}"
|
|
sleep 0.1
|
|
echo "${spi_address}" > "${spi_bind}"
|
|
fi
|
|
# BMC release SPI-NOR resource
|
|
gpio_name_set spi0-program-sel 0
|
|
return 0
|
|
}
|
|
|
|
unbind_aspeed_smc_driver() {
|
|
if [ -f "${spi_lock}" ]; then
|
|
pid=$1
|
|
pid_lock=$(cat "${spi_lock}")
|
|
if [[ "${pid}" != "${pid_lock}" ]]; then
|
|
echo "SPI-NOR resoure is lock by process $pid_lock . Wait 10s"
|
|
# Wait maximum 10 seconds for unlock SPI-NOR
|
|
cnt=10
|
|
while [ $cnt -gt 0 ]
|
|
do
|
|
if [ -f "${spi_lock}" ]; then
|
|
sleep 1
|
|
cnt=$((cnt - 1))
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
if [ "$cnt" -eq "0" ]; then
|
|
echo "Timeout 10 seconds, SPI-NOR still busy. Force unlock to access SPI"
|
|
rm -f "${spi_lock}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
HOST_MTD=$(< /proc/mtd grep "pnor" | sed -n 's/^\(.*\):.*/\1/p')
|
|
if [ -n "$HOST_MTD" ]; then
|
|
# If the HNOR partition is available, then unbind driver
|
|
# BMC access SPI-NOR resource
|
|
gpio_name_set spi0-program-sel 1
|
|
sleep 0.1
|
|
echo "Unbind the ASpeed SMC driver"
|
|
echo "${spi_address}" > "${spi_unbind}"
|
|
fi
|
|
# BMC release SPI-NOR resource
|
|
gpio_name_set spi0-program-sel 0
|
|
# Deassert BMC access SPI-NOR pin
|
|
gpio_name_set spi-nor-access 0
|
|
sleep 0.5
|
|
return 0
|
|
}
|
|
|
|
lock_spi_resource() {
|
|
# Wait maximum 10 seconds to lock SPI-NOR
|
|
cnt=10
|
|
while [ $cnt -gt 0 ]
|
|
do
|
|
if [ -f "${spi_lock}" ]; then
|
|
sleep 1
|
|
cnt=$((cnt - 1))
|
|
else
|
|
echo "$1" > "${spi_lock}"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ "$cnt" -eq "0" ]; then
|
|
echo "Timeout 10 seconds, SPI-NOR is still locked by another process"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
unlock_spi_resource() {
|
|
if [ ! -f "${spi_lock}" ]; then
|
|
echo "SPI-NOR is already unlocked"
|
|
return 0
|
|
fi
|
|
|
|
pid=$1
|
|
pid_lock=$(cat "${spi_lock}")
|
|
if [[ "${pid}" == "${pid_lock}" ]]; then
|
|
rm -f "${spi_lock}"
|
|
else
|
|
echo "Cannot unlock, SPI-NOR is locked by another process"
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
start_handshake_spi() {
|
|
if [ -f "${spi_lock}" ]; then
|
|
pid=$1
|
|
pid_lock=$(cat "${spi_lock}")
|
|
if [[ "${pid}" != "${pid_lock}" ]]; then
|
|
echo "SPI-NOR resoure is lock by process $pid_lock"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# Wait maximum 10 seconds to grant access SPI
|
|
cnt=10
|
|
while [ $cnt -gt 0 ]
|
|
do
|
|
spinor_access=$(gpio_name_get soc-spi-nor-access)
|
|
if [ "$spinor_access" == "1" ]; then
|
|
sleep 1
|
|
cnt=$((cnt - 1))
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ "$cnt" -eq "0" ]; then
|
|
echo "Timeout 10 seconds, host is still hold SPI-NOR."
|
|
return 1
|
|
fi
|
|
echo "Start handshake SPI-NOR"
|
|
# Grant BMC access SPI-NOR. The process call the scripts should only
|
|
# claim the bus for only maximum period 500ms.
|
|
gpio_name_set spi-nor-access 1
|
|
# Switch the Host SPI-NOR to BMC
|
|
gpio_name_set spi0-program-sel 1
|
|
}
|
|
|
|
stop_handshake_spi() {
|
|
if [ -f "${spi_lock}" ]; then
|
|
pid=$1
|
|
pid_lock=$(cat "${spi_lock}")
|
|
if [[ "${pid}" != "${pid_lock}" ]]; then
|
|
echo "SPI-NOR resoure is lock by process $pid_lock"
|
|
return 1
|
|
fi
|
|
fi
|
|
echo "Stop handshake SPI-NOR"
|
|
# Switch the Host SPI-NOR to HOST
|
|
gpio_name_set spi0-program-sel 0
|
|
# Deassert BMC access SPI-NOR pin
|
|
gpio_name_set spi-nor-access 0
|
|
}
|
|
|
|
|
|
if [ $# -eq 0 ]; then
|
|
echo "Usage:"
|
|
echo " - Handshake access SPI-NOR "
|
|
echo " $(basename "$0") cmd pid"
|
|
echo " <cmd>:"
|
|
echo " lock - lock the SPI-NOR resource"
|
|
echo " unlock - unlock the SPI-NOR resource"
|
|
echo " bind - bind the SPI-NOR resource"
|
|
echo " unbind - unbind the SPI-NOR resource"
|
|
echo " start_handshake - start handshake between BMC and Host"
|
|
echo " stop_handshake - release handshake between BMC and Host"
|
|
echo " <pid>: Optional - PID of the process call script"
|
|
exit 0
|
|
fi
|
|
|
|
CMD=$1
|
|
|
|
if [ ! -d "${spi_lock_dir}" ]; then
|
|
mkdir -p "${spi_lock_dir}"
|
|
fi
|
|
|
|
if [ -z "$2" ]; then
|
|
PID=$$
|
|
else
|
|
PID=$2
|
|
fi
|
|
|
|
if [[ "${CMD}" == "lock" ]]; then
|
|
lock_spi_resource "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot lock SPI-NOR, the resource is busy"
|
|
exit 1
|
|
fi
|
|
elif [[ "${CMD}" == "unlock" ]]; then
|
|
unlock_spi_resource "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot unlock SPI-NOR, the resource is busy"
|
|
exit 1
|
|
fi
|
|
elif [[ "${CMD}" == "bind" ]]; then
|
|
bind_aspeed_smc_driver "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot bind SPI-NOR, the resource is busy"
|
|
exit 1
|
|
fi
|
|
elif [[ "${CMD}" == "unbind" ]]; then
|
|
unbind_aspeed_smc_driver "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot unbind SPI-NOR, the resource is busy"
|
|
exit 1
|
|
fi
|
|
elif [[ "${CMD}" == "start_handshake" ]]; then
|
|
start_handshake_spi "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot start handshake SPI-NOR"
|
|
exit 1
|
|
fi
|
|
elif [[ "${CMD}" == "stop_handshake" ]]; then
|
|
stop_handshake_spi "${PID}"
|
|
ret=$?
|
|
if [[ "${ret}" == "1" ]]; then
|
|
echo "Cannot stop handshake SPI-NOR"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
exit 0
|