meta-ampere: power control: refactor power soft/off functions

The current ampere-hostctl package removes the power off/on services
of phosphor-state-manager and uses Ampere services. This solution is
not correct. Ampere platform should use power control functions of
phosphor-state-manager. And only appends or overides the default
services by Ampere's services if need.

By default, to handle power soft action, phosphor-state-manager will
trigger obmc-host-shutdown@0.target. This target then call
xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service to request OS
shutdown. When the host OS shutdown is already done, the target will
trigger obmc-chassis-poweroff@0.target to turn off the chassis. The
default xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service uses
Ipmi inband to communicate with the host. It is different with Ampere
Mt.Jade platform. We use the GPIO pin SHD_REQ to request shutdown the
host OS. The host will trigger SHD_ACK when shutdown is done. So
*.Ipmi.Internal.SoftPowerOff.service will be overide by Ampere service
named ampere.*.Ipmi.Internal.SoftPowerOff.service. This service will
trigger SHD_REQ pin and wait for SHD_ACK before start
obmc-chassis-poweroff@0.target.

This commit removes ampere-chassis-poweroff, ampere-host-shutdown
serives which handle power off/soft actions and restore
phosphor-state-manager's services. It also supports
ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service which
will overide xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service.

Tested:
    1. Create "power soft" actions use ipmitool, redfish and BMC web.
    2. Make sure the power order will be shutdown the host then power
       of the chassis.
    3. Create "power off" actions use ipmitool, redfish and BMC web.
    4. Make sure the power action will be power off the chassis.

Signed-off-by: ThuBaNguyen <thu@os.amperecomputing.com>
Change-Id: Ibc0dc8c62408e8282520c9b70e41ab75c10137f6
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
index e7c3cc1..f8e2954 100644
--- a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
+++ b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl.bb
@@ -13,10 +13,9 @@
 
 S = "${WORKDIR}"
 
-SRC_URI = "file://ampere-host-shutdown.service \
+SRC_URI = " \
           file://ampere-host-reset.service \
           file://ampere_power_util.sh \
-          file://ampere-chassis-poweroff.service \
           file://ampere-chassis-poweron.service \
           file://ampere-host-reset-ack.service \
           file://ampere-host-force-reset.service \
@@ -28,21 +27,13 @@
 
 SYSTEMD_PACKAGES = "${PN}"
 SYSTEMD_SERVICE_${PN} = " \
-        ampere-host-shutdown.service \
         ampere-host-reset.service \
-        ampere-chassis-poweroff.service \
         ampere-chassis-poweron.service \
         ampere-host-reset-ack.service \
         ampere-host-force-reset.service \
         ampere-host-power-cycle.service \
         "
 # host power control
-# overwrite the host shutdown to graceful shutdown
-HOST_SHUTDOWN_TMPL = "ampere-host-shutdown.service"
-HOST_SHUTDOWN_TGTFMT = "obmc-host-shutdown@{0}.target"
-HOST_SHUTDOWN_FMT = "../${HOST_SHUTDOWN_TMPL}:${HOST_SHUTDOWN_TGTFMT}.requires/${HOST_SHUTDOWN_TMPL}"
-SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'HOST_SHUTDOWN_FMT', 'OBMC_HOST_INSTANCES')}"
-
 # Force the power cycle target to run the ampere power cycle
 HOST_REBOOT_SVC = "ampere-host-power-cycle.service"
 HOST_REBOOT_SVC_TGTFMT = "obmc-host-reboot@{0}.target"
@@ -67,11 +58,6 @@
 CHASSIS_POWERON_FMT = "../${CHASSIS_POWERON_SVC}:${CHASSIS_POWERON_TGTFMT}.requires/${CHASSIS_POWERON_SVC}"
 SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWERON_FMT', 'OBMC_CHASSIS_INSTANCES')}"
 
-CHASSIS_POWEROFF_SVC = "ampere-chassis-poweroff.service"
-CHASSIS_POWEROFF_TGTFMT = "obmc-chassis-poweroff@{0}.target"
-CHASSIS_POWEROFF_FMT = "../${CHASSIS_POWEROFF_SVC}:${CHASSIS_POWEROFF_TGTFMT}.requires/${CHASSIS_POWEROFF_SVC}"
-SYSTEMD_LINK_${PN} += "${@compose_list_zip(d, 'CHASSIS_POWEROFF_FMT', 'OBMC_CHASSIS_INSTANCES')}"
-
 TMPL = "phosphor-gpio-monitor@.service"
 INSTFMT = "phosphor-gpio-monitor@{0}.service"
 TGT = "multi-user.target"
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service
deleted file mode 100644
index b0a1af7..0000000
--- a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-chassis-poweroff.service
+++ /dev/null
@@ -1,11 +0,0 @@
-[Unit]
-Description=Ampere Computing LLC Power OFF Chassis
-Requires=op-wait-power-off@%i.service
-Before=op-wait-power-off@%i.service
-Conflicts=obmc-chassis-poweron@0.target
-
-[Service]
-RemainAfterExit=no
-Type=oneshot
-ExecStart=/usr/bin/env ampere_power_util.sh mb off
-SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service b/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service
deleted file mode 100644
index be4d452..0000000
--- a/meta-ampere/meta-common/recipes-ac01/host/ampere-hostctrl/ampere-host-shutdown.service
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Ampere Computing LLC graceful shutdown host
-Conflicts=obmc-host-start@0.target
-OnFailure=obmc-chassis-poweroff@0.target
-
-[Service]
-RemainAfterExit=no
-Type=oneshot
-ExecStart=/usr/bin/env ampere_power_util.sh mb graceful_shutdown
-SyslogIdentifier=ampere_power_util.sh
diff --git a/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh
index 8bab9a3..9a8b06c 100644
--- a/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh
+++ b/meta-ampere/meta-common/recipes-ac01/host/files/ampere_power_util.sh
@@ -1,12 +1,11 @@
 #!/bin/bash
 # Usage of this utility
 function usage() {
-  echo "usage: power-util mb [on|off|status|cycle|reset|graceful_shutdown|graceful_reset|force_reset]";
+  echo "usage: power-util mb [on|status|cycle|reset|graceful_reset|force_reset|soft_off]";
 }
 
 power_off() {
-  echo "Shutting down Server $2"
-  busctl set-property xyz.openbmc_project.State.Chassis /xyz/openbmc_project/state/chassis0 xyz.openbmc_project.State.Chassis RequestedPowerTransition s xyz.openbmc_project.State.Chassis.Transition.Off
+  echo "power_off"
 }
 
 power_on() {
@@ -28,6 +27,19 @@
   busctl set-property xyz.openbmc_project.State.Host /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host RequestedHostTransition s xyz.openbmc_project.State.Host.Transition.Reboot
 }
 
+timestamp() {
+  date +"%s" # current time
+}
+
+shutdown_ack() {
+  if [ -f "/run/openbmc/host@0-softpoweroff" ]; then
+    echo "Receive shutdown ACK triggered after softportoff the host."
+    touch /run/openbmc/host@0-softpoweroff-shutdown-ack
+  else
+    echo "Receive shutdown ACK triggered"
+  fi
+}
+
 graceful_shutdown() {
   if [ -f "/run/openbmc/host@0-request" ]; then
     echo "shutdown host immediately"
@@ -41,6 +53,33 @@
   fi
 }
 
+soft_off() {
+  # Trigger shutdown_req
+  touch /run/openbmc/host@0-softpoweroff
+  gpioset -l 0 49=1
+  sleep 1s
+  gpioset -l 0 49=0
+
+  # Wait for shutdown_ack from the host in 30 seconds
+  cnt=30
+  while [ $cnt -gt 0 ];
+  do
+    # Wait for SHUTDOWN_ACK and create the host@0-softpoweroff-shutdown-ack
+    if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
+      break
+    fi
+    sleep 1
+    cnt=$((cnt - 1))
+  done
+  # Softpoweroff is successed
+  sleep 2
+  rm -rf /run/openbmc/host@0-softpoweroff
+  if [ -f "/run/openbmc/host@0-softpoweroff-shutdown-ack" ]; then
+    rm -rf /run/openbmc/host@0-softpoweroff-shutdown-ack
+  fi
+  echo 0
+}
+
 force_reset() {
   echo "Triggering sysreset pin"
   gpioset -l 0 91=1
@@ -65,16 +104,6 @@
   if [ $(power_status) == "off" ]; then
     power_on
   fi
-elif [ $2 = "off" ]; then
-  if [ $(power_status) == "on" ]; then
-    power_off
-  fi
-  # If any request of graceful reset, need to power on
-  if [ -f "/run/openbmc/host@0-graceful-reset" ]; then
-    sleep 20s
-    power_on
-    rm -f "/run/openbmc/host@0-graceful-reset"
-  fi
 elif [ $2 == "cycle" ]; then
   if [ $(power_status) == "on" ]; then
     echo "Powering off server"
@@ -90,8 +119,6 @@
   else
     echo "ERROR: Server not powered on"
   fi
-elif [[ $2 == "graceful_shutdown" ]]; then
-  graceful_shutdown
 elif [ $2 == "graceful_reset" ]; then
   mkdir -p "/run/openbmc/"
   touch "/run/openbmc/host@0-graceful-reset"
@@ -101,6 +128,14 @@
   power_status
 elif [ $2 == "force_reset" ]; then
   force_reset
+elif [ $2 == "soft_off" ]; then
+  ret=$(soft_off)
+  if [ $ret == 0 ]; then
+    echo "The host is already softoff"
+  else
+    echo "Failed to softoff the host"
+  fi
+  exit $ret;
 else
   echo "Invalid parameter2=$2"
   usage;
diff --git a/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend
index d54407b..78683f8 100644
--- a/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend
+++ b/meta-ampere/meta-common/recipes-phosphor/state/phosphor-state-manager_%.bbappend
@@ -4,15 +4,7 @@
 DEPS_TGT = "phosphor-discover-system-state@.service"
 SYSTEMD_OVERRIDE_${PN}-discover_append = "${DEPS_CFG}:${DEPS_TGT}.d/${DEPS_CFG}"
 
-# We don't want the obmc-host-shutdown (softoff) to require
-# obmc-chassis-poweroff. obmc-chassis-poweroff will be activated once
-# the Shutdown ACK pin is toggled (monitored by phosphor-gpio-monitor)
-HOST_STOP_FMT = ""
-HOST_REBOOT_FMT = ""
-
 pkg_postinst_${PN}-obmc-targets_append() {
-    rm "$D$systemd_system_unitdir/obmc-host-shutdown@0.target.requires/obmc-chassis-poweroff@0.target"
-
     rm "$D$systemd_system_unitdir/obmc-host-warm-reboot@0.target.requires/xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service"
     rm "$D$systemd_system_unitdir/obmc-host-warm-reboot@0.target.requires/obmc-host-force-warm-reboot@0.target"
 
diff --git a/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere-phosphor-softpoweroff b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere-phosphor-softpoweroff
new file mode 100644
index 0000000..214aeed
--- /dev/null
+++ b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere-phosphor-softpoweroff
@@ -0,0 +1,5 @@
+#!/bin/bash
+# Usage of this utility
+echo "Trigger soft off the host."
+/usr/sbin/ampere_power_util.sh mb soft_off
+exit $?;
diff --git a/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service
new file mode 100644
index 0000000..01b31b1
--- /dev/null
+++ b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host/ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Ampere Soft power off of the host
+Wants=obmc-host-stop-pre@0.target
+Before=obmc-host-stop-pre@0.target
+Conflicts=obmc-host-start@0.target
+ConditionPathExists=!/run/openbmc/host@0-request
+ConditionPathExists=!/lib/systemd/system/pldmSoftPowerOff.service
+
+[Service]
+Restart=no
+ExecStart=/usr/bin/env phosphor-softpoweroff
+SyslogIdentifier=phosphor-softpoweroff
+Type=oneshot
diff --git a/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
index c0bcbdd..b8ea8d8 100644
--- a/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
+++ b/meta-ampere/meta-jade/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend
@@ -3,13 +3,23 @@
 DEPENDS_append_mtjade = " mtjade-yaml-config"
 
 RRECOMMENDS_${PN} += "ipmitool"
+RDEPENDS_${PN} += "bash"
+
+SRC_URI += " \
+            file://ampere-phosphor-softpoweroff \
+            file://ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service \
+            "
 
 EXTRA_OECONF_mtjade = " \
     SENSOR_YAML_GEN=${STAGING_DIR_HOST}${datadir}/mtjade-yaml-config/ipmi-sensors-${MACHINE}.yaml \
     FRU_YAML_GEN=${STAGING_DIR_HOST}${datadir}/mtjade-yaml-config/ipmi-fru-read.yaml \
     "
 
+AMPERE_SOFTPOWEROFF_TMPL = "ampere.xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service"
+
 do_install_append_mtjade(){
     install -d ${D}${includedir}/phosphor-ipmi-host
     install -m 0644 -D ${S}/selutility.hpp ${D}${includedir}/phosphor-ipmi-host
+    install -m 0755 ${WORKDIR}/ampere-phosphor-softpoweroff ${D}/${bindir}/phosphor-softpoweroff
+    install -m 0644 ${WORKDIR}/${AMPERE_SOFTPOWEROFF_TMPL} ${D}${systemd_unitdir}/system/xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service
 }