1dfc7ec73SVishwanatha Subbanna #include <experimental/filesystem> 2dfc7ec73SVishwanatha Subbanna #include <phosphor-logging/log.hpp> 3dfc7ec73SVishwanatha Subbanna #include <phosphor-logging/elog-errors.hpp> 4dfc7ec73SVishwanatha Subbanna #include <xyz/openbmc_project/Common/error.hpp> 5dfc7ec73SVishwanatha Subbanna #include "occ_finder.hpp" 6dfc7ec73SVishwanatha Subbanna #include "occ_manager.hpp" 7dfc7ec73SVishwanatha Subbanna #include "i2c_occ.hpp" 8dfc7ec73SVishwanatha Subbanna #include "utils.hpp" 9dfc7ec73SVishwanatha Subbanna #include "config.h" 10dfc7ec73SVishwanatha Subbanna 11dfc7ec73SVishwanatha Subbanna namespace open_power 12dfc7ec73SVishwanatha Subbanna { 13dfc7ec73SVishwanatha Subbanna namespace occ 14dfc7ec73SVishwanatha Subbanna { 15dfc7ec73SVishwanatha Subbanna 16dfc7ec73SVishwanatha Subbanna void Manager::findAndCreateObjects() 17dfc7ec73SVishwanatha Subbanna { 18dfc7ec73SVishwanatha Subbanna for (auto id = 0; id < MAX_CPUS; ++id) 19dfc7ec73SVishwanatha Subbanna { 2030417a15SDeepak Kodihalli // Create one occ per cpu 2130417a15SDeepak Kodihalli auto occ = std::string(OCC_NAME) + std::to_string(id); 22dfc7ec73SVishwanatha Subbanna createObjects(occ); 23dfc7ec73SVishwanatha Subbanna } 24dfc7ec73SVishwanatha Subbanna } 25dfc7ec73SVishwanatha Subbanna 26dfc7ec73SVishwanatha Subbanna int Manager::cpuCreated(sdbusplus::message::message& msg) 27dfc7ec73SVishwanatha Subbanna { 28dfc7ec73SVishwanatha Subbanna namespace fs = std::experimental::filesystem; 29dfc7ec73SVishwanatha Subbanna 30dfc7ec73SVishwanatha Subbanna sdbusplus::message::object_path o; 31dfc7ec73SVishwanatha Subbanna msg.read(o); 32dfc7ec73SVishwanatha Subbanna fs::path cpuPath(std::string(std::move(o))); 33dfc7ec73SVishwanatha Subbanna 34dfc7ec73SVishwanatha Subbanna auto name = cpuPath.filename().string(); 35dfc7ec73SVishwanatha Subbanna auto index = name.find(CPU_NAME); 36dfc7ec73SVishwanatha Subbanna name.replace(index, std::strlen(CPU_NAME), OCC_NAME); 37dfc7ec73SVishwanatha Subbanna 38dfc7ec73SVishwanatha Subbanna createObjects(name); 39dfc7ec73SVishwanatha Subbanna 40dfc7ec73SVishwanatha Subbanna return 0; 41dfc7ec73SVishwanatha Subbanna } 42dfc7ec73SVishwanatha Subbanna 43dfc7ec73SVishwanatha Subbanna void Manager::createObjects(const std::string& occ) 44dfc7ec73SVishwanatha Subbanna { 45dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / occ; 46dfc7ec73SVishwanatha Subbanna 47dfc7ec73SVishwanatha Subbanna passThroughObjects.emplace_back( 48dfc7ec73SVishwanatha Subbanna std::make_unique<PassThrough>( 49dfc7ec73SVishwanatha Subbanna bus, 50dfc7ec73SVishwanatha Subbanna path.c_str())); 51dfc7ec73SVishwanatha Subbanna 52dfc7ec73SVishwanatha Subbanna statusObjects.emplace_back( 53dfc7ec73SVishwanatha Subbanna std::make_unique<Status>( 54dfc7ec73SVishwanatha Subbanna bus, 55dfc7ec73SVishwanatha Subbanna event, 56dfc7ec73SVishwanatha Subbanna path.c_str(), 57636577f4SEdward A. James *this, 58dfc7ec73SVishwanatha Subbanna std::bind(std::mem_fn(&Manager::statusCallBack), 59dfc7ec73SVishwanatha Subbanna this, std::placeholders::_1))); 60dfc7ec73SVishwanatha Subbanna 61dfc7ec73SVishwanatha Subbanna // Create the power cap monitor object for master occ (0) 62dfc7ec73SVishwanatha Subbanna if (!pcap) 63dfc7ec73SVishwanatha Subbanna { 64dfc7ec73SVishwanatha Subbanna pcap = std::make_unique<open_power::occ::powercap::PowerCap>( 65dfc7ec73SVishwanatha Subbanna bus, 66dfc7ec73SVishwanatha Subbanna *statusObjects.front()); 67dfc7ec73SVishwanatha Subbanna } 68dfc7ec73SVishwanatha Subbanna } 69dfc7ec73SVishwanatha Subbanna 70dfc7ec73SVishwanatha Subbanna void Manager::statusCallBack(bool status) 71dfc7ec73SVishwanatha Subbanna { 72dfc7ec73SVishwanatha Subbanna using namespace phosphor::logging; 73dfc7ec73SVishwanatha Subbanna using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 74dfc7ec73SVishwanatha Subbanna Error::InternalFailure; 75dfc7ec73SVishwanatha Subbanna 76dfc7ec73SVishwanatha Subbanna // At this time, it won't happen but keeping it 77dfc7ec73SVishwanatha Subbanna // here just in case something changes in the future 78dfc7ec73SVishwanatha Subbanna if ((activeCount == 0) && (!status)) 79dfc7ec73SVishwanatha Subbanna { 80dfc7ec73SVishwanatha Subbanna log<level::ERR>("Invalid update on OCCActive"); 81dfc7ec73SVishwanatha Subbanna elog<InternalFailure>(); 82dfc7ec73SVishwanatha Subbanna } 83dfc7ec73SVishwanatha Subbanna 84dfc7ec73SVishwanatha Subbanna activeCount += status ? 1 : -1; 85dfc7ec73SVishwanatha Subbanna 86dfc7ec73SVishwanatha Subbanna // If all the OCCs are bound, then start error detection 87dfc7ec73SVishwanatha Subbanna if (activeCount == statusObjects.size()) 88dfc7ec73SVishwanatha Subbanna { 89dfc7ec73SVishwanatha Subbanna for (const auto& occ: statusObjects) 90dfc7ec73SVishwanatha Subbanna { 91dfc7ec73SVishwanatha Subbanna occ->addErrorWatch(); 92dfc7ec73SVishwanatha Subbanna } 93dfc7ec73SVishwanatha Subbanna } 94dfc7ec73SVishwanatha Subbanna else if (!status) 95dfc7ec73SVishwanatha Subbanna { 96dfc7ec73SVishwanatha Subbanna // If some OCCs are not bound yet, those will be a NO-OP 97dfc7ec73SVishwanatha Subbanna for (const auto& occ: statusObjects) 98dfc7ec73SVishwanatha Subbanna { 99dfc7ec73SVishwanatha Subbanna occ->removeErrorWatch(); 100dfc7ec73SVishwanatha Subbanna } 101dfc7ec73SVishwanatha Subbanna } 102dfc7ec73SVishwanatha Subbanna } 103dfc7ec73SVishwanatha Subbanna 104dfc7ec73SVishwanatha Subbanna #ifdef I2C_OCC 105dfc7ec73SVishwanatha Subbanna void Manager::initStatusObjects() 106dfc7ec73SVishwanatha Subbanna { 107dfc7ec73SVishwanatha Subbanna // Make sure we have a valid path string 108dfc7ec73SVishwanatha Subbanna static_assert(sizeof(DEV_PATH) != 0); 109dfc7ec73SVishwanatha Subbanna 110dfc7ec73SVishwanatha Subbanna auto deviceNames = i2c_occ::getOccHwmonDevices(DEV_PATH); 111*41470e56SLei YU auto occMasterName = deviceNames.front(); 112dfc7ec73SVishwanatha Subbanna for (auto& name : deviceNames) 113dfc7ec73SVishwanatha Subbanna { 114dfc7ec73SVishwanatha Subbanna i2c_occ::i2cToDbus(name); 115b5259a1eSLei YU name = std::string(OCC_NAME) + '_' + name; 116dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / name; 117dfc7ec73SVishwanatha Subbanna statusObjects.emplace_back( 118dfc7ec73SVishwanatha Subbanna std::make_unique<Status>( 119dfc7ec73SVishwanatha Subbanna bus, 120dfc7ec73SVishwanatha Subbanna event, 121636577f4SEdward A. James path.c_str(), 122636577f4SEdward A. James *this)); 123dfc7ec73SVishwanatha Subbanna } 124*41470e56SLei YU // The first device is master occ 125*41470e56SLei YU pcap = std::make_unique<open_power::occ::powercap::PowerCap>( 126*41470e56SLei YU bus, 127*41470e56SLei YU *statusObjects.front(), 128*41470e56SLei YU occMasterName); 129dfc7ec73SVishwanatha Subbanna } 130dfc7ec73SVishwanatha Subbanna #endif 131dfc7ec73SVishwanatha Subbanna 132dfc7ec73SVishwanatha Subbanna } // namespace occ 133dfc7ec73SVishwanatha Subbanna } // namespace open_power 134