Shutdown system on GPU over-temps

Resolves openbmc/openbmc#1726

Change-Id: If3263678bc03df7714f31aa097f38ee6c09389f4
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/power-sequencer/main.cpp b/power-sequencer/main.cpp
index f324d3e..923b5dc 100644
--- a/power-sequencer/main.cpp
+++ b/power-sequencer/main.cpp
@@ -58,7 +58,7 @@
     auto bus = sdbusplus::bus::new_default();
     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
 
-    auto device = std::make_unique<UCD90160>(0);
+    auto device = std::make_unique<UCD90160>(0, bus);
 
     std::unique_ptr<DeviceMonitor> monitor;
 
diff --git a/power-sequencer/ucd90160.cpp b/power-sequencer/ucd90160.cpp
index 715dcd1..2e2578f 100644
--- a/power-sequencer/ucd90160.cpp
+++ b/power-sequencer/ucd90160.cpp
@@ -23,6 +23,7 @@
 #include <xyz/openbmc_project/Power/Fault/error.hpp>
 #include "names_values.hpp"
 #include "ucd90160.hpp"
+#include "utility.hpp"
 
 namespace witherspoon
 {
@@ -45,13 +46,14 @@
 using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
 using namespace sdbusplus::xyz::openbmc_project::Power::Fault::Error;
 
-UCD90160::UCD90160(size_t instance) :
+UCD90160::UCD90160(size_t instance, sdbusplus::bus::bus& bus) :
         Device(DEVICE_NAME, instance),
         interface(std::get<ucd90160::pathField>(
                           deviceMap.find(instance)->second),
                   DRIVER_NAME,
                   instance),
-        gpioDevice(findGPIODevice(interface.path()))
+        gpioDevice(findGPIODevice(interface.path())),
+        bus(bus)
 {
 }
 
@@ -309,6 +311,7 @@
 bool UCD90160::doGPIOAnalysis(ucd90160::extraAnalysisType type)
 {
     bool errorFound = false;
+    bool shutdown = false;
 
     const auto& analysisConfig = std::get<ucd90160::gpioAnalysisField>(
             deviceMap.find(getInstance())->second);
@@ -379,9 +382,24 @@
 
             //Save the part callout so we don't call it out again
             setPartCallout(callout);
+
+            //Some errors (like overtemps) require a shutdown
+            auto actions = static_cast<uint32_t>(
+                    std::get<ucd90160::optionFlagsField>(gpioConfig->second));
+
+            if (actions & static_cast<decltype(actions)>(
+                        ucd90160::optionFlags::shutdownOnFault))
+            {
+                shutdown = true;
+            }
         }
     }
 
+    if (shutdown)
+    {
+        util::powerOff(bus);
+    }
+
     return errorFound;
 }
 
diff --git a/power-sequencer/ucd90160.hpp b/power-sequencer/ucd90160.hpp
index b82711d..f14a99e 100644
--- a/power-sequencer/ucd90160.hpp
+++ b/power-sequencer/ucd90160.hpp
@@ -3,6 +3,7 @@
 #include <algorithm>
 #include <experimental/filesystem>
 #include <map>
+#include <sdbusplus/bus.hpp>
 #include <vector>
 #include "device.hpp"
 #include "gpio.hpp"
@@ -40,8 +41,9 @@
          * Constructor
          *
          * @param[in] instance - the device instance number
+         * @param[in] bus - D-Bus bus object
          */
-        UCD90160(size_t instance);
+        UCD90160(size_t instance, sdbusplus::bus::bus& bus);
 
         /**
          * Analyzes the device for errors when the device is
@@ -295,6 +297,11 @@
         std::experimental::filesystem::path gpioDevice;
 
         /**
+         * The D-Bus bus object
+         */
+        sdbusplus::bus::bus& bus;
+
+        /**
          * Map of device instance to the instance specific data
          */
         static const ucd90160::DeviceMap deviceMap;