xref: /openbmc/openbmc/meta-facebook/meta-harma/recipes-phosphor/state/phosphor-state-manager/power-cmd (revision a5915c00b50438dd8cccff22c628f790f43268d7)
142e7aff5SPeter Yin#!/bin/bash
242e7aff5SPeter Yin
342e7aff5SPeter Yin# shellcheck source=meta-facebook/recipes-fb/obmc_functions/files/fb-common-functions
442e7aff5SPeter Yinsource /usr/libexec/fb-common-functions
547b9cdbfSPeter Yinrenice -10 $$
642e7aff5SPeter Yin
744a5ddc0SPeter Yincheck_valid_sgpio() {
847b9cdbfSPeter Yin    sgpio_vaild0=$(get_gpio "power-card-enable")
9ed2b0b51SPeter Yin    sgpio_vaild1=$(get_gpio "power-12v-memory-good")
1047b9cdbfSPeter Yin    sgpio_vaild2=$(get_gpio "power-pvdd33-s5")
1144a5ddc0SPeter Yin
1244a5ddc0SPeter Yin    if [[ "$sgpio_vaild0" == "0" && "$sgpio_vaild1" == "0" && "$sgpio_vaild2" == "1" ]]; then
1344a5ddc0SPeter Yin        return 0  # true
1444a5ddc0SPeter Yin    else
1544a5ddc0SPeter Yin        return 1  # false
1644a5ddc0SPeter Yin    fi
1744a5ddc0SPeter Yin}
1844a5ddc0SPeter Yin
1942e7aff5SPeter Yin# Power Good Status
2042e7aff5SPeter Yinpower_status() {
2144a5ddc0SPeter Yin    check_valid_sgpio
2244a5ddc0SPeter Yin    valid_sgpio=$?
2344a5ddc0SPeter Yin
2444a5ddc0SPeter Yin    if [ "$(get_gpio "host0-ready")" -eq 1 ] && [ "$valid_sgpio" -eq 0 ] ; then
2542e7aff5SPeter Yin        echo "on"
2642e7aff5SPeter Yin    else
2742e7aff5SPeter Yin        echo "off"
2842e7aff5SPeter Yin    fi
2942e7aff5SPeter Yin}
3042e7aff5SPeter Yin
31abfbf2a0SPeter Yin# Force DC off
32abfbf2a0SPeter Yinforce_power_off() {
33abfbf2a0SPeter Yin    if [ "$(power_status)" == "on" ]; then
34abfbf2a0SPeter Yin        set_gpio power-host-control 0
35abfbf2a0SPeter Yin        sleep 6
36abfbf2a0SPeter Yin        set_gpio power-host-control 1
37744d50ceSPeter Yin        sleep 6
38744d50ceSPeter Yin    fi
39744d50ceSPeter Yin
40744d50ceSPeter Yin    # Workaround for AMD force shutdown failure.
41744d50ceSPeter Yin    if [ "$(power_status)" == "on" ]; then
42744d50ceSPeter Yin        set_gpio reset-control 0
43abfbf2a0SPeter Yin        sleep 1
44744d50ceSPeter Yin        set_gpio reset-control 1
45744d50ceSPeter Yin        sleep 3
46744d50ceSPeter Yin
47744d50ceSPeter Yin        set_gpio power-host-control 0
48744d50ceSPeter Yin        sleep 1
49744d50ceSPeter Yin        set_gpio power-host-control 1
50744d50ceSPeter Yin        sleep 1
51744d50ceSPeter Yin
52744d50ceSPeter Yin        for i in $(seq 1 10)
53744d50ceSPeter Yin        do
54744d50ceSPeter Yin            sleep 1
55744d50ceSPeter Yin            if [ "$(power_status)" == "off" ]; then
56744d50ceSPeter Yin               return 0
57744d50ceSPeter Yin            fi
58744d50ceSPeter Yin
59744d50ceSPeter Yin            if [ "$i" -eq 10 ]; then
60744d50ceSPeter Yin               return 1
61744d50ceSPeter Yin            fi
62744d50ceSPeter Yin        done
63abfbf2a0SPeter Yin    fi
64abfbf2a0SPeter Yin}
65abfbf2a0SPeter Yin
66abfbf2a0SPeter Yin# Graceful DC off
67591e5736SPeter Yingraceful_power_off() {
6842e7aff5SPeter Yin    if [ "$(power_status)" == "on" ]; then
69591e5736SPeter Yin        set_gpio power-host-control 0
70591e5736SPeter Yin        sleep 1
71591e5736SPeter Yin        set_gpio power-host-control 1
72591e5736SPeter Yin        sleep 1
73591e5736SPeter Yin
74591e5736SPeter Yin        # wait host power off
75744d50ceSPeter Yin        for i in $(seq 1 20)
76b91091d6SPeter Yin        do
77b91091d6SPeter Yin            sleep 1
78b91091d6SPeter Yin            if [ "$(power_status)" == "off" ]; then
79b91091d6SPeter Yin               break
80b91091d6SPeter Yin            fi
81b91091d6SPeter Yin        done
8242e7aff5SPeter Yin    fi
8342e7aff5SPeter Yin}
8442e7aff5SPeter Yin
8542e7aff5SPeter Yin# DC on
8642e7aff5SPeter Yinpower_on() {
8742e7aff5SPeter Yin    if [ "$(power_status)" == "off" ]; then
8842e7aff5SPeter Yin        set_gpio power-host-control 0
8942e7aff5SPeter Yin        sleep 1
9042e7aff5SPeter Yin        set_gpio power-host-control 1
9142e7aff5SPeter Yin        sleep 1
9242e7aff5SPeter Yin
9342e7aff5SPeter Yin        for i in $(seq 1 10)
9442e7aff5SPeter Yin        do
95ee5d7dd7SPeter Yin            sleep 1
9642e7aff5SPeter Yin            if [ "$(power_status)" == "on" ]; then
9742e7aff5SPeter Yin               return 0
9842e7aff5SPeter Yin            fi
9942e7aff5SPeter Yin
10042e7aff5SPeter Yin            if [ "$i" -eq 10 ]; then
10142e7aff5SPeter Yin               return 1
10242e7aff5SPeter Yin            fi
10342e7aff5SPeter Yin        done
104ee5d7dd7SPeter Yin    fi
105ee5d7dd7SPeter Yin    return 0
10642e7aff5SPeter Yin}
10754178431SPeter Yin
10854178431SPeter Yin# Host reset
10954178431SPeter Yinpower_reset() {
11054178431SPeter Yin    set_gpio reset-control 0
11154178431SPeter Yin    sleep 1
11254178431SPeter Yin    set_gpio reset-control 1
11354178431SPeter Yin    sleep 1
11454178431SPeter Yin    return 0
11554178431SPeter Yin}
116*176a0992SPeter Yin
117*176a0992SPeter Yin# Sync power state to "off" for abnormal power loss.
118*176a0992SPeter Yinpower_off_sync() {
119*176a0992SPeter Yin    local timeout=${1:-8}   # default 8 seconds if not provided
120*176a0992SPeter Yin    local delay=${2:-1}     # default 1 second interval if not provided
121*176a0992SPeter Yin
122*176a0992SPeter Yin    for ((i=0; i<timeout; i++)); do
123*176a0992SPeter Yin        local status
124*176a0992SPeter Yin        status=$(power_status)
125*176a0992SPeter Yin        if [ "$status" != "off" ]; then
126*176a0992SPeter Yin            return
127*176a0992SPeter Yin        fi
128*176a0992SPeter Yin        sleep "$delay"
129*176a0992SPeter Yin    done
130*176a0992SPeter Yin
131*176a0992SPeter Yin    local transition
132*176a0992SPeter Yin    transition=$(busctl get-property \
133*176a0992SPeter Yin        xyz.openbmc_project.State.Host0 \
134*176a0992SPeter Yin        /xyz/openbmc_project/state/host0 \
135*176a0992SPeter Yin        xyz.openbmc_project.State.Host \
136*176a0992SPeter Yin        RequestedHostTransition | awk '{print $2}' | tr -d '"')
137*176a0992SPeter Yin
138*176a0992SPeter Yin    if [ "$transition" != "xyz.openbmc_project.State.Host.Transition.Off" ] && [ "$(power_status)" == "off" ]; then
139*176a0992SPeter Yin        busctl set-property xyz.openbmc_project.State.Host0 \
140*176a0992SPeter Yin            /xyz/openbmc_project/state/host0 \
141*176a0992SPeter Yin            xyz.openbmc_project.State.Host \
142*176a0992SPeter Yin            RequestedHostTransition s \
143*176a0992SPeter Yin            xyz.openbmc_project.State.Host.Transition.Off
144*176a0992SPeter Yin    fi
145*176a0992SPeter Yin}
146*176a0992SPeter Yin
147*176a0992SPeter Yin# Sync power status to "On" for abnormal power-on scenarios.
148*176a0992SPeter Yinpower_on_sync() {
149*176a0992SPeter Yin    local timeout=${1:-3}   # default 3 seconds if not provided
150*176a0992SPeter Yin    local delay=${2:-1}     # default 1 second interval if not provided
151*176a0992SPeter Yin
152*176a0992SPeter Yin    for ((i=0; i<timeout; i++)); do
153*176a0992SPeter Yin        local status
154*176a0992SPeter Yin        status=$(power_status)
155*176a0992SPeter Yin        if [ "$status" != "on" ]; then
156*176a0992SPeter Yin            return
157*176a0992SPeter Yin        fi
158*176a0992SPeter Yin        sleep "$delay"
159*176a0992SPeter Yin    done
160*176a0992SPeter Yin
161*176a0992SPeter Yin    local transition
162*176a0992SPeter Yin    transition=$(busctl get-property \
163*176a0992SPeter Yin        xyz.openbmc_project.State.Host0 \
164*176a0992SPeter Yin        /xyz/openbmc_project/state/host0 \
165*176a0992SPeter Yin        xyz.openbmc_project.State.Host \
166*176a0992SPeter Yin        RequestedHostTransition | awk '{print $2}' | tr -d '"')
167*176a0992SPeter Yin
168*176a0992SPeter Yin    if [ "$transition" != "xyz.openbmc_project.State.Host.Transition.On" ] && [ "$(power_status)" == "on" ]; then
169*176a0992SPeter Yin        busctl set-property xyz.openbmc_project.State.Host0 \
170*176a0992SPeter Yin            /xyz/openbmc_project/state/host0 \
171*176a0992SPeter Yin            xyz.openbmc_project.State.Host \
172*176a0992SPeter Yin            RequestedHostTransition s \
173*176a0992SPeter Yin            xyz.openbmc_project.State.Host.Transition.On
174*176a0992SPeter Yin    fi
175*176a0992SPeter Yin}
176*176a0992SPeter Yin
177*176a0992SPeter Yin# Main execution
178*176a0992SPeter Yinif [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
179*176a0992SPeter Yin    case "$1" in
180*176a0992SPeter Yin        force_off)
181*176a0992SPeter Yin            force_power_off
182*176a0992SPeter Yin            ;;
183*176a0992SPeter Yin        graceful_off)
184*176a0992SPeter Yin            graceful_power_off
185*176a0992SPeter Yin            ;;
186*176a0992SPeter Yin        power_on)
187*176a0992SPeter Yin            power_on
188*176a0992SPeter Yin            ;;
189*176a0992SPeter Yin        power_reset)
190*176a0992SPeter Yin            power_reset
191*176a0992SPeter Yin            ;;
192*176a0992SPeter Yin        off_sync)
193*176a0992SPeter Yin            power_off_sync "$2" "$3"
194*176a0992SPeter Yin            ;;
195*176a0992SPeter Yin        on_sync)
196*176a0992SPeter Yin            power_on_sync "$2" "$3"
197*176a0992SPeter Yin            ;;
198*176a0992SPeter Yin        status)
199*176a0992SPeter Yin            power_status
200*176a0992SPeter Yin            ;;
201*176a0992SPeter Yin        *)
202*176a0992SPeter Yin            echo "Usage: $0 {force_off|graceful_off|power_on|power_reset|off_sync|on_sync|status}"
203*176a0992SPeter Yin            exit 0
204*176a0992SPeter Yin            ;;
205*176a0992SPeter Yin    esac
206*176a0992SPeter Yinfi
207*176a0992SPeter Yin
208