blob: 50dd11de958056b47e35022e2f67212bef604f58 [file] [log] [blame]
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05301#pragma once
2
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +05303#include "config.h"
Lei YU0ab90ca2017-07-13 17:02:23 +08004
Gunnar Mills94df8c92018-09-14 14:50:03 -05005#include "occ_errors.hpp"
6#include "occ_events.hpp"
7#include "occ_presence.hpp"
8
9#include <experimental/filesystem>
10#include <fstream>
Eddie James774f9af2019-03-19 20:58:53 +000011#include <org/open_power/OCC/Device/error.hpp>
Gunnar Mills94df8c92018-09-14 14:50:03 -050012
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053013namespace open_power
14{
15namespace occ
16{
17
Edward A. James636577f2017-10-06 10:53:55 -050018class Manager;
Eddie James482e31f2017-09-14 13:17:17 -050019class Status;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053020namespace fs = std::experimental::filesystem;
Eddie James774f9af2019-03-19 20:58:53 +000021using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053022
23/** @class Device
24 * @brief Binds and unbinds the OCC driver upon request
25 */
26class Device
27{
Gunnar Mills94df8c92018-09-14 14:50:03 -050028 public:
29 Device() = delete;
30 ~Device() = default;
31 Device(const Device&) = delete;
32 Device& operator=(const Device&) = delete;
33 Device(Device&&) = default;
34 Device& operator=(Device&&) = default;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053035
Gunnar Mills94df8c92018-09-14 14:50:03 -050036 /** @brief Constructs the Device object
37 *
38 * @param[in] event - Unique ptr reference to sd_event
Eddie James774f9af2019-03-19 20:58:53 +000039 * @param[in] path - Path to the OCC instance
Gunnar Mills94df8c92018-09-14 14:50:03 -050040 * @param[in] manager - OCC manager instance
41 * @param[in] callback - Optional callback on errors
42 */
Eddie James774f9af2019-03-19 20:58:53 +000043 Device(EventPtr& event, const fs::path& path, const Manager& manager,
Gunnar Mills94df8c92018-09-14 14:50:03 -050044 Status& status, std::function<void(bool)> callBack = nullptr) :
Eddie James774f9af2019-03-19 20:58:53 +000045 config(getPathBack(path)),
46 devPath(path), statusObject(status),
47 error(event, path / "occ_error", callBack),
48 presence(event, path / "occs_present", manager, callBack),
Gunnar Mills94df8c92018-09-14 14:50:03 -050049 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000050 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050051 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
52 std::placeholders::_1)),
53 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000054 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050055 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
56 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000057 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050058 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
59 this, std::placeholders::_1))
60 {
61 // Nothing to do here
62 }
63
64 /** @brief Binds device to the OCC driver */
65 inline void bind()
66 {
67 // Bind the device
68 return write(bindPath, config);
69 }
70
71 /** @brief Un-binds device from the OCC driver */
72 inline void unBind()
73 {
74 // Unbind the device
75 return write(unBindPath, config);
76 }
77
78 /** @brief Returns if device is already bound.
79 *
80 * On device bind, a soft link by the name $config
81 * gets created in OCC_HWMON_PATH and gets removed
82 * on unbind
83 *
84 * @return true if bound, else false
85 */
86 inline bool bound() const
87 {
88 return fs::exists(OCC_HWMON_PATH + config);
89 }
90
Eddie James774f9af2019-03-19 20:58:53 +000091 /** @brief Starts to monitor for errors
92 *
93 * @param[in] poll - Indicates whether or not the error file should
94 * actually be polled for changes. Disabling polling is
95 * necessary for error files that don't support the poll
96 * file operation.
97 */
98 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -050099 {
Eddie James774f9af2019-03-19 20:58:53 +0000100 try
101 {
102 throttleProcTemp.addWatch(poll);
103 }
104 catch (const OpenFailure& e)
105 {
106 // try the old kernel version
107 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
108 throttleProcTemp.addWatch(poll);
109 }
110
111 throttleProcPower.addWatch(poll);
112 throttleMemTemp.addWatch(poll);
113 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500114 }
115
116 /** @brief stops monitoring for errors */
117 inline void removeErrorWatch()
118 {
119 // we can always safely remove watch even if we don't add it
120 presence.removeWatch();
121 error.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500122 throttleMemTemp.removeWatch();
123 throttleProcPower.removeWatch();
124 throttleProcTemp.removeWatch();
125 }
126
127 /** @brief Starts to watch how many OCCs are present on the master */
128 inline void addPresenceWatchMaster()
129 {
130 if (master())
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530131 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500132 presence.addWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530133 }
Gunnar Mills94df8c92018-09-14 14:50:03 -0500134 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530135
Eddie James774f9af2019-03-19 20:58:53 +0000136 /** @brief helper function to get the last part of the path
137 *
138 * @param[in] path - Path to parse
139 * @return - Last directory name in the path
140 */
141 static std::string getPathBack(const fs::path& path);
142
Chris Cain78e86012021-03-04 16:15:31 -0600143 /** @brief Returns true if device represents the master OCC */
144 bool master() const;
145
Gunnar Mills94df8c92018-09-14 14:50:03 -0500146 private:
147 /** @brief Config value to be used to do bind and unbind */
148 const std::string config;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530149
Eddie James774f9af2019-03-19 20:58:53 +0000150 /** @brief This directory contains the error files */
151 const fs::path devPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530152
Gunnar Mills94df8c92018-09-14 14:50:03 -0500153 /** @brief To bind the device to the OCC driver, do:
154 *
155 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
156 */
157 static fs::path bindPath;
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +0530158
Gunnar Mills94df8c92018-09-14 14:50:03 -0500159 /** @brief To un-bind the device from the OCC driver, do:
160 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
161 */
162 static fs::path unBindPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530163
Gunnar Mills94df8c92018-09-14 14:50:03 -0500164 /** Store the associated Status instance */
165 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530166
Gunnar Mills94df8c92018-09-14 14:50:03 -0500167 /** Abstraction of error monitoring */
168 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600169
Gunnar Mills94df8c92018-09-14 14:50:03 -0500170 /** Abstraction of OCC presence monitoring */
171 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530172
Gunnar Mills94df8c92018-09-14 14:50:03 -0500173 /** Error instances for watching for throttling events */
174 Error throttleProcTemp;
175 Error throttleProcPower;
176 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530177
Gunnar Mills94df8c92018-09-14 14:50:03 -0500178 /** @brief file writer to achieve bind and unbind
179 *
180 * @param[in] filename - Name of file to be written
181 * @param[in] data - Data to be written to
182 * @return - None
183 */
184 void write(const fs::path& fileName, const std::string& data)
185 {
186 // If there is an error, move the exception all the way up
187 std::ofstream file(fileName, std::ios::out);
188 file << data;
189 file.close();
190 return;
191 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530192
Gunnar Mills94df8c92018-09-14 14:50:03 -0500193 /** @brief callback for the proc temp throttle event
194 *
195 * @param[in] error - True if an error is reported, false otherwise
196 */
197 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500198
Gunnar Mills94df8c92018-09-14 14:50:03 -0500199 /** @brief callback for the proc power throttle event
200 *
201 * @param[in] error - True if an error is reported, false otherwise
202 */
203 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530204
Gunnar Mills94df8c92018-09-14 14:50:03 -0500205 /** @brief callback for the proc temp throttle event
206 *
207 * @param[in] error - True if an error is reported, false otherwise
208 */
209 void throttleMemTempCallback(bool error);
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530210};
211
212} // namespace occ
213} // namespace open_power