meta-quanta: gbs: add hwmon sensors

Define the configuration files of the related sensors
and test pass

0001-lev-add-poweron-monitor-feature.patch
In-Review: https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-hwmon/+/28181

0002-lev-add-sensors-slow-readings.patch
In-Review: https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-hwmon/+/24337

Signed-off-by: George Hung <george.hung@quantatw.com>
Change-Id: I3ad7551faed454ddc74ec6fe328897a11c51d73e
diff --git a/meta-gbs/recipes-phosphor/sensors/phosphor-hwmon/0001-lev-add-poweron-monitor-feature.patch b/meta-gbs/recipes-phosphor/sensors/phosphor-hwmon/0001-lev-add-poweron-monitor-feature.patch
new file mode 100644
index 0000000..dfe82ef
--- /dev/null
+++ b/meta-gbs/recipes-phosphor/sensors/phosphor-hwmon/0001-lev-add-poweron-monitor-feature.patch
@@ -0,0 +1,256 @@
+From 58eec8f1f80e274ff669bd19c00b8f1ea8ceae0f Mon Sep 17 00:00:00 2001
+From: Duke Du <Duke.Du@quantatw.com>
+Date: Mon, 18 May 2020 19:45:27 +0800
+Subject: [PATCH] lev-add-poweron-monitor-feature
+
+---
+ Makefile.am    |   2 ++
+ mainloop.cpp   | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ sensor.cpp     |  11 ++++++-
+ sensor.hpp     |  13 ++++++++
+ thresholds.hpp |   2 --
+ 5 files changed, 126 insertions(+), 3 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 378c565..5fa230a 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -46,6 +46,7 @@ libhwmon_la_LIBADD = \
+ 	$(SDEVENTPLUS_LIBS) \
+ 	$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
+ 	$(PHOSPHOR_LOGGING_LIBS) \
++	$(PTHREAD_LIBS) \
+ 	$(GPIOPLUS_LIBS) \
+ 	$(STDPLUS_LIBS) \
+ 	$(CODE_COVERAGE_LIBS)
+@@ -54,6 +55,7 @@ libhwmon_la_CXXFLAGS = \
+ 	$(SDEVENTPLUS_CFLAGS) \
+ 	$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
+ 	$(PHOSPHOR_LOGGING_CFLAGS) \
++	$(PTHREAD_CFLAGS) \
+ 	$(STDPLUS_CFLAGS) \
+ 	$(CODE_COVERAGE_CXXFLAGS)
+ 
+diff --git a/mainloop.cpp b/mainloop.cpp
+index bd334a0..1769e94 100644
+--- a/mainloop.cpp
++++ b/mainloop.cpp
+@@ -39,6 +39,12 @@
+ #include <string>
+ #include <unordered_set>
+ #include <xyz/openbmc_project/Sensor/Device/error.hpp>
++#include <boost/container/flat_map.hpp>
++#include <boost/algorithm/string/predicate.hpp>
++#include <sdbusplus/asio/connection.hpp>
++#include <sdbusplus/asio/object_server.hpp>
++#include <sdbusplus/message/types.hpp>
++#include <sdbusplus/timer.hpp>
+ 
+ using namespace phosphor::logging;
+ 
+@@ -74,6 +80,12 @@ decltype(
+     Thresholds<CriticalObject>::alarmHi) Thresholds<CriticalObject>::alarmHi =
+     &CriticalObject::criticalAlarmHigh;
+ 
++static std::unique_ptr<phosphor::Timer> cacheTimer = nullptr;
++static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
++static bool powerStatusOn = false;
++static boost::asio::io_service io; 
++static auto conn = std::make_shared<sdbusplus::asio::connection>(io);
++
+ void updateSensorInterfaces(InterfaceMap& ifaces, int64_t value)
+ {
+     for (auto& iface : ifaces)
+@@ -101,6 +113,83 @@ void updateSensorInterfaces(InterfaceMap& ifaces, int64_t value)
+     }
+ }
+ 
++void powerStatusSet()
++{
++    powerStatusOn = true;
++    return;
++}
++
++void createTimer()
++{
++    if (cacheTimer == nullptr)
++    {
++        cacheTimer = std::make_unique<phosphor::Timer>(powerStatusSet);
++    }
++}
++
++bool isPowerOn(void)
++{
++    if (!powerMatch)
++    {
++        throw std::runtime_error("Power Match Not Created");
++    }
++    return powerStatusOn;
++}
++
++void setupPowerMatch(sdbusplus::bus::bus& bus)
++{
++    if (powerMatch)
++    {
++        return;
++    }
++
++    powerMatch = std::make_unique<sdbusplus::bus::match::match>(
++        bus,
++        "type='signal',interface='org.freedesktop.DBus.Properties',path='/xyz/"
++        "openbmc_project/state/"
++        "host0',arg0='xyz.openbmc_project.State.Host'",
++       [](sdbusplus::message::message& message) {
++            std::string objectName;
++            boost::container::flat_map<std::string, std::variant<std::string>>
++                values;
++	    message.read(objectName, values);
++	    auto findState = values.find("CurrentHostState");
++	    if (findState != values.end())
++	    {
++	        bool on = boost::ends_with(
++                    std::get<std::string>(findState->second), "Running");
++		if (!on)
++                {
++		    cacheTimer->stop();
++                    powerStatusOn = false;
++                    return;
++                }
++		cacheTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
++                    std::chrono::seconds(10)));
++	    }
++	    else {
++		powerStatusOn = false;
++            }
++       });
++
++    conn->async_method_call(
++        [](boost::system::error_code ec,
++           const std::variant<std::string>& state) {
++            if (ec)
++            {
++                return;
++            }
++            powerStatusOn =
++                boost::ends_with(std::get<std::string>(state), "Running");
++        },
++        "xyz.openbmc_project.State.Host", 
++	"/xyz/openbmc_project/state/host0", 
++	"org.freedesktop.DBus.Properties", "Get",
++        "xyz.openbmc_project.State.Host", "CurrentHostState");
++
++    createTimer();
++}
++
+ std::string MainLoop::getID(SensorSet::container_t::const_reference sensor)
+ {
+     std::string id;
+@@ -385,6 +474,7 @@ void MainLoop::init()
+             _interval = std::strtoull(interval.c_str(), NULL, 10);
+         }
+     }
++    setupPowerMatch(_bus);
+ }
+ 
+ void MainLoop::read()
+@@ -429,6 +519,12 @@ void MainLoop::read()
+ 
+         try
+         {
++            if(sensor->pwrOnMonitor() && !isPowerOn())
++            {
++                statusIface->functional(false);
++                continue;
++            }
++
+             if (sensor->hasFaultFile())
+             {
+                 auto fault = _ioAccess->read(sensorSysfsType, sensorSysfsNum,
+@@ -491,6 +587,11 @@ void MainLoop::read()
+                 }
+             }
+ 
++            if(sensor->pwrOnMonitor() && !isPowerOn())
++            {
++		statusIface->functional(false);
++	        continue;    
++            }
+             updateSensorInterfaces(obj, value);
+         }
+         catch (const std::system_error& e)
+diff --git a/sensor.cpp b/sensor.cpp
+index 145ba6c..93bbb03 100644
+--- a/sensor.cpp
++++ b/sensor.cpp
+@@ -41,7 +41,7 @@ Sensor::Sensor(const SensorSet::key_type& sensor,
+                const hwmonio::HwmonIOInterface* ioAccess,
+                const std::string& devPath) :
+     _sensor(sensor),
+-    _ioAccess(ioAccess), _devPath(devPath), _scale(0), _hasFaultFile(false)
++    _ioAccess(ioAccess), _devPath(devPath), _scale(0), _hasFaultFile(false), _pwrOnMonitor(false)
+ {
+     auto chip = env::getEnv("GPIOCHIP", sensor);
+     auto access = env::getEnv("GPIO", sensor);
+@@ -70,6 +70,15 @@ Sensor::Sensor(const SensorSet::key_type& sensor,
+     auto senRmRCs = env::getEnv("REMOVERCS", sensor);
+     // Add sensor removal return codes defined per sensor
+     addRemoveRCs(senRmRCs);
++
++    auto pwrOnMon = env::getEnv("PWRONMON", sensor);
++    if (!pwrOnMon.empty())
++    {
++        if (pwrOnMon == "ON")
++        {
++            _pwrOnMonitor = true;
++        }
++    }
+ }
+ 
+ void Sensor::addRemoveRCs(const std::string& rcList)
+diff --git a/sensor.hpp b/sensor.hpp
+index 4b2d281..369a252 100644
+--- a/sensor.hpp
++++ b/sensor.hpp
+@@ -135,6 +135,16 @@ class Sensor
+         return _hasFaultFile;
+     }
+ 
++    /**
++     * @brief Get whether the sensor only need to be monitored in power on state or not.
++     *
++     * @return - Boolean on whether the sensor only need to be monitored in power on state
++     */
++    inline bool pwrOnMonitor(void) const
++    {
++        return _pwrOnMonitor;
++    }
++
+   private:
+     /** @brief Sensor object's identifiers */
+     SensorSet::key_type _sensor;
+@@ -156,6 +166,9 @@ class Sensor
+ 
+     /** @brief Tracks whether the sensor has a fault file or not. */
+     bool _hasFaultFile;
++
++    /** @brief Whether the sensor only need to be monitored in power on state or not. */
++    bool _pwrOnMonitor;
+ };
+ 
+ /**
+diff --git a/thresholds.hpp b/thresholds.hpp
+index 4d2fcff..972a469 100644
+--- a/thresholds.hpp
++++ b/thresholds.hpp
+@@ -101,8 +101,6 @@ auto addThreshold(const std::string& sensorType, const std::string& sensorID,
+         auto hi = stod(tHi) * std::pow(10, scale);
+         (*iface.*Thresholds<T>::setLo)(lo);
+         (*iface.*Thresholds<T>::setHi)(hi);
+-        (*iface.*Thresholds<T>::alarmLo)(value <= lo);
+-        (*iface.*Thresholds<T>::alarmHi)(value >= hi);
+         auto type = Thresholds<T>::type;
+         obj[type] = iface;
+     }
+-- 
+2.7.4
+