blob: a877c8cb2e75701d8b012be9210505d53ae6b664 [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
George Liub5ca1012021-09-10 12:53:11 +08009#include <org/open_power/OCC/Device/error.hpp>
10
George Liubcef3b42021-09-10 12:39:02 +080011#include <filesystem>
Gunnar Mills94df8c92018-09-14 14:50:03 -050012#include <fstream>
13
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053014namespace open_power
15{
16namespace occ
17{
18
Edward A. James636577f2017-10-06 10:53:55 -050019class Manager;
Eddie James482e31f2017-09-14 13:17:17 -050020class Status;
George Liubcef3b42021-09-10 12:39:02 +080021namespace fs = std::filesystem;
Eddie James774f9af2019-03-19 20:58:53 +000022using namespace sdbusplus::org::open_power::OCC::Device::Error;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053023
24/** @class Device
25 * @brief Binds and unbinds the OCC driver upon request
26 */
27class Device
28{
Gunnar Mills94df8c92018-09-14 14:50:03 -050029 public:
30 Device() = delete;
31 ~Device() = default;
32 Device(const Device&) = delete;
33 Device& operator=(const Device&) = delete;
34 Device(Device&&) = default;
35 Device& operator=(Device&&) = default;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +053036
Gunnar Mills94df8c92018-09-14 14:50:03 -050037 /** @brief Constructs the Device object
38 *
39 * @param[in] event - Unique ptr reference to sd_event
Eddie James774f9af2019-03-19 20:58:53 +000040 * @param[in] path - Path to the OCC instance
Gunnar Mills94df8c92018-09-14 14:50:03 -050041 * @param[in] manager - OCC manager instance
42 * @param[in] callback - Optional callback on errors
43 */
Eddie James774f9af2019-03-19 20:58:53 +000044 Device(EventPtr& event, const fs::path& path, const Manager& manager,
Gunnar Mills94df8c92018-09-14 14:50:03 -050045 Status& status, std::function<void(bool)> callBack = nullptr) :
Eddie James774f9af2019-03-19 20:58:53 +000046 config(getPathBack(path)),
47 devPath(path), statusObject(status),
48 error(event, path / "occ_error", callBack),
49 presence(event, path / "occs_present", manager, callBack),
Gunnar Mills94df8c92018-09-14 14:50:03 -050050 throttleProcTemp(
Eddie James774f9af2019-03-19 20:58:53 +000051 event, path / "occ_dvfs_overtemp",
Gunnar Mills94df8c92018-09-14 14:50:03 -050052 std::bind(std::mem_fn(&Device::throttleProcTempCallback), this,
53 std::placeholders::_1)),
54 throttleProcPower(
Eddie James774f9af2019-03-19 20:58:53 +000055 event, path / "occ_dvfs_power",
Gunnar Mills94df8c92018-09-14 14:50:03 -050056 std::bind(std::mem_fn(&Device::throttleProcPowerCallback), this,
57 std::placeholders::_1)),
Eddie James774f9af2019-03-19 20:58:53 +000058 throttleMemTemp(event, path / "occ_mem_throttle",
Gunnar Mills94df8c92018-09-14 14:50:03 -050059 std::bind(std::mem_fn(&Device::throttleMemTempCallback),
60 this, std::placeholders::_1))
61 {
62 // Nothing to do here
63 }
64
65 /** @brief Binds device to the OCC driver */
66 inline void bind()
67 {
68 // Bind the device
69 return write(bindPath, config);
70 }
71
72 /** @brief Un-binds device from the OCC driver */
73 inline void unBind()
74 {
75 // Unbind the device
76 return write(unBindPath, config);
77 }
78
79 /** @brief Returns if device is already bound.
80 *
81 * On device bind, a soft link by the name $config
82 * gets created in OCC_HWMON_PATH and gets removed
83 * on unbind
84 *
85 * @return true if bound, else false
86 */
87 inline bool bound() const
88 {
89 return fs::exists(OCC_HWMON_PATH + config);
90 }
91
Eddie James774f9af2019-03-19 20:58:53 +000092 /** @brief Starts to monitor for errors
93 *
94 * @param[in] poll - Indicates whether or not the error file should
95 * actually be polled for changes. Disabling polling is
96 * necessary for error files that don't support the poll
97 * file operation.
98 */
99 inline void addErrorWatch(bool poll = true)
Gunnar Mills94df8c92018-09-14 14:50:03 -0500100 {
Eddie James774f9af2019-03-19 20:58:53 +0000101 try
102 {
103 throttleProcTemp.addWatch(poll);
104 }
105 catch (const OpenFailure& e)
106 {
107 // try the old kernel version
108 throttleProcTemp.setFile(devPath / "occ_dvfs_ot");
109 throttleProcTemp.addWatch(poll);
110 }
111
112 throttleProcPower.addWatch(poll);
113 throttleMemTemp.addWatch(poll);
114 error.addWatch(poll);
Gunnar Mills94df8c92018-09-14 14:50:03 -0500115 }
116
117 /** @brief stops monitoring for errors */
118 inline void removeErrorWatch()
119 {
120 // we can always safely remove watch even if we don't add it
121 presence.removeWatch();
122 error.removeWatch();
Gunnar Mills94df8c92018-09-14 14:50:03 -0500123 throttleMemTemp.removeWatch();
124 throttleProcPower.removeWatch();
125 throttleProcTemp.removeWatch();
126 }
127
128 /** @brief Starts to watch how many OCCs are present on the master */
129 inline void addPresenceWatchMaster()
130 {
131 if (master())
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530132 {
Gunnar Mills94df8c92018-09-14 14:50:03 -0500133 presence.addWatch();
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530134 }
Gunnar Mills94df8c92018-09-14 14:50:03 -0500135 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530136
Eddie James774f9af2019-03-19 20:58:53 +0000137 /** @brief helper function to get the last part of the path
138 *
139 * @param[in] path - Path to parse
140 * @return - Last directory name in the path
141 */
142 static std::string getPathBack(const fs::path& path);
143
Chris Cain78e86012021-03-04 16:15:31 -0600144 /** @brief Returns true if device represents the master OCC */
145 bool master() const;
146
Gunnar Mills94df8c92018-09-14 14:50:03 -0500147 private:
148 /** @brief Config value to be used to do bind and unbind */
149 const std::string config;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530150
Eddie James774f9af2019-03-19 20:58:53 +0000151 /** @brief This directory contains the error files */
152 const fs::path devPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530153
Gunnar Mills94df8c92018-09-14 14:50:03 -0500154 /** @brief To bind the device to the OCC driver, do:
155 *
156 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
157 */
158 static fs::path bindPath;
Vishwanatha Subbannab57f1512017-09-04 15:06:20 +0530159
Gunnar Mills94df8c92018-09-14 14:50:03 -0500160 /** @brief To un-bind the device from the OCC driver, do:
161 * Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
162 */
163 static fs::path unBindPath;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530164
Gunnar Mills94df8c92018-09-14 14:50:03 -0500165 /** Store the associated Status instance */
166 Status& statusObject;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530167
Gunnar Mills94df8c92018-09-14 14:50:03 -0500168 /** Abstraction of error monitoring */
169 Error error;
Eddie Jamesdae2d942017-12-20 10:50:03 -0600170
Gunnar Mills94df8c92018-09-14 14:50:03 -0500171 /** Abstraction of OCC presence monitoring */
172 Presence presence;
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530173
Gunnar Mills94df8c92018-09-14 14:50:03 -0500174 /** Error instances for watching for throttling events */
175 Error throttleProcTemp;
176 Error throttleProcPower;
177 Error throttleMemTemp;
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530178
Gunnar Mills94df8c92018-09-14 14:50:03 -0500179 /** @brief file writer to achieve bind and unbind
180 *
181 * @param[in] filename - Name of file to be written
182 * @param[in] data - Data to be written to
183 * @return - None
184 */
185 void write(const fs::path& fileName, const std::string& data)
186 {
187 // If there is an error, move the exception all the way up
188 std::ofstream file(fileName, std::ios::out);
189 file << data;
190 file.close();
191 return;
192 }
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530193
Gunnar Mills94df8c92018-09-14 14:50:03 -0500194 /** @brief callback for the proc temp throttle event
195 *
196 * @param[in] error - True if an error is reported, false otherwise
197 */
198 void throttleProcTempCallback(bool error);
Eddie James482e31f2017-09-14 13:17:17 -0500199
Gunnar Mills94df8c92018-09-14 14:50:03 -0500200 /** @brief callback for the proc power throttle event
201 *
202 * @param[in] error - True if an error is reported, false otherwise
203 */
204 void throttleProcPowerCallback(bool error);
Vishwanatha Subbannaee4d83d2017-06-29 18:35:00 +0530205
Gunnar Mills94df8c92018-09-14 14:50:03 -0500206 /** @brief callback for the proc temp throttle event
207 *
208 * @param[in] error - True if an error is reported, false otherwise
209 */
210 void throttleMemTempCallback(bool error);
Vishwanatha Subbanna32e84e92017-06-28 19:17:28 +0530211};
212
213} // namespace occ
214} // namespace open_power