psu-sensor: Add devmgmt and powercallback to PSU
Some PSU sensors are dependent on system power state.
Without change the device initialization would fail and
dbus-sensors and entity-manager wouldn't come back to
properly instantiate.
Same intention as this hwmontempsensor change: https://github.com/openbmc/dbus-sensors/commit/a1456c4abafc697e7caa6b8e95ac9ddb35c4e7d1
Tested: Same sensors are getting created. Sensors are
getting created/destroyed on host power events based
on their PowerState.
Signed-off-by: Matt Simmering <matthew.simmering@intel.com>
Change-Id: I3ee719cf65df225f964148d3994eec4d758d72a1
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index d4a7895..510dde4 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -284,11 +284,14 @@
std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
const ManagedObjectType& sensorConfigs,
const std::shared_ptr<boost::container::flat_set<std::string>>&
- sensorsChanged)
+ sensorsChanged,
+ bool activateOnly)
{
int numCreated = 0;
bool firstScan = sensorsChanged == nullptr;
+ auto devices = instantiateDevices(sensorConfigs, sensors, sensorTypes);
+
std::vector<fs::path> pmbusPaths;
if (!findFiles(fs::path("/sys/class/hwmon"), "name", pmbusPaths))
{
@@ -434,6 +437,18 @@
continue;
}
+ auto findI2CDev = devices.find(*interfacePath);
+
+ std::shared_ptr<I2CDevice> i2cDev;
+ if (findI2CDev != devices.end())
+ {
+ if (activateOnly && !findI2CDev->second.second)
+ {
+ continue;
+ }
+ i2cDev = findI2CDev->second.first;
+ }
+
auto findPSUName = baseConfig->find("Name");
if (findPSUName == baseConfig->end())
{
@@ -887,19 +902,33 @@
<< "\"\n";
}
// destruct existing one first if already created
- sensors[sensorName] = nullptr;
- sensors[sensorName] = std::make_shared<PSUSensor>(
- sensorPathStr, sensorType, objectServer, dbusConnection, io,
- sensorName, std::move(sensorThresholds), *interfacePath,
- readState, findSensorUnit->second, factor,
- psuProperty->maxReading, psuProperty->minReading,
- psuProperty->sensorOffset, labelHead, thresholdConfSize,
- pollRate);
- sensors[sensorName]->setupRead();
- ++numCreated;
- if constexpr (debug)
+
+ auto& sensor = sensors[sensorName];
+ if (!activateOnly)
{
- std::cerr << "Created " << numCreated << " sensors so far\n";
+ sensor = nullptr;
+ }
+
+ if (sensor != nullptr)
+ {
+ sensor->activate(sensorPathStr, i2cDev);
+ }
+ else
+ {
+ sensors[sensorName] = std::make_shared<PSUSensor>(
+ sensorPathStr, sensorType, objectServer, dbusConnection, io,
+ sensorName, std::move(sensorThresholds), *interfacePath,
+ readState, findSensorUnit->second, factor,
+ psuProperty->maxReading, psuProperty->minReading,
+ psuProperty->sensorOffset, labelHead, thresholdConfSize,
+ pollRate, i2cDev);
+ sensors[sensorName]->setupRead();
+ ++numCreated;
+ if constexpr (debug)
+ {
+ std::cerr << "Created " << numCreated
+ << " sensors so far\n";
+ }
}
}
@@ -922,13 +951,14 @@
boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
const std::shared_ptr<boost::container::flat_set<std::string>>&
- sensorsChanged)
+ sensorsChanged,
+ bool activateOnly)
{
auto getter = std::make_shared<GetSensorConfiguration>(
- dbusConnection, [&io, &objectServer, &dbusConnection, sensorsChanged](
- const ManagedObjectType& sensorConfigs) {
+ dbusConnection, [&io, &objectServer, &dbusConnection, sensorsChanged,
+ activateOnly](const ManagedObjectType& sensorConfigs) {
createSensorsCallback(io, objectServer, dbusConnection,
- sensorConfigs, sensorsChanged);
+ sensorConfigs, sensorsChanged, activateOnly);
});
std::vector<std::string> types(sensorTypes.size());
for (const auto& [type, dt] : sensorTypes)
@@ -1057,6 +1087,29 @@
{"fan4", {"fan4_alarm", "fan4_fault"}}}}};
}
+static void powerStateChanged(
+ PowerState type, bool newState,
+ boost::container::flat_map<std::string, std::shared_ptr<PSUSensor>>&
+ sensors,
+ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
+ std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+{
+ if (newState)
+ {
+ createSensors(io, objectServer, dbusConnection, nullptr, true);
+ }
+ else
+ {
+ for (auto& [path, sensor] : sensors)
+ {
+ if (sensor != nullptr && sensor->readState == type)
+ {
+ sensor->deactivate();
+ }
+ }
+ }
+}
+
int main()
{
boost::asio::io_context io;
@@ -1071,8 +1124,16 @@
propertyInitialize();
- boost::asio::post(
- io, [&]() { createSensors(io, objectServer, systemBus, nullptr); });
+ auto powerCallBack =
+ [&io, &objectServer, &systemBus](PowerState type, bool state) {
+ powerStateChanged(type, state, sensors, io, objectServer, systemBus);
+ };
+
+ setupPowerMatchCallback(systemBus, powerCallBack);
+
+ boost::asio::post(io, [&]() {
+ createSensors(io, objectServer, systemBus, nullptr, false);
+ });
boost::asio::steady_timer filterTimer(io);
std::function<void(sdbusplus::message_t&)> eventHandler =
[&](sdbusplus::message_t& message) {
@@ -1092,7 +1153,7 @@
{
std::cerr << "timer error\n";
}
- createSensors(io, objectServer, systemBus, sensorsChanged);
+ createSensors(io, objectServer, systemBus, sensorsChanged, false);
});
};
@@ -1147,7 +1208,7 @@
std::cerr << "timer error\n";
return;
}
- createSensors(io, objectServer, systemBus, nullptr);
+ createSensors(io, objectServer, systemBus, nullptr, false);
});
};