psu-ng: Clear faults if VIN_UV and READ_VIN good

If we see that we have set the VIN_UV fault indicator, but the READ_VIN
value is returning a non-zero voltage for input, attempt to clear the
faults. This could be a latched input voltage under-voltage condition
that has now cleared.

Save off actualVoltage in PowerSupply member variable. This allows for
comparing the previous actual voltage with the new reading, to trace out
the actual voltage instead of the calculated 0/110/220 voltage.

Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: Ibf1642a081ccf4d4a9c4202ce2536799806af017
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
index 1648bd3..7c8c646 100644
--- a/phosphor-power-supply/power_supply.cpp
+++ b/phosphor-power-supply/power_supply.cpp
@@ -9,7 +9,8 @@
 
 #include <xyz/openbmc_project/Common/Device/error.hpp>
 
-#include <chrono>  // sleep_for()
+#include <chrono> // sleep_for()
+#include <cmath>
 #include <cstdint> // uint8_t...
 #include <fstream>
 #include <thread> // sleep_for()
@@ -595,18 +596,39 @@
             // If voltage went from below minimum, and now is not, clear faults.
             // Note: getInputVoltage() has its own try/catch.
             int inputVoltageOld = inputVoltage;
-            double actualInputVoltage;
+            double actualInputVoltageOld = 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 = {}",
-                        shortName, inputVoltageOld, inputVoltage)
+                        "{} READ_VIN back in range: actualInputVoltageOld = {} "
+                        "actualInputVoltage = {}",
+                        shortName, actualInputVoltageOld, actualInputVoltage)
                         .c_str());
                 clearFaults();
             }
+            else if (vinUVFault && (inputVoltage != in_input::VIN_VOLTAGE_0))
+            {
+                log<level::INFO>(
+                    fmt::format(
+                        "{} CLEAR_FAULTS: vinUVFault {} actualInputVoltage {}",
+                        shortName, vinUVFault, actualInputVoltage)
+                        .c_str());
+                // Do we have a VIN_UV fault latched that can now be cleared
+                // due to voltage back in range? Attempt to clear all
+                // faults, re-check faults on next call.
+                clearFaults();
+            }
+            else if (std::abs(actualInputVoltageOld - actualInputVoltage) > 1.0)
+            {
+                log<level::INFO>(
+                    fmt::format(
+                        "{} actualInputVoltageOld = {} actualInputVoltage = {}",
+                        shortName, actualInputVoltageOld, actualInputVoltage)
+                        .c_str());
+            }
 
             checkAvailability();
         }