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 pollInterval; 15aed1f75dSBrandon Wyman int minPowerSupplies; 16aed1f75dSBrandon Wyman int maxPowerSupplies; 17aed1f75dSBrandon Wyman }; 18aed1f75dSBrandon Wyman 19a0f33ce3SBrandon Wyman using namespace phosphor::power::psu; 20a0f33ce3SBrandon Wyman using namespace phosphor::logging; 21a0f33ce3SBrandon Wyman 222bac8609SBrandon Wyman namespace phosphor 232bac8609SBrandon Wyman { 242bac8609SBrandon Wyman namespace power 252bac8609SBrandon Wyman { 262bac8609SBrandon Wyman namespace manager 272bac8609SBrandon Wyman { 282bac8609SBrandon Wyman 292bac8609SBrandon Wyman /** 302bac8609SBrandon Wyman * @class PSUManager 312bac8609SBrandon Wyman * 322bac8609SBrandon Wyman * This class will create an object used to manage and monitor a list of power 332bac8609SBrandon Wyman * supply devices. 342bac8609SBrandon Wyman */ 352bac8609SBrandon Wyman class PSUManager 362bac8609SBrandon Wyman { 372bac8609SBrandon Wyman public: 382bac8609SBrandon Wyman PSUManager() = delete; 392bac8609SBrandon Wyman ~PSUManager() = default; 402bac8609SBrandon Wyman PSUManager(const PSUManager&) = delete; 412bac8609SBrandon Wyman PSUManager& operator=(const PSUManager&) = delete; 422bac8609SBrandon Wyman PSUManager(PSUManager&&) = delete; 432bac8609SBrandon Wyman PSUManager& operator=(PSUManager&&) = delete; 442bac8609SBrandon Wyman 452bac8609SBrandon Wyman /** 462bac8609SBrandon Wyman * Constructor 472bac8609SBrandon Wyman * 482bac8609SBrandon Wyman * @param[in] bus - D-Bus bus object 492bac8609SBrandon Wyman * @param[in] e - event object 502fe5186eSBrandon Wyman * @param[in] configfile - string path to the configuration file 512bac8609SBrandon Wyman */ 522bac8609SBrandon Wyman PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e, 53aed1f75dSBrandon Wyman const std::string& configfile); 542fe5186eSBrandon Wyman 55aed1f75dSBrandon Wyman void getJSONProperties(const std::string& path, sdbusplus::bus::bus& bus, 56aed1f75dSBrandon Wyman sys_properties& p, 57aed1f75dSBrandon Wyman std::vector<std::unique_ptr<PowerSupply>>& psus); 582fe5186eSBrandon Wyman 592bac8609SBrandon Wyman /** 602bac8609SBrandon Wyman * Initializes the manager. 612bac8609SBrandon Wyman * 622bac8609SBrandon Wyman * Get current BMC state, ... 632bac8609SBrandon Wyman */ 642bac8609SBrandon Wyman void initialize() 652bac8609SBrandon Wyman { 66a0f33ce3SBrandon Wyman // When state = 1, system is powered on 67a0f33ce3SBrandon Wyman int32_t state = 0; 68a0f33ce3SBrandon Wyman 69a0f33ce3SBrandon Wyman try 70a0f33ce3SBrandon Wyman { 71a0f33ce3SBrandon Wyman // Use getProperty utility function to get power state. 72a0f33ce3SBrandon Wyman util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH, 73a0f33ce3SBrandon Wyman powerService, bus, state); 74a0f33ce3SBrandon Wyman 75a0f33ce3SBrandon Wyman if (state) 76a0f33ce3SBrandon Wyman { 77a0f33ce3SBrandon Wyman powerOn = true; 78a0f33ce3SBrandon Wyman } 79a0f33ce3SBrandon Wyman else 80a0f33ce3SBrandon Wyman { 81a0f33ce3SBrandon Wyman powerOn = false; 82a0f33ce3SBrandon Wyman } 83a0f33ce3SBrandon Wyman } 84a0f33ce3SBrandon Wyman catch (std::exception& e) 85a0f33ce3SBrandon Wyman { 86a0f33ce3SBrandon Wyman log<level::INFO>("Failed to get power state. Assuming it is off."); 87a0f33ce3SBrandon Wyman powerOn = false; 88a0f33ce3SBrandon Wyman } 89a0f33ce3SBrandon Wyman 90*59a35793SBrandon Wyman onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY); 91a0f33ce3SBrandon Wyman clearFaults(); 92a0f33ce3SBrandon Wyman updateInventory(); 932bac8609SBrandon Wyman } 942bac8609SBrandon Wyman 952bac8609SBrandon Wyman /** 962bac8609SBrandon Wyman * Starts the timer to start monitoring the list of devices. 972bac8609SBrandon Wyman */ 982bac8609SBrandon Wyman int run() 992bac8609SBrandon Wyman { 1002fe5186eSBrandon Wyman return timer->get_event().loop(); 1012bac8609SBrandon Wyman } 1022bac8609SBrandon Wyman 1032bac8609SBrandon Wyman /** 104*59a35793SBrandon Wyman * Write PMBus ON_OFF_CONFIG 105*59a35793SBrandon Wyman * 106*59a35793SBrandon Wyman * This function will be called to cause the PMBus device driver to send the 107*59a35793SBrandon Wyman * ON_OFF_CONFIG command. Takes one byte of data. 108*59a35793SBrandon Wyman */ 109*59a35793SBrandon Wyman void onOffConfig(const uint8_t data) 110*59a35793SBrandon Wyman { 111*59a35793SBrandon Wyman for (auto& psu : psus) 112*59a35793SBrandon Wyman { 113*59a35793SBrandon Wyman psu->onOffConfig(data); 114*59a35793SBrandon Wyman } 115*59a35793SBrandon Wyman } 116*59a35793SBrandon Wyman 117*59a35793SBrandon Wyman /** 1182bac8609SBrandon Wyman * This function will be called in various situations in order to clear 1192bac8609SBrandon Wyman * any fault status bits that may have been set, in order to start over 1202bac8609SBrandon Wyman * with a clean state. Presence changes and power state changes will want 1212bac8609SBrandon Wyman * to clear any faults logged. 1222bac8609SBrandon Wyman */ 1232bac8609SBrandon Wyman void clearFaults() 1242bac8609SBrandon Wyman { 125a0f33ce3SBrandon Wyman for (auto& psu : psus) 126a0f33ce3SBrandon Wyman { 127aed1f75dSBrandon Wyman psu->clearFaults(); 128a0f33ce3SBrandon Wyman } 1293f1242f3SBrandon Wyman 1303f1242f3SBrandon Wyman faultLogged = false; 1312bac8609SBrandon Wyman } 1322bac8609SBrandon Wyman 1332bac8609SBrandon Wyman private: 1342bac8609SBrandon Wyman /** 1352bac8609SBrandon Wyman * The D-Bus object 1362bac8609SBrandon Wyman */ 1372bac8609SBrandon Wyman sdbusplus::bus::bus& bus; 1382bac8609SBrandon Wyman 1392bac8609SBrandon Wyman /** 1402bac8609SBrandon Wyman * The timer that runs to periodically check the power supplies. 1412bac8609SBrandon Wyman */ 1422fe5186eSBrandon Wyman std::unique_ptr< 1432fe5186eSBrandon Wyman sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 1442fe5186eSBrandon Wyman timer; 1452bac8609SBrandon Wyman 1462bac8609SBrandon Wyman /** 1472bac8609SBrandon Wyman * Analyze the status of each of the power supplies. 1482bac8609SBrandon Wyman */ 1492bac8609SBrandon Wyman void analyze() 1502bac8609SBrandon Wyman { 151a0f33ce3SBrandon Wyman for (auto& psu : psus) 152a0f33ce3SBrandon Wyman { 153aed1f75dSBrandon Wyman psu->analyze(); 154a0f33ce3SBrandon Wyman } 1553f1242f3SBrandon Wyman 1563f1242f3SBrandon Wyman for (auto& psu : psus) 1573f1242f3SBrandon Wyman { 1583f1242f3SBrandon Wyman // TODO: Fault priorities #918 1593f1242f3SBrandon Wyman if (!faultLogged && psu->isFaulted()) 1603f1242f3SBrandon Wyman { 1613f1242f3SBrandon Wyman if (psu->hasInputFault()) 1623f1242f3SBrandon Wyman { 1633f1242f3SBrandon Wyman // TODO: Create error log 1643f1242f3SBrandon Wyman } 1653f1242f3SBrandon Wyman 1663f1242f3SBrandon Wyman if (psu->hasMFRFault()) 1673f1242f3SBrandon Wyman { 1683f1242f3SBrandon Wyman // TODO: Create error log 1693f1242f3SBrandon Wyman } 1703f1242f3SBrandon Wyman 1713f1242f3SBrandon Wyman if (psu->hasVINUVFault()) 1723f1242f3SBrandon Wyman { 1733f1242f3SBrandon Wyman // TODO: Create error log 1743f1242f3SBrandon Wyman } 1753f1242f3SBrandon Wyman } 1763f1242f3SBrandon Wyman } 1772bac8609SBrandon Wyman } 1782bac8609SBrandon Wyman 1792bac8609SBrandon Wyman /** @brief True if the power is on. */ 1802bac8609SBrandon Wyman bool powerOn = false; 1812bac8609SBrandon Wyman 1823f1242f3SBrandon Wyman /** @brief True if fault logged. Clear in clearFaults(). */ 1833f1242f3SBrandon Wyman bool faultLogged = false; 1843f1242f3SBrandon Wyman 185a0f33ce3SBrandon Wyman /** @brief Used as part of subscribing to power on state changes*/ 186a0f33ce3SBrandon Wyman std::string powerService; 187a0f33ce3SBrandon Wyman 1882bac8609SBrandon Wyman /** @brief Used to subscribe to D-Bus power on state changes */ 1892bac8609SBrandon Wyman std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 1902bac8609SBrandon Wyman 1912bac8609SBrandon Wyman /** 1922bac8609SBrandon Wyman * @brief Callback for power state property changes 1932bac8609SBrandon Wyman * 1942bac8609SBrandon Wyman * Process changes to the powered on state property for the system. 1952bac8609SBrandon Wyman * 1962bac8609SBrandon Wyman * @param[in] msg - Data associated with the power state signal 1972bac8609SBrandon Wyman */ 1982bac8609SBrandon Wyman void powerStateChanged(sdbusplus::message::message& msg); 1992bac8609SBrandon Wyman 2002bac8609SBrandon Wyman /** 2012bac8609SBrandon Wyman * @brief Adds properties to the inventory. 2022bac8609SBrandon Wyman * 2032bac8609SBrandon Wyman * Reads the values from the devices and writes them to the associated 2042bac8609SBrandon Wyman * power supply D-Bus inventory objects. 2052bac8609SBrandon Wyman * 2062bac8609SBrandon Wyman * This needs to be done on startup, and each time the presence state 2072bac8609SBrandon Wyman * changes. 2082bac8609SBrandon Wyman */ 209a0f33ce3SBrandon Wyman void updateInventory() 210a0f33ce3SBrandon Wyman { 211a0f33ce3SBrandon Wyman for (auto& psu : psus) 212a0f33ce3SBrandon Wyman { 213aed1f75dSBrandon Wyman psu->updateInventory(); 214a0f33ce3SBrandon Wyman } 215a0f33ce3SBrandon Wyman } 216a0f33ce3SBrandon Wyman 217a0f33ce3SBrandon Wyman /** 218aed1f75dSBrandon Wyman * @brief Minimum number of power supplies to operate. 219aed1f75dSBrandon Wyman */ 220aed1f75dSBrandon Wyman int minPSUs = 1; 221aed1f75dSBrandon Wyman 222aed1f75dSBrandon Wyman /** 223aed1f75dSBrandon Wyman * @brief Maximum number of power supplies possible. 224aed1f75dSBrandon Wyman */ 225aed1f75dSBrandon Wyman int maxPSUs = 1; 226aed1f75dSBrandon Wyman 227aed1f75dSBrandon Wyman /** 228a0f33ce3SBrandon Wyman * @brief The vector for power supplies. 229a0f33ce3SBrandon Wyman */ 230aed1f75dSBrandon Wyman std::vector<std::unique_ptr<PowerSupply>> psus; 2312bac8609SBrandon Wyman }; 2322bac8609SBrandon Wyman 2332bac8609SBrandon Wyman } // namespace manager 2342bac8609SBrandon Wyman } // namespace power 2352bac8609SBrandon Wyman } // namespace phosphor 236