meta-facebook: yosemite4: Monitor host power status

Description:
- Monitor host power status.
  - Request the host power transition when status change.

Note:
- Compatible table
  - SD CPLD firmware version: 00010302
    BMC INT_SMB_BMC_SLOT1_4_N or INT_SMB_BMC_SLOT5_8_N will be
    triggered when the CPU power status changes or a power fault
    occurs in the slot.

Test Plan:
- Check host power state after power cycle/on/off: 200 rounds Pass
- Check host power state after sled-cycle: 20 rounds Pass

Change-Id: I2b7cfd748cf3e56fb0b4527deede7bcecd9397d0
Signed-off-by: Lora Lin <lora.lin.wiwynn@gmail.com>
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt
new file mode 100644
index 0000000..60f6263
--- /dev/null
+++ b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt
@@ -0,0 +1,147 @@
+#!/bin/bash
+
+# Provide source directive to shellcheck.
+# shellcheck source=meta-facebook/meta-yosemite4/recipes-phosphor/state/phosphor-state-manager/power-cmd
+source /usr/libexec/phosphor-state-manager/power-cmd
+
+log_message() {
+    local slot_num=$(($1+1))
+    local MESSAGE="SLOT$slot_num $2 Power Fault"
+    local COMBINED_INFO="$3"
+
+    busctl call \
+        xyz.openbmc_project.Logging /xyz/openbmc_project/logging \
+        xyz.openbmc_project.Logging.Create Create "ssa{ss}" "$MESSAGE" \
+        "xyz.openbmc_project.Logging.Entry.Level.Error" 1 "FAULT" "$COMBINED_INFO"
+}
+
+host_power_status() {
+    id=$1
+    service_path="xyz.openbmc_project.State.Host${id}"
+    object_path="/xyz/openbmc_project/state/host${id}"
+    interface_path="xyz.openbmc_project.State.Host"
+    property="CurrentHostState"
+    status=$(busctl get-property "$service_path" "$object_path" $interface_path $property | cut -d"." -f6)
+    if [ "$status" == "Running\"" ]; then
+        echo "on"
+    else
+        echo "off"
+    fi
+}
+
+# Sleep for 10ms to ignore GPIO instability during blade hot-plug
+usleep 10000
+
+if [ "$1" = "slot1-slot4" ]; then
+    i2c_bus=8
+    mux_addr=0x70
+    slot_num_offset=0
+elif [ "$1" = "slot5-slot8" ]; then
+    i2c_bus=9
+    mux_addr=0x71
+    slot_num_offset=4
+else
+    echo "Invalid input: $1"
+    exit 1
+fi
+
+count=0
+check_count=0
+SLOT_RANGE=4
+CLEAR_BIT=20
+while [ $check_count -lt $SLOT_RANGE ]
+do
+    count=0
+
+    # i2ctranster to check which slot got interrupt
+    read -r INT_BYTE <<< "$(i2ctransfer -f -y $i2c_bus w1@$mux_addr 0 r1)"
+    INT_BYTE=$((INT_BYTE >> 4))
+
+    if [ $INT_BYTE -eq 0 ]; then
+        exit 0
+    fi
+
+    while [ $count -lt $SLOT_RANGE ]
+    do
+
+        fault=$(( (INT_BYTE >> count) & 1 ))
+        # if fault[i] == 1, means slot_x got ISR
+        if [ $fault -eq 1 ]; then
+            slot_num=$((count + slot_num_offset))
+
+            # i2ctranster to get CPLD IOE (0x24) addr 0x01 (port1, ac)
+            read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x01 r1)"
+
+            # check which pin fault, add to fault info
+            if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V8_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V8_STBY_FAULT"
+            elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V2_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V2_STBY_FAULT"
+            fi
+
+            # call logging function
+            if [ -n "$COMBINED_INFO" ]; then
+                log_message $slot_num "AC" "$COMBINED_INFO"
+            fi
+
+            # clean
+            COMBINED_INFO=""
+            # i2ctranster to get CPLD IOE (0x24) addr 0x02 (port2, dc)
+            read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x02 r1)"
+
+            # check which pin fault, add to fault info
+            if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU0_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU0_FAULT"
+            elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_SOC_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_SOC_FAULT"
+            elif (( (FAULT_BYTE >> 2) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU1_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU1_FAULT"
+            elif (( (FAULT_BYTE >> 3) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDIO_FAULT" || COMBINED_INFO="PWRGD_PVDDIO_FAULT"
+            elif (( (FAULT_BYTE >> 4) & 1 == 1 )); then
+                [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDD11_S3_R_FAULT" || COMBINED_INFO="PWRGD_PVDD11_S3_R_FAULT"
+            fi
+
+            # call logging function
+            if [ -n "$COMBINED_INFO" ]; then
+                log_message $slot_num "DC" $COMBINED_INFO
+            fi
+
+
+            # Check CPU power status
+            host_id=$((slot_num + 1))
+            read -r PWR_STATUS_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x23 0x02 r1)"
+            if (( (PWR_STATUS_BYTE >> 2) & 1 == 1 )); then
+                if [ "$(host_power_status $host_id)" == "off" ]; then
+                    echo "Host$host_id power status change to on"
+                    busctl set-property xyz.openbmc_project.State.Host$host_id /xyz/openbmc_project/state/host$host_id xyz.openbmc_project.State.Host RequestedHostTransition s "xyz.openbmc_project.State.Host.Transition.On"
+                fi
+            else
+                if [ "$(host_power_status $host_id)" == "on" ]; then
+                    echo "Host$host_id power status change to off"
+                    busctl set-property xyz.openbmc_project.State.Host$host_id /xyz/openbmc_project/state/host$host_id xyz.openbmc_project.State.Host RequestedHostTransition s "xyz.openbmc_project.State.Host.Transition.Off"
+                fi
+            fi
+
+
+            # Clear interrupt
+            cpld_ioe_chip=$(basename "/sys/bus/i2c/devices/$slot_num-0021/"*gpiochip*)
+
+            if ! gpio_set "$cpld_ioe_chip" "$CLEAR_BIT"=1
+            then
+                echo "Set slot_num: $slot_num register to clear interrupt fail"
+            fi
+
+            usleep 5000
+
+            if ! gpio_set "$cpld_ioe_chip" "$CLEAR_BIT"=0
+            then
+                echo "Set slot_num: $slot_num register to default status fail"
+            fi
+        fi
+
+        count=$((count + 1))
+    done
+
+    check_count=$((check_count + 1))
+done
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt@.service b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt@.service
new file mode 100644
index 0000000..261d163
--- /dev/null
+++ b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/check-interrupt@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Check %i interrupt
+
+[Service]
+Type=oneshot
+ExecStart=/usr/libexec/phosphor-gpio-monitor/check-interrupt %i
+SyslogIdentifier=check-interrupt%i
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault
deleted file mode 100644
index 73ab5be..0000000
--- a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/bash
-
-log_message() {
-    local slot_num=$(($1+1))
-    local MESSAGE="SLOT$slot_num $2 Power Fault"
-    local COMBINED_INFO="$3"
-
-    busctl call \
-        xyz.openbmc_project.Logging /xyz/openbmc_project/logging \
-        xyz.openbmc_project.Logging.Create Create "ssa{ss}" "$MESSAGE" \
-        "xyz.openbmc_project.Logging.Entry.Level.Error" 1 "FAULT" "$COMBINED_INFO"
-}
-
-
-
-# if $1 == 14, slot1 to slot4. Check mux0 at i2c-8 0x70.
-# if $1 == 58, slot5 to slot8. Check mux1 at i2c-9 0x71.
-
-if [ "$1" -eq 14 ]; then
-    i2c_bus=8
-    mux_addr=0x70
-    slot_num_offset=0
-elif [ "$1" -eq 58 ]; then
-    i2c_bus=9
-    mux_addr=0x71
-    slot_num_offset=4
-else
-    echo "Invalid input. Please provide 14 or 58."
-    exit 1
-fi
-
-
-# i2ctranster to check which slot got interrupt
-read -r INT_BYTE <<< "$(i2ctransfer -f -y $i2c_bus w1@$mux_addr 0 r1)"
-INT_BYTE=$((INT_BYTE >> 4))
-
-# Traverse INT_BYTE
-count=0
-SLOT_RANGE=4
-while [ $count -lt $SLOT_RANGE ]
-do
-    fault=$(( (INT_BYTE >> count) & 1 ))
-    # if fault[i] == 1, means slot_x got ISR
-    if [ $fault -eq 1 ]; then
-        slot_num=$((count + slot_num_offset))
-
-        # i2ctranster to get CPLD IOE (0x24) addr 0x01 (port1, ac)
-        read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x01 r1)"
-
-        # check which pin fault, add to fault info
-        if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V8_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V8_STBY_FAULT"
-        elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_P1V2_STBY_FAULT" || COMBINED_INFO="PWRGD_P1V2_STBY_FAULT"
-        fi
-
-        # call logging function
-        if [ -n "$COMBINED_INFO" ]; then
-            log_message $slot_num "AC" "$COMBINED_INFO"
-        fi
-
-        # clean
-        COMBINED_INFO=""
-        # i2ctranster to get CPLD IOE (0x24) addr 0x02 (port2, dc)
-        read -r FAULT_BYTE <<< "$(i2ctransfer -f -y $slot_num w1@0x24 0x02 r1)"
-
-        # check which pin fault, add to fault info
-        if (( (FAULT_BYTE >> 0) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU0_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU0_FAULT"
-        elif (( (FAULT_BYTE >> 1) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_SOC_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_SOC_FAULT"
-        elif (( (FAULT_BYTE >> 2) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDCR_CPU1_FAULT" || COMBINED_INFO="PWRGD_PVDDCR_CPU1_FAULT"
-        elif (( (FAULT_BYTE >> 3) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDDIO_FAULT" || COMBINED_INFO="PWRGD_PVDDIO_FAULT"
-        elif (( (FAULT_BYTE >> 4) & 1 == 1 )); then
-            [ -n "$COMBINED_INFO" ] && COMBINED_INFO="${COMBINED_INFO},PWRGD_PVDD11_S3_R_FAULT" || COMBINED_INFO="PWRGD_PVDD11_S3_R_FAULT"
-        fi
-
-        # call logging function
-        if [ -n "$COMBINED_INFO" ]; then
-            log_message $slot_num "DC" $COMBINED_INFO
-        fi
-    fi
-
-    count=$((count + 1))
-done
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault@.service b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault@.service
deleted file mode 100644
index f81ce05..0000000
--- a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/slot-power-fault@.service
+++ /dev/null
@@ -1,7 +0,0 @@
-[Unit]
-Description=slot power-fault:%i
-
-[Service]
-Type=oneshot
-ExecStart=/usr/libexec/phosphor-gpio-monitor/slot-power-fault %i
-SyslogIdentifier=slot-power-fault%i
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/yosemite4-phosphor-multi-gpio-monitor.json b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/yosemite4-phosphor-multi-gpio-monitor.json
index 50d0d65..6e722d6 100644
--- a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/yosemite4-phosphor-multi-gpio-monitor.json
+++ b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor/yosemite4-phosphor-multi-gpio-monitor.json
@@ -352,7 +352,7 @@
         "EventMon": "FALLING",
         "Targets": {
             "FALLING": [
-                "slot-power-fault@14.service"]
+                "check-interrupt@slot1-slot4.service"]
         },
         "Continue": true
     },
@@ -362,7 +362,7 @@
         "EventMon": "FALLING",
         "Targets": {
             "FALLING": [
-                "slot-power-fault@58.service"]
+                "check-interrupt@slot5-slot8.service"]
         },
         "Continue": true
     },
diff --git a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor_%.bbappend b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor_%.bbappend
index 38e6943..739aa70 100644
--- a/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor_%.bbappend
+++ b/meta-facebook/meta-yosemite4/recipes-phosphor/gpio/phosphor-gpio-monitor_%.bbappend
@@ -18,14 +18,14 @@
             file://rescan-wf-bic@.service \
             file://slot-hsc-fault \
             file://slot-hsc-fault@.service \
-            file://slot-power-fault \
-            file://slot-power-fault@.service \
             file://fan-board-efuse-fault \
             file://fan-board-efuse-fault@.service \
             file://enable-i3c-hub \
             file://enable-i3c-hub@.service \
             file://disable-i3c-hub \
             file://disable-i3c-hub@.service \
+            file://check-interrupt \
+            file://check-interrupt@.service \
             "
 
 RDEPENDS:${PN}:append = " bash"
@@ -41,11 +41,11 @@
     remove-nic-endpoint-slot@.service \
     rescan-wf-bic@.service \
     slot-hsc-fault@.service \
-    slot-power-fault@.service \
     fan-board-efuse-fault@.service \
     reconfig-net-interface@.service \
     enable-i3c-hub@.service \
     disable-i3c-hub@.service \
+    check-interrupt@.service \
     "
 
 SYSTEMD_AUTO_ENABLE = "enable"
@@ -63,20 +63,20 @@
     install -m 0644 ${WORKDIR}/remove-nic-endpoint-slot@.service ${D}${systemd_system_unitdir}/
     install -m 0644 ${WORKDIR}/rescan-wf-bic@.service ${D}${systemd_system_unitdir}/
     install -m 0644 ${WORKDIR}/slot-hsc-fault@.service ${D}${systemd_system_unitdir}/
-    install -m 0644 ${WORKDIR}/slot-power-fault@.service ${D}${systemd_system_unitdir}/
     install -m 0644 ${WORKDIR}/fan-board-efuse-fault@.service ${D}${systemd_system_unitdir}/
     install -m 0644 ${WORKDIR}/enable-i3c-hub@.service ${D}${systemd_system_unitdir}/
     install -m 0644 ${WORKDIR}/disable-i3c-hub@.service ${D}${systemd_system_unitdir}/
+    install -m 0644 ${WORKDIR}/check-interrupt@.service ${D}${systemd_system_unitdir}/
     install -d ${D}${libexecdir}/${PN}
     install -m 0755 ${WORKDIR}/probe-slot-device ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/reconfig-net-interface ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/rescan-fru-ocp-setting ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/rescan-wf-bic ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/slot-hsc-fault ${D}${libexecdir}/${PN}/
-    install -m 0755 ${WORKDIR}/slot-power-fault ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/fan-board-efuse-fault ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/enable-i3c-hub ${D}${libexecdir}/${PN}/
     install -m 0755 ${WORKDIR}/disable-i3c-hub ${D}${libexecdir}/${PN}/
+    install -m 0755 ${WORKDIR}/check-interrupt ${D}${libexecdir}/${PN}/
     install -d ${D}/${bindir}
     install -m 0755 ${WORKDIR}/configure-nic-mctp-endpoint ${D}/${bindir}/
 }