Add JSON config support for x86-power-control
Adding a flexibility to configure GPIOs for the power control with a json
configuration file.
TESTED: Tested and verified in Tiogapass. The existing functionality
is not broken after adding the JSON parser implementation in Tiogapass.
Signed-off-by: Priyatharshan P <priyatharshanp@hcl.com>
Change-Id: I9eb0c845e0924e0bb642d3691fcfaf948b773ce0
diff --git a/power-control-x86/src/power_control.cpp b/power-control-x86/src/power_control.cpp
index 3ba16dd..84d1500 100644
--- a/power-control-x86/src/power_control.cpp
+++ b/power-control-x86/src/power_control.cpp
@@ -22,6 +22,7 @@
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <gpiod.hpp>
+#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/asio/object_server.hpp>
@@ -34,6 +35,22 @@
{
static boost::asio::io_service io;
std::shared_ptr<sdbusplus::asio::connection> conn;
+
+static std::string node = "0";
+
+static std::string powerOutName;
+static std::string powerOkName;
+static std::string resetOutName;
+static std::string nmiOutName;
+static std::string sioPwrGoodName;
+static std::string sioOnControlName;
+static std::string sioS5Name;
+static std::string postCompleteName;
+static std::string powerButtonName;
+static std::string resetButtonName;
+static std::string idButtonName;
+static std::string nmiButtonName;
+
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> chassisSysIface;
@@ -64,9 +81,6 @@
const static constexpr std::string_view powerStateFile = "power-state";
static bool nmiEnabled = true;
-static constexpr const char* nmiOutName = "NMI_OUT";
-static constexpr const char* powerOutName = "POWER_OUT";
-static constexpr const char* resetOutName = "RESET_OUT";
// Timers
// Time holding GPIOs asserted
@@ -2003,6 +2017,89 @@
postCompleteHandler();
});
}
+
+static int loadConfigValues()
+{
+ const std::string configFilePath =
+ "/usr/share/x86-power-control/power-config-host" + power_control::node +
+ ".json";
+ std::ifstream configFile(configFilePath.c_str());
+ if (!configFile.is_open())
+ {
+ std::cerr << "loadConfigValues : Cannot open config path\n ";
+ return -1;
+ }
+ auto data = nlohmann::json::parse(configFile, nullptr);
+
+ if (data.is_discarded())
+ {
+ std::cerr << "Power config readings JSON parser failure";
+ return -1;
+ }
+
+ if (data.contains("IdButton"))
+ {
+ idButtonName = data["IdButton"];
+ }
+
+ if (data.contains("NMIButton"))
+ {
+ nmiButtonName = data["NMIButton"];
+ }
+
+ if (data.contains("NMIOut"))
+ {
+ nmiOutName = data["NMIOut"];
+ }
+
+ if (data.contains("PostComplete"))
+ {
+ postCompleteName = data["PostComplete"];
+ }
+
+ if (data.contains("PwrButton"))
+ {
+ powerButtonName = data["PwrButton"];
+ }
+
+ if (data.contains("PwrOK"))
+ {
+ powerOkName = data["PwrOK"];
+ }
+
+ if (data.contains("PwrOut"))
+ {
+ powerOutName = data["PwrOut"];
+ }
+
+ if (data.contains("RstButton"))
+ {
+ resetButtonName = data["RstButton"];
+ }
+
+ if (data.contains("RstOut"))
+ {
+ resetOutName = data["RstOut"];
+ }
+
+ if (data.contains("SIOOnCtl"))
+ {
+ sioOnControlName = data["SIOOnCtl"];
+ }
+
+ if (data.contains("SIOPwrGd"))
+ {
+ sioPwrGoodName = data["SIOPwrGd"];
+ }
+
+ if (data.contains("SIOS5"))
+ {
+ sioS5Name = data["SIOS5"];
+ }
+
+ return 0;
+}
+
} // namespace power_control
int main(int argc, char* argv[])
@@ -2011,6 +2108,13 @@
power_control::conn =
std::make_shared<sdbusplus::asio::connection>(power_control::io);
+ // Load GPIO's through json config file
+ if (power_control::loadConfigValues() == -1)
+ {
+ std::cerr << "Host" << power_control::node << ": "
+ << "Error in Parsing...\n";
+ }
+
// 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");
@@ -2022,68 +2126,144 @@
"xyz.openbmc_project.Control.Host.RestartCause");
// Request PS_PWROK GPIO events
- if (!power_control::requestGPIOEvents(
- "PS_PWROK", power_control::psPowerOKHandler,
- power_control::psPowerOKLine, power_control::psPowerOKEvent))
+ if (!power_control::powerOkName.empty())
{
+ if (!power_control::requestGPIOEvents(
+ power_control::powerOkName, power_control::psPowerOKHandler,
+ power_control::psPowerOKLine, power_control::psPowerOKEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "PowerOk name should be configured from json config file\n";
return -1;
}
// Request SIO_POWER_GOOD GPIO events
- if (!power_control::requestGPIOEvents(
- "SIO_POWER_GOOD", power_control::sioPowerGoodHandler,
- power_control::sioPowerGoodLine, power_control::sioPowerGoodEvent))
+ if (!power_control::sioPwrGoodName.empty())
{
+ if (!power_control::requestGPIOEvents(
+ power_control::sioPwrGoodName,
+ power_control::sioPowerGoodHandler,
+ power_control::sioPowerGoodLine,
+ power_control::sioPowerGoodEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "sioPwrGood name should be configured from json config file\n";
return -1;
}
// Request SIO_ONCONTROL GPIO events
- if (!power_control::requestGPIOEvents(
- "SIO_ONCONTROL", power_control::sioOnControlHandler,
- power_control::sioOnControlLine, power_control::sioOnControlEvent))
+ if (!power_control::sioOnControlName.empty())
{
+ if (!power_control::requestGPIOEvents(
+ power_control::sioOnControlName,
+ power_control::sioOnControlHandler,
+ power_control::sioOnControlLine,
+ power_control::sioOnControlEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "sioOnControl name should be configured from json config file\n";
return -1;
}
// Request SIO_S5 GPIO events
- if (!power_control::requestGPIOEvents("SIO_S5", power_control::sioS5Handler,
- power_control::sioS5Line,
- power_control::sioS5Event))
+ if (!power_control::sioS5Name.empty())
{
+ if (!power_control::requestGPIOEvents(
+ power_control::sioS5Name, power_control::sioS5Handler,
+ power_control::sioS5Line, power_control::sioS5Event))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr << "sioS5 name should be configured from json config file\n";
return -1;
}
// Request POWER_BUTTON GPIO events
- if (!power_control::requestGPIOEvents(
- "POWER_BUTTON", power_control::powerButtonHandler,
- power_control::powerButtonLine, power_control::powerButtonEvent))
+ if (!power_control::powerButtonName.empty())
{
+ if (!power_control::requestGPIOEvents(power_control::powerButtonName,
+ power_control::powerButtonHandler,
+ power_control::powerButtonLine,
+ power_control::powerButtonEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "powerButton name should be configured from json config file\n";
return -1;
}
// Request RESET_BUTTON GPIO events
- if (!power_control::requestGPIOEvents(
- "RESET_BUTTON", power_control::resetButtonHandler,
- power_control::resetButtonLine, power_control::resetButtonEvent))
+ if (!power_control::resetButtonName.empty())
{
+ if (!power_control::requestGPIOEvents(power_control::resetButtonName,
+ power_control::resetButtonHandler,
+ power_control::resetButtonLine,
+ power_control::resetButtonEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "resetButton name should be configured from json config file\n";
return -1;
}
// Request NMI_BUTTON GPIO events
- power_control::requestGPIOEvents(
- "NMI_BUTTON", power_control::nmiButtonHandler,
- power_control::nmiButtonLine, power_control::nmiButtonEvent);
+ if (!power_control::nmiButtonName.empty())
+ {
+ power_control::requestGPIOEvents(
+ power_control::nmiButtonName, power_control::nmiButtonHandler,
+ power_control::nmiButtonLine, power_control::nmiButtonEvent);
+ }
// Request ID_BUTTON GPIO events
- power_control::requestGPIOEvents(
- "ID_BUTTON", power_control::idButtonHandler,
- power_control::idButtonLine, power_control::idButtonEvent);
+ if (!power_control::idButtonName.empty())
+ {
+ power_control::requestGPIOEvents(
+ power_control::idButtonName, power_control::idButtonHandler,
+ power_control::idButtonLine, power_control::idButtonEvent);
+ }
// Request POST_COMPLETE GPIO events
- if (!power_control::requestGPIOEvents(
- "POST_COMPLETE", power_control::postCompleteHandler,
- power_control::postCompleteLine, power_control::postCompleteEvent))
+ if (!power_control::postCompleteName.empty())
{
+ if (!power_control::requestGPIOEvents(
+ power_control::postCompleteName,
+ power_control::postCompleteHandler,
+ power_control::postCompleteLine,
+ power_control::postCompleteEvent))
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ std::cerr
+ << "postComplete name should be configured from json config file\n";
return -1;
}