xref: /openbmc/phosphor-power/phosphor-power-supply/psu_manager.hpp (revision 59a3579313458ce41d3e619148c9dea7eab27601)
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