#pragma once #include "compatible_system_types_finder.hpp" #include "device_finder.hpp" #include "power_interface.hpp" #include "power_sequencer_device.hpp" #include "rail.hpp" #include "services.hpp" #include #include #include #include #include #include #include #include #include #include #include #include namespace phosphor::power::sequencer { using PowerObject = sdbusplus::server::object_t; /** * @class PowerControl * This class implements GPIO control of power on / off, and monitoring of the * chassis power good. */ class PowerControl : public PowerObject { public: PowerControl() = delete; PowerControl(const PowerControl&) = delete; PowerControl& operator=(const PowerControl&) = delete; PowerControl(PowerControl&&) = delete; PowerControl& operator=(PowerControl&&) = delete; ~PowerControl() = default; /** * Creates a controller object for power on and off. * @param bus D-Bus bus object * @param event event object */ PowerControl(sdbusplus::bus_t& bus, const sdeventplus::Event& event); /** @copydoc PowerInterface::getPgood() */ int getPgood() const override; /** @copydoc PowerInterface::getPgoodTimeout() */ int getPgoodTimeout() const override; /** @copydoc PowerInterface::getState() */ int getState() const override; /** @copydoc PowerInterface::setPgoodTimeout() */ void setPgoodTimeout(int timeout) override; /** @copydoc PowerInterface::setState() */ void setState(int state) override; /** @copydoc PowerInterface::setPowerSupplyError() */ void setPowerSupplyError(const std::string& error) override; /** * Callback that is called when a list of compatible system types is found. * * @param types Compatible system types for the current system ordered from * most to least specific */ void compatibleSystemTypesFound(const std::vector& types); /** * Callback that is called when a power sequencer device is found. * * @param properties Properties of device that was found */ void deviceFound(const DeviceProperties& properties); private: /** * The D-Bus bus object */ sdbusplus::bus_t& bus; /** * System services like hardware presence and the journal. */ BMCServices services; /** * Object that finds the compatible system types for the current system. */ std::unique_ptr compatSysTypesFinder; /** * Compatible system types for the current system ordered from most to least * specific. */ std::vector compatibleSystemTypes; /** * Object that finds the power sequencer device in the system. */ std::unique_ptr deviceFinder; /** * Power sequencer device properties. */ std::optional deviceProperties; /** * Power sequencer device that enables and monitors the voltage rails. */ std::unique_ptr device; /** * Indicates if a failure has already been found. Cleared at power on. */ bool failureFound{false}; /** * Indicates if a state transition is taking place */ bool inStateTransition{false}; /** * Minimum time from cold start to power on constant */ static constexpr std::chrono::seconds minimumColdStartTime{15}; /** * Minimum time from power off to power on constant */ static constexpr std::chrono::seconds minimumPowerOffTime{25}; /** * Power good */ int pgood{0}; /** * GPIO line object for chassis power good */ gpiod::line pgoodLine; /** * Power good timeout constant */ static constexpr std::chrono::seconds pgoodTimeout{10}; /** * Point in time at which power good timeout will take place */ std::chrono::time_point pgoodTimeoutTime; /** * Timer to wait after pgood failure. This is to allow the power supplies * and other hardware time to complete failure processing. */ sdeventplus::utility::Timer pgoodWaitTimer; /** * Poll interval constant */ static constexpr std::chrono::milliseconds pollInterval{3000}; /** * GPIO line object for power on / power off control */ gpiod::line powerControlLine; /** * Point in time at which minumum power off time will have passed */ std::chrono::time_point powerOnAllowedTime; /** * Power supply error. Cleared at power on. */ std::string powerSupplyError; /** * Power state */ int state{0}; /** * Power good timeout */ std::chrono::seconds timeout{pgoodTimeout}; /** * Timer to poll the pgood */ sdeventplus::utility::Timer timer; /** * Callback to begin failure processing after observing pgood failure wait */ void onFailureCallback(); /** * Begin pgood failure processing * * @param wasTimeOut Indicates whether failure state was determined by * timing out */ void onFailure(bool wasTimeOut); /** * Polling method for monitoring the system power good */ void pollPgood(); /** * Set up GPIOs */ void setUpGpio(); /** * Loads the JSON configuration file and creates the power sequencer device * object. * * Does nothing if the compatible system types or device properties have not * been found yet. These are obtained from D-Bus. The order in which they * are found and the time to find them varies. */ void loadConfigFileAndCreateDevice(); /** * Finds the JSON configuration file for the current system based on the * compatible system types. * * Does nothing if the compatible system types have not been found yet. * * @return absolute path to the config file, or empty path if file not found */ std::filesystem::path findConfigFile(); /** * Parses the specified JSON configuration file. * * Returns the resulting vector of Rail objects in the output parameter. * * @param configFile Absolute path to the config file * @param rails Rail objects within the config file * @return true if file was parsed successfully, false otherwise */ bool parseConfigFile(const std::filesystem::path& configFile, std::vector>& rails); /** * Creates the power sequencer device object based on the device properties. * * Does nothing if the device properties have not been found yet. * * @param rails Voltage rails that are enabled and monitored by the device */ void createDevice(std::vector> rails); }; } // namespace phosphor::power::sequencer