Powercap: add p8 support
P8 uses i2c-occ and powercap is not created.
Add P8 support by creating powercap object with i2c device name.
Fixes openbmc/openbmc#2688
Change-Id: Ia63070d63f4392cc4b084ab628cdbdcf4206c883
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/i2c_occ.cpp b/i2c_occ.cpp
index c364967..00e4187 100644
--- a/i2c_occ.cpp
+++ b/i2c_occ.cpp
@@ -12,6 +12,8 @@
namespace fs = std::experimental::filesystem;
+// The occ_master sysfs file
+constexpr auto OCC_MASTER_FILE = "occ_master";
// The device name's length, e.g. "p8-occ-hwmon"
constexpr auto DEVICE_NAME_LENGTH = 12;
// The occ name's length, e.g. "occ"
@@ -21,6 +23,13 @@
static_assert(sizeof(I2C_OCC_DEVICE_NAME) -1 == DEVICE_NAME_LENGTH);
static_assert(sizeof(OCC_NAME) -1 == OCC_NAME_LENGTH);
+static bool isMasterOcc(const fs::directory_entry& p)
+{
+ auto f = p / OCC_MASTER_FILE;
+ auto str = getFileContent(f);
+ return (!str.empty()) && (str[0] == '1');
+}
+
std::string getFileContent(const fs::path& f)
{
std::string ret(DEVICE_NAME_LENGTH, 0);
@@ -46,10 +55,22 @@
auto str = getFileContent(f);
if (str == I2C_OCC_DEVICE_NAME)
{
- result.emplace_back(p.path().filename());
+ if (isMasterOcc(p))
+ {
+ // Insert master occ at the beginning
+ result.emplace(result.begin(), p.path().filename());
+ }
+ else
+ {
+ result.emplace_back(p.path().filename());
+ }
}
}
- std::sort(result.begin(), result.end());
+ }
+ if (!result.empty())
+ {
+ // Sort the occ devices except for master
+ std::sort(result.begin() + 1, result.end());
}
return result;
}
diff --git a/i2c_occ.hpp b/i2c_occ.hpp
index 31b6721..66dc12c 100644
--- a/i2c_occ.hpp
+++ b/i2c_occ.hpp
@@ -31,6 +31,7 @@
* @param[in] path - The path to search
*
* @return A vector of strings containing the occ hwmon device path
+ where the first device is master occ
*/
std::vector<std::string> getOccHwmonDevices(const char* path);
diff --git a/occ_manager.cpp b/occ_manager.cpp
index 42b6390..67e96a6 100644
--- a/occ_manager.cpp
+++ b/occ_manager.cpp
@@ -108,6 +108,7 @@
static_assert(sizeof(DEV_PATH) != 0);
auto deviceNames = i2c_occ::getOccHwmonDevices(DEV_PATH);
+ auto occMasterName = deviceNames.front();
for (auto& name : deviceNames)
{
i2c_occ::i2cToDbus(name);
@@ -120,6 +121,11 @@
path.c_str(),
*this));
}
+ // The first device is master occ
+ pcap = std::make_unique<open_power::occ::powercap::PowerCap>(
+ bus,
+ *statusObjects.front(),
+ occMasterName);
}
#endif
diff --git a/powercap.cpp b/powercap.cpp
index 0aca3e4..f2ae331 100644
--- a/powercap.cpp
+++ b/powercap.cpp
@@ -118,7 +118,7 @@
// Create path out to master occ hwmon entry
std::unique_ptr<fs::path> fileName =
std::make_unique<fs::path>(OCC_HWMON_PATH);
- *fileName /= OCC_MASTER_NAME;
+ *fileName /= occMasterName;
*fileName /= "/hwmon/";
// Need to get the hwmonXX directory name, there better only be 1 dir
diff --git a/powercap.hpp b/powercap.hpp
index ddf2a74..6a77c9d 100644
--- a/powercap.hpp
+++ b/powercap.hpp
@@ -35,8 +35,10 @@
* @param[in] occStatus - The occ status object
*/
PowerCap(sdbusplus::bus::bus &bus,
- Status &occStatus) :
+ Status &occStatus,
+ const std::string& occMasterName = OCC_MASTER_NAME) :
bus(bus),
+ occMasterName(occMasterName),
occStatus(occStatus),
pcapMatch(
bus,
@@ -100,6 +102,9 @@
/** @brief Reference to sdbus **/
sdbusplus::bus::bus& bus;
+ /** @brief The master occ name */
+ std::string occMasterName;
+
/* @brief OCC Status object */
Status &occStatus;
diff --git a/test/TestI2cOcc.cpp b/test/TestI2cOcc.cpp
index c92da5b..bf976d7 100644
--- a/test/TestI2cOcc.cpp
+++ b/test/TestI2cOcc.cpp
@@ -28,6 +28,7 @@
const auto I2C_6_0056 = BASE + STR_6_0056;
const auto I2C_7_0057 = BASE + STR_7_0057;
const auto NAME = "/name";
+const auto OCC_MASTER_NAME = "/occ_master";
const auto P8_OCC_HWMON = "p8-occ-hwmon";
const auto OTHER_STRING = "SomeOtherString123"s;
@@ -69,14 +70,26 @@
ofs << "p8-occ-hwmon\n"; // 4-0050/name is p8-occ-hwmon
ofs.close();
+ ofs.open(I2C_4_0050 + OCC_MASTER_NAME);
+ ofs << "0\n"; // Make 4-0050 the slave occ
+ ofs.close();
+
ofs.open(I2C_5_0051 + NAME);
ofs << "p8-occ-hwmon\n"; // 5-0051/name is p8-occ-hwmon
ofs.close();
+ ofs.open(I2C_5_0051 + OCC_MASTER_NAME);
+ ofs << "0\n"; // Make 5-0051 the slave occ
+ ofs.close();
+
ofs.open(I2C_6_0056 + NAME);
ofs << "p8-occ-hwmon\n"; // 6-0056/name is p8-occ-hwmon
ofs.close();
+ ofs.open(I2C_6_0056 + OCC_MASTER_NAME);
+ ofs << "1\n"; // Make 6-0056 the master occ
+ ofs.close();
+
ofs.open(I2C_7_0057 + NAME);
ofs << "p8-occ-hwmon\n"; // 7-0057/name is p8-occ-hwmon
ofs.close();
@@ -94,9 +107,11 @@
// With test env, it shall find all the 4 p8-occ-hwmon devices
auto ret = getOccHwmonDevices(BASE.c_str());
EXPECT_EQ(4u, ret.size());
- EXPECT_EQ(STR_4_0050, ret[0]);
- EXPECT_EQ(STR_5_0051, ret[1]);
- EXPECT_EQ(STR_6_0056, ret[2]);
+ // The first one shall be master occ
+ EXPECT_EQ(STR_6_0056, ret[0]);
+ // The left is sorted
+ EXPECT_EQ(STR_4_0050, ret[1]);
+ EXPECT_EQ(STR_5_0051, ret[2]);
EXPECT_EQ(STR_7_0057, ret[3]);
}