/** * Copyright © 2019 IBM Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "configuration.hpp" #include "i2c_interface.hpp" #include "id_map.hpp" #include "phase_fault_detection.hpp" #include "presence_detection.hpp" #include "rail.hpp" #include "services.hpp" #include #include #include #include namespace phosphor::power::regulators { // Forward declarations to avoid circular dependencies class Chassis; class System; /** * @class Device * * A hardware device, such as a voltage regulator or I/O expander. */ class Device { public: // Specify which compiler-generated methods we want Device() = delete; Device(const Device&) = delete; Device(Device&&) = delete; Device& operator=(const Device&) = delete; Device& operator=(Device&&) = delete; ~Device() = default; /** * Constructor. * * @param id unique device ID * @param isRegulator indicates whether this device is a voltage regulator * @param fru Field-Replaceable Unit (FRU) for this device * @param i2cInterface I2C interface to this device * @param presenceDetection presence detection for this device, if any * @param configuration configuration changes to apply to this device, if * any * @param phaseFaultDetection phase fault detection for this device, if any * @param rails voltage rails produced by this device, if any */ explicit Device( const std::string& id, bool isRegulator, const std::string& fru, std::unique_ptr i2cInterface, std::unique_ptr presenceDetection = nullptr, std::unique_ptr configuration = nullptr, std::unique_ptr phaseFaultDetection = nullptr, std::vector> rails = std::vector>{}) : id{id}, isRegulatorDevice{isRegulator}, fru{fru}, i2cInterface{std::move(i2cInterface)}, presenceDetection{std::move(presenceDetection)}, configuration{std::move(configuration)}, phaseFaultDetection{std::move(phaseFaultDetection)}, rails{std::move(rails)} {} /** * Adds this Device object to the specified IDMap. * * Also adds any Rail objects in this Device to the IDMap. * * @param idMap mapping from IDs to the associated Device/Rail/Rule objects */ void addToIDMap(IDMap& idMap); /** * Clear any cached data about hardware devices. */ void clearCache(); /** * Clears all error history. * * All data on previously logged errors will be deleted. If errors occur * again in the future they will be logged again. * * This method is normally called when the system is being powered on. */ void clearErrorHistory(); /** * Closes this device. * * Closes any interfaces that are open to this device. Releases any other * operating system resources associated with this device. * * @param services system services like error logging and the journal */ void close(Services& services); /** * Configure this device. * * Applies the configuration changes that are defined for this device, if * any. * * Also configures the voltage rails produced by this device, if any. * * This method should be called during the boot before regulators are * enabled. * * @param services system services like error logging and the journal * @param system system that contains the chassis * @param chassis chassis that contains this device */ void configure(Services& services, System& system, Chassis& chassis); /** * Detect redundant phase faults in this device. * * Does nothing if phase fault detection is not defined for this device. * * This method should be called repeatedly based on a timer. * * @param services system services like error logging and the journal * @param system system that contains the chassis * @param chassis chassis that contains the device */ void detectPhaseFaults(Services& services, System& system, Chassis& chassis); /** * Returns the configuration changes to apply to this device, if any. * * @return Pointer to Configuration object. Will equal nullptr if no * configuration changes are defined for this device. */ const std::unique_ptr& getConfiguration() const { return configuration; } /** * Returns the Field-Replaceable Unit (FRU) for this device. * * Returns the D-Bus inventory path of the FRU. If the device itself is not * a FRU, returns the FRU that contains the device. * * @return FRU for this device */ const std::string& getFRU() const { return fru; } /** * Returns the I2C interface to this device. * * @return I2C interface to device */ i2c::I2CInterface& getI2CInterface() { return *i2cInterface; } /** * Returns the unique ID of this device. * * @return device ID */ const std::string& getID() const { return id; } /** * Returns the phase fault detection for this device, if any. * * @return Pointer to PhaseFaultDetection object. Will equal nullptr if no * phase fault detection is defined for this device. */ const std::unique_ptr& getPhaseFaultDetection() const { return phaseFaultDetection; } /** * Returns the presence detection for this device, if any. * * @return Pointer to PresenceDetection object. Will equal nullptr if no * presence detection is defined for this device. */ const std::unique_ptr& getPresenceDetection() const { return presenceDetection; } /** * Returns the voltage rails produced by this device, if any. * * @return voltage rails */ const std::vector>& getRails() const { return rails; } /** * Returns whether this device is present. * * @return true if device is present, false otherwise */ bool isPresent(Services& services, System& system, Chassis& chassis) { if (presenceDetection) { // Execute presence detection to determine if device is present return presenceDetection->execute(services, system, chassis, *this); } else { // No presence detection defined; assume device is present return true; } } /** * Returns whether this device is a voltage regulator. * * @return true if device is a voltage regulator, false otherwise */ bool isRegulator() const { return isRegulatorDevice; } /** * Monitors the sensors for the voltage rails produced by this device, if * any. * * This method should be called repeatedly based on a timer. * * @param services system services like error logging and the journal * @param system system that contains the chassis * @param chassis chassis that contains the device */ void monitorSensors(Services& services, System& system, Chassis& chassis); private: /** * Unique ID of this device. */ const std::string id{}; /** * Indicates whether this device is a voltage regulator. */ const bool isRegulatorDevice{false}; /** * Field-Replaceable Unit (FRU) for this device. * * Set to the D-Bus inventory path of the FRU. If the device itself is not * a FRU, set to the FRU that contains the device. */ const std::string fru{}; /** * I2C interface to this device. */ std::unique_ptr i2cInterface{}; /** * Presence detection for this device, if any. Set to nullptr if no * presence detection is defined for this device. */ std::unique_ptr presenceDetection{}; /** * Configuration changes to apply to this device, if any. Set to nullptr if * no configuration changes are defined for this device. */ std::unique_ptr configuration{}; /** * Phase fault detection for this device, if any. Set to nullptr if no * phase fault detection is defined for this device. */ std::unique_ptr phaseFaultDetection{}; /** * Voltage rails produced by this device, if any. Vector is empty if no * voltage rails are defined for this device. */ std::vector> rails{}; }; } // namespace phosphor::power::regulators