psu-ng: Add a clearVinUVFault function

Create a clearVinUVFault() function specifically for clearing the VIN_UV
and unit is off fault bits.

Use this function when see a vinUVFault with good voltage read back from
READ_VIN. This should clear the latched fault if the fault is no longer
active. If the fault is still active, the next read will show the fault
again.

Also call clearVinUVFault() from the clearFaults() function.

Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
Change-Id: Ic26029fe64e3cd3e232c615b223cafb774bf77f9
diff --git a/phosphor-power-supply/power_supply.cpp b/phosphor-power-supply/power_supply.cpp
index 7c8c646..4b43cb2 100644
--- a/phosphor-power-supply/power_supply.cpp
+++ b/phosphor-power-supply/power_supply.cpp
@@ -607,7 +607,7 @@
                         "actualInputVoltage = {}",
                         shortName, actualInputVoltageOld, actualInputVoltage)
                         .c_str());
-                clearFaults();
+                clearVinUVFault();
             }
             else if (vinUVFault && (inputVoltage != in_input::VIN_VOLTAGE_0))
             {
@@ -617,9 +617,9 @@
                         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();
+                // due to voltage back in range? Attempt to clear the fault(s),
+                // re-check faults on next call.
+                clearVinUVFault();
             }
             else if (std::abs(actualInputVoltageOld - actualInputVoltage) > 1.0)
             {
@@ -670,6 +670,19 @@
     }
 }
 
+void PowerSupply::clearVinUVFault()
+{
+    // Read in1_lcrit_alarm to clear bits 3 and 4 of STATUS_INPUT.
+    // The fault bits in STAUTS_INPUT roll-up to STATUS_WORD. Clearing those
+    // bits in STATUS_INPUT should result in the corresponding STATUS_WORD bits
+    // also clearing.
+    //
+    // Do not care about return value. Should be 1 if active, 0 if not.
+    static_cast<void>(
+        pmbusIntf->read("in1_lcrit_alarm", phosphor::pmbus::Type::Hwmon));
+    vinUVFault = 0;
+}
+
 void PowerSupply::clearFaults()
 {
     log<level::DEBUG>(
@@ -689,6 +702,7 @@
 
         try
         {
+            clearVinUVFault();
             static_cast<void>(
                 pmbusIntf->read("in1_input", phosphor::pmbus::Type::Hwmon));
         }