Implement de-glitch for PGOOD and UNIT_IS_OFF
De-glitch the powerOnFault so that a fault is logged only if the
POWER_GOOD Negated or UNIT_IS_OFF bits are in the wrong state three
times in a row.
Resolves openbmc/openbmc#2473
Change-Id: Icbb45010f921bd3e11018f5e7bdc2d155242d464
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index 277a800..0952cb9 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -199,7 +199,7 @@
readFailLogged = false;
vinUVFault = false;
inputFault = false;
- powerOnFault = false;
+ powerOnFault = 0;
outputOCFault = false;
outputOVFault = false;
fanFault = false;
@@ -315,28 +315,44 @@
{
using namespace witherspoon::pmbus;
- // Check PG# and UNIT_IS_OFF
- if (((statusWord & status_word::POWER_GOOD_NEGATED) ||
- (statusWord & status_word::UNIT_IS_OFF)) &&
- !powerOnFault)
+ if (powerOnFault < FAULT_COUNT)
{
- util::NamesValues nv;
- nv.add("STATUS_WORD", statusWord);
- captureCmd(nv, STATUS_INPUT, Type::Debug);
- auto status0Vout = pmbusIntf.insertPageNum(STATUS_VOUT, 0);
- captureCmd(nv, status0Vout, Type::Debug);
- captureCmd(nv, STATUS_IOUT, Type::Debug);
- captureCmd(nv, STATUS_MFR, Type::Debug);
+ // Check PG# and UNIT_IS_OFF
+ if ((statusWord & status_word::POWER_GOOD_NEGATED) ||
+ (statusWord & status_word::UNIT_IS_OFF))
+ {
+ log<level::INFO>("PGOOD or UNIT_IS_OFF bit bad",
+ entry("STATUS_WORD=0x%04X", statusWord));
+ powerOnFault++;
+ }
+ else
+ {
+ if (powerOnFault > 0)
+ {
+ log<level::INFO>("PGOOD and UNIT_IS_OFF bits good");
+ powerOnFault = 0;
+ }
+ }
- using metadata = org::open_power::Witherspoon::Fault::
- PowerSupplyShouldBeOn;
+ if (powerOnFault >= FAULT_COUNT)
+ {
+ util::NamesValues nv;
+ nv.add("STATUS_WORD", statusWord);
+ captureCmd(nv, STATUS_INPUT, Type::Debug);
+ auto status0Vout = pmbusIntf.insertPageNum(STATUS_VOUT, 0);
+ captureCmd(nv, status0Vout, Type::Debug);
+ captureCmd(nv, STATUS_IOUT, Type::Debug);
+ captureCmd(nv, STATUS_MFR, Type::Debug);
- // A power supply is OFF (or pgood low) but should be on.
- report<PowerSupplyShouldBeOn>(metadata::RAW_STATUS(nv.get().c_str()),
- metadata::CALLOUT_INVENTORY_PATH(
- inventoryPath.c_str()));
+ using metadata = org::open_power::Witherspoon::Fault::
+ PowerSupplyShouldBeOn;
- powerOnFault = true;
+ // A power supply is OFF (or pgood low) but should be on.
+ report<PowerSupplyShouldBeOn>(
+ metadata::RAW_STATUS(nv.get().c_str()),
+ metadata::CALLOUT_INVENTORY_PATH(
+ inventoryPath.c_str()));
+ }
}
}
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index 474ad8d..38e2342 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -14,6 +14,8 @@
namespace sdbusRule = sdbusplus::bus::match::rules;
+constexpr auto FAULT_COUNT = 3;
+
/**
* @class PowerSupply
* Represents a PMBus power supply device.
@@ -97,8 +99,11 @@
/** @brief True if the power is on. */
bool powerOn = false;
- /** @brief True if power on fault has been detected/reported. */
- bool powerOnFault = false;
+ /**
+ * @brief Equal to FAULT_COUNT if power on fault has been
+ * detected.
+ */
+ size_t powerOnFault = 0;
/** @brief The sd_event structure used by the power on timer. */
event::Event& event;