Sync w/ updated power control interfaces
setPowerState/getPowerState methods are removed.
all properties are removed except PGood and State.
return value of forcePowerOff is changed to bool from int32
TestBy:
Ipmi command and click buttons
Change-Id: I0b5e51cea959594acf04257c566893da6ffe7d26
Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
diff --git a/power-control/inc/power_control.hpp b/power-control/inc/power_control.hpp
index f68b71d..ae98a8d 100644
--- a/power-control/inc/power_control.hpp
+++ b/power-control/inc/power_control.hpp
@@ -25,12 +25,29 @@
#include <xyz/openbmc_project/Chassis/Control/Power/server.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
-// static constexpr size_t POLLING_INTERVAL_MS = 500;
-
+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_UP_PIN_PULSE_TIME_MS = 200;
+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
{
@@ -51,7 +68,69 @@
// phosphor::watchdog::EventPtr event,
sd_event_io_handler_t handler = PowerControl::EventHandler) :
sdbusplus::server::object_t<pwr_control>(bus, path),
- bus(bus), callbackHandler(handler)
+ 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';
@@ -166,13 +245,16 @@
}
bool forcePowerOff() override;
- // todo: when dbus interfaces is fixed, these should be override
- int32_t setPowerState(int32_t newState); // override;
- int32_t getPowerState(); // 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
index 763c115..2bb601c 100644
--- a/power-control/service-files/intel-power-start@.service
+++ b/power-control/service-files/intel-power-start@.service
@@ -7,8 +7,8 @@
[Service]
Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
- /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 1"
+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
diff --git a/power-control/service-files/intel-power-stop@.service b/power-control/service-files/intel-power-stop@.service
index 5d0e46f..aac1946 100644
--- a/power-control/service-files/intel-power-stop@.service
+++ b/power-control/service-files/intel-power-stop@.service
@@ -7,8 +7,8 @@
[Service]
Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
- /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 0"
+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
diff --git a/power-control/service-files/intel-power-warm-reset@.service b/power-control/service-files/intel-power-warm-reset@.service
index c8bd4fc..ede20ac 100644
--- a/power-control/service-files/intel-power-warm-reset@.service
+++ b/power-control/service-files/intel-power-warm-reset@.service
@@ -7,8 +7,8 @@
[Service]
Type=oneshot
-ExecStart=/bin/sh -c "busctl call `mapper get-service /xyz/openbmc_project/Chassis/Control/Power%i` \
- /xyz/openbmc_project/Chassis/Control/Power%i xyz.openbmc_project.Chassis.Control.Power setPowerState i 2"
+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]
diff --git a/power-control/service-files/obmc-chassis-hard-poweroff@.target b/power-control/service-files/obmc-chassis-hard-poweroff@.target
index 5f53251..9b66218 100644
--- a/power-control/service-files/obmc-chassis-hard-poweroff@.target
+++ b/power-control/service-files/obmc-chassis-hard-poweroff@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Chassis%i (Hard Power Off)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-chassis-poweroff@.target b/power-control/service-files/obmc-chassis-poweroff@.target
index aa026cf..1bc0691 100644
--- a/power-control/service-files/obmc-chassis-poweroff@.target
+++ b/power-control/service-files/obmc-chassis-poweroff@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Chassis%i (Power Off)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-chassis-poweron@.target b/power-control/service-files/obmc-chassis-poweron@.target
index 572dfa0..4b77af6 100644
--- a/power-control/service-files/obmc-chassis-poweron@.target
+++ b/power-control/service-files/obmc-chassis-poweron@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Chassis%i (Power On)
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-chassis-powerreset@.target b/power-control/service-files/obmc-chassis-powerreset@.target
index 8d7c47e..6f93925 100644
--- a/power-control/service-files/obmc-chassis-powerreset@.target
+++ b/power-control/service-files/obmc-chassis-powerreset@.target
@@ -4,4 +4,4 @@
RefuseManualStop=yes
[Install]
-WantedBy={SYSTEMD_DEFAULT_TARGET}
+WantedBy=obmc-standby.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
index 2522012..e779ab2 100644
--- a/power-control/service-files/obmc-host-reboot@.target
+++ b/power-control/service-files/obmc-host-reboot@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Reboot Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-host-soft-reboot@.target b/power-control/service-files/obmc-host-soft-reboot@.target
index ae620c4..0bb2938 100644
--- a/power-control/service-files/obmc-host-soft-reboot@.target
+++ b/power-control/service-files/obmc-host-soft-reboot@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Soft Reboot Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-host-start@.target b/power-control/service-files/obmc-host-start@.target
index 96e6ea1..38f76c6 100644
--- a/power-control/service-files/obmc-host-start@.target
+++ b/power-control/service-files/obmc-host-start@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Start Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-host-startmin@.target b/power-control/service-files/obmc-host-startmin@.target
index bb79370..98f044f 100644
--- a/power-control/service-files/obmc-host-startmin@.target
+++ b/power-control/service-files/obmc-host-startmin@.target
@@ -1,6 +1,6 @@
[Unit]
Description=Start Host%i Minimum
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
index df371b9..5178e83 100644
--- a/power-control/service-files/obmc-host-stop@.target
+++ b/power-control/service-files/obmc-host-stop@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Stop Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/obmc-host-warm-reset@.target b/power-control/service-files/obmc-host-warm-reset@.target
index 6d4cbcf..8c6fa5a 100644
--- a/power-control/service-files/obmc-host-warm-reset@.target
+++ b/power-control/service-files/obmc-host-warm-reset@.target
@@ -1,7 +1,7 @@
[Unit]
Description=Warm reset Host%i
-Wants={SYSTEMD_DEFAULT_TARGET}
-After={SYSTEMD_DEFAULT_TARGET}
+Wants=obmc-standby.target
+After=obmc-standby.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
diff --git a/power-control/service-files/op-reset-chassis-running@.service b/power-control/service-files/op-reset-chassis-running@.service
index 3280d0a..2d6d32c 100644
--- a/power-control/service-files/op-reset-chassis-running@.service
+++ b/power-control/service-files/op-reset-chassis-running@.service
@@ -9,7 +9,7 @@
[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"
+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
index fe69931..3bbfb17 100644
--- a/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
+++ b/power-control/service-files/xyz.openbmc_project.Chassis.Control.Power@.service
@@ -10,8 +10,8 @@
ExecStart=/usr/bin/env power-control
SyslogIdentifier=power-control
Type=dbus
-BusName={BUSNAME}
+BusName=xyz.openbmc_project.Chassis.Control.Power
[Install]
-WantedBy={SYSTEMD_DEFAULT_TARGET}
+WantedBy=obmc-standby.target
diff --git a/power-control/src/power_control.cpp b/power-control/src/power_control.cpp
index 3014370..4a3ca4b 100644
--- a/power-control/src/power_control.cpp
+++ b/power-control/src/power_control.cpp
@@ -20,15 +20,69 @@
return true;
}
-int32_t PowerControl::setPowerState(int32_t newState)
+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>(
@@ -37,6 +91,8 @@
return 0;
}
+ state(newState);
+
ret = ::lseek(power_up_fd, 0, SEEK_SET);
if (ret < 0)
{
@@ -45,42 +101,57 @@
IOError();
}
- /*
- This power control just handle out pin "POWER_UP_PIN", change it
- to low "0" form high "1" and set it back to high after over 200ms,
- which will notify host (PCH) to switch power. Host to determine it
- is power on or power off operation based on current power status.
- For BMC (power control), just need to notify host (PCH) to switch
- power, don't need to judge it should power on or off.
- */
buf = '0';
+
ret = ::write(power_up_fd, &buf, sizeof(buf));
if (ret < 0)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "write error for setting 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(POWER_UP_PIN_PULSE_TIME_MS));
+ 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 for setting 1 !");
+ phosphor::logging::log<phosphor::logging::level::ERR>("write error!");
throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
IOError();
}
- state(newState);
+ 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;
}
-
-int32_t PowerControl::getPowerState()
-{
- return state();
-}