Switch to setting Device active

With the latest Linux driver, the hwmon device is always bound, so
instead use the occ_active attribute to tell the driver when the
OCC has gone active.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Change-Id: Ia89b517d90a1947f87bb5937bf0d4c1b50191201
diff --git a/occ_device.cpp b/occ_device.cpp
index 5cadf14..a660fa2 100644
--- a/occ_device.cpp
+++ b/occ_device.cpp
@@ -15,8 +15,21 @@
 
 using namespace phosphor::logging;
 
-fs::path Device::bindPath = fs::path(OCC_HWMON_PATH) / "bind";
-fs::path Device::unBindPath = fs::path(OCC_HWMON_PATH) / "unbind";
+void Device::setActive(bool active)
+{
+    std::string data = active ? "1" : "0";
+    auto activeFile = devPath / "occ_active";
+    try
+    {
+        write(activeFile, data);
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(fmt::format("Failed to set {} active: {}",
+                                    devPath.c_str(), e.what())
+                            .c_str());
+    }
+}
 
 std::string Device::getPathBack(const fs::path& path)
 {
@@ -38,20 +51,30 @@
     }
 }
 
+bool Device::active() const
+{
+    return readBinary("occ_active");
+}
+
 bool Device::master() const
 {
-    int master;
-    auto masterFile = devPath / "occ_master";
-    std::ifstream file(masterFile, std::ios::in);
+    return readBinary("occ_master");
+}
+
+bool Device::readBinary(const std::string& fileName) const
+{
+    int v;
+    auto filePath = devPath / fileName;
+    std::ifstream file(filePath, std::ios::in);
 
     if (!file)
     {
         return false;
     }
 
-    file >> master;
+    file >> v;
     file.close();
-    return (master != 0);
+    return v == 1;
 }
 
 void Device::errorCallback(bool error)
diff --git a/occ_device.hpp b/occ_device.hpp
index 5b66bf5..873ecfc 100644
--- a/occ_device.hpp
+++ b/occ_device.hpp
@@ -51,9 +51,8 @@
            std::unique_ptr<powermode::PowerMode>& powerModeRef,
 #endif
            unsigned int instance = 0) :
-        config(getPathBack(path)),
-        devPath(path), instance(instance), statusObject(status),
-        managerObject(manager),
+        devPath(path),
+        instance(instance), statusObject(status), managerObject(manager),
         error(event, path / "occ_error",
               std::bind(std::mem_fn(&Device::errorCallback), this,
                         std::placeholders::_1)),
@@ -91,32 +90,11 @@
         // Nothing to do here
     }
 
-    /** @brief Binds device to the OCC driver */
-    inline void bind()
-    {
-        // Bind the device
-        return write(bindPath, config);
-    }
-
-    /** @brief Un-binds device from the OCC driver */
-    inline void unBind()
-    {
-        // Unbind the device
-        return write(unBindPath, config);
-    }
-
-    /** @brief Returns if device is already bound.
+    /** @brief Sets the device active or inactive
      *
-     *  On device bind, a soft link by the name $config
-     *  gets created in OCC_HWMON_PATH and gets removed
-     *  on unbind
-     *
-     *  @return true if bound, else false
+     * @param[in] active - Indicates whether or not to set the device active
      */
-    inline bool bound() const
-    {
-        return fs::exists(OCC_HWMON_PATH + config);
-    }
+    void setActive(bool active);
 
     /** @brief Starts to monitor for errors
      *
@@ -204,30 +182,19 @@
      */
     static std::string getPathBack(const fs::path& path);
 
+    /** @brief Returns true if the device is active */
+    bool active() const;
+
     /** @brief Returns true if device represents the master OCC */
     bool master() const;
 
   private:
-    /** @brief Config value to be used to do bind and unbind */
-    const std::string config;
-
     /** @brief This directory contains the error files */
     const fs::path devPath;
 
     /** @brief OCC instance ID */
     const unsigned int instance;
 
-    /**  @brief To bind the device to the OCC driver, do:
-     *
-     *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
-     */
-    static fs::path bindPath;
-
-    /**  @brief To un-bind the device from the OCC driver, do:
-     *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
-     */
-    static fs::path unBindPath;
-
     /**  Store the associated Status instance */
     Status& statusObject;
 
@@ -256,6 +223,13 @@
     std::unique_ptr<powermode::PowerMode>& pmode;
 #endif
 
+    /** @brief file reader to read a binary string ("1" or "0")
+     *
+     * @param[in] fileName - Name of file to be read
+     * @return             - The value returned by reading the file
+     */
+    bool readBinary(const std::string& fileName) const;
+
     /** @brief file writer to achieve bind and unbind
      *
      *  @param[in] filename - Name of file to be written
diff --git a/occ_status.cpp b/occ_status.cpp
index 789afba..c883b69 100644
--- a/occ_status.cpp
+++ b/occ_status.cpp
@@ -31,8 +31,8 @@
                              .c_str());
         if (value)
         {
-            // Bind the device
-            device.bind();
+            // Set the device active
+            device.setActive(true);
 
             // Start watching for errors
             addErrorWatch();
@@ -78,11 +78,11 @@
             // Stop watching for errors
             removeErrorWatch();
 
-            // Do the unbind.
-            device.unBind();
+            // Set the device inactive
+            device.setActive(false);
         }
     }
-    else if (value && !device.bound())
+    else if (value && !device.active())
     {
         // Existing error watch is on a dead file descriptor.
         removeErrorWatch();
@@ -96,12 +96,12 @@
          * later do FSI rescan, we will end up with occActive = true and device
          * NOT bound. Lets correct that situation here.
          */
-        device.bind();
+        device.setActive(true);
 
         // Add error watch again
         addErrorWatch();
     }
-    else if (!value && device.bound())
+    else if (!value && device.active())
     {
         removeErrorWatch();
 
@@ -110,7 +110,7 @@
         // with the host on, since the initial OCC driver probe will discover
         // the OCCs), this application needs to be able to unbind the device
         // when we get the OCC inactive signal.
-        device.unBind();
+        device.setActive(false);
     }
     return Base::Status::occActive(value);
 }