psu-ng: Clear faults when voltage back in range
If the last read voltage (via READ_VIN) was below the minimum and
now it is back in a valid range (100 or 200 volt range valid), clear all
the faults to allow for re-detection of faults and logging of new errors.
Trace if INPUT_FAULT_WARN or VIN_UV clear. We should not expect to see
that without sending a CLEAR_FAULTS command (or a power cycle).
Tested:
Rainier 2S2U real hardware.
ePDU outlet off/on allows re-detection of injected CML fault.
- input fault, vin_uv fault, pgood/off fault.
- repeat shows faults cleared, and new faults logged.
Simulator pgood fault, then low voltage followed by good voltage.
Verify simulator can re-detect faults after voltage back in range.
Simulator fake input fault/warn on, then off and other fault on.
- verified tracing input going off without clear faults sent.
Simulator fake input fault/warn on, then no faults.
- verified tracing input going off without clear faults sent.
Change-Id: Ic8022cf137978ff660680e9680f778853cbecf0d
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
index d416c94..c2dccfb 100644
--- a/phosphor-power-supply/power_supply.cpp
+++ b/phosphor-power-supply/power_supply.cpp
@@ -220,6 +220,20 @@
inputFault = true;
}
+
+ // If had INPUT/VIN_UV fault, and now off.
+ // Trace that odd behavior.
+ if (inputFault &&
+ !(statusWord & phosphor::pmbus::status_word::INPUT_FAULT_WARN))
+ {
+ log<level::INFO>(
+ fmt::format("INPUT fault cleared: STATUS_WORD = {:#04x}, "
+ "STATUS_MFR_SPECIFIC = {:#02x}, "
+ "STATUS_INPUT = {:#02x}",
+ statusWord, statusMFR, statusInput)
+ .c_str());
+ inputFault = false;
+ }
}
void PowerSupply::analyzeVoutOVFault()
@@ -390,6 +404,18 @@
vinUVFault = true;
}
+
+ if (vinUVFault &&
+ !(statusWord & phosphor::pmbus::status_word::VIN_UV_FAULT))
+ {
+ log<level::INFO>(
+ fmt::format("VIN_UV fault cleared: STATUS_WORD = {:#04x}, "
+ "STATUS_MFR_SPECIFIC = {:#02x}, "
+ "STATUS_INPUT = {:#02x}",
+ statusWord, statusMFR, statusInput)
+ .c_str());
+ vinUVFault = false;
+ }
}
void PowerSupply::analyze()
@@ -470,6 +496,24 @@
clearFaultFlags();
}
+
+ // Save off old inputVoltage value.
+ // Get latest inputVoltage.
+ // If voltage went from below minimum, and now is not, clear faults.
+ // Note: getInputVoltage() has its own try/catch.
+ int inputVoltageOld = inputVoltage;
+ double actualInputVoltage;
+ getInputVoltage(actualInputVoltage, inputVoltage);
+ if ((inputVoltageOld == in_input::VIN_VOLTAGE_0) &&
+ (inputVoltage != in_input::VIN_VOLTAGE_0))
+ {
+ log<level::INFO>(
+ fmt::format(
+ "READ_VIN back in range: inputVoltageOld = {} inputVoltage = {}",
+ inputVoltageOld, inputVoltage)
+ .c_str());
+ clearFaults();
+ }
}
catch (const ReadFailure& e)
{
@@ -505,6 +549,8 @@
void PowerSupply::clearFaults()
{
+ log<level::DEBUG>(
+ fmt::format("clearFaults() inventoryPath: {}", inventoryPath).c_str());
faultLogged = false;
// The PMBus device driver does not allow for writing CLEAR_FAULTS
// directly. However, the pmbus hwmon device driver code will send a