Update analyze to check VIN_UV_FAULT
The function is a pure virtual function in DeviceMonitor, add in the
implementation of that for PowerSupply. Read the file that represents
that bit from the STATUS_WORD. If fault is on, report a fault.
Change-Id: I05a4bff997bb0c8b8b71db444e9db0e506765689
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/power-supply/main.cpp b/power-supply/main.cpp
index eb3f9ed..e36bd24 100644
--- a/power-supply/main.cpp
+++ b/power-supply/main.cpp
@@ -56,13 +56,16 @@
return -4;
}
+ auto bus = sdbusplus::bus::new_default();
+
auto objname = "power_supply" + instnum;
auto instance = std::stoul(instnum);
auto psuDevice = std::make_unique<psu::PowerSupply>(objname,
std::move(instance),
std::move(objpath),
- std::move(invpath));
- auto bus = sdbusplus::bus::new_default();
+ std::move(invpath),
+ bus);
+
sd_event* events = nullptr;
auto r = sd_event_default(&events);
@@ -81,6 +84,14 @@
// TODO: Use inventory path to subscribe to signal change for power supply presence.
+ //Attach the event object to the bus object so we can
+ //handle both sd_events (for the timers) and dbus signals.
+ bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
+
+ // TODO: Get power state on startup.
+ // TODO: Get presence state on startup and subscribe to presence changes.
+ // TODO - set to vinUVFault to false on presence change & start of poweron
+ // TODO - set readFailLogged to false on presence change and start of poweron
auto pollInterval = std::chrono::milliseconds(1000);
DeviceMonitor mainloop(std::move(psuDevice), eventPtr, pollInterval);
mainloop.run();
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index e9f5d6b..8dd4c3e 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -13,7 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <xyz/openbmc_project/Sensor/Device/error.hpp>
+#include <xyz/openbmc_project/Control/Device/error.hpp>
+#include <xyz/openbmc_project/Power/Fault/error.hpp>
+#include "elog-errors.hpp"
#include "power_supply.hpp"
+#include "pmbus.hpp"
+#include "utility.hpp"
+
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
+using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
+using namespace sdbusplus::xyz::openbmc_project::Power::Fault::Error;
namespace witherspoon
{
@@ -22,15 +35,56 @@
namespace psu
{
+
void PowerSupply::analyze()
{
- //TODO analyze() needs to be implemented in this class.
+ using namespace witherspoon::pmbus;
+
+ try
+ {
+ auto curUVFault = pmbusIntf.readBit(VIN_UV_FAULT, Type::Hwmon);
+ //TODO: 3 consecutive reads should be performed.
+ // If 3 consecutive reads are seen, log the fault.
+ // Driver gives cached value, read once a second.
+ // increment for fault on, decrement for fault off, to deglitch.
+ // If count reaches 3, we have fault. If count reaches 0, fault is
+ // cleared.
+
+ //TODO: INPUT FAULT or WARNING bit to check from STATUS_WORD
+ // pmbus-core update to read high byte of STATUS_WORD?
+
+ if ((curUVFault != vinUVFault) || inputFault)
+ {
+ if (curUVFault)
+ {
+ //FIXME - metadata
+ report<PowerSupplyUnderVoltageFault>();
+ vinUVFault = true;
+ }
+ else
+ {
+ log<level::INFO>("VIN_UV_FAULT cleared");
+ vinUVFault = false;
+ }
+ }
+ }
+ catch (ReadFailure& e)
+ {
+ if (!readFailLogged)
+ {
+ commit<ReadFailure>();
+ readFailLogged = true;
+ // TODO - Need to reset that to false at start of power on, or
+ // presence change.
+ }
+ }
+
return;
}
void PowerSupply::clearFaults()
{
- //TODO
+ //TODO - Clear faults at pre-poweron.
return;
}
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index 4249024..43489d2 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -1,5 +1,6 @@
#pragma once
#include "device.hpp"
+#include "pmbus.hpp"
namespace witherspoon
{
@@ -29,10 +30,14 @@
* @param[in] inst - the device instance
* @param[in] objpath - the path to monitor
* @param[in] invpath - the inventory path to use
+ * @param[in] bus - D-Bus bus object
*/
PowerSupply(const std::string& name, size_t inst,
- const std::string& objpath, const std::string& invpath)
- : Device(name, inst), monitorPath(objpath), inventoryPath(invpath)
+ const std::string& objpath,
+ const std::string& invpath,
+ sdbusplus::bus::bus& bus)
+ : Device(name, inst), monitorPath(objpath), inventoryPath(invpath),
+ bus(bus), pmbusIntf(objpath)
{
}
@@ -65,6 +70,39 @@
* The D-Bus path to use for this power supply's inventory status.
*/
std::string inventoryPath;
+
+ /** @brief Connection for sdbusplus bus */
+ sdbusplus::bus::bus& bus;
+
+ /**
+ * @brief Pointer to the PMBus interface
+ *
+ * Used to read out of or write to the /sysfs tree(s) containing files
+ * that a device driver monitors the PMBus interface to the power
+ * supplies.
+ */
+ witherspoon::pmbus::PMBus pmbusIntf;
+
+ /**
+ * @brief Has a PMBus read failure already been logged?
+ */
+ bool readFailLogged = false;
+
+ /**
+ * @brief Set to true when a VIN UV fault has been detected
+ *
+ * This is the VIN_UV_FAULT bit in the low byte from the STATUS_WORD
+ * command response.
+ */
+ bool vinUVFault = false;
+
+ /**
+ * @brief Set to true when an input fault or warning is detected
+ *
+ * This is the "INPUT FAULT OR WARNING" bit in the high byte from the
+ * STATUS_WORD command response.
+ */
+ bool inputFault = false;
};
}