Reinvent x86 power control application

The previous application that was posted here had a TON of timing
issues that made it basically unworkable, and was missing several
features (like power button override, VR timers, ect) that weren't
really possible in the old scheme.

This commit shows a reimagining of power control on the AST2500, and
seems to work much more reliably in testing across several platforms.

The key differentiators here are:
1. It gets rid of the target files.  Despite _many_ attempts to make the
target file approach reliable across 1000/10000 reboot cycle testings,
it was clear that the timing differences in the activation times caused
too many hard to fix race conditions.  To this end, the power state
machine has been moved into c++, where we can be very explicit about our
IO, and event timings.
2. It implements several features that were not present in the old
implementation, like soft power cycle.  These were required to implement
the full Redfish ComputerSystem schema properly.
3. It implements proper handling when collisions occur.  For example
when two power off requests come in at the same time.  Because of #1 we
can now service both of these requests "correctly" and remove the
possibility of desyncronizing the state machine from the host state.

A majority of this work was accomplished by Jason Bills.  The history is
available here, which can be pushed if needed, but I don't beleive it's
wanted.

https://github.com/Intel-BMC/intel-chassis-control/commits/master

Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Change-Id: I2eb7fb1dbcab3d374df9d2e8c62407f0277e2583
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0aa5bb4..8186017 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/gpio/inc)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/i2c/inc)
 
-add_subdirectory(gpio)
-add_subdirectory(power-control)
+add_subdirectory(i2c)
+add_subdirectory(power-control-x86)
diff --git a/README.md b/README.md
index 56f5d95..b1c74b2 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,46 @@
-# x86-power-control
\ No newline at end of file
+# X86 power control
+
+This repository contains an OpenBMC compliant implementation of power control
+for x86 servers.  It relies on a number of features to do its job.  It has
+several intentional design goals.
+1. The BMC should maintain the Host state machine internally, and be able to
+   track state changes.
+2. The implementation should either give the requested power control result, or
+   should log an error on the failure it detected.
+3. The BMC should support all the common operations, hard power on/off/cycle,
+   soft power on/off/cycle.
+
+At this point in time, this daemon targets Lewisburg based, dual socket x86
+server platforms, such as S2600WFT.  It is likely that other platforms will work
+as well.
+
+Because this relies on the hardware passthrough support in the AST2500 to
+function, it requires a few patches to work correctly.
+
+This patch adds support to UBOOT to keep the passthrough enabled
+https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-common/
+recipes-bsp/u-boot/files/0005-enable-passthrough-in-uboot.patch
+
+The DTS file for your platform will need the following GPIO definitions
+RESET_BUTTON
+RESET_OUT
+POWER_BUTTON
+POWER_OUT
+
+On an aspeed, these are generally connected to E0, E1, E2, and E3 respecitvely.
+An example of this is available in the s2600WF config.
+
+This patch allows the passthrough to be reenabled to the default condition when
+the appropriate pin is released.  This allows power control to take control
+when needed by a user power action, but leave the hardware in control a majority
+of the time, reducing the possibilty of bricking a system due to a failed BMC.
+
+https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-ast2500/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch
+https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-ast2500/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch
+https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-ast2500/recipes-kernel/linux/linux-aspeed/0006-Allow-monitoring-of-power-control-input-GPIOs.patch
+
+
+Caveats:
+This implementation does not currently implement the common targets that other
+implementations do.  There were several attempts to, but all ended in timing
+issues and boot inconsistencies during stress operations.
diff --git a/gpio/src/gpio.cpp b/gpio/src/gpio.cpp
deleted file mode 100644
index d31782f..0000000
--- a/gpio/src/gpio.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-
-#include "gpio.hpp"
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <experimental/filesystem>
-#include <fstream>
-#include <phosphor-logging/elog-errors.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
-
-const static constexpr char* SYSMGR_SERVICE = "org.openbmc.managers.System";
-const static constexpr char* SYSMGR_OBJ_PATH = "/org/openbmc/managers/System";
-const static constexpr char* SYSMGR_INTERFACE = "org.openbmc.managers.System";
-
-int closeGpio(int fd)
-{
-    if (fd > 0)
-    {
-        ::close(fd);
-    }
-    return 0;
-}
-
-int configGpio(const char* gpioName, int* fd, sdbusplus::bus::bus& bus)
-{
-    sdbusplus::message::message method = bus.new_method_call(
-        SYSMGR_SERVICE, SYSMGR_OBJ_PATH, SYSMGR_INTERFACE, "gpioInit");
-
-    method.append(gpioName);
-
-    sdbusplus::message::message result = bus.call(method);
-
-    if (result.is_method_error())
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "configGPIO: bus call error!");
-        return -1;
-    }
-
-    int32_t gpioNum = -1;
-    std::string gpioDev;
-    std::string gpioDirection;
-
-    result.read(gpioDev, gpioNum, gpioDirection);
-
-    if (gpioDev.empty())
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "configGPIO: gpioDev error!");
-        return -1;
-    }
-
-    if (gpioDirection.empty())
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "configGPIO: gpioDirection error!");
-        return -1;
-    }
-
-    std::fstream stream;
-
-    stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
-
-    std::string devPath =
-        gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
-
-    std::experimental::filesystem::path fullPath(devPath);
-
-    if (std::experimental::filesystem::exists(fullPath))
-    {
-        phosphor::logging::log<phosphor::logging::level::INFO>(
-            "GPIO exported",
-            phosphor::logging::entry("PATH=%s", devPath.c_str()));
-    }
-    else
-    {
-        devPath = gpioDev + "/export";
-
-        stream.open(devPath, std::fstream::out);
-
-        if (!stream.good())
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in opening for write!",
-                phosphor::logging::entry("PATH=%s", devPath.c_str()),
-                phosphor::logging::entry("NUM=%d", gpioNum));
-            return -1;
-        }
-
-        stream << gpioNum;
-        stream.close();
-    }
-
-    if (gpioDirection == "out")
-    {
-        devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
-
-        uint32_t currentValue = 0;
-
-        stream.open(devPath, std::fstream::in);
-
-        if (!stream.good())
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in opening for read!",
-                phosphor::logging::entry("PATH=%s", devPath.c_str()));
-            return -1;
-        }
-
-        stream >> currentValue;
-        stream.close();
-
-        const char* direction = currentValue ? "high" : "low";
-
-        devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/direction";
-
-        stream.open(devPath, std::fstream::out);
-
-        if (!stream.good())
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in opening for write!");
-            return -1;
-        }
-
-        stream << direction;
-        stream.close();
-    }
-    else if (gpioDirection == "in")
-    {
-        devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/direction";
-
-        stream.open(devPath, std::fstream::out);
-
-        if (!stream.good())
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in opening for write!");
-            return -1;
-        }
-
-        stream << gpioDirection;
-        stream.close();
-    }
-    else if (gpioDirection == "both")
-    {
-
-        // For gpio configured as ‘both’, it is an interrupt pin and trigged on
-        // both rising and falling signals
-        devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/edge";
-
-        stream.open(devPath, std::fstream::out);
-
-        if (!stream.good())
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error in opening for write!");
-            return -1;
-        }
-
-        stream << gpioDirection;
-        stream.close();
-    }
-
-    devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
-
-    *fd = ::open(devPath.c_str(), O_RDWR | O_NONBLOCK);
-
-    if (*fd < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("open error!");
-        return -1;
-    }
-
-    return 0;
-}
diff --git a/gpio/CMakeLists.txt b/i2c/CMakeLists.txt
similarity index 92%
rename from gpio/CMakeLists.txt
rename to i2c/CMakeLists.txt
index b2d25ab..273a42a 100644
--- a/gpio/CMakeLists.txt
+++ b/i2c/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
-project(chassisgpio CXX)
+project(chassisi2c CXX)
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
@@ -15,7 +15,7 @@
 include(GNUInstallDirs)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
 
-add_library(${PROJECT_NAME} SHARED src/gpio.cpp)
+add_library(${PROJECT_NAME} SHARED src/i2c.cpp)
 
 set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "0.1.0")
 set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION "0")
@@ -27,7 +27,7 @@
   ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT stlib
   COMPONENT dev)
 
-install(FILES "inc/gpio.hpp"
+install(FILES "inc/i2c.hpp"
   DESTINATION "${INSTALL_INCLUDE_DIR}/" )
 
 install(EXPORT "${PROJECT_NAME}EXPORT"
diff --git a/gpio/inc/gpio.hpp b/i2c/inc/i2c.hpp
similarity index 79%
rename from gpio/inc/gpio.hpp
rename to i2c/inc/i2c.hpp
index 876b5ce..0aa3a52 100644
--- a/gpio/inc/gpio.hpp
+++ b/i2c/inc/i2c.hpp
@@ -15,8 +15,11 @@
 */
 
 #pragma once
+#include <cstdint>
 
-#include <sdbusplus/bus.hpp>
+extern "C" {
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
 
-int configGpio(const char* gpioName, int* fd, sdbusplus::bus::bus& bus);
-int closeGpio(int fd);
+int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value);
diff --git a/i2c/src/i2c.cpp b/i2c/src/i2c.cpp
new file mode 100644
index 0000000..dcef067
--- /dev/null
+++ b/i2c/src/i2c.cpp
@@ -0,0 +1,93 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "i2c.hpp"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+// TODO Add 16-bit I2C support in the furture
+int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value)
+{
+    unsigned long funcs = 0;
+    std::string devPath = "/dev/i2c-" + std::to_string(bus);
+
+    int fd = ::open(devPath.c_str(), O_RDWR);
+    if (fd < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error in open!",
+            phosphor::logging::entry("PATH=%s", devPath.c_str()),
+            phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
+        return -1;
+    }
+
+    if (::ioctl(fd, I2C_FUNCS, &funcs) < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error in I2C_FUNCS!",
+            phosphor::logging::entry("PATH=%s", devPath.c_str()),
+            phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
+
+        ::close(fd);
+        return -1;
+    }
+
+    if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+    {
+
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "i2c bus does not support write!",
+            phosphor::logging::entry("PATH=%s", devPath.c_str()),
+            phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
+        ::close(fd);
+        return -1;
+    }
+
+    if (::ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error in I2C_SLAVE_FORCE!",
+            phosphor::logging::entry("PATH=%s", devPath.c_str()),
+            phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
+        ::close(fd);
+        return -1;
+    }
+
+    if (::i2c_smbus_write_byte_data(fd, regAddr, value) < 0)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Error in i2c write!",
+            phosphor::logging::entry("PATH=%s", devPath.c_str()),
+            phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
+        ::close(fd);
+        return -1;
+    }
+
+    // TODO For testing, will remove the below debug loging in the future
+    phosphor::logging::log<phosphor::logging::level::DEBUG>(
+        "i2cset successfully",
+        phosphor::logging::entry("PATH=%s", devPath.c_str()),
+        phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr),
+        phosphor::logging::entry("REGADDR=0x%x", regAddr),
+        phosphor::logging::entry("VALUE=0x%x", value));
+    ::close(fd);
+    return 0;
+}
diff --git a/power-control-x86/CMakeLists.txt b/power-control-x86/CMakeLists.txt
new file mode 100644
index 0000000..a2426d8
--- /dev/null
+++ b/power-control-x86/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
+project(power-control CXX)
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
+add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
+add_definitions(-DBOOST_ALL_NO_LIB)
+add_definitions(-DBOOST_NO_RTTI)
+add_definitions(-DBOOST_NO_TYPEID)
+add_definitions(-DBOOST_ASIO_DISABLE_THREADS)
+
+set(SRC_FILES src/power_control.cpp)
+
+add_executable(${PROJECT_NAME} ${SRC_FILES})
+target_link_libraries(${PROJECT_NAME} -lstdc++fs)
+target_link_libraries(${PROJECT_NAME} chassisi2c)
+target_link_libraries(${PROJECT_NAME} i2c)
+target_link_libraries(${PROJECT_NAME} gpiodcxx)
+target_link_libraries(${PROJECT_NAME} systemd)
+target_link_libraries(${PROJECT_NAME} sdbusplus)
+
+install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti")
+
+set(
+  SERVICE_FILES
+  ${PROJECT_SOURCE_DIR}/service_files/xyz.openbmc_project.Chassis.Control.Power.service
+  )
+install(FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/)
diff --git a/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service b/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service
new file mode 100644
index 0000000..a80235e
--- /dev/null
+++ b/power-control-x86/service_files/xyz.openbmc_project.Chassis.Control.Power.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Intel Power Control
+
+[Service]
+Restart=always
+RestartSec=3
+ExecStart=/usr/bin/power-control
+Type=dbus
+BusName=xyz.openbmc_project.State.Host
+
+[Install]
+WantedBy=sysinit.target
+
diff --git a/power-control-x86/src/power_control.cpp b/power-control-x86/src/power_control.cpp
new file mode 100644
index 0000000..dce3440
--- /dev/null
+++ b/power-control-x86/src/power_control.cpp
@@ -0,0 +1,2145 @@
+/*
+// Copyright (c) 2018-2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "i2c.hpp"
+
+#include <sys/sysinfo.h>
+#include <systemd/sd-journal.h>
+
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <boost/container/flat_map.hpp>
+#include <filesystem>
+#include <fstream>
+#include <gpiod.hpp>
+#include <iostream>
+#include <sdbusplus/asio/object_server.hpp>
+#include <string_view>
+
+namespace power_control
+{
+static boost::asio::io_service io;
+std::shared_ptr<sdbusplus::asio::connection> conn;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> hostIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> chassisIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> powerButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> resetButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> nmiButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> osIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> idButtonIface;
+
+static gpiod::line powerButtonMask;
+static gpiod::line resetButtonMask;
+static bool nmiButtonMasked = false;
+static bool resetInProgress = false;
+
+const static constexpr int powerPulseTimeMs = 200;
+const static constexpr int forceOffPulseTimeMs = 15000;
+const static constexpr int resetPulseTimeMs = 500;
+const static constexpr int powerCycleTimeMs = 1000;
+const static constexpr int sioPowerGoodWatchdogTimeMs = 1000;
+const static constexpr int psPowerOKWatchdogTimeMs = 8000;
+const static constexpr int gracefulPowerOffTimeMs = 60000;
+const static constexpr int buttonMaskTimeMs = 60000;
+const static constexpr int powerOffSaveTimeMs = 7000;
+
+const static std::filesystem::path powerControlDir = "/var/lib/power-control";
+const static constexpr std::string_view powerStateFile = "power-state";
+
+static bool nmiEnabled = true;
+static constexpr const char* nmiOutName = "NMI_OUT";
+
+// Timers
+// Time holding GPIOs asserted
+static boost::asio::steady_timer gpioAssertTimer(io);
+// Time between off and on during a power cycle
+static boost::asio::steady_timer powerCycleTimer(io);
+// Time OS gracefully powering off
+static boost::asio::steady_timer gracefulPowerOffTimer(io);
+// Time power supply power OK assertion on power-on
+static boost::asio::steady_timer psPowerOKWatchdogTimer(io);
+// Time SIO power good assertion on power-on
+static boost::asio::steady_timer sioPowerGoodWatchdogTimer(io);
+// Time power-off state save for power loss tracking
+static boost::asio::steady_timer powerStateSaveTimer(io);
+// POH timer
+static boost::asio::steady_timer pohCounterTimer(io);
+
+// GPIO Lines and Event Descriptors
+static gpiod::line psPowerOKLine;
+static boost::asio::posix::stream_descriptor psPowerOKEvent(io);
+static gpiod::line sioPowerGoodLine;
+static boost::asio::posix::stream_descriptor sioPowerGoodEvent(io);
+static gpiod::line sioOnControlLine;
+static boost::asio::posix::stream_descriptor sioOnControlEvent(io);
+static gpiod::line sioS5Line;
+static boost::asio::posix::stream_descriptor sioS5Event(io);
+static gpiod::line powerButtonLine;
+static boost::asio::posix::stream_descriptor powerButtonEvent(io);
+static gpiod::line resetButtonLine;
+static boost::asio::posix::stream_descriptor resetButtonEvent(io);
+static gpiod::line nmiButtonLine;
+static boost::asio::posix::stream_descriptor nmiButtonEvent(io);
+static gpiod::line idButtonLine;
+static boost::asio::posix::stream_descriptor idButtonEvent(io);
+static gpiod::line postCompleteLine;
+static boost::asio::posix::stream_descriptor postCompleteEvent(io);
+static gpiod::line nmiOutLine;
+
+static constexpr uint8_t beepPowerFail = 8;
+
+static void beep(const uint8_t& beepPriority)
+{
+    std::cerr << "Beep with priority: " << (unsigned)beepPriority << "\n";
+
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "beep returned error with "
+                             "async_method_call (ec = "
+                          << ec << ")\n";
+                return;
+            }
+        },
+        "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
+        "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
+}
+
+enum class PowerState
+{
+    on,
+    waitForPSPowerOK,
+    waitForSIOPowerGood,
+    failedTransitionToOn,
+    off,
+    transitionToOff,
+    gracefulTransitionToOff,
+    cycleOff,
+    transitionToCycleOff,
+    gracefulTransitionToCycleOff,
+};
+static PowerState powerState;
+static std::string getPowerStateName(PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+            return "On";
+            break;
+        case PowerState::waitForPSPowerOK:
+            return "Wait for Power Supply Power OK";
+            break;
+        case PowerState::waitForSIOPowerGood:
+            return "Wait for SIO Power Good";
+            break;
+        case PowerState::failedTransitionToOn:
+            return "Failed Transition to On";
+            break;
+        case PowerState::off:
+            return "Off";
+            break;
+        case PowerState::transitionToOff:
+            return "Transition to Off";
+            break;
+        case PowerState::gracefulTransitionToOff:
+            return "Graceful Transition to Off";
+            break;
+        case PowerState::cycleOff:
+            return "Power Cycle Off";
+            break;
+        case PowerState::transitionToCycleOff:
+            return "Transition to Power Cycle Off";
+            break;
+        case PowerState::gracefulTransitionToCycleOff:
+            return "Graceful Transition to Power Cycle Off";
+            break;
+        default:
+            return "unknown state: " + std::to_string(static_cast<int>(state));
+            break;
+    }
+}
+static void logStateTransition(const PowerState state)
+{
+    std::cerr << "Moving to \"" << getPowerStateName(state) << "\" state.\n";
+}
+
+enum class Event
+{
+    psPowerOKAssert,
+    psPowerOKDeAssert,
+    sioPowerGoodAssert,
+    sioPowerGoodDeAssert,
+    sioS5Assert,
+    sioS5DeAssert,
+    powerButtonPressed,
+    powerCycleTimerExpired,
+    psPowerOKWatchdogTimerExpired,
+    sioPowerGoodWatchdogTimerExpired,
+    gracefulPowerOffTimerExpired,
+    powerOnRequest,
+    powerOffRequest,
+    powerCycleRequest,
+    resetRequest,
+    gracefulPowerOffRequest,
+    gracefulPowerCycleRequest,
+};
+static std::string getEventName(Event event)
+{
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            return "power supply power OK assert";
+            break;
+        case Event::psPowerOKDeAssert:
+            return "power supply power OK de-assert";
+            break;
+        case Event::sioPowerGoodAssert:
+            return "SIO power good assert";
+            break;
+        case Event::sioPowerGoodDeAssert:
+            return "SIO power good de-assert";
+            break;
+        case Event::sioS5Assert:
+            return "SIO S5 assert";
+            break;
+        case Event::sioS5DeAssert:
+            return "SIO S5 de-assert";
+            break;
+        case Event::powerButtonPressed:
+            return "power button pressed";
+            break;
+        case Event::powerCycleTimerExpired:
+            return "power cycle timer expired";
+            break;
+        case Event::psPowerOKWatchdogTimerExpired:
+            return "power supply power OK watchdog timer expired";
+            break;
+        case Event::sioPowerGoodWatchdogTimerExpired:
+            return "SIO power good watchdog timer expired";
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            return "graceful power-off timer expired";
+            break;
+        case Event::powerOnRequest:
+            return "power-on request";
+            break;
+        case Event::powerOffRequest:
+            return "power-off request";
+            break;
+        case Event::powerCycleRequest:
+            return "power-cycle request";
+            break;
+        case Event::resetRequest:
+            return "reset request";
+            break;
+        case Event::gracefulPowerOffRequest:
+            return "graceful power-off request";
+            break;
+        case Event::gracefulPowerCycleRequest:
+            return "graceful power-cycle request";
+            break;
+        default:
+            return "unknown event: " + std::to_string(static_cast<int>(event));
+            break;
+    }
+}
+static void logEvent(const std::string_view stateHandler, const Event event)
+{
+    std::cerr << stateHandler << ": " << getEventName(event)
+              << " event received.\n";
+}
+
+// Power state handlers
+static void powerStateOn(const Event event);
+static void powerStateWaitForPSPowerOK(const Event event);
+static void powerStateWaitForSIOPowerGood(const Event event);
+static void powerStateFailedTransitionToOn(const Event event);
+static void powerStateOff(const Event event);
+static void powerStateTransitionToOff(const Event event);
+static void powerStateGracefulTransitionToOff(const Event event);
+static void powerStateCycleOff(const Event event);
+static void powerStateTransitionToCycleOff(const Event event);
+static void powerStateGracefulTransitionToCycleOff(const Event event);
+
+static std::function<void(const Event)> getPowerStateHandler(PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+            return powerStateOn;
+            break;
+        case PowerState::waitForPSPowerOK:
+            return powerStateWaitForPSPowerOK;
+            break;
+        case PowerState::waitForSIOPowerGood:
+            return powerStateWaitForSIOPowerGood;
+            break;
+        case PowerState::failedTransitionToOn:
+            return powerStateFailedTransitionToOn;
+            break;
+        case PowerState::off:
+            return powerStateOff;
+            break;
+        case PowerState::transitionToOff:
+            return powerStateTransitionToOff;
+            break;
+        case PowerState::gracefulTransitionToOff:
+            return powerStateGracefulTransitionToOff;
+            break;
+        case PowerState::cycleOff:
+            return powerStateCycleOff;
+            break;
+        case PowerState::transitionToCycleOff:
+            return powerStateTransitionToCycleOff;
+            break;
+        case PowerState::gracefulTransitionToCycleOff:
+            return powerStateGracefulTransitionToCycleOff;
+            break;
+        default:
+            return std::function<void(const Event)>{};
+            break;
+    }
+};
+
+static void sendPowerControlEvent(const Event event)
+{
+    std::function<void(const Event)> handler = getPowerStateHandler(powerState);
+    if (handler == nullptr)
+    {
+        std::cerr << "Failed to find handler for power state: "
+                  << static_cast<int>(powerState) << "\n";
+        return;
+    }
+    handler(event);
+}
+
+static uint64_t getCurrentTimeMs()
+{
+    struct timespec time = {};
+
+    if (clock_gettime(CLOCK_REALTIME, &time) < 0)
+    {
+        return 0;
+    }
+    uint64_t currentTimeMs = static_cast<uint64_t>(time.tv_sec) * 1000;
+    currentTimeMs += static_cast<uint64_t>(time.tv_nsec) / 1000 / 1000;
+
+    return currentTimeMs;
+}
+
+static constexpr std::string_view getHostState(const PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+        case PowerState::transitionToOff:
+        case PowerState::gracefulTransitionToOff:
+        case PowerState::transitionToCycleOff:
+        case PowerState::gracefulTransitionToCycleOff:
+            return "xyz.openbmc_project.State.Host.HostState.Running";
+            break;
+        case PowerState::waitForPSPowerOK:
+        case PowerState::waitForSIOPowerGood:
+        case PowerState::failedTransitionToOn:
+        case PowerState::off:
+        case PowerState::cycleOff:
+            return "xyz.openbmc_project.State.Host.HostState.Off";
+            break;
+        default:
+            return "";
+            break;
+    }
+};
+static constexpr std::string_view getChassisState(const PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+        case PowerState::transitionToOff:
+        case PowerState::gracefulTransitionToOff:
+        case PowerState::transitionToCycleOff:
+        case PowerState::gracefulTransitionToCycleOff:
+            return "xyz.openbmc_project.State.Chassis.PowerState.On";
+            break;
+        case PowerState::waitForPSPowerOK:
+        case PowerState::waitForSIOPowerGood:
+        case PowerState::failedTransitionToOn:
+        case PowerState::off:
+        case PowerState::cycleOff:
+            return "xyz.openbmc_project.State.Chassis.PowerState.Off";
+            break;
+        default:
+            return "";
+            break;
+    }
+};
+static void savePowerState(const PowerState state)
+{
+    powerStateSaveTimer.expires_after(
+        std::chrono::milliseconds(powerOffSaveTimeMs));
+    powerStateSaveTimer.async_wait([state](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Power-state save async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        std::ofstream powerStateStream(powerControlDir / powerStateFile);
+        powerStateStream << getChassisState(state);
+    });
+}
+static void setPowerState(const PowerState state)
+{
+    powerState = state;
+    logStateTransition(state);
+
+    hostIface->set_property("CurrentHostState",
+                            std::string(getHostState(powerState)));
+
+    chassisIface->set_property("CurrentPowerState",
+                               std::string(getChassisState(powerState)));
+    chassisIface->set_property("LastStateChangeTime", getCurrentTimeMs());
+
+    // Save the power state for the restore policy
+    savePowerState(state);
+}
+
+enum class RestartCause
+{
+    command,
+    resetButton,
+    powerButton,
+    powerPolicyOn,
+    powerPolicyRestore,
+    softReset,
+};
+static std::string getRestartCause(RestartCause cause)
+{
+    switch (cause)
+    {
+        case RestartCause::command:
+            return "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand";
+            break;
+        case RestartCause::resetButton:
+            return "xyz.openbmc_project.State.Host.RestartCause.ResetButton";
+            break;
+        case RestartCause::powerButton:
+            return "xyz.openbmc_project.State.Host.RestartCause.PowerButton";
+            break;
+        case RestartCause::powerPolicyOn:
+            return "xyz.openbmc_project.State.Host.RestartCause."
+                   "PowerPolicyAlwaysOn";
+            break;
+        case RestartCause::powerPolicyRestore:
+            return "xyz.openbmc_project.State.Host.RestartCause."
+                   "PowerPolicyPreviousState";
+            break;
+        case RestartCause::softReset:
+            return "xyz.openbmc_project.State.Host.RestartCause.SoftReset";
+            break;
+        default:
+            return "xyz.openbmc_project.State.Host.RestartCause.Unknown";
+            break;
+    }
+}
+static void setRestartCause(const RestartCause cause)
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set RestartCause\n";
+            }
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/restart_cause",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Common.RestartCause", "RestartCause",
+        std::variant<std::string>(getRestartCause(cause)));
+}
+
+static void powerRestorePolicyLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: power restore policy applied",
+                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.PowerRestorePolicyApplied", NULL);
+}
+
+static void powerButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.PowerButtonPressed", NULL);
+}
+
+static void resetButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: reset button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.ResetButtonPressed", NULL);
+}
+
+static void nmiButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: NMI button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.NMIButtonPressed", NULL);
+}
+
+static void nmiDiagIntLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: NMI Diagnostic Interrupt",
+                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.NMIDiagnosticInterrupt", NULL);
+}
+
+static int initializePowerStateStorage()
+{
+    // create the power control directory if it doesn't exist
+    std::error_code ec;
+    if (!(std::filesystem::create_directories(powerControlDir, ec)))
+    {
+        if (ec.value() != 0)
+        {
+            std::cerr << "failed to create " << powerControlDir << ": "
+                      << ec.message() << "\n";
+            return -1;
+        }
+    }
+    // Create the power state file if it doesn't exist
+    if (!std::filesystem::exists(powerControlDir / powerStateFile))
+    {
+        std::ofstream powerStateStream(powerControlDir / powerStateFile);
+        powerStateStream << getChassisState(powerState);
+    }
+    return 0;
+}
+
+static bool wasPowerDropped()
+{
+    std::ifstream powerStateStream(powerControlDir / powerStateFile);
+    if (!powerStateStream.is_open())
+    {
+        std::cerr << "Failed to open power state file\n";
+        return false;
+    }
+
+    std::string state;
+    std::getline(powerStateStream, state);
+    return state == "xyz.openbmc_project.State.Chassis.PowerState.On";
+}
+
+static void invokePowerRestorePolicy(const std::string& policy)
+{
+    // Async events may call this twice, but we only want to run once
+    static bool policyInvoked = false;
+    if (policyInvoked)
+    {
+        return;
+    }
+    policyInvoked = true;
+
+    std::cerr << "Power restore delay expired, invoking " << policy << "\n";
+    if (policy ==
+        "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
+    {
+        sendPowerControlEvent(Event::powerOnRequest);
+        setRestartCause(RestartCause::powerPolicyOn);
+    }
+    else if (policy == "xyz.openbmc_project.Control.Power.RestorePolicy."
+                       "Policy.Restore")
+    {
+        if (wasPowerDropped())
+        {
+            std::cerr << "Power was dropped, restoring Host On state\n";
+            sendPowerControlEvent(Event::powerOnRequest);
+            setRestartCause(RestartCause::powerPolicyRestore);
+        }
+        else
+        {
+            std::cerr << "No power drop, restoring Host Off state\n";
+        }
+    }
+}
+
+static void powerRestorePolicyDelay(int delay)
+{
+    // Async events may call this twice, but we only want to run once
+    static bool delayStarted = false;
+    if (delayStarted)
+    {
+        return;
+    }
+    delayStarted = true;
+    // Calculate the delay from now to meet the requested delay
+    // Subtract the approximate uboot time
+    static constexpr const int ubootSeconds = 20;
+    delay -= ubootSeconds;
+    // Subtract the time since boot
+    struct sysinfo info = {};
+    if (sysinfo(&info) == 0)
+    {
+        delay -= info.uptime;
+    }
+    // 0 is the minimum delay
+    delay = std::max(delay, 0);
+
+    static boost::asio::steady_timer powerRestorePolicyTimer(io);
+    powerRestorePolicyTimer.expires_after(std::chrono::seconds(delay));
+    std::cerr << "Power restore delay of " << delay << " seconds started\n";
+    powerRestorePolicyTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "power restore policy async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        // Get Power Restore Policy
+        // In case PowerRestorePolicy is not available, set a match for it
+        static std::unique_ptr<sdbusplus::bus::match::match>
+            powerRestorePolicyMatch = std::make_unique<
+                sdbusplus::bus::match::match>(
+                *conn,
+                "type='signal',interface='org.freedesktop.DBus.Properties',"
+                "member='PropertiesChanged',arg0namespace='xyz.openbmc_"
+                "project.Control.Power.RestorePolicy'",
+                [](sdbusplus::message::message& msg) {
+                    std::string interfaceName;
+                    boost::container::flat_map<std::string,
+                                               std::variant<std::string>>
+                        propertiesChanged;
+                    std::string policy;
+                    try
+                    {
+                        msg.read(interfaceName, propertiesChanged);
+                        policy = std::get<std::string>(
+                            propertiesChanged.begin()->second);
+                    }
+                    catch (std::exception& e)
+                    {
+                        std::cerr
+                            << "Unable to read power restore policy value\n";
+                        powerRestorePolicyMatch.reset();
+                        return;
+                    }
+                    invokePowerRestorePolicy(policy);
+                    powerRestorePolicyMatch.reset();
+                });
+
+        // Check if it's already on DBus
+        conn->async_method_call(
+            [](boost::system::error_code ec,
+               const std::variant<std::string>& policyProperty) {
+                if (ec)
+                {
+                    return;
+                }
+                powerRestorePolicyMatch.reset();
+                const std::string* policy =
+                    std::get_if<std::string>(&policyProperty);
+                if (policy == nullptr)
+                {
+                    std::cerr << "Unable to read power restore policy value\n";
+                    return;
+                }
+                invokePowerRestorePolicy(*policy);
+            },
+            "xyz.openbmc_project.Settings",
+            "/xyz/openbmc_project/control/host0/power_restore_policy",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.Control.Power.RestorePolicy",
+            "PowerRestorePolicy");
+    });
+}
+
+static void powerRestorePolicyStart()
+{
+    std::cerr << "Power restore policy started\n";
+    powerRestorePolicyLog();
+
+    // Get the desired delay time
+    // In case PowerRestoreDelay is not available, set a match for it
+    static std::unique_ptr<sdbusplus::bus::match::match>
+        powerRestoreDelayMatch = std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Control."
+            "Power.RestoreDelay'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string, std::variant<uint16_t>>
+                    propertiesChanged;
+                int delay = 0;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    delay =
+                        std::get<uint16_t>(propertiesChanged.begin()->second);
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read power restore delay value\n";
+                    powerRestoreDelayMatch.reset();
+                    return;
+                }
+                powerRestorePolicyDelay(delay);
+                powerRestoreDelayMatch.reset();
+            });
+
+    // Check if it's already on DBus
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const std::variant<uint16_t>& delayProperty) {
+            if (ec)
+            {
+                return;
+            }
+            powerRestoreDelayMatch.reset();
+            const uint16_t* delay = std::get_if<uint16_t>(&delayProperty);
+            if (delay == nullptr)
+            {
+                std::cerr << "Unable to read power restore delay value\n";
+                return;
+            }
+            powerRestorePolicyDelay(*delay);
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/power_restore_delay",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Control.Power.RestoreDelay", "PowerRestoreDelay");
+}
+
+static void powerRestorePolicyCheck()
+{
+    // In case ACBoot is not available, set a match for it
+    static std::unique_ptr<sdbusplus::bus::match::match> acBootMatch =
+        std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Common."
+            "ACBoot'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string,
+                                           std::variant<std::string>>
+                    propertiesChanged;
+                std::string acBoot;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    acBoot = std::get<std::string>(
+                        propertiesChanged.begin()->second);
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read AC Boot status\n";
+                    acBootMatch.reset();
+                    return;
+                }
+                if (acBoot == "Unknown")
+                {
+                    return;
+                }
+                if (acBoot == "True")
+                {
+                    // Start the Power Restore policy
+                    powerRestorePolicyStart();
+                }
+                acBootMatch.reset();
+            });
+
+    // Check if it's already on DBus
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const std::variant<std::string>& acBootProperty) {
+            if (ec)
+            {
+                return;
+            }
+            const std::string* acBoot =
+                std::get_if<std::string>(&acBootProperty);
+            if (acBoot == nullptr)
+            {
+                std::cerr << "Unable to read AC Boot status\n";
+                return;
+            }
+            if (*acBoot == "Unknown")
+            {
+                return;
+            }
+            if (*acBoot == "True")
+            {
+                // Start the Power Restore policy
+                powerRestorePolicyStart();
+            }
+            acBootMatch.reset();
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/ac_boot",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Common.ACBoot", "ACBoot");
+}
+
+static bool requestGPIOEvents(
+    const std::string& name, const std::function<void()>& handler,
+    gpiod::line& gpioLine,
+    boost::asio::posix::stream_descriptor& gpioEventDescriptor)
+{
+    // Find the GPIO line
+    gpioLine = gpiod::find_line(name);
+    if (!gpioLine)
+    {
+        std::cerr << "Failed to find the " << name << " line\n";
+        return false;
+    }
+
+    try
+    {
+        gpioLine.request(
+            {"power-control", gpiod::line_request::EVENT_BOTH_EDGES});
+    }
+    catch (std::exception&)
+    {
+        std::cerr << "Failed to request events for " << name << "\n";
+        return false;
+    }
+
+    int gpioLineFd = gpioLine.event_get_fd();
+    if (gpioLineFd < 0)
+    {
+        std::cerr << "Failed to get " << name << " fd\n";
+        return false;
+    }
+
+    gpioEventDescriptor.assign(gpioLineFd);
+
+    gpioEventDescriptor.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [&name, handler](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << name << " fd handler error: " << ec.message()
+                          << "\n";
+                // TODO: throw here to force power-control to restart?
+                return;
+            }
+            handler();
+        });
+    return true;
+}
+
+static bool setGPIOOutput(const std::string& name, const int value,
+                          gpiod::line& gpioLine)
+{
+    // Find the GPIO line
+    gpioLine = gpiod::find_line(name);
+    if (!gpioLine)
+    {
+        std::cerr << "Failed to find the " << name << " line.\n";
+        return false;
+    }
+
+    // Request GPIO output to specified value
+    try
+    {
+        gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT},
+                         value);
+    }
+    catch (std::exception&)
+    {
+        std::cerr << "Failed to request " << name << " output\n";
+        return false;
+    }
+
+    std::cerr << name << " set to " << std::to_string(value) << "\n";
+    return true;
+}
+
+static int setMaskedGPIOOutputForMs(gpiod::line& maskedGPIOLine,
+                                    const std::string& name, const int value,
+                                    const int durationMs)
+{
+    // Set the masked GPIO line to the specified value
+    maskedGPIOLine.set_value(value);
+    std::cerr << name << " set to " << std::to_string(value) << "\n";
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
+    gpioAssertTimer.async_wait(
+        [maskedGPIOLine, value, name](const boost::system::error_code ec) {
+            // Set the masked GPIO line back to the opposite value
+            maskedGPIOLine.set_value(!value);
+            std::cerr << name << " released\n";
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << name << " async_wait failed: " + ec.message()
+                              << "\n";
+                }
+            }
+        });
+    return 0;
+}
+
+static int setGPIOOutputForMs(const std::string& name, const int value,
+                              const int durationMs)
+{
+    // If the requested GPIO is masked, use the mask line to set the output
+    if (powerButtonMask && name == "POWER_OUT")
+    {
+        return setMaskedGPIOOutputForMs(powerButtonMask, name, value,
+                                        durationMs);
+    }
+    if (resetButtonMask && name == "RESET_OUT")
+    {
+        return setMaskedGPIOOutputForMs(resetButtonMask, name, value,
+                                        durationMs);
+    }
+
+    // No mask set, so request and set the GPIO normally
+    gpiod::line gpioLine;
+    if (!setGPIOOutput(name, value, gpioLine))
+    {
+        return -1;
+    }
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
+    gpioAssertTimer.async_wait(
+        [gpioLine, name](const boost::system::error_code ec) {
+            std::cerr << name << " released\n";
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << name << " async_wait failed: " << ec.message()
+                              << "\n";
+                }
+            }
+        });
+    return 0;
+}
+
+static void powerOn()
+{
+    setGPIOOutputForMs("POWER_OUT", 0, powerPulseTimeMs);
+}
+
+static void gracefulPowerOff()
+{
+    setGPIOOutputForMs("POWER_OUT", 0, powerPulseTimeMs);
+}
+
+static void forcePowerOff()
+{
+    if (setGPIOOutputForMs("POWER_OUT", 0, forceOffPulseTimeMs) < 0)
+    {
+        return;
+    }
+
+    // If the force off timer expires, then the PCH power-button override
+    // failed, so attempt the Unconditional Powerdown SMBus command.
+    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Force power off async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        std::cerr << "PCH Power-button override failed. Issuing Unconditional "
+                     "Powerdown SMBus command.\n";
+        const static constexpr size_t pchDevBusAddress = 3;
+        const static constexpr size_t pchDevSlaveAddress = 0x44;
+        const static constexpr size_t pchCmdReg = 0;
+        const static constexpr size_t pchPowerDownCmd = 0x02;
+        if (i2cSet(pchDevBusAddress, pchDevSlaveAddress, pchCmdReg,
+                   pchPowerDownCmd) < 0)
+        {
+            std::cerr << "Unconditional Powerdown command failed! Not sure "
+                         "what to do now.\n";
+        }
+    });
+}
+
+static void reset()
+{
+    setGPIOOutputForMs("RESET_OUT", 0, resetPulseTimeMs);
+}
+
+static void gracefulPowerOffTimerStart()
+{
+    std::cerr << "Graceful power-off timer started\n";
+    gracefulPowerOffTimer.expires_after(
+        std::chrono::milliseconds(gracefulPowerOffTimeMs));
+    gracefulPowerOffTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Graceful power-off async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            std::cerr << "Graceful power-off timer canceled\n";
+            return;
+        }
+        std::cerr << "Graceful power-off timer completed\n";
+        sendPowerControlEvent(Event::gracefulPowerOffTimerExpired);
+    });
+}
+
+static void powerCycleTimerStart()
+{
+    std::cerr << "Power-cycle timer started\n";
+    powerCycleTimer.expires_after(std::chrono::milliseconds(powerCycleTimeMs));
+    powerCycleTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Power-cycle async_wait failed: " << ec.message()
+                          << "\n";
+            }
+            std::cerr << "Power-cycle timer canceled\n";
+            return;
+        }
+        std::cerr << "Power-cycle timer completed\n";
+        sendPowerControlEvent(Event::powerCycleTimerExpired);
+    });
+}
+
+static void psPowerOKWatchdogTimerStart()
+{
+    std::cerr << "power supply power OK watchdog timer started\n";
+    psPowerOKWatchdogTimer.expires_after(
+        std::chrono::milliseconds(psPowerOKWatchdogTimeMs));
+    psPowerOKWatchdogTimer.async_wait(
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr
+                        << "power supply power OK watchdog async_wait failed: "
+                        << ec.message() << "\n";
+                }
+                std::cerr << "power supply power OK watchdog timer canceled\n";
+                return;
+            }
+            std::cerr << "power supply power OK watchdog timer expired\n";
+            sendPowerControlEvent(Event::psPowerOKWatchdogTimerExpired);
+        });
+}
+
+static void pohCounterTimerStart()
+{
+    std::cerr << "POH timer started\n";
+    // Set the time-out as 1 hour, to align with POH command in ipmid
+    pohCounterTimer.expires_after(std::chrono::hours(1));
+    pohCounterTimer.async_wait([](const boost::system::error_code& ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "POH timer async_wait failed: " << ec.message()
+                          << "\n";
+            }
+            std::cerr << "POH timer canceled\n";
+            return;
+        }
+
+        if (getHostState(powerState) !=
+            "xyz.openbmc_project.State.Host.HostState.Running")
+        {
+            return;
+        }
+
+        conn->async_method_call(
+            [](boost::system::error_code ec,
+               const std::variant<uint32_t>& pohCounterProperty) {
+                if (ec)
+                {
+                    std::cerr << "error to get poh counter\n";
+                    return;
+                }
+                const uint32_t* pohCounter =
+                    std::get_if<uint32_t>(&pohCounterProperty);
+                if (pohCounter == nullptr)
+                {
+                    std::cerr << "unable to read poh counter\n";
+                    return;
+                }
+
+                conn->async_method_call(
+                    [](boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            std::cerr << "failed to set poh counter\n";
+                        }
+                    },
+                    "xyz.openbmc_project.Settings",
+                    "/xyz/openbmc_project/state/chassis0",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.State.PowerOnHours", "POHCounter",
+                    std::variant<uint32_t>(*pohCounter + 1));
+            },
+            "xyz.openbmc_project.Settings",
+            "/xyz/openbmc_project/state/chassis0",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.State.PowerOnHours", "POHCounter");
+
+        pohCounterTimerStart();
+    });
+}
+
+static void currentHostStateMonitor()
+{
+    static auto match = sdbusplus::bus::match::match(
+        *conn,
+        "type='signal',member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "arg0namespace='xyz.openbmc_project.State.Host'",
+        [](sdbusplus::message::message& message) {
+            std::string intfName;
+            std::map<std::string, std::variant<std::string>> properties;
+
+            message.read(intfName, properties);
+
+            std::variant<std::string> currentHostState;
+
+            try
+            {
+                currentHostState = properties.at("CurrentHostState");
+            }
+            catch (const std::out_of_range& e)
+            {
+                std::cerr << "Error in finding CurrentHostState property\n";
+
+                return;
+            }
+
+            if (std::get<std::string>(currentHostState) ==
+                "xyz.openbmc_project.State.Host.HostState.Running")
+            {
+                pohCounterTimerStart();
+            }
+            else
+            {
+                pohCounterTimer.cancel();
+            }
+        });
+}
+
+static void sioPowerGoodWatchdogTimerStart()
+{
+    std::cerr << "SIO power good watchdog timer started\n";
+    sioPowerGoodWatchdogTimer.expires_after(
+        std::chrono::milliseconds(sioPowerGoodWatchdogTimeMs));
+    sioPowerGoodWatchdogTimer.async_wait(
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << "SIO power good watchdog async_wait failed: "
+                              << ec.message() << "\n";
+                }
+                std::cerr << "SIO power good watchdog timer canceled\n";
+                return;
+            }
+            std::cerr << "SIO power good watchdog timer completed\n";
+            sendPowerControlEvent(Event::sioPowerGoodWatchdogTimerExpired);
+        });
+}
+
+static void powerStateOn(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            setPowerState(PowerState::off);
+            // DC power is unexpectedly lost, beep
+            beep(beepPowerFail);
+            break;
+        case Event::sioS5Assert:
+            setPowerState(PowerState::transitionToOff);
+            setRestartCause(RestartCause::softReset);
+            break;
+        case Event::powerButtonPressed:
+            setPowerState(PowerState::gracefulTransitionToOff);
+            gracefulPowerOffTimerStart();
+            break;
+        case Event::powerOffRequest:
+            setPowerState(PowerState::transitionToOff);
+            forcePowerOff();
+            break;
+        case Event::gracefulPowerOffRequest:
+            setPowerState(PowerState::gracefulTransitionToOff);
+            gracefulPowerOffTimerStart();
+            gracefulPowerOff();
+            break;
+        case Event::powerCycleRequest:
+            setPowerState(PowerState::transitionToCycleOff);
+            forcePowerOff();
+            break;
+        case Event::gracefulPowerCycleRequest:
+            setPowerState(PowerState::gracefulTransitionToCycleOff);
+            gracefulPowerOffTimerStart();
+            gracefulPowerOff();
+            break;
+        case Event::resetRequest:
+            reset();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateWaitForPSPowerOK(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            psPowerOKWatchdogTimer.cancel();
+            sioPowerGoodWatchdogTimerStart();
+            setPowerState(PowerState::waitForSIOPowerGood);
+            break;
+        case Event::psPowerOKWatchdogTimerExpired:
+            setPowerState(PowerState::failedTransitionToOn);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateWaitForSIOPowerGood(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::sioPowerGoodAssert:
+            sioPowerGoodWatchdogTimer.cancel();
+            setPowerState(PowerState::on);
+            break;
+        case Event::sioPowerGoodWatchdogTimerExpired:
+            setPowerState(PowerState::failedTransitionToOn);
+            forcePowerOff();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateFailedTransitionToOn(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            // We're in a failure state, so don't allow the system to turn on
+            // without a user request
+            forcePowerOff();
+            break;
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            break;
+        case Event::powerButtonPressed:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerOnRequest:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            setPowerState(PowerState::waitForSIOPowerGood);
+            break;
+        case Event::sioS5DeAssert:
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerButtonPressed:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerOnRequest:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateTransitionToOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            setPowerState(PowerState::off);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateGracefulTransitionToOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            gracefulPowerOffTimer.cancel();
+            setPowerState(PowerState::off);
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            setPowerState(PowerState::on);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::powerCycleTimerExpired:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateTransitionToCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            setPowerState(PowerState::cycleOff);
+            powerCycleTimerStart();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateGracefulTransitionToCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            gracefulPowerOffTimer.cancel();
+            setPowerState(PowerState::cycleOff);
+            powerCycleTimerStart();
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            setPowerState(PowerState::on);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void psPowerOKHandler()
+{
+    gpiod::line_event gpioLineEvent = psPowerOKLine.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
+            ? Event::psPowerOKAssert
+            : Event::psPowerOKDeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    psPowerOKEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "power supply power OK handler error: "
+                          << ec.message() << "\n";
+                return;
+            }
+            psPowerOKHandler();
+        });
+}
+
+static void sioPowerGoodHandler()
+{
+    gpiod::line_event gpioLineEvent = sioPowerGoodLine.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
+            ? Event::sioPowerGoodAssert
+            : Event::sioPowerGoodDeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    sioPowerGoodEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "SIO power good handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            sioPowerGoodHandler();
+        });
+}
+
+static void sioOnControlHandler()
+{
+    gpiod::line_event gpioLineEvent = sioOnControlLine.event_read();
+
+    bool sioOnControl =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
+    std::cerr << "SIO_ONCONTROL value changed: " << sioOnControl << "\n";
+    sioOnControlEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "SIO ONCONTROL handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            sioOnControlHandler();
+        });
+}
+
+static void sioS5Handler()
+{
+    gpiod::line_event gpioLineEvent = sioS5Line.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE
+            ? Event::sioS5Assert
+            : Event::sioS5DeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    sioS5Event.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                          [](const boost::system::error_code ec) {
+                              if (ec)
+                              {
+                                  std::cerr << "SIO S5 handler error: "
+                                            << ec.message() << "\n";
+                                  return;
+                              }
+                              sioS5Handler();
+                          });
+}
+
+static void powerButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = powerButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        powerButtonPressLog();
+        powerButtonIface->set_property("ButtonPressed", true);
+        if (!powerButtonMask)
+        {
+            sendPowerControlEvent(Event::powerButtonPressed);
+            setRestartCause(RestartCause::powerButton);
+        }
+        else
+        {
+            std::cerr << "power button press masked\n";
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        powerButtonIface->set_property("ButtonPressed", false);
+    }
+    powerButtonEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "power button handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            powerButtonHandler();
+        });
+}
+
+static void resetButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = resetButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        resetButtonPressLog();
+        resetButtonIface->set_property("ButtonPressed", true);
+        if (!resetButtonMask)
+        {
+            resetInProgress = true;
+            setRestartCause(RestartCause::resetButton);
+        }
+        else
+        {
+            std::cerr << "reset button press masked\n";
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        resetButtonIface->set_property("ButtonPressed", false);
+    }
+    resetButtonEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "reset button handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            resetButtonHandler();
+        });
+}
+
+static void nmiSetEnablePorperty(bool value)
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set NMI source\n";
+            }
+        },
+        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
+        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
+        "Enabled", std::variant<bool>{value});
+}
+
+static void nmiReset(void)
+{
+    static constexpr const uint8_t value = 1;
+    const static constexpr int nmiOutPulseTimeMs = 200;
+
+    std::cerr << "NMI out action \n";
+    nmiOutLine.set_value(value);
+    std::cerr << nmiOutName << " set to " << std::to_string(value) << "\n";
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(nmiOutPulseTimeMs));
+    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
+        // restore the NMI_OUT GPIO line back to the opposite value
+        nmiOutLine.set_value(!value);
+        std::cerr << nmiOutName << " released\n";
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << nmiOutName << " async_wait failed: " + ec.message()
+                          << "\n";
+            }
+        }
+    });
+    // log to redfish
+    nmiDiagIntLog();
+    std::cerr << "NMI out action completed\n";
+    // reset Enable Property
+    nmiSetEnablePorperty(false);
+}
+
+static void nmiSourcePropertyMonitor(void)
+{
+    std::cerr << " NMI Source Property Monitor \n";
+
+    static std::unique_ptr<sdbusplus::bus::match::match> nmiSourceMatch =
+        std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',"
+            "member='PropertiesChanged',arg0namespace='com.intel.Control."
+            "NMISource'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string,
+                                           std::variant<bool, std::string>>
+                    propertiesChanged;
+                std::string state;
+                bool value = true;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    if (propertiesChanged.begin()->first == "Enabled")
+                    {
+                        value =
+                            std::get<bool>(propertiesChanged.begin()->second);
+                        std::cerr
+                            << " NMI Enabled propertiesChanged value: " << value
+                            << "\n";
+                        nmiEnabled = value;
+                        if (nmiEnabled)
+                        {
+                            nmiReset();
+                        }
+                    }
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read NMI source\n";
+                    return;
+                }
+            });
+}
+
+static void setNmiSource()
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set NMI source\n";
+            }
+        },
+        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
+        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
+        "BMCSource",
+        std::variant<std::string>{
+            "com.intel.Control.NMISource.BMCSourceSignal.FpBtn"});
+    // set Enable Property
+    nmiSetEnablePorperty(true);
+}
+
+static void nmiButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = nmiButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        nmiButtonPressLog();
+        nmiButtonIface->set_property("ButtonPressed", true);
+        if (nmiButtonMasked)
+        {
+            std::cerr << "NMI button press masked\n";
+        }
+        else
+        {
+            setNmiSource();
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        nmiButtonIface->set_property("ButtonPressed", false);
+    }
+    nmiButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                              [](const boost::system::error_code ec) {
+                                  if (ec)
+                                  {
+                                      std::cerr << "NMI button handler error: "
+                                                << ec.message() << "\n";
+                                      return;
+                                  }
+                                  nmiButtonHandler();
+                              });
+}
+
+static void idButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = idButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        idButtonIface->set_property("ButtonPressed", true);
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        idButtonIface->set_property("ButtonPressed", false);
+    }
+    idButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                             [](const boost::system::error_code& ec) {
+                                 if (ec)
+                                 {
+                                     std::cerr << "ID button handler error: "
+                                               << ec.message() << "\n";
+                                     return;
+                                 }
+                                 idButtonHandler();
+                             });
+}
+
+static void postCompleteHandler()
+{
+    gpiod::line_event gpioLineEvent = postCompleteLine.event_read();
+
+    bool postComplete =
+        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
+    std::cerr << "POST complete value changed: " << postComplete << "\n";
+    if (postComplete)
+    {
+        osIface->set_property("OperatingSystemState", std::string("Standby"));
+        resetInProgress = false;
+    }
+    else
+    {
+        osIface->set_property("OperatingSystemState", std::string("Inactive"));
+        // Set the restart cause if POST complete de-asserted by host software
+        if (powerState == PowerState::on && !resetInProgress)
+        {
+            resetInProgress = true;
+            setRestartCause(RestartCause::softReset);
+        }
+    }
+    postCompleteEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "POST complete handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            postCompleteHandler();
+        });
+}
+} // namespace power_control
+
+int main(int argc, char* argv[])
+{
+    std::cerr << "Start Chassis power control service...\n";
+    power_control::conn =
+        std::make_shared<sdbusplus::asio::connection>(power_control::io);
+
+    // Request all the dbus names
+    power_control::conn->request_name("xyz.openbmc_project.State.Host");
+    power_control::conn->request_name("xyz.openbmc_project.State.Chassis");
+    power_control::conn->request_name(
+        "xyz.openbmc_project.State.OperatingSystem");
+    power_control::conn->request_name("xyz.openbmc_project.Chassis.Buttons");
+
+    // Request PS_PWROK GPIO events
+    if (!power_control::requestGPIOEvents(
+            "PS_PWROK", power_control::psPowerOKHandler,
+            power_control::psPowerOKLine, power_control::psPowerOKEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_POWER_GOOD GPIO events
+    if (!power_control::requestGPIOEvents(
+            "SIO_POWER_GOOD", power_control::sioPowerGoodHandler,
+            power_control::sioPowerGoodLine, power_control::sioPowerGoodEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_ONCONTROL GPIO events
+    if (!power_control::requestGPIOEvents(
+            "SIO_ONCONTROL", power_control::sioOnControlHandler,
+            power_control::sioOnControlLine, power_control::sioOnControlEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_S5 GPIO events
+    if (!power_control::requestGPIOEvents("SIO_S5", power_control::sioS5Handler,
+                                          power_control::sioS5Line,
+                                          power_control::sioS5Event))
+    {
+        return -1;
+    }
+
+    // Request POWER_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "POWER_BUTTON", power_control::powerButtonHandler,
+            power_control::powerButtonLine, power_control::powerButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request RESET_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "RESET_BUTTON", power_control::resetButtonHandler,
+            power_control::resetButtonLine, power_control::resetButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request NMI_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "NMI_BUTTON", power_control::nmiButtonHandler,
+            power_control::nmiButtonLine, power_control::nmiButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request ID_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "ID_BUTTON", power_control::idButtonHandler,
+            power_control::idButtonLine, power_control::idButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request POST_COMPLETE GPIO events
+    if (!power_control::requestGPIOEvents(
+            "POST_COMPLETE", power_control::postCompleteHandler,
+            power_control::postCompleteLine, power_control::postCompleteEvent))
+    {
+        return -1;
+    }
+
+    // initialize NMI_OUT GPIO.
+    if (!power_control::setGPIOOutput(power_control::nmiOutName, 0,
+                                      power_control::nmiOutLine))
+    {
+        return -1;
+    }
+
+    // Initialize the power state
+    power_control::powerState = power_control::PowerState::off;
+    // Check power good
+    if (power_control::psPowerOKLine.get_value() > 0)
+    {
+        power_control::powerState = power_control::PowerState::on;
+    }
+
+    // Initialize the power state storage
+    if (power_control::initializePowerStateStorage() < 0)
+    {
+        return -1;
+    }
+
+    // Check if we need to start the Power Restore policy
+    power_control::powerRestorePolicyCheck();
+
+    power_control::nmiSourcePropertyMonitor();
+
+    std::cerr << "Initializing power state. ";
+    power_control::logStateTransition(power_control::powerState);
+
+    // Power Control Service
+    sdbusplus::asio::object_server hostServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Power Control Interface
+    power_control::hostIface = hostServer.add_interface(
+        "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host");
+
+    power_control::hostIface->register_property(
+        "RequestedHostTransition",
+        std::string("xyz.openbmc_project.State.Host.Transition.Off"),
+        [](const std::string& requested, std::string& resp) {
+            if (requested == "xyz.openbmc_project.State.Host.Transition.Off")
+            {
+                sendPowerControlEvent(
+                    power_control::Event::gracefulPowerOffRequest);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Host.Transition.On")
+            {
+                sendPowerControlEvent(power_control::Event::powerOnRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Host.Transition.Reboot")
+            {
+                sendPowerControlEvent(
+                    power_control::Event::gracefulPowerCycleRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else
+            {
+                std::cerr << "Unrecognized host state transition request.\n";
+                throw std::invalid_argument("Unrecognized Transition Request");
+                return 0;
+            }
+            resp = requested;
+            return 1;
+        });
+    power_control::hostIface->register_property(
+        "CurrentHostState",
+        std::string(power_control::getHostState(power_control::powerState)));
+
+    power_control::currentHostStateMonitor();
+
+    power_control::hostIface->initialize();
+
+    // Chassis Control Service
+    sdbusplus::asio::object_server chassisServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Chassis Control Interface
+    power_control::chassisIface =
+        chassisServer.add_interface("/xyz/openbmc_project/state/chassis0",
+                                    "xyz.openbmc_project.State.Chassis");
+
+    power_control::chassisIface->register_property(
+        "RequestedPowerTransition",
+        std::string("xyz.openbmc_project.State.Chassis.Transition.Off"),
+        [](const std::string& requested, std::string& resp) {
+            if (requested == "xyz.openbmc_project.State.Chassis.Transition.Off")
+            {
+                sendPowerControlEvent(power_control::Event::powerOffRequest);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.On")
+            {
+                sendPowerControlEvent(power_control::Event::powerOnRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.PowerCycle")
+            {
+                sendPowerControlEvent(power_control::Event::powerCycleRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.Reset")
+            {
+                setRestartCause(power_control::RestartCause::command);
+                sendPowerControlEvent(power_control::Event::resetRequest);
+            }
+            else
+            {
+                std::cerr << "Unrecognized chassis state transition request.\n";
+                throw std::invalid_argument("Unrecognized Transition Request");
+                return 0;
+            }
+            resp = requested;
+            return 1;
+        });
+    power_control::chassisIface->register_property(
+        "CurrentPowerState",
+        std::string(power_control::getChassisState(power_control::powerState)));
+    power_control::chassisIface->register_property(
+        "LastStateChangeTime", power_control::getCurrentTimeMs());
+
+    power_control::chassisIface->initialize();
+
+    // Buttons Service
+    sdbusplus::asio::object_server buttonsServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Power Button Interface
+    power_control::powerButtonIface = buttonsServer.add_interface(
+        "/xyz/openbmc_project/chassis/buttons/power",
+        "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::powerButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (requested)
+            {
+                if (power_control::powerButtonMask)
+                {
+                    return 1;
+                }
+                if (!power_control::setGPIOOutput(
+                        "POWER_OUT", 1, power_control::powerButtonMask))
+                {
+                    throw std::runtime_error("Failed to request GPIO");
+                    return 0;
+                }
+                std::cerr << "Power Button Masked.\n";
+            }
+            else
+            {
+                if (!power_control::powerButtonMask)
+                {
+                    return 1;
+                }
+                std::cerr << "Power Button Un-masked\n";
+                power_control::powerButtonMask.reset();
+            }
+            // Update the mask setting
+            current = requested;
+            return 1;
+        });
+
+    // Check power button state
+    bool powerButtonPressed = power_control::powerButtonLine.get_value() == 0;
+    power_control::powerButtonIface->register_property("ButtonPressed",
+                                                       powerButtonPressed);
+
+    power_control::powerButtonIface->initialize();
+
+    // Reset Button Interface
+    power_control::resetButtonIface = buttonsServer.add_interface(
+        "/xyz/openbmc_project/chassis/buttons/reset",
+        "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::resetButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (requested)
+            {
+                if (power_control::resetButtonMask)
+                {
+                    return 1;
+                }
+                if (!power_control::setGPIOOutput(
+                        "RESET_OUT", 1, power_control::resetButtonMask))
+                {
+                    throw std::runtime_error("Failed to request GPIO");
+                    return 0;
+                }
+                std::cerr << "Reset Button Masked.\n";
+            }
+            else
+            {
+                if (!power_control::resetButtonMask)
+                {
+                    return 1;
+                }
+                std::cerr << "Reset Button Un-masked\n";
+                power_control::resetButtonMask.reset();
+            }
+            // Update the mask setting
+            current = requested;
+            return 1;
+        });
+
+    // Check reset button state
+    bool resetButtonPressed = power_control::resetButtonLine.get_value() == 0;
+    power_control::resetButtonIface->register_property("ButtonPressed",
+                                                       resetButtonPressed);
+
+    power_control::resetButtonIface->initialize();
+
+    // NMI Button Interface
+    power_control::nmiButtonIface =
+        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/nmi",
+                                    "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::nmiButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (power_control::nmiButtonMasked == requested)
+            {
+                // NMI button mask is already set as requested, so no change
+                return 1;
+            }
+            if (requested)
+            {
+                std::cerr << "NMI Button Masked.\n";
+                power_control::nmiButtonMasked = true;
+            }
+            else
+            {
+                std::cerr << "NMI Button Un-masked.\n";
+                power_control::nmiButtonMasked = false;
+            }
+            // Update the mask setting
+            current = power_control::nmiButtonMasked;
+            return 1;
+        });
+
+    // Check NMI button state
+    bool nmiButtonPressed = power_control::nmiButtonLine.get_value() == 0;
+    power_control::nmiButtonIface->register_property("ButtonPressed",
+                                                     nmiButtonPressed);
+
+    power_control::nmiButtonIface->initialize();
+
+    // ID Button Interface
+    power_control::idButtonIface =
+        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/id",
+                                    "xyz.openbmc_project.Chassis.Buttons");
+
+    // Check ID button state
+    bool idButtonPressed = power_control::idButtonLine.get_value() == 0;
+    power_control::idButtonIface->register_property("ButtonPressed",
+                                                    idButtonPressed);
+
+    power_control::idButtonIface->initialize();
+
+    // OS State Service
+    sdbusplus::asio::object_server osServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // OS State Interface
+    power_control::osIface = osServer.add_interface(
+        "/xyz/openbmc_project/state/os",
+        "xyz.openbmc_project.State.OperatingSystem.Status");
+
+    // Get the initial OS state based on POST complete
+    //      0: Asserted, OS state is "Standby" (ready to boot)
+    //      1: De-Asserted, OS state is "Inactive"
+    std::string osState = power_control::postCompleteLine.get_value() > 0
+                              ? "Inactive"
+                              : "Standby";
+
+    power_control::osIface->register_property("OperatingSystemState",
+                                              std::string(osState));
+
+    power_control::osIface->initialize();
+
+    power_control::io.run();
+
+    return 0;
+}
diff --git a/power-control/CMakeLists.txt b/power-control/CMakeLists.txt
deleted file mode 100644
index 1f9aba2..0000000
--- a/power-control/CMakeLists.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
-project(power-control CXX)
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-
-set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
-include(GNUInstallDirs)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-set(DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Control/Power")
-set(DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Control.Power")
-
-add_definitions(-DDBUS_OBJECT_NAME="/${DBUS_OBJECT_NAME}0")
-add_definitions(-DDBUS_INTF_NAME="${DBUS_INTF_NAME}")
-set(SRC_FILES
-    src/power_control.cpp
-    src/main.cpp
-)
-
-set (
-    SERVICE_FILES
-    service-files/intel-power-start@.service
-    service-files/intel-power-stop@.service
-    service-files/intel-power-warm-reset@.service
-    service-files/obmc-chassis-hard-poweroff@.target
-    service-files/obmc-chassis-poweroff@.target
-    service-files/obmc-chassis-poweron@.target
-    service-files/obmc-chassis-powerreset@.target
-    service-files/obmc-host-reboot@.target
-    service-files/obmc-host-soft-reboot@.target
-    service-files/obmc-host-start@.target
-    service-files/obmc-host-startmin@.target
-    service-files/obmc-host-stop@.target
-    service-files/obmc-host-warm-reset@.target
-    service-files/obmc-send-signal-host-starting@.service
-    service-files/obmc-send-signal-host-stopping@.service
-    service-files/obmc-send-signal-post-host-start@.service
-    service-files/obmc-send-signal-post-host-stop@.service
-    service-files/obmc-send-signal-pre-host-start@.service
-    service-files/obmc-send-signal-pre-host-stop@.service
-    service-files/op-reset-chassis-on@.service
-    service-files/op-reset-chassis-running@.service
-    service-files/xyz.openbmc_project.Chassis.Control.Power@.service
-)
-
-# import sdbusplus
-find_package(PkgConfig REQUIRED)
-pkg_check_modules(SDBUSPLUSPLUS sdbusplus REQUIRED)
-include_directories(${SDBUSPLUSPLUS_INCLUDE_DIRS})
-link_directories(${SDBUSPLUSPLUS_LIBRARY_DIRS})
-find_program(SDBUSPLUSPLUS sdbus++)
-
-# import phosphor-logging
-find_package(PkgConfig REQUIRED)
-pkg_check_modules(LOGGING phosphor-logging REQUIRED)
-include_directories(${LOGGING_INCLUDE_DIRS})
-link_directories(${LOGGING_LIBRARY_DIRS})
-
-# phosphor-dbus-interfaces
-find_package(PkgConfig REQUIRED)
-pkg_check_modules(DBUSINTERFACE phosphor-dbus-interfaces REQUIRED)
-include_directories(${DBUSINTERFACE_INCLUDE_DIRS})
-link_directories(${DBUSINTERFACE_LIBRARY_DIRS})
-
-add_executable(${PROJECT_NAME} ${SRC_FILES})
-target_link_libraries(${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES}
-                      chassisgpio )
-target_link_libraries(${PROJECT_NAME} "${SDBUSPLUSPLUS_LIBRARIES} -lstdc++fs -lphosphor_dbus")
-
-install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
-install (FILES ${SERVICE_FILES} DESTINATION /lib/systemd/system/)
-
diff --git a/power-control/inc/power_control.hpp b/power-control/inc/power_control.hpp
deleted file mode 100644
index ae98a8d..0000000
--- a/power-control/inc/power_control.hpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-
-#pragma once
-#include "gpio.hpp"
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <phosphor-logging/elog-errors.hpp>
-#include <xyz/openbmc_project/Chassis/Common/error.hpp>
-#include <xyz/openbmc_project/Chassis/Control/Power/server.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
-
-static constexpr size_t POLLING_INTERVAL_MS = 500;
-const static constexpr char* PGOOD_PIN = "PGOOD";
-const static constexpr char* POWER_UP_PIN = "POWER_UP_PIN";
-
-const static constexpr size_t POWER_PULSE_TIME_MS = 200;
-const static constexpr size_t RESET_PULSE_TIME_MS = 500;
-const static constexpr char* PowerControlPath =
-    "/xyz/openbmc_project/Chassis/Control/Power0";
-const static constexpr char* PowerControlIntf =
-    "xyz.openbmc_project.Chassis.Control.Power";
-const static constexpr char* PowerButtonPath =
-    "/xyz/openbmc_project/Chassis/Buttons/Power0";
-const static constexpr char* PowerButtonIntf =
-    "xyz.openbmc_project.Chassis.Buttons.Power";
-const static constexpr char* ResetButtonPath =
-    "/xyz/openbmc_project/Chassis/Buttons/Reset0";
-const static constexpr char* ResetButtonIntf =
-    "xyz.openbmc_project.Chassis.Buttons.Reset";
-
-const static constexpr int32_t powerStateOff = 0;
-const static constexpr int32_t powerStateOn = 1;
-const static constexpr int32_t powerStateReset = 2;
-const static constexpr int32_t powerStateMax = 3;
-
-struct EventDeleter
-{
-    void operator()(sd_event* event) const
-    {
-        event = sd_event_unref(event);
-    }
-};
-
-using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
-
-using pwr_control =
-    sdbusplus::xyz::openbmc_project::Chassis::Control::server::Power;
-
-struct PowerControl : sdbusplus::server::object_t<pwr_control>
-{
-    PowerControl(sdbusplus::bus::bus& bus, const char* path, EventPtr& event,
-                 // phosphor::watchdog::EventPtr event,
-                 sd_event_io_handler_t handler = PowerControl::EventHandler) :
-        sdbusplus::server::object_t<pwr_control>(bus, path),
-        bus(bus), callbackHandler(handler),
-        powerButtonPressedSignal(
-            bus,
-            sdbusplus::bus::match::rules::type::signal() +
-                sdbusplus::bus::match::rules::member("Pressed") +
-                sdbusplus::bus::match::rules::path(PowerButtonPath) +
-                sdbusplus::bus::match::rules::interface(PowerButtonIntf),
-            [this](sdbusplus::message::message& msg) {
-                phosphor::logging::log<phosphor::logging::level::INFO>(
-                    "powerButtonPressed callback function is called...");
-                if (powerStateOn == this->state())
-                {
-                    this->state(powerStateOff);
-                }
-                else if (powerStateOff == this->state())
-                {
-                    this->state(powerStateOn);
-                }
-                else
-                {
-                    phosphor::logging::log<phosphor::logging::level::ERR>(
-                        "UNKNOWN power state");
-                }
-                return;
-            }),
-        resetButtonPressedSignal(
-            bus,
-            sdbusplus::bus::match::rules::type::signal() +
-                sdbusplus::bus::match::rules::member("Pressed") +
-                sdbusplus::bus::match::rules::path(ResetButtonPath) +
-                sdbusplus::bus::match::rules::interface(ResetButtonIntf),
-            [this](sdbusplus::message::message& msg) {
-                phosphor::logging::log<phosphor::logging::level::INFO>(
-                    "resetButtonPressed callback function is called...");
-                this->state(powerStateReset);
-                return;
-            }),
-        propertiesChangedSignal(
-            bus,
-            sdbusplus::bus::match::rules::type::signal() +
-                sdbusplus::bus::match::rules::member("PropertiesChanged") +
-                sdbusplus::bus::match::rules::path(PowerControlPath) +
-                sdbusplus::bus::match::rules::interface(PowerControlIntf),
-            [this](sdbusplus::message::message& msg) {
-                phosphor::logging::log<phosphor::logging::level::INFO>(
-                    "PowerControl propertiesChangedSignal callback function is "
-                    "called...");
-                std::string objectName;
-                std::map<std::string,
-                         sdbusplus::message::variant<int, bool, std::string>>
-                    msgData;
-                msg.read(objectName, msgData);
-                // Check if it was the Value property that changed.
-                auto valPropMap = msgData.find("State");
-                {
-                    if (valPropMap != msgData.end())
-                    {
-                        this->setPowerState(
-                            sdbusplus::message::variant_ns::get<int>(
-                                valPropMap->second));
-                    }
-                }
-            })
-    {
-        int ret = -1;
-        char buf = '0';
-
-        // config gpio
-        ret = configGpio(PGOOD_PIN, &pgood_fd, bus);
-        if (ret < 0)
-        {
-            throw std::runtime_error("failed to config PGOOD_PIN");
-        }
-
-        ret = configGpio(POWER_UP_PIN, &power_up_fd, bus);
-        if (ret < 0)
-        {
-            closeGpio(pgood_fd);
-            throw std::runtime_error("failed to config POWER_UP_PIN");
-        }
-        /*
-                ret = sd_event_add_io(event.get(), nullptr, pgood_fd, EPOLLPRI,
-                                      callbackHandler, this);
-                if (ret < 0)
-                {
-                    closeGpio(pgood_fd);
-                    closeGpio(power_up_fd);
-                    throw std::runtime_error("failed to add to event loop");
-                }
-
-                timer.start(std::chrono::duration_cast<std::chrono::microseconds>(
-                    std::chrono::milliseconds(POLLING_INTERVAL_MS)));
-                timer.setEnabled<std::true_type>();
-                phosphor::logging::log<phosphor::logging::level::DEBUG>("Enable
-           timer");
-        */
-    }
-
-    ~PowerControl()
-    {
-        closeGpio(pgood_fd);
-        closeGpio(power_up_fd);
-    }
-
-    static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
-                            void* userdata)
-    {
-        // For the first event, only set the initial status,  do not emit signal
-        // since is it not triggered by the real gpio change
-        static bool first_event = true;
-        int n = -1;
-        char buf = '0';
-
-        if (!userdata)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "userdata null!");
-            return -1;
-        }
-
-        PowerControl* powercontrol = static_cast<PowerControl*>(userdata);
-
-        if (!powercontrol)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "null pointer!");
-            return -1;
-        }
-
-        n = ::lseek(fd, 0, SEEK_SET);
-        if (n < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "lseek error!");
-            return n;
-        }
-
-        n = ::read(fd, &buf, sizeof(buf));
-        if (n < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "read error!");
-            return n;
-        }
-
-        if (buf == '0')
-        {
-            powercontrol->state(0);
-            powercontrol->pGood(0);
-
-            if (first_event)
-            {
-                first_event = false;
-            }
-            else
-            {
-                // powercontrol->powerLost();
-            }
-        }
-        else
-        {
-            powercontrol->state(1);
-            powercontrol->pGood(1);
-            if (first_event)
-            {
-                first_event = false;
-            }
-            else
-            {
-                //                powercontrol->powerGood();
-            }
-        }
-
-        return 0;
-    }
-
-    bool forcePowerOff() override;
-
-  private:
-    int reset_out_fd;
-    int power_up_fd;
-    int pgood_fd;
-    sdbusplus::bus::bus& bus;
-    sd_event_io_handler_t callbackHandler;
-    int32_t setPowerState(int newState);
-    int32_t triggerReset();
-    sdbusplus::bus::match_t propertiesChangedSignal;
-    sdbusplus::bus::match_t powerButtonPressedSignal;
-    sdbusplus::bus::match_t resetButtonPressedSignal;
-};
diff --git a/power-control/service-files/intel-power-start@.service b/power-control/service-files/intel-power-start@.service
deleted file mode 100644
index 2bb601c..0000000
--- a/power-control/service-files/intel-power-start@.service
+++ /dev/null
@@ -1,16 +0,0 @@
-[Unit]
-Description=Start Power%i on
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweroff@%i.target
-ConditionPathExists=!/run/openbmc/chassis@%i-on
-
-[Service]
-Type=oneshot
-ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 1"
-SyslogIdentifier=intel-power-start
-StartLimitInterval=0
-
-[Install]
-WantedBy=obmc-host-start@%i.target
diff --git a/power-control/service-files/intel-power-stop@.service b/power-control/service-files/intel-power-stop@.service
deleted file mode 100644
index aac1946..0000000
--- a/power-control/service-files/intel-power-stop@.service
+++ /dev/null
@@ -1,20 +0,0 @@
-[Unit]
-Description=Stop Power%i
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweron@%i.target
-Conflicts=obmc-host-start@%i.target
-
-[Service]
-Type=oneshot
-ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 0"
-SyslogIdentifier=intel-power-stop
-StartLimitInterval=0
-
-ExecStart=/bin/rm -f /run/openbmc/chassis@%i-on
-ExecStart=/bin/rm -f /run/openbmc/host@%i-on
-ExecStart=/bin/rm -f /run/openbmc/host@%i-request
-
-[Install]
-WantedBy=obmc-chassis-poweroff@%i.target
diff --git a/power-control/service-files/intel-power-warm-reset@.service b/power-control/service-files/intel-power-warm-reset@.service
deleted file mode 100644
index ede20ac..0000000
--- a/power-control/service-files/intel-power-warm-reset@.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=Power%i warm reset
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweroff@%i.target
-ConditionPathExists=!/run/openbmc/chassis@%i-on
-
-[Service]
-Type=oneshot
-ExecStart=/bin/sh -c "busctl set-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
-          /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power State i 2"
-SyslogIdentifier=intel-power-warm-reset
-
-[Install]
-WantedBy=obmc-host-warm-reset@%i.target
diff --git a/power-control/service-files/obmc-chassis-hard-poweroff@.target b/power-control/service-files/obmc-chassis-hard-poweroff@.target
deleted file mode 100644
index af78430..0000000
--- a/power-control/service-files/obmc-chassis-hard-poweroff@.target
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=Chassis%i (Hard Power Off)
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweron@%i.target
-Conflicts=obmc-chassis-reset@%i.target
-Conflicts=obmc-host-shutdown@%i.target
-Conflicts=xyz.openbmc_project.Ipmi.Internal.SoftPowerOff.service
-RefuseManualStop=yes
-
diff --git a/power-control/service-files/obmc-chassis-poweroff@.target b/power-control/service-files/obmc-chassis-poweroff@.target
deleted file mode 100644
index ad61036..0000000
--- a/power-control/service-files/obmc-chassis-poweroff@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Chassis%i (Power Off)
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweron@%i.target
-Conflicts=obmc-chassis-reset@%i.target
-RefuseManualStop=yes
-
diff --git a/power-control/service-files/obmc-chassis-poweron@.target b/power-control/service-files/obmc-chassis-poweron@.target
deleted file mode 100644
index 2c77193..0000000
--- a/power-control/service-files/obmc-chassis-poweron@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Chassis%i (Power On)
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-chassis-poweroff@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-chassis-poweroff@%i.target
-OnFailureJobMode=flush
diff --git a/power-control/service-files/obmc-chassis-powerreset@.target b/power-control/service-files/obmc-chassis-powerreset@.target
deleted file mode 100644
index 7bce100..0000000
--- a/power-control/service-files/obmc-chassis-powerreset@.target
+++ /dev/null
@@ -1,7 +0,0 @@
-[Unit]
-Description=Chassis%i (Reset Check)
-Conflicts=obmc-chassis-poweroff@%i.target
-RefuseManualStop=yes
-
-[Install]
-WantedBy=multi-user.target
\ No newline at end of file
diff --git a/power-control/service-files/obmc-host-reboot@.target b/power-control/service-files/obmc-host-reboot@.target
deleted file mode 100644
index f21d285..0000000
--- a/power-control/service-files/obmc-host-reboot@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Reboot Host%i
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-host-startmin@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-chassis-poweroff@%i.target
-OnFailureJobMode=flush
diff --git a/power-control/service-files/obmc-host-soft-reboot@.target b/power-control/service-files/obmc-host-soft-reboot@.target
deleted file mode 100644
index 77a0885..0000000
--- a/power-control/service-files/obmc-host-soft-reboot@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Soft Reboot Host%i
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-host-startmin@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-chassis-poweroff@%i.target
-OnFailureJobMode=flush
diff --git a/power-control/service-files/obmc-host-start@.target b/power-control/service-files/obmc-host-start@.target
deleted file mode 100644
index 46ba6fb..0000000
--- a/power-control/service-files/obmc-host-start@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Start Host%i
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-host-stop@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-host-quiesce@%i.target
-OnFailureJobMode=flush
\ No newline at end of file
diff --git a/power-control/service-files/obmc-host-startmin@.target b/power-control/service-files/obmc-host-startmin@.target
deleted file mode 100644
index e8bd924..0000000
--- a/power-control/service-files/obmc-host-startmin@.target
+++ /dev/null
@@ -1,6 +0,0 @@
-[Unit]
-Description=Start Host%i Minimum
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
diff --git a/power-control/service-files/obmc-host-stop@.target b/power-control/service-files/obmc-host-stop@.target
deleted file mode 100644
index 6a91c74..0000000
--- a/power-control/service-files/obmc-host-stop@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Stop Host%i
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-host-startmin@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-chassis-poweroff@%i.target
-OnFailureJobMode=flush
\ No newline at end of file
diff --git a/power-control/service-files/obmc-host-warm-reset@.target b/power-control/service-files/obmc-host-warm-reset@.target
deleted file mode 100644
index 0d8cbc5..0000000
--- a/power-control/service-files/obmc-host-warm-reset@.target
+++ /dev/null
@@ -1,10 +0,0 @@
-[Unit]
-Description=Warm reset Host%i
-Wants=multi-user.target
-After=multi-user.target
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Conflicts=obmc-host-stop@%i.target
-RefuseManualStop=yes
-OnFailure=obmc-host-quiesce@%i.target
-OnFailureJobMode=flush
diff --git a/power-control/service-files/obmc-send-signal-host-starting@.service b/power-control/service-files/obmc-send-signal-host-starting@.service
deleted file mode 100644
index 4e84c87..0000000
--- a/power-control/service-files/obmc-send-signal-host-starting@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Broadcast host starting signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.HostStarting"
-SyslogIdentifier=hoststartingsignal
-
-[Install]
-WantedBy=obmc-host-starting@%i.target
diff --git a/power-control/service-files/obmc-send-signal-host-stopping@.service b/power-control/service-files/obmc-send-signal-host-stopping@.service
deleted file mode 100644
index 0f89f94..0000000
--- a/power-control/service-files/obmc-send-signal-host-stopping@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Broadcast host stopping signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.HostStoping"
-SyslogIdentifier=hoststoppingsignal
-
-[Install]
-WantedBy=obmc-host-stopping@%i.target
diff --git a/power-control/service-files/obmc-send-signal-post-host-start@.service b/power-control/service-files/obmc-send-signal-post-host-start@.service
deleted file mode 100644
index f7e0a3b..0000000
--- a/power-control/service-files/obmc-send-signal-post-host-start@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Broadcast post host start signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.PostHostStart"
-SyslogIdentifier=posthoststartsignal
-
-[Install]
-WantedBy=obmc-host-started@%i.target
diff --git a/power-control/service-files/obmc-send-signal-post-host-stop@.service b/power-control/service-files/obmc-send-signal-post-host-stop@.service
deleted file mode 100644
index 90007db..0000000
--- a/power-control/service-files/obmc-send-signal-post-host-stop@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Broadcast post host stop signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.PostHostStop"
-SyslogIdentifier=posthoststopsignal
-
-[Install]
-WantedBy=obmc-host-stopped@%i.target
diff --git a/power-control/service-files/obmc-send-signal-pre-host-start@.service b/power-control/service-files/obmc-send-signal-pre-host-start@.service
deleted file mode 100644
index a57423e..0000000
--- a/power-control/service-files/obmc-send-signal-pre-host-start@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Broadcast pre host start signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.PreHostStart"
-SyslogIdentifier=prehoststartsignal
-
-[Install]
-WantedBy=obmc-host-start-pre@%i.target
diff --git a/power-control/service-files/obmc-send-signal-pre-host-stop@.service b/power-control/service-files/obmc-send-signal-pre-host-stop@.service
deleted file mode 100644
index ec6f453..0000000
--- a/power-control/service-files/obmc-send-signal-pre-host-stop@.service
+++ /dev/null
@@ -1,14 +0,0 @@
-[Unit]
-Description=Broadcast pre host stop signal to dbus
-Wants=mapper-wait@-xyz-openbmc_project-state-host%i.service
-After=mapper-wait@-xyz-openbmc_project-state-host%i.service
-
-[Service]
-Restart=no
-Type=oneshot
-ExecStart=/bin/sh -c "dbus-send --system --type=signal /xyz/openbmc_project/state/host0 xyz.openbmc_project.State.Host.PreHostStop"
-SyslogIdentifier=prehoststopsignal
-
-[Install]
-WantedBy=obmc-host-stop-pre@%i.target
-
diff --git a/power-control/service-files/op-reset-chassis-on@.service b/power-control/service-files/op-reset-chassis-on@.service
deleted file mode 100644
index d3ea716..0000000
--- a/power-control/service-files/op-reset-chassis-on@.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=Start chassis%i on after BMC reset
-Requires=op-reset-chassis-running@%i.service
-After=op-reset-chassis-running@%i.service
-After=obmc-power-reset-on@%i.target
-Requires=obmc-power-reset-on@%i.target
-ConditionPathExists=/run/openbmc/chassis@%i-on
-
-[Service]
-RemainAfterExit=no
-ExecStart=/bin/systemctl start obmc-host-start@%i.target
-
-
-[Install]
-WantedBy=obmc-chassis-powerreset@%i.target
diff --git a/power-control/service-files/op-reset-chassis-running@.service b/power-control/service-files/op-reset-chassis-running@.service
deleted file mode 100644
index 2d6d32c..0000000
--- a/power-control/service-files/op-reset-chassis-running@.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=Check Chassis%i pgood and create a file to indicate it
-Wants=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-After=mapper-wait@-xyz-openbmc_project-Chassis-Control-Power%i.service
-Wants=obmc-power-reset-on@%i.target
-Before=obmc-power-reset-on@%i.target
-Conflicts=obmc-chassis-poweroff@%i.target
-
-[Service]
-RemainAfterExit=no
-Type=oneshot
-ExecStart=/bin/sh -c "if [ $(busctl get-property `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power PGood | sed 's/i\s*[1]/on/' | grep on | wc -l) != 0 ]; then mkdir -p /run/openbmc/ && touch /run/openbmc/chassis@%i-on; fi"
-
-[Install]
-WantedBy=obmc-chassis-powerreset@%i.target
diff --git a/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service b/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
deleted file mode 100644
index 028e8c7..0000000
--- a/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
+++ /dev/null
@@ -1,17 +0,0 @@
-
-[Unit]
-Description=Intel Power Control%i
-Wants=mapper-wait@-org-openbmc-managers-System.service
-After=mapper-wait@-org-openbmc-managers-System.service
-
-[Service]
-Restart=always
-RestartSec=3
-ExecStart=/usr/bin/env power-control
-SyslogIdentifier=power-control
-Type=dbus
-BusName=xyz.openbmc_project.Chassis.Control.Power
-
-[Install]
-WantedBy=multi-user.target
-
diff --git a/power-control/src/main.cpp b/power-control/src/main.cpp
deleted file mode 100644
index caea051..0000000
--- a/power-control/src/main.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-#include "power_control.hpp"
-
-int main(int argc, char* argv[])
-{
-    int ret = 0;
-
-    phosphor::logging::log<phosphor::logging::level::INFO>(
-        "Start Chassis power control service...");
-
-    sd_event* event = nullptr;
-    ret = sd_event_default(&event);
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "Error creating a default sd_event handler");
-        return ret;
-    }
-    // phosphor::watchdog::EventPtr eventP{event,
-    //                                  phosphor::watchdog::EventDeleter()};
-    EventPtr eventP{event};
-    event = nullptr;
-
-    sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
-    sdbusplus::server::manager_t m{bus, DBUS_OBJECT_NAME};
-
-    bus.request_name(DBUS_INTF_NAME);
-
-    PowerControl powerControl{bus, DBUS_OBJECT_NAME, eventP};
-
-    auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(
-        std::chrono::system_clock::now());
-
-    try
-    {
-        bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
-        ret = sd_event_loop(eventP.get());
-        if (ret < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error occurred during the sd_event_loop",
-                phosphor::logging::entry("RET=%d", ret));
-        }
-    }
-    catch (std::exception& e)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
-        return -1;
-    }
-    return 0;
-}
diff --git a/power-control/src/power_control.cpp b/power-control/src/power_control.cpp
deleted file mode 100644
index 4a3ca4b..0000000
--- a/power-control/src/power_control.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-#include "power_control.hpp"
-
-bool PowerControl::forcePowerOff()
-{
-    return true;
-}
-
-int32_t PowerControl::triggerReset()
-{
-    int ret = 0;
-    int count = 0;
-    char buf = '0';
-
-    phosphor::logging::log<phosphor::logging::level::DEBUG>("triggerReset");
-
-    ret = ::lseek(reset_out_fd, 0, SEEK_SET);
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("lseek error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-
-    buf = '0';
-
-    ret = ::write(reset_out_fd, &buf, sizeof(buf));
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-
-    std::this_thread::sleep_for(std::chrono::milliseconds(RESET_PULSE_TIME_MS));
-
-    buf = '1';
-    ret = ::write(reset_out_fd, &buf, sizeof(buf));
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-    return 0;
-}
-
-int32_t PowerControl::setPowerState(int newState)
-{
-    int ret = 0;
-    int count = 0;
-    char buf = '0';
-
-    if (newState < 0 || newState >= powerStateMax)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>(
-            "error! invalid parameter!");
-        return -1;
-    }
-
-    phosphor::logging::log<phosphor::logging::level::DEBUG>(
-        "setPowerState", phosphor::logging::entry("NEWSTATE=%d", newState));
-
-    if (powerStateReset == newState)
-    {
-        phosphor::logging::log<phosphor::logging::level::DEBUG>(
-            "setPowerState system reset");
-        triggerReset();
-        return 0;
-    }
-
-    if (state() == newState)
-    {
-        phosphor::logging::log<phosphor::logging::level::WARNING>(
-            "Same powerstate",
-            phosphor::logging::entry("NEWSTATE=%d", newState));
-        return 0;
-    }
-
-    state(newState);
-
-    ret = ::lseek(power_up_fd, 0, SEEK_SET);
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("lseek error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-
-    buf = '0';
-
-    ret = ::write(power_up_fd, &buf, sizeof(buf));
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-
-    phosphor::logging::log<phosphor::logging::level::DEBUG>(
-        "setPowerState power on");
-    std::this_thread::sleep_for(std::chrono::milliseconds(POWER_PULSE_TIME_MS));
-
-    buf = '1';
-    ret = ::write(power_up_fd, &buf, sizeof(buf));
-    if (ret < 0)
-    {
-        phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
-        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-            IOError();
-    }
-
-    if (0 == newState)
-    {
-        /*
-         * For power off, currently there is a known issue, the "long-press"
-         * power button cannot power off the host, a workaround is perform force
-         * power off after waitting for a while
-         */
-        std::this_thread::sleep_for(
-            std::chrono::milliseconds(POWER_PULSE_TIME_MS));
-        if (1 == pGood())
-        { // still on, force off!
-            phosphor::logging::log<phosphor::logging::level::DEBUG>(
-                "Perform force power off");
-            count = 0;
-            do
-            {
-                if (count++ > 5)
-                {
-                    phosphor::logging::log<phosphor::logging::level::ERR>(
-                        "forcePowerOff error!");
-                    throw sdbusplus::xyz::openbmc_project::Chassis::Common::
-                        Error::IOError();
-                }
-                ret = forcePowerOff();
-                std::this_thread::sleep_for(
-                    std::chrono::milliseconds(POLLING_INTERVAL_MS));
-            } while (ret != 0);
-        }
-    }
-    return 0;
-}