blob: 2ca94f51f84e6febb06d72f265f46a651a10508d [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;
Eddie James482e31f2017-09-14 13:17:17 -050016class Status;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053017namespace fs = std::experimental::filesystem;
18
19/** @class Device
20 * @brief Binds and unbinds the OCC driver upon request
21 */
22class Device
23{
24 public:
25 Device() = delete;
26 ~Device() = default;
27 Device(const Device&) = delete;
28 Device& operator=(const Device&) = delete;
29 Device(Device&&) = default;
30 Device& operator=(Device&&) = default;
31
32 /** @brief Constructs the Device object
33 *
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053034 * @param[in] event - Unique ptr reference to sd_event
35 * @param[in] name - OCC instance name
Edward A. James636577f2017-10-06 10:53:55 -050036 * @param[in] manager - OCC manager instance
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053037 * @param[in] callback - Optional callback on errors
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053038 */
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053039 Device(EventPtr& event,
40 const std::string& name,
Edward A. James636577f2017-10-06 10:53:55 -050041 const Manager& manager,
Eddie James482e31f2017-09-14 13:17:17 -050042 Status& status,
43 std::function<void(bool)> callBack = nullptr) :
Lei YU0ab90ca2017-07-13 17:02:23 +080044#ifdef I2C_OCC
45 config(name),
46#else
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053047 config(name + '-' + "dev0"),
Lei YU0ab90ca2017-07-13 17:02:23 +080048#endif
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053049 errorFile(fs::path(config) / "occ_error"),
Eddie James482e31f2017-09-14 13:17:17 -050050 statusObject(status),
Edward A. James636577f2017-10-06 10:53:55 -050051 error(event, errorFile, callBack),
52 presence(event,
53 fs::path(config) / "occs_present",
54 manager,
Eddie James482e31f2017-09-14 13:17:17 -050055 callBack),
56 throttleProcTemp(
57 event,
58 fs::path(config) / "occ_dvfs_ot",
59 std::bind(std::mem_fn(&Device::throttleProcTempCallback),
60 this,
61 std::placeholders::_1)),
62 throttleProcPower(
63 event,
64 fs::path(config) / "occ_dvfs_power",
65 std::bind(std::mem_fn(&Device::throttleProcPowerCallback),
66 this,
67 std::placeholders::_1)),
68 throttleMemTemp(
69 event,
70 fs::path(config) / "occ_mem_throttle",
71 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
72 this,
73 std::placeholders::_1))
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053074 {
75 // Nothing to do here
76 }
77
78 /** @brief Binds device to the OCC driver */
79 inline void bind()
80 {
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053081 // Bind the device
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053082 return write(bindPath, config);
83 }
84
85 /** @brief Un-binds device from the OCC driver */
86 inline void unBind()
87 {
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +053088 // Unbind the device
89 return write(unBindPath, config);
90 }
91
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +053092 /** @brief Returns if device is already bound.
93 *
94 * On device bind, a soft link by the name $config
95 * gets created in OCC_HWMON_PATH and gets removed
96 * on unbind
97 *
98 * @return true if bound, else false
99 */
100 inline bool bound() const
101 {
102 return fs::exists(OCC_HWMON_PATH + config);
103 }
104
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530105 /** @brief Starts to monitor for errors */
106 inline void addErrorWatch()
107 {
Eddie James482e31f2017-09-14 13:17:17 -0500108 throttleProcTemp.addWatch();
109 throttleProcPower.addWatch();
110 throttleMemTemp.addWatch();
Edward A. James636577f2017-10-06 10:53:55 -0500111 error.addWatch();
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530112 }
113
114 /** @brief stops monitoring for errors */
115 inline void removeErrorWatch()
116 {
Edward A. James636577f2017-10-06 10:53:55 -0500117 // we can always safely remove watch even if we don't add it
118 presence.removeWatch();
119 error.removeWatch();
Eddie James482e31f2017-09-14 13:17:17 -0500120 error.removeWatch();
121 throttleMemTemp.removeWatch();
122 throttleProcPower.removeWatch();
123 throttleProcTemp.removeWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530124 }
125
Eddie Jamesdae2d942017-12-20 10:50:03 -0600126 /** @brief Starts to watch how many OCCs are present on the master */
127 inline void addPresenceWatchMaster()
128 {
129 if (master())
130 {
131 presence.addWatch();
132 }
133 }
134
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530135 private:
136 /** @brief Config value to be used to do bind and unbind */
137 const std::string config;
138
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530139 /** @brief This file contains 0 for success, non-zero for errors */
140 const fs::path errorFile;
141
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530142 /** @brief To bind the device to the OCC driver, do:
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530143 *
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530144 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
145 */
146 static fs::path bindPath;
147
148 /** @brief To un-bind the device from the OCC driver, do:
149 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
150 */
151 static fs::path unBindPath;
152
Eddie James482e31f2017-09-14 13:17:17 -0500153 /** Store the associated Status instance */
154 Status& statusObject;
155
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530156 /** Abstraction of error monitoring */
157 Error error;
158
Edward A. James636577f2017-10-06 10:53:55 -0500159 /** Abstraction of OCC presence monitoring */
160 Presence presence;
161
Eddie James482e31f2017-09-14 13:17:17 -0500162 /** Error instances for watching for throttling events */
163 Error throttleProcTemp;
164 Error throttleProcPower;
165 Error throttleMemTemp;
166
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530167 /** @brief file writer to achieve bind and unbind
168 *
169 * @param[in] filename - Name of file to be written
170 * @param[in] data - Data to be written to
171 * @return - None
172 */
173 void write(const fs::path& fileName, const std::string& data)
174 {
175 // If there is an error, move the exception all the way up
176 std::ofstream file(fileName, std::ios::out);
177 file << data;
178 file.close();
179 return;
180 }
Edward A. James636577f2017-10-06 10:53:55 -0500181
182 /** @brief Returns if device represents the master OCC */
183 bool master() const;
Eddie James482e31f2017-09-14 13:17:17 -0500184
185 /** @brief callback for the proc temp throttle event
186 *
187 * @param[in] error - True if an error is reported, false otherwise
188 */
189 void throttleProcTempCallback(bool error);
190
191 /** @brief callback for the proc power throttle event
192 *
193 * @param[in] error - True if an error is reported, false otherwise
194 */
195 void throttleProcPowerCallback(bool error);
196
197 /** @brief callback for the proc temp throttle event
198 *
199 * @param[in] error - True if an error is reported, false otherwise
200 */
201 void throttleMemTempCallback(bool error);
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530202};
203
204} // namespace occ
205} // namespace open_power