pseq: Retrieve device info from entity manager
Retrieve power sequencer device information from entity manager using
appropriate DBUS methods.
Signed-off-by: Jim Wright <jlwright@us.ibm.com>
Change-Id: I4b0f821345fa9be9146e1a480d2b4e8aabd2c267
diff --git a/phosphor-power-sequencer/src/meson.build b/phosphor-power-sequencer/src/meson.build
index adb8a3f..8f74c7e 100644
--- a/phosphor-power-sequencer/src/meson.build
+++ b/phosphor-power-sequencer/src/meson.build
@@ -15,6 +15,9 @@
sdeventplus,
stdplus
],
+ link_with: [
+ libpower
+ ],
implicit_include_directories: false,
include_directories: phosphor_power_sequencer_include_directories,
install: true
diff --git a/phosphor-power-sequencer/src/power_control.cpp b/phosphor-power-sequencer/src/power_control.cpp
index 981a957..6e9fa58 100644
--- a/phosphor-power-sequencer/src/power_control.cpp
+++ b/phosphor-power-sequencer/src/power_control.cpp
@@ -17,7 +17,6 @@
#include "power_control.hpp"
#include "types.hpp"
-#include "utility.hpp"
#include <fmt/format.h>
#include <sys/types.h>
@@ -36,8 +35,10 @@
namespace phosphor::power::sequencer
{
-const std::string powerControlLineName = "power-chassis-control";
-const std::string pgoodLineName = "power-chassis-good";
+const std::string interfaceName = "xyz.openbmc_project.Configuration.UCD90320";
+const std::string addressPropertyName = "Address";
+const std::string busPropertyName = "Bus";
+const std::string namePropertyName = "Name";
PowerControl::PowerControl(sdbusplus::bus::bus& bus,
const sdeventplus::Event& event) :
@@ -47,9 +48,59 @@
{
// Obtain dbus service name
bus.request_name(POWER_IFACE);
+
+ // Subscribe to D-Bus interfacesAdded signal from Entity Manager. This
+ // notifies us if the interface becomes available later.
+ match = std::make_unique<sdbusplus::bus::match_t>(
+ bus,
+ sdbusplus::bus::match::rules::interfacesAdded() +
+ sdbusplus::bus::match::rules::sender(
+ "xyz.openbmc_project.EntityManager"),
+ std::bind(&PowerControl::interfacesAddedHandler, this,
+ std::placeholders::_1));
+ setUpDevice();
setUpGpio();
}
+void PowerControl::getDeviceProperties(util::DbusPropertyMap& properties)
+{
+ uint64_t* i2cBus = nullptr;
+ uint64_t* i2cAddress = nullptr;
+ std::string* name = nullptr;
+
+ for (const auto& property : properties)
+ {
+ try
+ {
+ if (property.first == busPropertyName)
+ {
+ i2cBus = std::get_if<uint64_t>(&properties[busPropertyName]);
+ }
+ else if (property.first == addressPropertyName)
+ {
+ i2cAddress =
+ std::get_if<uint64_t>(&properties[addressPropertyName]);
+ }
+ else if (property.first == namePropertyName)
+ {
+ name = std::get_if<std::string>(&properties[namePropertyName]);
+ }
+ }
+ catch (std::exception& e)
+ {}
+ }
+
+ if (i2cBus && i2cAddress && name && !name->empty())
+ {
+ log<level::INFO>(
+ fmt::format(
+ "Found power sequencer device properties, name: {}, bus: {} addr: {:#02x} ",
+ *name, *i2cBus, *i2cAddress)
+ .c_str());
+ // Create device object
+ }
+}
+
int PowerControl::getPgood() const
{
return pgood;
@@ -65,6 +116,37 @@
return state;
}
+void PowerControl::interfacesAddedHandler(sdbusplus::message::message& msg)
+{
+ // Verify message is valid
+ if (!msg)
+ {
+ return;
+ }
+
+ try
+ {
+ // Read the dbus message
+ sdbusplus::message::object_path objPath;
+ std::map<std::string, std::map<std::string, util::DbusVariant>>
+ interfaces;
+ msg.read(objPath, interfaces);
+
+ // Find the device interface, if present
+ auto itIntf = interfaces.find(interfaceName);
+ if (itIntf != interfaces.cend())
+ {
+ log<level::INFO>(
+ fmt::format("InterfacesAdded for: {}", interfaceName).c_str());
+ getDeviceProperties(itIntf->second);
+ }
+ }
+ catch (const std::exception&)
+ {
+ // Error trying to read interfacesAdded message.
+ }
+}
+
void PowerControl::pollPgood()
{
if (inStateTransition)
@@ -179,8 +261,41 @@
emitPropertyChangedSignal("state");
}
+void PowerControl::setUpDevice()
+{
+ try
+ {
+ auto objects = util::getSubTree(bus, "/", interfaceName, 0);
+
+ // Search for matching interface in returned objects
+ for (const auto& [path, services] : objects)
+ {
+ auto service = services.begin()->first;
+
+ if (path.empty() || service.empty())
+ {
+ continue;
+ }
+
+ // Get the properties for the device interface
+ auto properties =
+ util::getAllProperties(bus, path, interfaceName, service);
+
+ getDeviceProperties(properties);
+ }
+ }
+ catch (const std::exception& e)
+ {
+ // Interface or property not found. Let the Interfaces Added callback
+ // process the information once the interfaces are added to D-Bus.
+ }
+}
+
void PowerControl::setUpGpio()
{
+ const std::string powerControlLineName = "power-chassis-control";
+ const std::string pgoodLineName = "power-chassis-good";
+
pgoodLine = gpiod::find_line(pgoodLineName);
if (!pgoodLine)
{
diff --git a/phosphor-power-sequencer/src/power_control.hpp b/phosphor-power-sequencer/src/power_control.hpp
index 4359074..1699dcc 100644
--- a/phosphor-power-sequencer/src/power_control.hpp
+++ b/phosphor-power-sequencer/src/power_control.hpp
@@ -1,9 +1,11 @@
#pragma once
#include "power_interface.hpp"
+#include "utility.hpp"
#include <gpiod.hpp>
#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/server/object.hpp>
#include <sdeventplus/clock.hpp>
@@ -48,6 +50,12 @@
/** @copydoc PowerInterface::getState() */
int getState() const override;
+ /**
+ * Callback function to handle interfacesAdded D-Bus signals
+ * @param msg Expanded sdbusplus message data
+ */
+ void interfacesAddedHandler(sdbusplus::message::message& msg);
+
/** @copydoc PowerInterface::setPgoodTimeout() */
void setPgoodTimeout(int timeout) override;
@@ -66,6 +74,11 @@
bool inStateTransition{false};
/**
+ * The match to Entity Manager interfaces added.
+ */
+ std::unique_ptr<sdbusplus::bus::match_t> match;
+
+ /**
* Power good
*/
int pgood{0};
@@ -113,11 +126,22 @@
sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
/**
+ * Get the device properties
+ * @param[in] properties A map of property names and values
+ */
+ void getDeviceProperties(util::DbusPropertyMap& properties);
+
+ /**
* Polling method for monitoring the system power good
*/
void pollPgood();
/**
+ * Set up power sequencer device
+ */
+ void setUpDevice();
+
+ /**
* Set up GPIOs
*/
void setUpGpio();