blob: 7ffb0efa5a46fae56436172fe861289f8b48d7d1 [file] [log] [blame]
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05301#pragma once
2
3#include <fstream>
4#include <experimental/filesystem>
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +05305#include "occ_events.hpp"
6#include "occ_errors.hpp"
Edward A. James636577f2017-10-06 10:53:55 -05007#include "occ_presence.hpp"
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05308#include "config.h"
Lei YU0ab90ca2017-07-13 17:02:23 +08009
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053010namespace open_power
11{
12namespace occ
13{
14
Edward A. James636577f2017-10-06 10:53:55 -050015class Manager;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053016namespace fs = std::experimental::filesystem;
17
18/** @class Device
19 * @brief Binds and unbinds the OCC driver upon request
20 */
21class Device
22{
23 public:
24 Device() = delete;
25 ~Device() = default;
26 Device(const Device&) = delete;
27 Device& operator=(const Device&) = delete;
28 Device(Device&&) = default;
29 Device& operator=(Device&&) = default;
30
31 /** @brief Constructs the Device object
32 *
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053033 * @param[in] event - Unique ptr reference to sd_event
34 * @param[in] name - OCC instance name
Edward A. James636577f2017-10-06 10:53:55 -050035 * @param[in] manager - OCC manager instance
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053036 * @param[in] callback - Optional callback on errors
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053037 */
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053038 Device(EventPtr& event,
39 const std::string& name,
Edward A. James636577f2017-10-06 10:53:55 -050040 const Manager& manager,
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053041 std::function<void()> callBack = nullptr) :
Lei YU0ab90ca2017-07-13 17:02:23 +080042#ifdef I2C_OCC
43 config(name),
44#else
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053045 config(name + '-' + "dev0"),
Lei YU0ab90ca2017-07-13 17:02:23 +080046#endif
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053047 errorFile(fs::path(config) / "occ_error"),
Edward A. James636577f2017-10-06 10:53:55 -050048 error(event, errorFile, callBack),
49 presence(event,
50 fs::path(config) / "occs_present",
51 manager,
52 callBack)
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053053 {
54 // Nothing to do here
55 }
56
57 /** @brief Binds device to the OCC driver */
58 inline void bind()
59 {
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053060 // Bind the device
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053061 return write(bindPath, config);
62 }
63
64 /** @brief Un-binds device from the OCC driver */
65 inline void unBind()
66 {
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053067 // Unbind the device
68 return write(unBindPath, config);
69 }
70
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +053071 /** @brief Returns if device is already bound.
72 *
73 * On device bind, a soft link by the name $config
74 * gets created in OCC_HWMON_PATH and gets removed
75 * on unbind
76 *
77 * @return true if bound, else false
78 */
79 inline bool bound() const
80 {
81 return fs::exists(OCC_HWMON_PATH + config);
82 }
83
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053084 /** @brief Starts to monitor for errors */
85 inline void addErrorWatch()
86 {
Edward A. James636577f2017-10-06 10:53:55 -050087 if (master())
88 {
89 presence.addWatch();
90 }
91
92 error.addWatch();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053093 }
94
95 /** @brief stops monitoring for errors */
96 inline void removeErrorWatch()
97 {
Edward A. James636577f2017-10-06 10:53:55 -050098 // we can always safely remove watch even if we don't add it
99 presence.removeWatch();
100 error.removeWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530101 }
102
103 private:
104 /** @brief Config value to be used to do bind and unbind */
105 const std::string config;
106
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530107 /** @brief This file contains 0 for success, non-zero for errors */
108 const fs::path errorFile;
109
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530110 /** @brief To bind the device to the OCC driver, do:
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530111 *
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530112 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
113 */
114 static fs::path bindPath;
115
116 /** @brief To un-bind the device from the OCC driver, do:
117 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
118 */
119 static fs::path unBindPath;
120
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530121 /** Abstraction of error monitoring */
122 Error error;
123
Edward A. James636577f2017-10-06 10:53:55 -0500124 /** Abstraction of OCC presence monitoring */
125 Presence presence;
126
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530127 /** @brief file writer to achieve bind and unbind
128 *
129 * @param[in] filename - Name of file to be written
130 * @param[in] data - Data to be written to
131 * @return - None
132 */
133 void write(const fs::path& fileName, const std::string& data)
134 {
135 // If there is an error, move the exception all the way up
136 std::ofstream file(fileName, std::ios::out);
137 file << data;
138 file.close();
139 return;
140 }
Edward A. James636577f2017-10-06 10:53:55 -0500141
142 /** @brief Returns if device represents the master OCC */
143 bool master() const;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530144};
145
146} // namespace occ
147} // namespace open_power