12bac8609SBrandon Wyman #pragma once 22bac8609SBrandon Wyman 3a0f33ce3SBrandon Wyman #include "power_supply.hpp" 4a0f33ce3SBrandon Wyman #include "types.hpp" 5a0f33ce3SBrandon Wyman #include "utility.hpp" 6a0f33ce3SBrandon Wyman 7a0f33ce3SBrandon Wyman #include <phosphor-logging/log.hpp> 82bac8609SBrandon Wyman #include <sdbusplus/bus/match.hpp> 92bac8609SBrandon Wyman #include <sdeventplus/event.hpp> 102bac8609SBrandon Wyman #include <sdeventplus/utility/timer.hpp> 112bac8609SBrandon Wyman 12aed1f75dSBrandon Wyman struct sys_properties 13aed1f75dSBrandon Wyman { 14aed1f75dSBrandon Wyman int minPowerSupplies; 15aed1f75dSBrandon Wyman int maxPowerSupplies; 16aed1f75dSBrandon Wyman }; 17aed1f75dSBrandon Wyman 18a0f33ce3SBrandon Wyman using namespace phosphor::power::psu; 19a0f33ce3SBrandon Wyman using namespace phosphor::logging; 20a0f33ce3SBrandon Wyman 21*63ea78b9SBrandon Wyman namespace phosphor::power::manager 222bac8609SBrandon Wyman { 232bac8609SBrandon Wyman 242bac8609SBrandon Wyman /** 252bac8609SBrandon Wyman * @class PSUManager 262bac8609SBrandon Wyman * 272bac8609SBrandon Wyman * This class will create an object used to manage and monitor a list of power 282bac8609SBrandon Wyman * supply devices. 292bac8609SBrandon Wyman */ 302bac8609SBrandon Wyman class PSUManager 312bac8609SBrandon Wyman { 322bac8609SBrandon Wyman public: 332bac8609SBrandon Wyman PSUManager() = delete; 342bac8609SBrandon Wyman ~PSUManager() = default; 352bac8609SBrandon Wyman PSUManager(const PSUManager&) = delete; 362bac8609SBrandon Wyman PSUManager& operator=(const PSUManager&) = delete; 372bac8609SBrandon Wyman PSUManager(PSUManager&&) = delete; 382bac8609SBrandon Wyman PSUManager& operator=(PSUManager&&) = delete; 392bac8609SBrandon Wyman 402bac8609SBrandon Wyman /** 412bac8609SBrandon Wyman * Constructor 422bac8609SBrandon Wyman * 432bac8609SBrandon Wyman * @param[in] bus - D-Bus bus object 442bac8609SBrandon Wyman * @param[in] e - event object 452fe5186eSBrandon Wyman * @param[in] configfile - string path to the configuration file 462bac8609SBrandon Wyman */ 472bac8609SBrandon Wyman PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e, 48aed1f75dSBrandon Wyman const std::string& configfile); 492fe5186eSBrandon Wyman 50aed1f75dSBrandon Wyman void getJSONProperties(const std::string& path, sdbusplus::bus::bus& bus, 51aed1f75dSBrandon Wyman sys_properties& p, 52aed1f75dSBrandon Wyman std::vector<std::unique_ptr<PowerSupply>>& psus); 532fe5186eSBrandon Wyman 542bac8609SBrandon Wyman /** 552bac8609SBrandon Wyman * Initializes the manager. 562bac8609SBrandon Wyman * 572bac8609SBrandon Wyman * Get current BMC state, ... 582bac8609SBrandon Wyman */ 592bac8609SBrandon Wyman void initialize() 602bac8609SBrandon Wyman { 61a0f33ce3SBrandon Wyman // When state = 1, system is powered on 62a0f33ce3SBrandon Wyman int32_t state = 0; 63a0f33ce3SBrandon Wyman 64a0f33ce3SBrandon Wyman try 65a0f33ce3SBrandon Wyman { 66a0f33ce3SBrandon Wyman // Use getProperty utility function to get power state. 67a0f33ce3SBrandon Wyman util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH, 68a0f33ce3SBrandon Wyman powerService, bus, state); 69a0f33ce3SBrandon Wyman 70a0f33ce3SBrandon Wyman if (state) 71a0f33ce3SBrandon Wyman { 72a0f33ce3SBrandon Wyman powerOn = true; 73a0f33ce3SBrandon Wyman } 74a0f33ce3SBrandon Wyman else 75a0f33ce3SBrandon Wyman { 76a0f33ce3SBrandon Wyman powerOn = false; 77a0f33ce3SBrandon Wyman } 78a0f33ce3SBrandon Wyman } 79a0f33ce3SBrandon Wyman catch (std::exception& e) 80a0f33ce3SBrandon Wyman { 81a0f33ce3SBrandon Wyman log<level::INFO>("Failed to get power state. Assuming it is off."); 82a0f33ce3SBrandon Wyman powerOn = false; 83a0f33ce3SBrandon Wyman } 84a0f33ce3SBrandon Wyman 8559a35793SBrandon Wyman onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY); 86a0f33ce3SBrandon Wyman clearFaults(); 87a0f33ce3SBrandon Wyman updateInventory(); 882bac8609SBrandon Wyman } 892bac8609SBrandon Wyman 902bac8609SBrandon Wyman /** 912bac8609SBrandon Wyman * Starts the timer to start monitoring the list of devices. 922bac8609SBrandon Wyman */ 932bac8609SBrandon Wyman int run() 942bac8609SBrandon Wyman { 952fe5186eSBrandon Wyman return timer->get_event().loop(); 962bac8609SBrandon Wyman } 972bac8609SBrandon Wyman 982bac8609SBrandon Wyman /** 9959a35793SBrandon Wyman * Write PMBus ON_OFF_CONFIG 10059a35793SBrandon Wyman * 10159a35793SBrandon Wyman * This function will be called to cause the PMBus device driver to send the 10259a35793SBrandon Wyman * ON_OFF_CONFIG command. Takes one byte of data. 10359a35793SBrandon Wyman */ 10459a35793SBrandon Wyman void onOffConfig(const uint8_t data) 10559a35793SBrandon Wyman { 10659a35793SBrandon Wyman for (auto& psu : psus) 10759a35793SBrandon Wyman { 10859a35793SBrandon Wyman psu->onOffConfig(data); 10959a35793SBrandon Wyman } 11059a35793SBrandon Wyman } 11159a35793SBrandon Wyman 11259a35793SBrandon Wyman /** 1132bac8609SBrandon Wyman * This function will be called in various situations in order to clear 1142bac8609SBrandon Wyman * any fault status bits that may have been set, in order to start over 1152bac8609SBrandon Wyman * with a clean state. Presence changes and power state changes will want 1162bac8609SBrandon Wyman * to clear any faults logged. 1172bac8609SBrandon Wyman */ 1182bac8609SBrandon Wyman void clearFaults() 1192bac8609SBrandon Wyman { 120a0f33ce3SBrandon Wyman for (auto& psu : psus) 121a0f33ce3SBrandon Wyman { 122aed1f75dSBrandon Wyman psu->clearFaults(); 123a0f33ce3SBrandon Wyman } 1243f1242f3SBrandon Wyman 1253f1242f3SBrandon Wyman faultLogged = false; 1262bac8609SBrandon Wyman } 1272bac8609SBrandon Wyman 1282bac8609SBrandon Wyman private: 1292bac8609SBrandon Wyman /** 1302bac8609SBrandon Wyman * The D-Bus object 1312bac8609SBrandon Wyman */ 1322bac8609SBrandon Wyman sdbusplus::bus::bus& bus; 1332bac8609SBrandon Wyman 1342bac8609SBrandon Wyman /** 1352bac8609SBrandon Wyman * The timer that runs to periodically check the power supplies. 1362bac8609SBrandon Wyman */ 1372fe5186eSBrandon Wyman std::unique_ptr< 1382fe5186eSBrandon Wyman sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 1392fe5186eSBrandon Wyman timer; 1402bac8609SBrandon Wyman 1412bac8609SBrandon Wyman /** 1422bac8609SBrandon Wyman * Analyze the status of each of the power supplies. 1432bac8609SBrandon Wyman */ 144*63ea78b9SBrandon Wyman void analyze(); 1452bac8609SBrandon Wyman 1462bac8609SBrandon Wyman /** @brief True if the power is on. */ 1472bac8609SBrandon Wyman bool powerOn = false; 1482bac8609SBrandon Wyman 1493f1242f3SBrandon Wyman /** @brief True if fault logged. Clear in clearFaults(). */ 1503f1242f3SBrandon Wyman bool faultLogged = false; 1513f1242f3SBrandon Wyman 152a0f33ce3SBrandon Wyman /** @brief Used as part of subscribing to power on state changes*/ 153a0f33ce3SBrandon Wyman std::string powerService; 154a0f33ce3SBrandon Wyman 1552bac8609SBrandon Wyman /** @brief Used to subscribe to D-Bus power on state changes */ 1562bac8609SBrandon Wyman std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 1572bac8609SBrandon Wyman 1582bac8609SBrandon Wyman /** 1592bac8609SBrandon Wyman * @brief Callback for power state property changes 1602bac8609SBrandon Wyman * 1612bac8609SBrandon Wyman * Process changes to the powered on state property for the system. 1622bac8609SBrandon Wyman * 1632bac8609SBrandon Wyman * @param[in] msg - Data associated with the power state signal 1642bac8609SBrandon Wyman */ 1652bac8609SBrandon Wyman void powerStateChanged(sdbusplus::message::message& msg); 1662bac8609SBrandon Wyman 1672bac8609SBrandon Wyman /** 1682bac8609SBrandon Wyman * @brief Adds properties to the inventory. 1692bac8609SBrandon Wyman * 1702bac8609SBrandon Wyman * Reads the values from the devices and writes them to the associated 1712bac8609SBrandon Wyman * power supply D-Bus inventory objects. 1722bac8609SBrandon Wyman * 1732bac8609SBrandon Wyman * This needs to be done on startup, and each time the presence state 1742bac8609SBrandon Wyman * changes. 1752bac8609SBrandon Wyman */ 176a0f33ce3SBrandon Wyman void updateInventory() 177a0f33ce3SBrandon Wyman { 178a0f33ce3SBrandon Wyman for (auto& psu : psus) 179a0f33ce3SBrandon Wyman { 180aed1f75dSBrandon Wyman psu->updateInventory(); 181a0f33ce3SBrandon Wyman } 182a0f33ce3SBrandon Wyman } 183a0f33ce3SBrandon Wyman 184a0f33ce3SBrandon Wyman /** 185aed1f75dSBrandon Wyman * @brief Minimum number of power supplies to operate. 186aed1f75dSBrandon Wyman */ 187aed1f75dSBrandon Wyman int minPSUs = 1; 188aed1f75dSBrandon Wyman 189aed1f75dSBrandon Wyman /** 190aed1f75dSBrandon Wyman * @brief Maximum number of power supplies possible. 191aed1f75dSBrandon Wyman */ 192aed1f75dSBrandon Wyman int maxPSUs = 1; 193aed1f75dSBrandon Wyman 194aed1f75dSBrandon Wyman /** 195a0f33ce3SBrandon Wyman * @brief The vector for power supplies. 196a0f33ce3SBrandon Wyman */ 197aed1f75dSBrandon Wyman std::vector<std::unique_ptr<PowerSupply>> psus; 1982bac8609SBrandon Wyman }; 1992bac8609SBrandon Wyman 200*63ea78b9SBrandon Wyman } // namespace phosphor::power::manager 201