#!/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 " :" 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 " : 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