pseq: Add support for UCD90160 EM configuration
Add power control support for receiving Entity Manager configuration for
a UCD90160 device and instantiating an object of that type.
Tested:
* Test where EntityManager information is available when application
starts
* Test where EntityManager information is not available when application
starts
* Verify the EntityManager information is found later via
InterfacesAdded events
* Test where xyz.openbmc_project.Configuration.UCD90320 interface is
found
* Verify UCD90320Monitor object is created
* Test where xyz.openbmc_project.Configuration.UCD90160 interface is
found
* Verify UCD90160Monitor object is created
* Verify chassis can be powered on without errors
* Verify chassis can be powered off without errors
* Verify pgood error is detected and logged
Signed-off-by: Jim Wright <jlwright@us.ibm.com>
Change-Id: Ibdb86db176971f27bbd2a998a39a0325997c6677
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/phosphor-power-sequencer/src/power_control.cpp b/phosphor-power-sequencer/src/power_control.cpp
index 096fe5f..b4b993d 100644
--- a/phosphor-power-sequencer/src/power_control.cpp
+++ b/phosphor-power-sequencer/src/power_control.cpp
@@ -17,10 +17,12 @@
#include "power_control.hpp"
#include "types.hpp"
+#include "ucd90160_monitor.hpp"
#include "ucd90320_monitor.hpp"
#include <fmt/chrono.h>
#include <fmt/format.h>
+#include <fmt/ranges.h>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
@@ -28,17 +30,20 @@
#include <xyz/openbmc_project/Common/error.hpp>
#include <exception>
-#include <string>
+#include <vector>
using namespace phosphor::logging;
namespace phosphor::power::sequencer
{
-const std::string interfaceName = "xyz.openbmc_project.Configuration.UCD90320";
+const std::vector<std::string>
+ interfaceNames({"xyz.openbmc_project.Configuration.UCD90160",
+ "xyz.openbmc_project.Configuration.UCD90320"});
const std::string addressPropertyName = "Address";
const std::string busPropertyName = "Bus";
const std::string namePropertyName = "Name";
+const std::string typePropertyName = "Type";
PowerControl::PowerControl(sdbusplus::bus_t& bus,
const sdeventplus::Event& event) :
@@ -61,43 +66,58 @@
setUpGpio();
}
-void PowerControl::getDeviceProperties(util::DbusPropertyMap& properties)
+void PowerControl::getDeviceProperties(const util::DbusPropertyMap& properties)
{
- uint64_t* i2cBus = nullptr;
- uint64_t* i2cAddress = nullptr;
- std::string* name = nullptr;
+ uint64_t i2cBus{0};
+ uint64_t i2cAddress{0};
+ std::string name;
+ std::string type;
- for (const auto& property : properties)
+ for (const auto& [property, value] : properties)
{
try
{
- if (property.first == busPropertyName)
+ if (property == busPropertyName)
{
- i2cBus = std::get_if<uint64_t>(&properties[busPropertyName]);
+ i2cBus = std::get<uint64_t>(value);
}
- else if (property.first == addressPropertyName)
+ else if (property == addressPropertyName)
{
- i2cAddress =
- std::get_if<uint64_t>(&properties[addressPropertyName]);
+ i2cAddress = std::get<uint64_t>(value);
}
- else if (property.first == namePropertyName)
+ else if (property == namePropertyName)
{
- name = std::get_if<std::string>(&properties[namePropertyName]);
+ name = std::get<std::string>(value);
+ }
+ else if (property == typePropertyName)
+ {
+ type = std::get<std::string>(value);
}
}
- catch (const std::exception&)
- {}
+ catch (const std::exception& e)
+ {
+ log<level::INFO>(
+ fmt::format("Error getting device properties, error: {}",
+ e.what())
+ .c_str());
+ }
}
- if (i2cBus && i2cAddress && name && !name->empty())
+ log<level::INFO>(
+ fmt::format(
+ "Found power sequencer device properties, name: {}, type: {}, bus: {} addr: {:#02x} ",
+ name, type, i2cBus, i2cAddress)
+ .c_str());
+
+ // Create device object
+ if (type == "UCD90320")
{
- log<level::DEBUG>(
- fmt::format(
- "Found power sequencer device properties, name: {}, bus: {} addr: {:#02x} ",
- *name, *i2cBus, *i2cAddress)
- .c_str());
- // Create device object
- device = std::make_unique<UCD90320Monitor>(bus, *i2cBus, *i2cAddress);
+ device = std::make_unique<UCD90320Monitor>(bus, i2cBus, i2cAddress);
+ deviceFound = true;
+ }
+ else if (type == "UCD90160")
+ {
+ device = std::make_unique<UCD90160Monitor>(bus, i2cBus, i2cAddress);
deviceFound = true;
}
}
@@ -117,10 +137,10 @@
return state;
}
-void PowerControl::interfacesAddedHandler(sdbusplus::message_t& msg)
+void PowerControl::interfacesAddedHandler(sdbusplus::message_t& message)
{
// Only continue if message is valid and device has not already been found
- if (!msg || deviceFound)
+ if (!message || deviceFound)
{
return;
}
@@ -128,23 +148,42 @@
try
{
// Read the dbus message
- sdbusplus::message::object_path objPath;
+ sdbusplus::message::object_path path;
std::map<std::string, std::map<std::string, util::DbusVariant>>
interfaces;
- msg.read(objPath, interfaces);
+ message.read(path, interfaces);
- // Find the device interface, if present
- auto itIntf = interfaces.find(interfaceName);
- if (itIntf != interfaces.cend())
+ for (const auto& [interface, properties] : interfaces)
{
- log<level::INFO>(
- fmt::format("InterfacesAdded for: {}", interfaceName).c_str());
- getDeviceProperties(itIntf->second);
+ log<level::DEBUG>(
+ fmt::format(
+ "Interfaces added handler found path: {}, interface: {}",
+ path.str, interface)
+ .c_str());
+
+ // Find the device interface, if present
+ for (const auto& interfaceName : interfaceNames)
+ {
+ if (interface == interfaceName)
+ {
+ log<level::INFO>(
+ fmt::format(
+ "Interfaces added handler matched interface name: {}",
+ interfaceName)
+ .c_str());
+ getDeviceProperties(properties);
+ }
+ }
}
}
- catch (const std::exception&)
+ catch (const std::exception& e)
{
// Error trying to read interfacesAdded message.
+ log<level::INFO>(
+ fmt::format(
+ "Error trying to read interfacesAdded message, error: {}",
+ e.what())
+ .c_str());
}
}
@@ -299,29 +338,42 @@
{
try
{
- auto objects = util::getSubTree(bus, "/", interfaceName, 0);
+ // Check if device information is already available
+ auto objects = util::getSubTree(bus, "/", interfaceNames, 0);
// Search for matching interface in returned objects
for (const auto& [path, services] : objects)
{
- auto service = services.begin()->first;
-
- if (path.empty() || service.empty())
+ log<level::DEBUG>(
+ fmt::format("Found path: {}, services: {}", path, services)
+ .c_str());
+ for (const auto& [service, interfaces] : services)
{
- continue;
+ log<level::DEBUG>(
+ fmt::format("Found service: {}, interfaces: {}", service,
+ interfaces)
+ .c_str());
+ for (const auto& interface : interfaces)
+ {
+ log<level::DEBUG>(
+ fmt::format("Found interface: {}", interface).c_str());
+ // Get the properties for the device interface
+ auto properties =
+ util::getAllProperties(bus, path, interface, service);
+
+ getDeviceProperties(properties);
+ }
}
-
- // Get the properties for the device interface
- auto properties = util::getAllProperties(bus, path, interfaceName,
- service);
-
- getDeviceProperties(properties);
}
}
- catch (const std::exception&)
+ 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.
+ // Interface or property not found. Let the Interfaces Added
+ // callback process the information once the interfaces are added to
+ // D-Bus.
+ log<level::DEBUG>(
+ fmt::format("Error setting up device, error: {}", e.what())
+ .c_str());
}
}
diff --git a/phosphor-power-sequencer/src/power_control.hpp b/phosphor-power-sequencer/src/power_control.hpp
index 660b90b..f623fd8 100644
--- a/phosphor-power-sequencer/src/power_control.hpp
+++ b/phosphor-power-sequencer/src/power_control.hpp
@@ -14,6 +14,7 @@
#include <sdeventplus/utility/timer.hpp>
#include <chrono>
+#include <string>
namespace phosphor::power::sequencer
{
@@ -172,7 +173,7 @@
* Get the device properties
* @param properties A map of property names and values
*/
- void getDeviceProperties(util::DbusPropertyMap& properties);
+ void getDeviceProperties(const util::DbusPropertyMap& properties);
/**
* Callback to begin failure processing after observing pgood failure wait