Add in detection of output overvoltage fault

If bit 5 of the lower byte to STATUS_WORD (STATUS_BYTE) is on when the
power is on, the power supply is indicating that it has detected an
output overvoltage fault condition. Log an error pointing to the power
supply that is indicating this overvoltage condition.

Change-Id: Ie369a30e6b82be805ae3aafd67812700ce2421f7
Signed-off-by: Brandon Wyman <bjwyman@gmail.com>
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index 90f33ae..b3d556c 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -108,6 +108,7 @@
             {
                 checkPGOrUnitOffFault(statusWord);
                 checkCurrentOutOverCurrentFault(statusWord);
+                checkOutputOvervoltageFault(statusWord);
             }
         }
     }
@@ -141,6 +142,7 @@
             vinUVFault = false;
             inputFault = false;
             outputOCFault = false;
+            outputOVFault = false;
         }
     }
 
@@ -191,6 +193,7 @@
             inputFault = false;
             powerOnFault = false;
             outputOCFault = false;
+            outputOVFault = false;
             powerOnTimer.start(powerOnInterval, Timer::TimerType::oneshot);
         }
         else
@@ -378,6 +381,43 @@
     }
 }
 
+void PowerSupply::checkOutputOvervoltageFault(const uint16_t statusWord)
+{
+    using namespace witherspoon::pmbus;
+
+    std::uint8_t  statusInput = 0;
+    std::uint8_t  statusVout = 0;
+    std::uint8_t  statusIout = 0;
+    std::uint8_t  statusMFR  = 0;
+
+    // Check for an output overvoltage fault.
+    if ((statusWord & status_word::VOUT_OV_FAULT) &&
+        !outputOVFault)
+    {
+        statusInput = pmbusIntf.read(STATUS_INPUT, Type::Debug);
+        statusVout = pmbusIntf.read(STATUS_VOUT, Type::Debug);
+        statusIout = pmbusIntf.read(STATUS_IOUT, Type::Debug);
+        statusMFR = pmbusIntf.read(STATUS_MFR, Type::Debug);
+
+        util::NamesValues nv;
+        nv.add("STATUS_WORD", statusWord);
+        nv.add("STATUS_INPUT", statusInput);
+        nv.add("STATUS_VOUT", statusVout);
+        nv.add("STATUS_IOUT", statusIout);
+        nv.add("MFR_SPECIFIC", statusMFR);
+
+        using metadata = xyz::openbmc_project::Power::Fault::
+                PowerSupplyOutputOvervoltage;
+
+        report<PowerSupplyOutputOvervoltage>(metadata::RAW_STATUS(
+                                                     nv.get().c_str()),
+                                             metadata::CALLOUT_INVENTORY_PATH(
+                                                     inventoryPath.c_str()));
+
+        outputOVFault = true;
+    }
+}
+
 void PowerSupply::clearFaults()
 {
     //TODO - Clear faults at pre-poweron. openbmc/openbmc#1736
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index ae03ee9..98c4c0b 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -150,6 +150,11 @@
         bool outputOCFault = false;
 
         /**
+         * @brief Set to true when the output overvoltage fault is detected
+         */
+        bool outputOVFault = false;
+
+        /**
          * @brief Callback for inventory property changes
          *
          * Process change of Present property for power supply.
@@ -211,6 +216,15 @@
          */
         void checkCurrentOutOverCurrentFault(const uint16_t statusWord);
 
+        /**
+         * @brief Checks for output overvoltage fault.
+         *
+         * VOUT_OV_FAULT is checked, if on, appropriate error is logged.
+         *
+         * @param[in] statusWord  - 2 byte STATUS_WORD value read from sysfs
+         */
+        void checkOutputOvervoltageFault(const uint16_t statusWord);
+
 };
 
 }