Only create buttons when their GPIOs are defined
Look in /etc/default/obmc/gpio/gpio_defs.json to see
if the GPIO for a button is defined, and only create
the button object if it is.
This is how a system implementer can specify which
button objects are needed for their particular system.
Change-Id: I359f87875b6bb5741fdf4718b30b0f5b4552a528
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/inc/gpio.hpp b/inc/gpio.hpp
index 98df21b..ca83082 100644
--- a/inc/gpio.hpp
+++ b/inc/gpio.hpp
@@ -19,3 +19,10 @@
int configGpio(const char* gpioName, int* fd, sdbusplus::bus::bus& bus);
void closeGpio(int fd);
+bool gpioDefined(const std::string& gpioName);
+
+template <typename T>
+bool hasGpio()
+{
+ return gpioDefined(T::getGpioName());
+}
diff --git a/inc/id_button.hpp b/inc/id_button.hpp
index a5c4180..af100ef 100644
--- a/inc/id_button.hpp
+++ b/inc/id_button.hpp
@@ -70,6 +70,11 @@
void simPress() override;
+ static const char* getGpioName()
+ {
+ return ID_BUTTON;
+ }
+
static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
void* userdata)
{
diff --git a/inc/power_button.hpp b/inc/power_button.hpp
index d00f1c6..e4cc660 100644
--- a/inc/power_button.hpp
+++ b/inc/power_button.hpp
@@ -71,6 +71,11 @@
void simPress() override;
void simLongPress() override;
+ static const char* getGpioName()
+ {
+ return POWER_BUTTON;
+ }
+
static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
void* userdata)
{
diff --git a/inc/reset_button.hpp b/inc/reset_button.hpp
index b10f241..d0534e8 100644
--- a/inc/reset_button.hpp
+++ b/inc/reset_button.hpp
@@ -70,6 +70,11 @@
void simPress() override;
+ static const char* getGpioName()
+ {
+ return RESET_BUTTON;
+ }
+
static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
void* userdata)
{
diff --git a/src/gpio.cpp b/src/gpio.cpp
index b78d2bc..27fc74d 100644
--- a/src/gpio.cpp
+++ b/src/gpio.cpp
@@ -21,13 +21,19 @@
#include <experimental/filesystem>
#include <fstream>
+#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.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";
+static constexpr auto gpioDefs = "/etc/default/obmc/gpio/gpio_defs.json";
+
+using namespace phosphor::logging;
+
void closeGpio(int fd)
{
if (fd > 0)
@@ -36,6 +42,32 @@
}
}
+bool gpioDefined(const std::string& gpioName)
+{
+ try
+ {
+ std::ifstream gpios{gpioDefs};
+ auto json = nlohmann::json::parse(gpios, nullptr, true);
+ auto defs = json["gpio_definitions"];
+
+ auto gpio =
+ std::find_if(defs.begin(), defs.end(), [&gpioName](const auto g) {
+ return gpioName == g["name"];
+ });
+
+ if (gpio != defs.end())
+ {
+ return true;
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>("Error parsing GPIO JSON", entry("ERROR=%s", e.what()),
+ entry("GPIO_NAME=%s", gpioName.c_str()));
+ }
+ return false;
+}
+
int configGpio(const char* gpioName, int* fd, sdbusplus::bus::bus& bus)
{
auto method = bus.new_method_call(SYSMGR_SERVICE, SYSMGR_OBJ_PATH,
@@ -47,8 +79,7 @@
if (result.is_method_error())
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "bus call error!");
+ log<level::ERR>("bus call error!");
return -1;
}
@@ -71,9 +102,7 @@
if (std::experimental::filesystem::exists(fullPath))
{
- phosphor::logging::log<phosphor::logging::level::INFO>(
- "GPIO exported",
- phosphor::logging::entry("PATH=%s", devPath.c_str()));
+ log<level::INFO>("GPIO exported", entry("PATH=%s", devPath.c_str()));
}
else
{
@@ -89,10 +118,9 @@
catch (const std::exception& e)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Error in writing!",
- phosphor::logging::entry("PATH=%s", devPath.c_str()),
- phosphor::logging::entry("NUM=%d", gpioNum));
+ log<level::ERR>("Error in writing!",
+ entry("PATH=%s", devPath.c_str()),
+ entry("NUM=%d", gpioNum));
return -1;
}
}
@@ -113,9 +141,8 @@
catch (const std::exception& e)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Error in reading!",
- phosphor::logging::entry("PATH=%s", devPath.c_str()));
+ log<level::ERR>("Error in reading!",
+ entry("PATH=%s", devPath.c_str()));
return -1;
}
@@ -133,8 +160,7 @@
catch (const std::exception& e)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Error in writing!");
+ log<level::ERR>("Error in writing!");
return -1;
}
}
@@ -152,8 +178,7 @@
catch (const std::exception& e)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Error in writing!");
+ log<level::ERR>("Error in writing!");
return -1;
}
}
@@ -174,8 +199,7 @@
catch (const std::exception& e)
{
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Error in writing!");
+ log<level::ERR>("Error in writing!");
return -1;
}
}
@@ -187,7 +211,7 @@
if (*fd < 0)
{
- phosphor::logging::log<phosphor::logging::level::ERR>("open error!");
+ log<level::ERR>("open error!");
return -1;
}
diff --git a/src/main.cpp b/src/main.cpp
index 6107949..eb96b13 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -42,11 +42,23 @@
bus.request_name("xyz.openbmc_project.Chassis.Buttons");
- PowerButton powerButton{bus, POWER_DBUS_OBJECT_NAME, eventP};
+ std::unique_ptr<PowerButton> pb;
+ if (hasGpio<PowerButton>())
+ {
+ pb = std::make_unique<PowerButton>(bus, POWER_DBUS_OBJECT_NAME, eventP);
+ }
- ResetButton resetButton{bus, RESET_DBUS_OBJECT_NAME, eventP};
+ std::unique_ptr<ResetButton> rb;
+ if (hasGpio<ResetButton>())
+ {
+ rb = std::make_unique<ResetButton>(bus, RESET_DBUS_OBJECT_NAME, eventP);
+ }
- IDButton idButton{bus, ID_DBUS_OBJECT_NAME, eventP};
+ std::unique_ptr<IDButton> ib;
+ if (hasGpio<IDButton>())
+ {
+ ib = std::make_unique<IDButton>(bus, ID_DBUS_OBJECT_NAME, eventP);
+ }
try
{