1#!/bin/bash
2
3# shellcheck disable=SC2046
4
5# Usage of this utility
6function usage() {
7	echo "usage: power-util mb [status|shutdown_ack|force_reset|soft_off|host_reboot_wa]";
8}
9
10power_status() {
11	st=$(busctl get-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis CurrentPowerState | cut -d"." -f6)
12	if [ "$st" == "On\"" ]; then
13		echo "on"
14	else
15		echo "off"
16	fi
17}
18
19shutdown_ack() {
20	if [ -f "/run/openbmc/host@0-softpoweroff" ]; then
21		echo "Receive shutdown ACK triggered after softportoff the host."
22		touch /run/openbmc/host@0-softpoweroff-shutdown-ack
23	else
24		echo "Receive shutdown ACK triggered"
25		sleep 3
26		systemctl start obmc-chassis-poweroff@0.target
27	fi
28}
29
30soft_off() {
31	# Trigger shutdown_req
32	touch /run/openbmc/host@0-softpoweroff
33	gpioset $(gpiofind host0-shd-req-n)=0
34	sleep 0.05
35	gpioset $(gpiofind host0-shd-req-n)=1
36
37	# Wait for shutdown_ack from the host in 30 seconds
38	cnt=30
39	while [ $cnt -gt 0 ];
40	do
41		# Wait for SHUTDOWN_ACK and create the host@0-softpoweroff-shutdown-ack
42		if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
43			break
44		fi
45		sleep 1
46		cnt=$((cnt - 1))
47	done
48
49	# Softpoweroff is successful
50	sleep 2
51	rm -rf /run/openbmc/host@0-softpoweroff
52	if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
53		rm -rf /run/openbmc/host@0-softpoweroff-shutdown-ack
54	fi
55	echo 0
56}
57
58force_reset() {
59	if [ -f "/run/openbmc/host@0-softpoweroff" ]; then
60		# In graceful host reset, after trigger os shutdown,
61		# the phosphor-state-manager will call force-warm-reset
62		# in this case the force_reset should wait for shutdown_ack from host
63		cnt=30
64		while [ $cnt -gt 0 ];
65		do
66			if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
67				break
68			fi
69			echo "Waiting for shutdown-ack count down $cnt"
70			sleep 1
71			cnt=$((cnt - 1))
72		done
73		# The host OS is failed to shutdown
74		if [ $cnt == 0 ]; then
75			echo "Shutdown-ack time out after 30s."
76			exit 0
77		fi
78	fi
79	rm -f /run/openbmc/host@0-on
80	echo "Triggering sysreset pin"
81	gpioset $(gpiofind host0-sysreset-n)=0
82	sleep 1
83	gpioset $(gpiofind host0-sysreset-n)=1
84}
85
86host_reboot_wa() {
87    busctl set-property xyz.openbmc_project.State.Chassis \
88        /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis \
89        RequestedPowerTransition s "xyz.openbmc_project.State.Chassis.Transition.Off"
90
91    while ( true )
92    do
93        if systemctl status obmc-power-off@0.target | grep "Active: active"; then
94            break;
95        fi
96        sleep 2
97    done
98    echo "The power is already Off."
99
100    busctl set-property xyz.openbmc_project.State.Host \
101        /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host \
102        RequestedHostTransition s "xyz.openbmc_project.State.Host.Transition.On"
103}
104
105if [ ! -d "/run/openbmc/" ]; then
106	mkdir -p "/run/openbmc/"
107fi
108
109if [ "$2" == "shutdown_ack" ]; then
110	shutdown_ack
111elif [ "$2" == "status" ]; then
112	power_status
113elif [ "$2" == "force_reset" ]; then
114	force_reset
115elif [ "$2" == "host_reboot_wa" ]; then
116	host_reboot_wa
117elif [ "$2" == "soft_off" ]; then
118	ret=$(soft_off)
119	if [ "$ret" == 0 ]; then
120		echo "The host is already softoff"
121	else
122		echo "Failed to softoff the host"
123	fi
124	exit "$ret";
125else
126	echo "Invalid parameter2=$2"
127	usage;
128fi
129
130exit 0;
131