1 #pragma once 2 3 #include <fstream> 4 #include <experimental/filesystem> 5 #include "occ_events.hpp" 6 #include "occ_errors.hpp" 7 #include "config.h" 8 9 namespace open_power 10 { 11 namespace occ 12 { 13 14 namespace fs = std::experimental::filesystem; 15 16 /** @class Device 17 * @brief Binds and unbinds the OCC driver upon request 18 */ 19 class Device 20 { 21 public: 22 Device() = delete; 23 ~Device() = default; 24 Device(const Device&) = delete; 25 Device& operator=(const Device&) = delete; 26 Device(Device&&) = default; 27 Device& operator=(Device&&) = default; 28 29 /** @brief Constructs the Device object 30 * 31 * @param[in] event - Unique ptr reference to sd_event 32 * @param[in] name - OCC instance name 33 * @param[in] callback - Optional callback on errors 34 */ 35 Device(EventPtr& event, 36 const std::string& name, 37 std::function<void()> callBack = nullptr) : 38 #ifdef I2C_OCC 39 config(name), 40 #else 41 config(name + '-' + "dev0"), 42 #endif 43 errorFile(fs::path(config) / "occ_error"), 44 error(event, errorFile, callBack) 45 { 46 // Nothing to do here 47 } 48 49 /** @brief Binds device to the OCC driver */ 50 inline void bind() 51 { 52 // Bind the device 53 return write(bindPath, config); 54 } 55 56 /** @brief Un-binds device from the OCC driver */ 57 inline void unBind() 58 { 59 // Unbind the device 60 return write(unBindPath, config); 61 } 62 63 /** @brief Returns if device is already bound. 64 * 65 * On device bind, a soft link by the name $config 66 * gets created in OCC_HWMON_PATH and gets removed 67 * on unbind 68 * 69 * @return true if bound, else false 70 */ 71 inline bool bound() const 72 { 73 return fs::exists(OCC_HWMON_PATH + config); 74 } 75 76 /** @brief Starts to monitor for errors */ 77 inline void addErrorWatch() 78 { 79 return error.addWatch(); 80 } 81 82 /** @brief stops monitoring for errors */ 83 inline void removeErrorWatch() 84 { 85 return error.removeWatch(); 86 } 87 88 private: 89 /** @brief Config value to be used to do bind and unbind */ 90 const std::string config; 91 92 /** @brief This file contains 0 for success, non-zero for errors */ 93 const fs::path errorFile; 94 95 /** @brief To bind the device to the OCC driver, do: 96 * 97 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind 98 */ 99 static fs::path bindPath; 100 101 /** @brief To un-bind the device from the OCC driver, do: 102 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind 103 */ 104 static fs::path unBindPath; 105 106 /** Abstraction of error monitoring */ 107 Error error; 108 109 /** @brief file writer to achieve bind and unbind 110 * 111 * @param[in] filename - Name of file to be written 112 * @param[in] data - Data to be written to 113 * @return - None 114 */ 115 void write(const fs::path& fileName, const std::string& data) 116 { 117 // If there is an error, move the exception all the way up 118 std::ofstream file(fileName, std::ios::out); 119 file << data; 120 file.close(); 121 return; 122 } 123 }; 124 125 } // namespace occ 126 } // namespace open_power 127