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