17f88fe61SMatt Spinler #pragma once 23e1bb274SMatthew Barth #include "fan.hpp" 33e1bb274SMatthew Barth #include "sdbusplus.hpp" 43e1bb274SMatthew Barth #include "types.hpp" 53e1bb274SMatthew Barth #include "xyz/openbmc_project/Control/ThermalMode/server.hpp" 63e1bb274SMatthew Barth 73e1bb274SMatthew Barth #include <sdbusplus/bus.hpp> 83e1bb274SMatthew Barth #include <sdeventplus/event.hpp> 93e1bb274SMatthew Barth 108fd879fbSWilliam A. Kennington III #include <algorithm> 112c8e1988SWilliam A. Kennington III #include <cassert> 12a956184bSMatthew Barth #include <chrono> 13ed7b0342SPatrick Williams #include <cmath> 145a80f3aeSMatthew Barth #include <optional> 153e1bb274SMatthew Barth #include <vector> 167f88fe61SMatt Spinler 177f88fe61SMatt Spinler namespace phosphor 187f88fe61SMatt Spinler { 197f88fe61SMatt Spinler namespace fan 207f88fe61SMatt Spinler { 217f88fe61SMatt Spinler namespace control 227f88fe61SMatt Spinler { 237f88fe61SMatt Spinler 24cb356d48SPatrick Williams using ThermalObject = sdbusplus::server::object_t< 2593af4194SMatthew Barth sdbusplus::xyz::openbmc_project::Control::server::ThermalMode>; 2693af4194SMatthew Barth 277f88fe61SMatt Spinler /** 2814184131SMatthew Barth * The mode fan control will run in: 2914184131SMatthew Barth * - init - only do the initialization steps 3014184131SMatthew Barth * - control - run normal control algorithms 3114184131SMatthew Barth */ 3214184131SMatthew Barth enum class Mode 3314184131SMatthew Barth { 3414184131SMatthew Barth init, 3514184131SMatthew Barth control 3614184131SMatthew Barth }; 3714184131SMatthew Barth 3814184131SMatthew Barth /** 397f88fe61SMatt Spinler * @class Represents a fan control zone, which is a group of fans 407f88fe61SMatt Spinler * that behave the same. 417f88fe61SMatt Spinler */ 4293af4194SMatthew Barth class Zone : public ThermalObject 437f88fe61SMatt Spinler { 447f88fe61SMatt Spinler public: 457f88fe61SMatt Spinler Zone() = delete; 467f88fe61SMatt Spinler Zone(const Zone&) = delete; 470081fdb8SMatthew Barth Zone(Zone&&) = delete; 487f88fe61SMatt Spinler Zone& operator=(const Zone&) = delete; 497f88fe61SMatt Spinler Zone& operator=(Zone&&) = delete; 507f88fe61SMatt Spinler ~Zone() = default; 517f88fe61SMatt Spinler 527f88fe61SMatt Spinler /** 537f88fe61SMatt Spinler * Constructor 547f88fe61SMatt Spinler * Creates the appropriate fan objects based on 557f88fe61SMatt Spinler * the zone definition data passed in. 567f88fe61SMatt Spinler * 5714184131SMatthew Barth * @param[in] mode - mode of fan control 587f88fe61SMatt Spinler * @param[in] bus - the dbus object 5993af4194SMatthew Barth * @param[in] path - object instance path 601cfc2f11SWilliam A. Kennington III * @param[in] event - Event loop reference 617f88fe61SMatt Spinler * @param[in] def - the fan zone definition data 627f88fe61SMatt Spinler */ 63cb356d48SPatrick Williams Zone(Mode mode, sdbusplus::bus_t& bus, const std::string& path, 643e1bb274SMatthew Barth const sdeventplus::Event& event, const ZoneDefinition& def); 657f88fe61SMatt Spinler 667f88fe61SMatt Spinler /** 67016bd24cSMatthew Barth * @brief Get the zone's bus 68016bd24cSMatthew Barth * 69016bd24cSMatthew Barth * @return The bus used by the zone 70016bd24cSMatthew Barth */ getBus()71016bd24cSMatthew Barth inline auto& getBus() 72016bd24cSMatthew Barth { 73016bd24cSMatthew Barth return _bus; 74016bd24cSMatthew Barth } 75016bd24cSMatthew Barth 76016bd24cSMatthew Barth /** 77016bd24cSMatthew Barth * @brief Get the zone's path 78016bd24cSMatthew Barth * 79016bd24cSMatthew Barth * @return The path of this zone 80016bd24cSMatthew Barth */ getPath()81016bd24cSMatthew Barth inline auto& getPath() 82016bd24cSMatthew Barth { 83016bd24cSMatthew Barth return _path; 84016bd24cSMatthew Barth } 85016bd24cSMatthew Barth 86016bd24cSMatthew Barth /** 87016bd24cSMatthew Barth * @brief Get the zone's hosted interfaces 88016bd24cSMatthew Barth * 89016bd24cSMatthew Barth * @return The interfaces hosted by this zone 90016bd24cSMatthew Barth */ getIfaces()91016bd24cSMatthew Barth inline auto& getIfaces() 92016bd24cSMatthew Barth { 93016bd24cSMatthew Barth return _ifaces; 94016bd24cSMatthew Barth } 95016bd24cSMatthew Barth 96016bd24cSMatthew Barth /** 977f88fe61SMatt Spinler * Sets all fans in the zone to the speed 9860b00766SMatthew Barth * passed in when the zone is active 997f88fe61SMatt Spinler * 1007f88fe61SMatt Spinler * @param[in] speed - the fan speed 1017f88fe61SMatt Spinler */ 1027f88fe61SMatt Spinler void setSpeed(uint64_t speed); 1037f88fe61SMatt Spinler 1047f88fe61SMatt Spinler /** 10560b00766SMatthew Barth * Sets the zone to full speed regardless of zone's active state 1067f88fe61SMatt Spinler */ 10760b00766SMatthew Barth void setFullSpeed(); 1087f88fe61SMatt Spinler 10938a93a8aSMatthew Barth /** 110861d77c3SMatthew Barth * @brief Sets the automatic fan control allowed active state 111861d77c3SMatthew Barth * 112861d77c3SMatthew Barth * @param[in] group - A group that affects the active state 113861d77c3SMatthew Barth * @param[in] isActiveAllow - Active state according to group 114861d77c3SMatthew Barth */ 115861d77c3SMatthew Barth void setActiveAllow(const Group* group, bool isActiveAllow); 116861d77c3SMatthew Barth 117861d77c3SMatthew Barth /** 11898726c45SMatthew Barth * @brief Sets the floor change allowed state 11998726c45SMatthew Barth * 12098726c45SMatthew Barth * @param[in] group - A group that affects floor changes 12198726c45SMatthew Barth * @param[in] isAllow - Allow state according to group 12298726c45SMatthew Barth */ setFloorChangeAllow(const Group * group,bool isAllow)12398726c45SMatthew Barth inline void setFloorChangeAllow(const Group* group, bool isAllow) 12498726c45SMatthew Barth { 12598726c45SMatthew Barth _floorChange[*(group)] = isAllow; 12698726c45SMatthew Barth } 12798726c45SMatthew Barth 12898726c45SMatthew Barth /** 129e4338cdbSMatthew Barth * @brief Sets the decrease allowed state of a group 130e4338cdbSMatthew Barth * 131e4338cdbSMatthew Barth * @param[in] group - A group that affects speed decreases 132e4338cdbSMatthew Barth * @param[in] isAllow - Allow state according to group 133e4338cdbSMatthew Barth */ setDecreaseAllow(const Group * group,bool isAllow)134e4338cdbSMatthew Barth inline void setDecreaseAllow(const Group* group, bool isAllow) 135e4338cdbSMatthew Barth { 136e4338cdbSMatthew Barth _decAllowed[*(group)] = isAllow; 137e4338cdbSMatthew Barth } 138e4338cdbSMatthew Barth 139e4338cdbSMatthew Barth /** 140016bd24cSMatthew Barth * @brief Sets a given object's event data for a property on this zone 141016bd24cSMatthew Barth * 142016bd24cSMatthew Barth * @param[in] object - Name of the object containing the property 143016bd24cSMatthew Barth * @param[in] interface - Interface name containing the property 144016bd24cSMatthew Barth * @param[in] property - Property name 145016bd24cSMatthew Barth * @param[in] data - Property value 146016bd24cSMatthew Barth */ setObjectData(const std::string & object,const std::string & interface,const std::string & property,EventData * data)147016bd24cSMatthew Barth inline void setObjectData(const std::string& object, 148016bd24cSMatthew Barth const std::string& interface, 1493e1bb274SMatthew Barth const std::string& property, EventData* data) 150016bd24cSMatthew Barth { 151016bd24cSMatthew Barth _objects[object][interface][property] = data; 152016bd24cSMatthew Barth } 153016bd24cSMatthew Barth 154016bd24cSMatthew Barth /** 15538a93a8aSMatthew Barth * @brief Sets a given object's property value 15638a93a8aSMatthew Barth * 15738a93a8aSMatthew Barth * @param[in] object - Name of the object containing the property 158cec5ab76SMatthew Barth * @param[in] interface - Interface name containing the property 15938a93a8aSMatthew Barth * @param[in] property - Property name 16038a93a8aSMatthew Barth * @param[in] value - Property value 16138a93a8aSMatthew Barth */ 1629e741ed0SMatthew Barth template <typename T> setPropertyValue(const char * object,const char * interface,const char * property,T value)1633e1bb274SMatthew Barth void setPropertyValue(const char* object, const char* interface, 1643e1bb274SMatthew Barth const char* property, T value) 16538a93a8aSMatthew Barth { 166cec5ab76SMatthew Barth _properties[object][interface][property] = value; 167b2e9a4fcSMike Capps } 16838a93a8aSMatthew Barth 16917d1fe23SMatthew Barth /** 170016bd24cSMatthew Barth * @brief Sets a given object's property value 171016bd24cSMatthew Barth * 172016bd24cSMatthew Barth * @param[in] object - Name of the object containing the property 173016bd24cSMatthew Barth * @param[in] interface - Interface name containing the property 174016bd24cSMatthew Barth * @param[in] property - Property name 175016bd24cSMatthew Barth * @param[in] value - Property value 176016bd24cSMatthew Barth */ 177016bd24cSMatthew Barth template <typename T> setPropertyValue(const std::string & object,const std::string & interface,const std::string & property,T value)178016bd24cSMatthew Barth void setPropertyValue(const std::string& object, 179016bd24cSMatthew Barth const std::string& interface, 1803e1bb274SMatthew Barth const std::string& property, T value) 181016bd24cSMatthew Barth { 182016bd24cSMatthew Barth _properties[object][interface][property] = value; 183b2e9a4fcSMike Capps } 184016bd24cSMatthew Barth 185016bd24cSMatthew Barth /** 18617d1fe23SMatthew Barth * @brief Get the value of an object's property 18717d1fe23SMatthew Barth * 18817d1fe23SMatthew Barth * @param[in] object - Name of the object containing the property 189cec5ab76SMatthew Barth * @param[in] interface - Interface name containing the property 19017d1fe23SMatthew Barth * @param[in] property - Property name 19117d1fe23SMatthew Barth * 19217d1fe23SMatthew Barth * @return - The property value 19317d1fe23SMatthew Barth */ 1949e741ed0SMatthew Barth template <typename T> getPropertyValue(const std::string & object,const std::string & interface,const std::string & property)19517d1fe23SMatthew Barth inline auto getPropertyValue(const std::string& object, 196cec5ab76SMatthew Barth const std::string& interface, 19717d1fe23SMatthew Barth const std::string& property) 19817d1fe23SMatthew Barth { 1993e1bb274SMatthew Barth return std::get<T>(_properties.at(object).at(interface).at(property)); 200b2e9a4fcSMike Capps } 20117d1fe23SMatthew Barth 2021de66629SMatthew Barth /** 203604329efSMatthew Barth * @brief Get the object's property variant 204604329efSMatthew Barth * 205604329efSMatthew Barth * @param[in] object - Name of the object containing the property 206604329efSMatthew Barth * @param[in] interface - Interface name containing the property 207604329efSMatthew Barth * @param[in] property - Property name 208604329efSMatthew Barth * 209604329efSMatthew Barth * @return - The property variant 210604329efSMatthew Barth */ getPropValueVariant(const std::string & object,const std::string & interface,const std::string & property)211604329efSMatthew Barth inline auto getPropValueVariant(const std::string& object, 212604329efSMatthew Barth const std::string& interface, 213604329efSMatthew Barth const std::string& property) 214604329efSMatthew Barth { 215604329efSMatthew Barth return _properties.at(object).at(interface).at(property); 216b2e9a4fcSMike Capps } 217604329efSMatthew Barth 218604329efSMatthew Barth /** 2197f4c548dSMatthew Barth * @brief Get a property's value after applying a set of visitors 2207f4c548dSMatthew Barth * to translate the property value's type change to keep from 2217f4c548dSMatthew Barth * affecting the configured use of the property. 2227f4c548dSMatthew Barth * 2237f4c548dSMatthew Barth * @param[in] intf = Interface name containing the property 2247f4c548dSMatthew Barth * @param[in] prop = Property name 2257f4c548dSMatthew Barth * @param[in] variant = Variant containing the property's value from 2267f4c548dSMatthew Barth * the supported property types. 2277f4c548dSMatthew Barth */ 2287f4c548dSMatthew Barth template <typename T> getPropertyValueVisitor(const char * intf,const char * prop,PropertyVariantType & variant)2293e1bb274SMatthew Barth inline auto getPropertyValueVisitor(const char* intf, const char* prop, 2307f4c548dSMatthew Barth PropertyVariantType& variant) 2317f4c548dSMatthew Barth { 2327f4c548dSMatthew Barth // Handle the transition of the dbus sensor value type from 2337f4c548dSMatthew Barth // int64 to double which also removed the scale property. 2347f4c548dSMatthew Barth // https://gerrit.openbmc-project.xyz/11739 2357f4c548dSMatthew Barth if (strcmp(intf, "xyz.openbmc_project.Sensor.Value") == 0 && 2367f4c548dSMatthew Barth strcmp(prop, "Value") == 0) 2377f4c548dSMatthew Barth { 2385a80f3aeSMatthew Barth // Use 'optional' variable to determine if the sensor value 2395a80f3aeSMatthew Barth // is set within the visitor based on the supported types. 2405a80f3aeSMatthew Barth // A non-supported type configured will assert. 2415a80f3aeSMatthew Barth std::optional<T> value; 2423e1bb274SMatthew Barth std::visit( 2433e1bb274SMatthew Barth [&value](auto&& val) { 2447f4c548dSMatthew Barth // If the type configured is int64, but the sensor value 2457f4c548dSMatthew Barth // property's type is double, scale it by 1000 and return 2467f4c548dSMatthew Barth // the value as an int64 as configured. 2477f4c548dSMatthew Barth using V = std::decay_t<decltype(val)>; 2487f4c548dSMatthew Barth if constexpr (std::is_same_v<T, int64_t> && 2497f4c548dSMatthew Barth std::is_same_v<V, double>) 2507f4c548dSMatthew Barth { 2517f4c548dSMatthew Barth val = val * 1000; 252ed7b0342SPatrick Williams value = std::lround(val); 2537f4c548dSMatthew Barth } 2547f4c548dSMatthew Barth // If the type configured matches the sensor value 2557f4c548dSMatthew Barth // property's type, just return the value as its 2567f4c548dSMatthew Barth // given type. 2575a80f3aeSMatthew Barth else if constexpr (std::is_same_v<T, V>) 2587f4c548dSMatthew Barth { 2597f4c548dSMatthew Barth value = val; 2607f4c548dSMatthew Barth } 2613e1bb274SMatthew Barth }, 2623e1bb274SMatthew Barth variant); 2637f4c548dSMatthew Barth 2645a80f3aeSMatthew Barth // Unable to return Sensor Value property 2655a80f3aeSMatthew Barth // as given type configured. 2665a80f3aeSMatthew Barth assert(value); 2675a80f3aeSMatthew Barth 2685a80f3aeSMatthew Barth return value.value(); 2697f4c548dSMatthew Barth } 2707f4c548dSMatthew Barth 2717f4c548dSMatthew Barth // Default to return the property's value by the data type 2727f4c548dSMatthew Barth // configured, applying no visitors to the variant. 2735a80f3aeSMatthew Barth return std::get<T>(variant); 274b2e9a4fcSMike Capps } 2757f4c548dSMatthew Barth 2767f4c548dSMatthew Barth /** 2771499a5c3SMatthew Barth * @brief Remove an object's interface 2781499a5c3SMatthew Barth * 2791499a5c3SMatthew Barth * @param[in] object - Name of the object with the interface 2801499a5c3SMatthew Barth * @param[in] interface - Interface name to remove 2811499a5c3SMatthew Barth */ removeObjectInterface(const char * object,const char * interface)2823e1bb274SMatthew Barth inline void removeObjectInterface(const char* object, const char* interface) 2831499a5c3SMatthew Barth { 2841499a5c3SMatthew Barth auto it = _properties.find(object); 2851499a5c3SMatthew Barth if (it != std::end(_properties)) 2861499a5c3SMatthew Barth { 2871499a5c3SMatthew Barth _properties[object].erase(interface); 2881499a5c3SMatthew Barth } 2891499a5c3SMatthew Barth } 2901499a5c3SMatthew Barth 2911499a5c3SMatthew Barth /** 29255dea643SMatthew Barth * @brief Remove a service associated to a group 29355dea643SMatthew Barth * 29455dea643SMatthew Barth * @param[in] group - Group associated with service 29555dea643SMatthew Barth * @param[in] name - Service name to remove 29655dea643SMatthew Barth */ 2973e1bb274SMatthew Barth void removeService(const Group* group, const std::string& name); 29855dea643SMatthew Barth 29955dea643SMatthew Barth /** 300e59fdf70SMatthew Barth * @brief Set or update a service name owner in use 301e59fdf70SMatthew Barth * 302e59fdf70SMatthew Barth * @param[in] group - Group associated with service 303e59fdf70SMatthew Barth * @param[in] name - Service name 304e59fdf70SMatthew Barth * @param[in] hasOwner - Whether the service is owned or not 305e59fdf70SMatthew Barth */ 3063e1bb274SMatthew Barth void setServiceOwner(const Group* group, const std::string& name, 307e59fdf70SMatthew Barth const bool hasOwner); 308e59fdf70SMatthew Barth 309e59fdf70SMatthew Barth /** 310480787c1SMatthew Barth * @brief Set or update all services for a group 311480787c1SMatthew Barth * 312480787c1SMatthew Barth * @param[in] group - Group to get service names for 313480787c1SMatthew Barth */ 314480787c1SMatthew Barth void setServices(const Group* group); 315480787c1SMatthew Barth 316480787c1SMatthew Barth /** 317bfb1a566SMatthew Barth * @brief Get the group's list of service names 318bfb1a566SMatthew Barth * 319bfb1a566SMatthew Barth * @param[in] group - Group to get service names for 320bfb1a566SMatthew Barth * 321bfb1a566SMatthew Barth * @return - The list of service names 322bfb1a566SMatthew Barth */ getGroupServices(const Group * group)323bfb1a566SMatthew Barth inline auto getGroupServices(const Group* group) 324bfb1a566SMatthew Barth { 325bfb1a566SMatthew Barth return _services.at(*group); 326bfb1a566SMatthew Barth } 327bfb1a566SMatthew Barth 328bfb1a566SMatthew Barth /** 329604329efSMatthew Barth * @brief Initialize a set speed event properties and actions 330604329efSMatthew Barth * 331604329efSMatthew Barth * @param[in] event - Set speed event 332604329efSMatthew Barth */ 333604329efSMatthew Barth void initEvent(const SetSpeedEvent& event); 334604329efSMatthew Barth 335604329efSMatthew Barth /** 336f6b76d8eSMatthew Barth * @brief Removes all the set speed event properties and actions 337f6b76d8eSMatthew Barth * 338f6b76d8eSMatthew Barth * @param[in] event - Set speed event 339f6b76d8eSMatthew Barth */ 340f6b76d8eSMatthew Barth void removeEvent(const SetSpeedEvent& event); 341f6b76d8eSMatthew Barth 342f6b76d8eSMatthew Barth /** 3431de66629SMatthew Barth * @brief Get the default floor speed 3441de66629SMatthew Barth * 3451de66629SMatthew Barth * @return - The defined default floor speed 3461de66629SMatthew Barth */ getDefFloor()3471de66629SMatthew Barth inline auto getDefFloor() 3481de66629SMatthew Barth { 3491de66629SMatthew Barth return _defFloorSpeed; 350b2e9a4fcSMike Capps } 3511de66629SMatthew Barth 3524af419cdSMatthew Barth /** 3538d06a838SMatthew Barth * @brief Set the default floor 3548d06a838SMatthew Barth * 3558d06a838SMatthew Barth * @param[in] speed - Speed to set the default floor to 3568d06a838SMatthew Barth */ setDefFloor(uint64_t speed)3578d06a838SMatthew Barth inline void setDefFloor(uint64_t speed) 3588d06a838SMatthew Barth { 3598d06a838SMatthew Barth _defFloorSpeed = speed; 360b2e9a4fcSMike Capps } 3618d06a838SMatthew Barth 3628d06a838SMatthew Barth /** 363e0ca13ebSMatthew Barth * @brief Get the ceiling speed 364e0ca13ebSMatthew Barth * 365e0ca13ebSMatthew Barth * @return - The current ceiling speed 366e0ca13ebSMatthew Barth */ getCeiling() const367e0ca13ebSMatthew Barth inline auto& getCeiling() const 368e0ca13ebSMatthew Barth { 369e0ca13ebSMatthew Barth return _ceilingSpeed; 370b2e9a4fcSMike Capps } 371e0ca13ebSMatthew Barth 372e0ca13ebSMatthew Barth /** 373e0ca13ebSMatthew Barth * @brief Set the ceiling speed to the given speed 374e0ca13ebSMatthew Barth * 375e0ca13ebSMatthew Barth * @param[in] speed - Speed to set the ceiling to 376e0ca13ebSMatthew Barth */ setCeiling(uint64_t speed)377e0ca13ebSMatthew Barth inline void setCeiling(uint64_t speed) 378e0ca13ebSMatthew Barth { 379e0ca13ebSMatthew Barth _ceilingSpeed = speed; 380b2e9a4fcSMike Capps } 381e0ca13ebSMatthew Barth 382e0ca13ebSMatthew Barth /** 383e0ca13ebSMatthew Barth * @brief Swaps the ceiling key value with what's given and 384e0ca13ebSMatthew Barth * returns the value that was swapped. 385e0ca13ebSMatthew Barth * 386e0ca13ebSMatthew Barth * @param[in] keyValue - New ceiling key value 387e0ca13ebSMatthew Barth * 388e0ca13ebSMatthew Barth * @return - Ceiling key value prior to swapping 389e0ca13ebSMatthew Barth */ swapCeilingKeyValue(int64_t keyValue)390e0ca13ebSMatthew Barth inline auto swapCeilingKeyValue(int64_t keyValue) 391e0ca13ebSMatthew Barth { 392e0ca13ebSMatthew Barth std::swap(_ceilingKeyValue, keyValue); 393e0ca13ebSMatthew Barth return keyValue; 394b2e9a4fcSMike Capps } 395e0ca13ebSMatthew Barth 39624623523SMatthew Barth /** 39724623523SMatthew Barth * @brief Get the increase speed delta 39824623523SMatthew Barth * 39924623523SMatthew Barth * @return - The current increase speed delta 40024623523SMatthew Barth */ getIncSpeedDelta() const40124623523SMatthew Barth inline auto& getIncSpeedDelta() const 40224623523SMatthew Barth { 40324623523SMatthew Barth return _incSpeedDelta; 404b2e9a4fcSMike Capps } 40524623523SMatthew Barth 406240397b9SMatthew Barth /** 4070ce99d8bSMatthew Barth * @brief Get the decrease speed delta 4080ce99d8bSMatthew Barth * 4090ce99d8bSMatthew Barth * @return - The current decrease speed delta 4100ce99d8bSMatthew Barth */ getDecSpeedDelta() const4110ce99d8bSMatthew Barth inline auto& getDecSpeedDelta() const 4120ce99d8bSMatthew Barth { 4130ce99d8bSMatthew Barth return _decSpeedDelta; 414b2e9a4fcSMike Capps } 4150ce99d8bSMatthew Barth 4160ce99d8bSMatthew Barth /** 417b4a7cb99SMatthew Barth * @brief Set the floor speed to the given speed and increase target 41898726c45SMatthew Barth * speed to the floor when target is below floor where floor changes 41998726c45SMatthew Barth * are allowed. 420b4a7cb99SMatthew Barth * 421b4a7cb99SMatthew Barth * @param[in] speed - Speed to set the floor to 422b4a7cb99SMatthew Barth */ 423b4a7cb99SMatthew Barth void setFloor(uint64_t speed); 424b4a7cb99SMatthew Barth 425b4a7cb99SMatthew Barth /** 4261bfdc423SMatthew Barth * @brief Set the requested speed base to be used as the speed to 4271bfdc423SMatthew Barth * base a new requested speed target from 4281bfdc423SMatthew Barth * 4291bfdc423SMatthew Barth * @param[in] speedBase - Base speed value to use 4301bfdc423SMatthew Barth */ setRequestSpeedBase(uint64_t speedBase)4311bfdc423SMatthew Barth inline void setRequestSpeedBase(uint64_t speedBase) 4321bfdc423SMatthew Barth { 4331bfdc423SMatthew Barth _requestSpeedBase = speedBase; 434b2e9a4fcSMike Capps } 4351bfdc423SMatthew Barth 4361bfdc423SMatthew Barth /** 437240397b9SMatthew Barth * @brief Calculate the requested target speed from the given delta 438240397b9SMatthew Barth * and increase the fan speeds, not going above the ceiling. 439240397b9SMatthew Barth * 440240397b9SMatthew Barth * @param[in] targetDelta - The delta to increase the target speed by 441240397b9SMatthew Barth */ 442240397b9SMatthew Barth void requestSpeedIncrease(uint64_t targetDelta); 443240397b9SMatthew Barth 4440ce99d8bSMatthew Barth /** 4450ce99d8bSMatthew Barth * @brief Calculate the requested target speed from the given delta 4460ce99d8bSMatthew Barth * and increase the fan speeds, not going above the ceiling. 4470ce99d8bSMatthew Barth * 4480ce99d8bSMatthew Barth * @param[in] targetDelta - The delta to increase the target speed by 4490ce99d8bSMatthew Barth */ 4500ce99d8bSMatthew Barth void requestSpeedDecrease(uint64_t targetDelta); 4510ce99d8bSMatthew Barth 4528600d9a0SMatthew Barth /** 4531ee48f2bSMatthew Barth * @brief Callback function for the increase timer that delays 4541ee48f2bSMatthew Barth * processing of requested speed increases while fans are increasing 4551ee48f2bSMatthew Barth */ 4561ee48f2bSMatthew Barth void incTimerExpired(); 4571ee48f2bSMatthew Barth 4581ee48f2bSMatthew Barth /** 4598600d9a0SMatthew Barth * @brief Callback function for the decrease timer that processes any 4608600d9a0SMatthew Barth * requested speed decreases if allowed 4618600d9a0SMatthew Barth */ 4628600d9a0SMatthew Barth void decTimerExpired(); 4638600d9a0SMatthew Barth 4649014980aSMatthew Barth /** 4651cfc2f11SWilliam A. Kennington III * @brief Get the event loop used with this zone's timers 466bfb1a566SMatthew Barth * 4671cfc2f11SWilliam A. Kennington III * @return - The event loop for timers 468bfb1a566SMatthew Barth */ getEventLoop()4691cfc2f11SWilliam A. Kennington III inline auto& getEventLoop() 470bfb1a566SMatthew Barth { 4711cfc2f11SWilliam A. Kennington III return _eventLoop; 472bfb1a566SMatthew Barth } 473bfb1a566SMatthew Barth 474bfb1a566SMatthew Barth /** 47533bfe761SMatthew Barth * @brief Remove the given signal event 47633bfe761SMatthew Barth * 47733bfe761SMatthew Barth * @param[in] seIter - Iterator pointing to the signal event to remove 47833bfe761SMatthew Barth */ removeSignal(std::vector<SignalEvent>::iterator & seIter)47933bfe761SMatthew Barth inline void removeSignal(std::vector<SignalEvent>::iterator& seIter) 48033bfe761SMatthew Barth { 48133bfe761SMatthew Barth std::get<signalEventDataPos>(*seIter).reset(); 48233bfe761SMatthew Barth if (std::get<signalMatchPos>(*seIter) != nullptr) 48333bfe761SMatthew Barth { 48433bfe761SMatthew Barth std::get<signalMatchPos>(*seIter).reset(); 48533bfe761SMatthew Barth } 48633bfe761SMatthew Barth } 48733bfe761SMatthew Barth 48833bfe761SMatthew Barth /** 489bfb1a566SMatthew Barth * @brief Get the list of timer events 490bfb1a566SMatthew Barth * 491bfb1a566SMatthew Barth * @return - List of timer events 492bfb1a566SMatthew Barth */ getTimerEvents()493bfb1a566SMatthew Barth inline auto& getTimerEvents() 494bfb1a566SMatthew Barth { 495bfb1a566SMatthew Barth return _timerEvents; 496bfb1a566SMatthew Barth } 497bfb1a566SMatthew Barth 498bfb1a566SMatthew Barth /** 499bfb1a566SMatthew Barth * @brief Find the first instance of a timer event 500bfb1a566SMatthew Barth * 501bfb1a566SMatthew Barth * @param[in] eventGroup - Group associated with a timer 502bfb1a566SMatthew Barth * @param[in] eventActions - List of actions associated with a timer 503d7b716a6SMatthew Barth * @param[in] eventTimers - List of timers to find the timer in 504bfb1a566SMatthew Barth * 505bfb1a566SMatthew Barth * @return - Iterator to the timer event 506bfb1a566SMatthew Barth */ 507*dfddd648SPatrick Williams std::vector<TimerEvent>::iterator findTimer( 508*dfddd648SPatrick Williams const Group& eventGroup, const std::vector<Action>& eventActions, 509d7b716a6SMatthew Barth std::vector<TimerEvent>& eventTimers); 510bfb1a566SMatthew Barth 511bfb1a566SMatthew Barth /** 512bfb1a566SMatthew Barth * @brief Add a timer to the list of timer based events 513bfb1a566SMatthew Barth * 514d7b716a6SMatthew Barth * @param[in] name - Event name associated with timer 51594fe1a0cSWilliam A. Kennington III * @param[in] group - Group associated with a timer 51694fe1a0cSWilliam A. Kennington III * @param[in] actions - List of actions associated with a timer 51794fe1a0cSWilliam A. Kennington III * @param[in] tConf - Configuration for the new timer 518bfb1a566SMatthew Barth */ 5193e1bb274SMatthew Barth void addTimer(const std::string& name, const Group& group, 5203e1bb274SMatthew Barth const std::vector<Action>& actions, const TimerConf& tConf); 521bfb1a566SMatthew Barth 522bfb1a566SMatthew Barth /** 5239014980aSMatthew Barth * @brief Callback function for event timers that processes the given 524f9201abbSMatthew Barth * actions for a group 5259014980aSMatthew Barth * 526f9201abbSMatthew Barth * @param[in] eventGroup - Group to process actions on 527f9201abbSMatthew Barth * @param[in] eventActions - List of event actions to run 5289014980aSMatthew Barth */ 529c0c5f07fSWilliam A. Kennington III void timerExpired(const Group& eventGroup, 530c0c5f07fSWilliam A. Kennington III const std::vector<Action>& eventActions); 5319014980aSMatthew Barth 532a603ed01SMatthew Barth /** 533a603ed01SMatthew Barth * @brief Get the service for a given path and interface from cached 534a603ed01SMatthew Barth * dataset and add a service that's not found 535a603ed01SMatthew Barth * 536a603ed01SMatthew Barth * @param[in] path - Path to get service for 537a603ed01SMatthew Barth * @param[in] intf - Interface to get service for 538a603ed01SMatthew Barth * 539a603ed01SMatthew Barth * @return - The service name 540a603ed01SMatthew Barth */ 541a603ed01SMatthew Barth const std::string& getService(const std::string& path, 542a603ed01SMatthew Barth const std::string& intf); 543a603ed01SMatthew Barth 544a603ed01SMatthew Barth /** 545a603ed01SMatthew Barth * @brief Add a set of services for a path and interface 546a603ed01SMatthew Barth * by retrieving all the path subtrees to the given depth 547a603ed01SMatthew Barth * from root for the interface 548a603ed01SMatthew Barth * 549a603ed01SMatthew Barth * @param[in] path - Path to add services for 550a603ed01SMatthew Barth * @param[in] intf - Interface to add services for 551a603ed01SMatthew Barth * @param[in] depth - Depth of tree traversal from root path 552a603ed01SMatthew Barth * 553a603ed01SMatthew Barth * @return - The associated service to the given path and interface 554a603ed01SMatthew Barth * or empty string for no service found 555a603ed01SMatthew Barth */ 556a603ed01SMatthew Barth const std::string& addServices(const std::string& path, 5573e1bb274SMatthew Barth const std::string& intf, int32_t depth); 558a603ed01SMatthew Barth 5596faf8943SMatthew Barth /** 560016bd24cSMatthew Barth * @brief Dbus signal change callback handler 561016bd24cSMatthew Barth * 562016bd24cSMatthew Barth * @param[in] msg - Expanded sdbusplus message data 563016bd24cSMatthew Barth * @param[in] eventData - The single event's data 564016bd24cSMatthew Barth */ 565cb356d48SPatrick Williams void handleEvent(sdbusplus::message_t& msg, const EventData* eventData); 566016bd24cSMatthew Barth 567016bd24cSMatthew Barth /** 568016bd24cSMatthew Barth * @brief Add a signal to the list of signal based events 569016bd24cSMatthew Barth * 57079cb8312SMatthew Barth * @param[in] name - Event name 571016bd24cSMatthew Barth * @param[in] data - Event data for signal 572016bd24cSMatthew Barth * @param[in] match - Subscribed signal match 573016bd24cSMatthew Barth */ addSignal(const std::string & name,std::unique_ptr<EventData> && data,std::unique_ptr<sdbusplus::bus::match_t> && match)5743ea9ec2bSPatrick Williams inline void addSignal(const std::string& name, 5753ea9ec2bSPatrick Williams std::unique_ptr<EventData>&& data, 5763ea9ec2bSPatrick Williams std::unique_ptr<sdbusplus::bus::match_t>&& match) 577016bd24cSMatthew Barth { 57879cb8312SMatthew Barth _signalEvents[name].emplace_back(std::move(data), std::move(match)); 579016bd24cSMatthew Barth } 580016bd24cSMatthew Barth 581016bd24cSMatthew Barth /** 58270b2e7daSMatthew Barth * @brief Set a property to be persisted 58370b2e7daSMatthew Barth * 58470b2e7daSMatthew Barth * @param[in] intf - Interface containing property 58570b2e7daSMatthew Barth * @param[in] prop - Property to be persisted 58670b2e7daSMatthew Barth */ setPersisted(const std::string & intf,const std::string & prop)5873e1bb274SMatthew Barth inline void setPersisted(const std::string& intf, const std::string& prop) 58870b2e7daSMatthew Barth { 58970b2e7daSMatthew Barth _persisted[intf].emplace_back(prop); 59070b2e7daSMatthew Barth } 59170b2e7daSMatthew Barth 59270b2e7daSMatthew Barth /** 59370b2e7daSMatthew Barth * @brief Get persisted property 59470b2e7daSMatthew Barth * 59570b2e7daSMatthew Barth * @param[in] intf - Interface containing property 59670b2e7daSMatthew Barth * @param[in] prop - Property persisted 59770b2e7daSMatthew Barth * 59870b2e7daSMatthew Barth * @return - True if property is to be persisted, false otherwise 59970b2e7daSMatthew Barth */ 6003e1bb274SMatthew Barth auto getPersisted(const std::string& intf, const std::string& prop); 60170b2e7daSMatthew Barth 60270b2e7daSMatthew Barth /** 603766f8545SMatthew Barth * @brief Get a property value from the zone object or the bus when 604766f8545SMatthew Barth * the property requested is not on the zone object 605766f8545SMatthew Barth * 606766f8545SMatthew Barth * @param[in] path - Path of object 607766f8545SMatthew Barth * @param[in] intf - Object interface 608766f8545SMatthew Barth * @param[in] prop - Object property 609766f8545SMatthew Barth * 610766f8545SMatthew Barth * @return - Property's value 611766f8545SMatthew Barth */ 612766f8545SMatthew Barth template <typename T> getPropertyByName(const std::string & path,const std::string & intf,const std::string & prop)6133e1bb274SMatthew Barth auto getPropertyByName(const std::string& path, const std::string& intf, 614766f8545SMatthew Barth const std::string& prop) 615766f8545SMatthew Barth { 616766f8545SMatthew Barth T value; 617766f8545SMatthew Barth auto pathIter = _objects.find(path); 618766f8545SMatthew Barth if (pathIter != _objects.end()) 619766f8545SMatthew Barth { 620766f8545SMatthew Barth auto intfIter = pathIter->second.find(intf); 621766f8545SMatthew Barth if (intfIter != pathIter->second.end()) 622766f8545SMatthew Barth { 623766f8545SMatthew Barth if (intf == "xyz.openbmc_project.Control.ThermalMode") 624766f8545SMatthew Barth { 625766f8545SMatthew Barth auto var = ThermalMode::getPropertyByName(prop); 626766f8545SMatthew Barth // Use visitor to determine if requested property 627766f8545SMatthew Barth // type(T) is available on this interface and read it 6283e1bb274SMatthew Barth std::visit( 6293e1bb274SMatthew Barth [&value](auto&& val) { 630766f8545SMatthew Barth using V = std::decay_t<decltype(val)>; 631766f8545SMatthew Barth if constexpr (std::is_same_v<T, V>) 632766f8545SMatthew Barth { 633766f8545SMatthew Barth value = val; 634766f8545SMatthew Barth } 6353e1bb274SMatthew Barth }, 6363e1bb274SMatthew Barth var); 637766f8545SMatthew Barth 638766f8545SMatthew Barth return value; 639766f8545SMatthew Barth } 640766f8545SMatthew Barth } 641766f8545SMatthew Barth } 642766f8545SMatthew Barth 6437f4c548dSMatthew Barth // Retrieve the property's value applying any visitors necessary 644766f8545SMatthew Barth auto service = getService(path, intf); 6453e1bb274SMatthew Barth auto variant = util::SDBusPlus::getPropertyVariant<PropertyVariantType>( 6467f4c548dSMatthew Barth _bus, service, path, intf, prop); 6473e1bb274SMatthew Barth value = getPropertyValueVisitor<T>(intf.c_str(), prop.c_str(), variant); 648766f8545SMatthew Barth 649766f8545SMatthew Barth return value; 650b2e9a4fcSMike Capps } 651766f8545SMatthew Barth 652766f8545SMatthew Barth /** 6536faf8943SMatthew Barth * @brief Overridden thermal object's set 'Current' property function 6546faf8943SMatthew Barth * 6556faf8943SMatthew Barth * @param[in] value - Value to set 'Current' to 6566faf8943SMatthew Barth * 6576faf8943SMatthew Barth * @return - The updated value of the 'Current' property 6586faf8943SMatthew Barth */ 6596faf8943SMatthew Barth virtual std::string current(std::string value); 6606faf8943SMatthew Barth 6617f88fe61SMatt Spinler private: 6627f88fe61SMatt Spinler /** 6637f88fe61SMatt Spinler * The dbus object 6647f88fe61SMatt Spinler */ 665cb356d48SPatrick Williams sdbusplus::bus_t& _bus; 6667f88fe61SMatt Spinler 6677f88fe61SMatt Spinler /** 66893af4194SMatthew Barth * Zone object path 66993af4194SMatthew Barth */ 67093af4194SMatthew Barth const std::string _path; 67193af4194SMatthew Barth 67293af4194SMatthew Barth /** 673766f8545SMatthew Barth * Zone supported interfaces 674766f8545SMatthew Barth */ 675766f8545SMatthew Barth const std::vector<std::string> _ifaces; 676766f8545SMatthew Barth 677766f8545SMatthew Barth /** 6787f88fe61SMatt Spinler * Full speed for the zone 6797f88fe61SMatt Spinler */ 6807f88fe61SMatt Spinler const uint64_t _fullSpeed; 6817f88fe61SMatt Spinler 6827f88fe61SMatt Spinler /** 6837f88fe61SMatt Spinler * The zone number 6847f88fe61SMatt Spinler */ 6857f88fe61SMatt Spinler const size_t _zoneNum; 6867f88fe61SMatt Spinler 6877f88fe61SMatt Spinler /** 6881de66629SMatthew Barth * The default floor speed for the zone 6891de66629SMatthew Barth */ 6908d06a838SMatthew Barth uint64_t _defFloorSpeed; 6911de66629SMatthew Barth 6921de66629SMatthew Barth /** 693e0ca13ebSMatthew Barth * The default ceiling speed for the zone 694e0ca13ebSMatthew Barth */ 695e0ca13ebSMatthew Barth const uint64_t _defCeilingSpeed; 696e0ca13ebSMatthew Barth 697e0ca13ebSMatthew Barth /** 6984af419cdSMatthew Barth * The floor speed to not go below 6994af419cdSMatthew Barth */ 7004af419cdSMatthew Barth uint64_t _floorSpeed = _defFloorSpeed; 7014af419cdSMatthew Barth 7024af419cdSMatthew Barth /** 703e0ca13ebSMatthew Barth * The ceiling speed to not go above 704e0ca13ebSMatthew Barth */ 705e0ca13ebSMatthew Barth uint64_t _ceilingSpeed = _defCeilingSpeed; 706e0ca13ebSMatthew Barth 707e0ca13ebSMatthew Barth /** 708e0ca13ebSMatthew Barth * The previous sensor value for calculating the ceiling 709e0ca13ebSMatthew Barth */ 710e0ca13ebSMatthew Barth int64_t _ceilingKeyValue = 0; 711e0ca13ebSMatthew Barth 712e0ca13ebSMatthew Barth /** 713861d77c3SMatthew Barth * Automatic fan control active state 714861d77c3SMatthew Barth */ 715861d77c3SMatthew Barth bool _isActive = true; 716861d77c3SMatthew Barth 717861d77c3SMatthew Barth /** 718240397b9SMatthew Barth * Target speed for this zone 719240397b9SMatthew Barth */ 720240397b9SMatthew Barth uint64_t _targetSpeed = _fullSpeed; 721240397b9SMatthew Barth 722240397b9SMatthew Barth /** 72324623523SMatthew Barth * Speed increase delta 72424623523SMatthew Barth */ 72524623523SMatthew Barth uint64_t _incSpeedDelta = 0; 72624623523SMatthew Barth 72724623523SMatthew Barth /** 7280ce99d8bSMatthew Barth * Speed decrease delta 7290ce99d8bSMatthew Barth */ 7300ce99d8bSMatthew Barth uint64_t _decSpeedDelta = 0; 7310ce99d8bSMatthew Barth 7320ce99d8bSMatthew Barth /** 7331bfdc423SMatthew Barth * Requested speed base 7341bfdc423SMatthew Barth */ 7351bfdc423SMatthew Barth uint64_t _requestSpeedBase = 0; 7361bfdc423SMatthew Barth 7371bfdc423SMatthew Barth /** 738a956184bSMatthew Barth * Speed increase delay in seconds 739a956184bSMatthew Barth */ 740a956184bSMatthew Barth std::chrono::seconds _incDelay; 741a956184bSMatthew Barth 742a956184bSMatthew Barth /** 743a956184bSMatthew Barth * Speed decrease interval in seconds 744a956184bSMatthew Barth */ 745a956184bSMatthew Barth std::chrono::seconds _decInterval; 746a956184bSMatthew Barth 747a956184bSMatthew Barth /** 7481ee48f2bSMatthew Barth * The increase timer object 7491ee48f2bSMatthew Barth */ 7508fd879fbSWilliam A. Kennington III Timer _incTimer; 7511ee48f2bSMatthew Barth 7521ee48f2bSMatthew Barth /** 7538600d9a0SMatthew Barth * The decrease timer object 7548600d9a0SMatthew Barth */ 7558fd879fbSWilliam A. Kennington III Timer _decTimer; 7568600d9a0SMatthew Barth 7578600d9a0SMatthew Barth /** 7581cfc2f11SWilliam A. Kennington III * Event loop used on set speed event timers 7599014980aSMatthew Barth */ 7601cfc2f11SWilliam A. Kennington III sdeventplus::Event _eventLoop; 7619014980aSMatthew Barth 7629014980aSMatthew Barth /** 7637f88fe61SMatt Spinler * The vector of fans in this zone 7647f88fe61SMatt Spinler */ 7657f88fe61SMatt Spinler std::vector<std::unique_ptr<Fan>> _fans; 76638a93a8aSMatthew Barth 76738a93a8aSMatthew Barth /** 76838a93a8aSMatthew Barth * @brief Map of object property values 76938a93a8aSMatthew Barth */ 770cec5ab76SMatthew Barth std::map<std::string, 7713e1bb274SMatthew Barth std::map<std::string, std::map<std::string, PropertyVariantType>>> 7723e1bb274SMatthew Barth _properties; 77338a93a8aSMatthew Barth 77438a93a8aSMatthew Barth /** 775766f8545SMatthew Barth * @brief Map of zone objects 776766f8545SMatthew Barth */ 777766f8545SMatthew Barth std::map<std::string, 7783e1bb274SMatthew Barth std::map<std::string, std::map<std::string, EventData*>>> 7793e1bb274SMatthew Barth _objects; 780766f8545SMatthew Barth 781766f8545SMatthew Barth /** 78270b2e7daSMatthew Barth * @brief Map of interfaces to persisted properties 78370b2e7daSMatthew Barth */ 78470b2e7daSMatthew Barth std::map<std::string, std::vector<std::string>> _persisted; 78570b2e7daSMatthew Barth 78670b2e7daSMatthew Barth /** 787861d77c3SMatthew Barth * @brief Map of active fan control allowed by groups 788861d77c3SMatthew Barth */ 78960b00766SMatthew Barth std::map<const Group, bool> _active; 790861d77c3SMatthew Barth 791861d77c3SMatthew Barth /** 79298726c45SMatthew Barth * @brief Map of floor change allowed by groups 79398726c45SMatthew Barth */ 79498726c45SMatthew Barth std::map<const Group, bool> _floorChange; 79598726c45SMatthew Barth 79698726c45SMatthew Barth /** 797e4338cdbSMatthew Barth * @brief Map of groups controlling decreases allowed 798e4338cdbSMatthew Barth */ 799e4338cdbSMatthew Barth std::map<const Group, bool> _decAllowed; 800e4338cdbSMatthew Barth 801e4338cdbSMatthew Barth /** 802e59fdf70SMatthew Barth * @brief Map of group service names 803e59fdf70SMatthew Barth */ 804e59fdf70SMatthew Barth std::map<const Group, std::vector<Service>> _services; 805e59fdf70SMatthew Barth 806e59fdf70SMatthew Barth /** 807a603ed01SMatthew Barth * @brief Map tree of paths to services of interfaces 808a603ed01SMatthew Barth */ 8093e1bb274SMatthew Barth std::map<std::string, std::map<std::string, std::vector<std::string>>> 8103e1bb274SMatthew Barth _servTree; 811a603ed01SMatthew Barth 812a603ed01SMatthew Barth /** 81379cb8312SMatthew Barth * @brief List of signal event arguments and Dbus matches 81479cb8312SMatthew Barth * for callbacks per event name 81538a93a8aSMatthew Barth */ 81679cb8312SMatthew Barth std::map<std::string, std::vector<SignalEvent>> _signalEvents; 81738a93a8aSMatthew Barth 81838a93a8aSMatthew Barth /** 819d7b716a6SMatthew Barth * @brief List of timers per event name 8209014980aSMatthew Barth */ 821d7b716a6SMatthew Barth std::map<std::string, std::vector<TimerEvent>> _timerEvents; 8229014980aSMatthew Barth 8239014980aSMatthew Barth /** 824cc8912e9SMatthew Barth * @brief Save the thermal control current mode property 825cc8912e9SMatthew Barth * to persisted storage 826cc8912e9SMatthew Barth */ 827cc8912e9SMatthew Barth void saveCurrentMode(); 828cc8912e9SMatthew Barth 829cc8912e9SMatthew Barth /** 8309e4db25cSMatthew Barth * @brief Restore persisted thermal control current mode property 8319e4db25cSMatthew Barth * value, setting the mode to "Default" otherwise 8329e4db25cSMatthew Barth */ 8339e4db25cSMatthew Barth void restoreCurrentMode(); 8349e4db25cSMatthew Barth 8359e4db25cSMatthew Barth /** 8364e728542SMatthew Barth * @brief Get the request speed base if defined, otherwise the 8374e728542SMatthew Barth * the current target speed is returned 8384e728542SMatthew Barth * 8394e728542SMatthew Barth * @return - The request speed base or current target speed 8404e728542SMatthew Barth */ getRequestSpeedBase() const8414e728542SMatthew Barth inline auto getRequestSpeedBase() const 8424e728542SMatthew Barth { 8434e728542SMatthew Barth return (_requestSpeedBase != 0) ? _requestSpeedBase : _targetSpeed; 844b2e9a4fcSMike Capps } 8457f88fe61SMatt Spinler }; 8467f88fe61SMatt Spinler 8473e1bb274SMatthew Barth } // namespace control 8483e1bb274SMatthew Barth } // namespace fan 8493e1bb274SMatthew Barth } // namespace phosphor 850