Support for syncing power supply input history

When a power supply is hotplugged the code will toggle
a GPIO to cause the power supplies to sync their
input history collection.  This clears out old values
and restarts measurement at the same time zero.

An external service handles this during a power on.

It doesn't need to be done when the application first
starts because it will either be with power off with
uninteresting power values, and a sync will occur on a
power on anyway, or it was a reboot at runtime where
the power supplies are still synced up anyway.

Change-Id: Ic8787c05e163e48ed775ea075f241ffd8d65585e
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/power-supply/power_supply.cpp b/power-supply/power_supply.cpp
index 50d647a..3d7673c 100644
--- a/power-supply/power_supply.cpp
+++ b/power-supply/power_supply.cpp
@@ -19,6 +19,7 @@
 #include <xyz/openbmc_project/Common/Device/error.hpp>
 #include <xyz/openbmc_project/Software/Version/server.hpp>
 #include "elog-errors.hpp"
+#include "gpio.hpp"
 #include "names_values.hpp"
 #include "power_supply.hpp"
 #include "pmbus.hpp"
@@ -79,6 +80,9 @@
                        pmbusIntf.findHwmonDir();
                        this->present = true;
 
+                       // Sync the INPUT_HISTORY data for all PSs
+                       syncHistory();
+
                        // Update the inventory for the new device
                        updateInventory();
                    }),
@@ -752,6 +756,36 @@
     }
 }
 
+void PowerSupply::syncHistory()
+{
+    using namespace witherspoon::gpio;
+
+    if (syncGPIODevPath.empty())
+    {
+        //Sync not implemented
+        return;
+    }
+
+    GPIO gpio{syncGPIODevPath,
+              static_cast<gpioNum_t>(syncGPIONumber),
+              Direction::output};
+
+    try
+    {
+        gpio.set(Value::low);
+
+        std::this_thread::sleep_for(std::chrono::milliseconds{5});
+
+        gpio.set(Value::high);
+
+        recordManager->clear();
+    }
+    catch (std::exception& e)
+    {
+        //Do nothing.  There would already be a journal entry.
+    }
+}
+
 void PowerSupply::enableHistory(const std::string& objectPath,
                                 size_t numRecords,
                                 const std::string& syncGPIOPath,
diff --git a/power-supply/power_supply.hpp b/power-supply/power_supply.hpp
index 5eb96a9..e88e257 100644
--- a/power-supply/power_supply.hpp
+++ b/power-supply/power_supply.hpp
@@ -389,6 +389,20 @@
         void updateInventory();
 
         /**
+         * @brief Toggles the GPIO to sync power supply input history readings
+         *
+         * This GPIO is connected to all supplies.  This will clear the
+         * previous readings out of the supplies and restart them both at the
+         * same time zero and at record ID 0.  The supplies will return 0
+         * bytes of data for the input history command right after this until
+         * a new entry shows up.
+         *
+         * This will cause the code to delete all previous history data and
+         * start fresh.
+         */
+        void syncHistory();
+
+        /**
          * @brief Reads the most recent input history record from the power
          *        supply and updates the average and maximum properties in
          *        D-Bus if there is a new reading available.