Monitor UCD90160 for faults at runtime

Add the RuntimeMonitor class that will monitor the
UCD90160 faults in 2 ways:

1) Watch for the PowerLost signal, meaning system
   PGOOD was lost.  When it occurs, analyze the
   chip for errors and then issue a proper shutdown
   so a faulted device doesn't keep getting power.

2) Poll on an interval for nonfatal errors that need
   to be logged but don't cause a PGOOD loss.

The main executable can now launch either the PGOODMonitor
or the RuntimeMonitor based on commandline arguments.

Change-Id: If2856f173d5d6288d8333538334b4b4cb4a60097
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/power-sequencer/runtime_monitor.hpp b/power-sequencer/runtime_monitor.hpp
new file mode 100644
index 0000000..aae17ed
--- /dev/null
+++ b/power-sequencer/runtime_monitor.hpp
@@ -0,0 +1,114 @@
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server.hpp>
+#include "device.hpp"
+#include "event.hpp"
+#include "device_monitor.hpp"
+#include "timer.hpp"
+
+namespace witherspoon
+{
+namespace power
+{
+
+/**
+ * @class RuntimeMonitor
+ *
+ * Monitors the power sequencer for faults at runtime
+ *
+ * Triggers the power sequencer fault check 2 different ways:
+ *
+ * 1) Listens for the PowerLost signal that indicates master
+ *    PGOOD was dropped due to a fatal fault.  After the analysis,
+ *    a power off will be issued so the sequencer will stop
+ *    driving power to a faulted component.
+ *
+ * 2) Polls for faults, as some won't always drop PGOOD.
+ *
+ * The application this runs in will only run while PGOOD is
+ * expected to be asserted, so any loss of PGOOD is considered
+ * an error.
+ */
+class RuntimeMonitor : public DeviceMonitor
+{
+    public:
+
+        RuntimeMonitor() = delete;
+        ~RuntimeMonitor() = default;
+        RuntimeMonitor(const RuntimeMonitor&) = delete;
+        RuntimeMonitor& operator=(const RuntimeMonitor&) = delete;
+        RuntimeMonitor(RuntimeMonitor&&) = delete;
+        RuntimeMonitor& operator=(RuntimeMonitor&&) = delete;
+
+        /**
+         * Constructor
+         *
+         * @param[in] d - the device to monitor
+         * @param[in] b - D-Bus bus object
+         * @param[in] e - event object
+         * @param[in] i - poll interval
+         */
+        RuntimeMonitor(std::unique_ptr<witherspoon::power::Device>&& d,
+                sdbusplus::bus::bus& b,
+                witherspoon::power::event::Event& e,
+                std::chrono::seconds& i) :
+            DeviceMonitor(std::move(d), e, i),
+            bus(b),
+            match(bus,
+                  getMatchString(),
+                  std::bind(std::mem_fn(&RuntimeMonitor::onPowerLost),
+                            this, std::placeholders::_1))
+        {
+        }
+
+        /**
+         * Clears faults and then runs DeviceMonitor::run to
+         * call Device::analyze() on an ongoing interval.
+         *
+         * @return the return value from sd_event_loop()
+         */
+        int run() override;
+
+    private:
+
+        /**
+         * The PowerLost signal handler.
+         *
+         * After doing an analysis, will issue a power off
+         * as some device has a power fault and needs to be
+         * properly shut down.
+         *
+         * @param[in] msg - D-Bus message for callback
+         */
+        void onPowerLost(sdbusplus::message::message& msg);
+
+        /**
+         * Returns the match string for the PowerLost signal
+         */
+        std::string getMatchString()
+        {
+            using namespace sdbusplus::bus::match::rules;
+
+            std::string s =
+                type::signal() +
+                path("/org/openbmc/control/power0") +
+                interface("org.openbmc.control.Power") +
+                member("PowerLost");
+
+            return s;
+        }
+
+        /**
+         * The D-Bus object
+         */
+        sdbusplus::bus::bus& bus;
+
+        /**
+         * Match object for PowerLost signals
+         */
+        sdbusplus::bus::match_t match;
+};
+
+}
+}