From 41470e56e5dce5d9d138fd2a136f0010571bc613 Mon Sep 17 00:00:00 2001 From: Lei YU Date: Thu, 30 Nov 2017 16:03:50 +0800 Subject: 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 --- i2c_occ.cpp | 25 +++++++++++++++++++++++-- i2c_occ.hpp | 1 + occ_manager.cpp | 6 ++++++ powercap.cpp | 2 +- powercap.hpp | 7 ++++++- test/TestI2cOcc.cpp | 21 ++++++++++++++++++--- 6 files changed, 55 insertions(+), 7 deletions(-) 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 i2c_occ 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 @@ constexpr auto OCC_NAME_LENGTH = 3; 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 @@ std::vector getOccHwmonDevices(const char* path) 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 @@ std::string getFileContent(const fs::path& f); * @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 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 @@ void Manager::initStatusObjects() 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 @@ void Manager::initStatusObjects() path.c_str(), *this)); } + // The first device is master occ + pcap = std::make_unique( + 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 @@ void PowerCap::writeOcc(uint32_t pcapValue) // Create path out to master occ hwmon entry std::unique_ptr fileName = std::make_unique(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 @@ public: * @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 @@ private: /** @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_5_0051 = BASE + STR_5_0051; 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 @@ public: 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 @@ TEST_F(TestUtilGetOccHwmonDevices, getDevicesOK) // 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]); } -- cgit v1.2.1