1 #pragma once 2 3 #include "pmbus.hpp" 4 #include "types.hpp" 5 #include "util.hpp" 6 #include "utility.hpp" 7 8 #include <gpiod.hpp> 9 #include <sdbusplus/bus/match.hpp> 10 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 11 #include <xyz/openbmc_project/Sensor/Value/server.hpp> 12 #include <xyz/openbmc_project/State/Decorator/Availability/server.hpp> 13 #include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp> 14 15 #include <filesystem> 16 #include <stdexcept> 17 18 namespace phosphor::power::psu 19 { 20 21 #if IBM_VPD 22 // PMBus device driver "file name" to read for CCIN value. 23 constexpr auto CCIN = "ccin"; 24 constexpr auto PART_NUMBER = "mfr_revision"; 25 constexpr auto FRU_NUMBER = "mfr_model"; 26 constexpr auto SERIAL_HEADER = "mfr_location"; 27 constexpr auto SERIAL_NUMBER = "mfr_serial"; 28 constexpr auto FW_VERSION = "fw_version"; 29 30 // The D-Bus property name to update with the CCIN value. 31 constexpr auto MODEL_PROP = "Model"; 32 constexpr auto PN_PROP = "PartNumber"; 33 constexpr auto SPARE_PN_PROP = "SparePartNumber"; 34 constexpr auto SN_PROP = "SerialNumber"; 35 constexpr auto VERSION_PROP = "Version"; 36 37 // ipzVPD Keyword sizes 38 static constexpr auto FL_KW_SIZE = 20; 39 static constexpr auto FN_KW_SIZE = 7; 40 static constexpr auto PN_KW_SIZE = 7; 41 // For IBM power supplies, the SN is 6-byte header + 6-byte serial. 42 static constexpr auto SN_KW_SIZE = 12; 43 static constexpr auto CC_KW_SIZE = 4; 44 #endif 45 46 constexpr auto LOG_LIMIT = 3; 47 constexpr auto DEGLITCH_LIMIT = 3; 48 constexpr auto PGOOD_DEGLITCH_LIMIT = 5; 49 // Number of polls to remember that an AC fault occured. Should remain greater 50 // than PGOOD_DEGLITCH_LIMIT. 51 constexpr auto AC_FAULT_LIMIT = 6; 52 53 constexpr auto IBMCFFPS_DD_NAME = "ibm-cffps"; 54 constexpr auto ACBEL_FSG032_DD_NAME = "acbel-fsg032"; 55 56 using AvailabilityInterface = 57 sdbusplus::xyz::openbmc_project::State::Decorator::server::Availability; 58 using OperationalStatusInterface = sdbusplus::xyz::openbmc_project::State:: 59 Decorator::server::OperationalStatus; 60 using AssocDefInterface = 61 sdbusplus::xyz::openbmc_project::Association::server::Definitions; 62 using SensorInterface = sdbusplus::xyz::openbmc_project::Sensor::server::Value; 63 using SensorObject = sdbusplus::server::object_t<SensorInterface>; 64 using PowerSensorObject = 65 sdbusplus::server::object_t<SensorInterface, OperationalStatusInterface, 66 AvailabilityInterface, AssocDefInterface>; 67 68 using AssociationTuple = std::tuple<std::string, std::string, std::string>; 69 70 /** 71 * @class PowerSupply 72 * Represents a PMBus power supply device. 73 */ 74 class PowerSupply 75 { 76 public: 77 PowerSupply() = delete; 78 PowerSupply(const PowerSupply&) = delete; 79 PowerSupply(PowerSupply&&) = delete; 80 PowerSupply& operator=(const PowerSupply&) = delete; 81 PowerSupply& operator=(PowerSupply&&) = delete; 82 ~PowerSupply() = default; 83 84 /** 85 * @param[in] invpath - String for inventory path to use 86 * @param[in] i2cbus - The bus number this power supply is on 87 * @param[in] i2caddr - The 16-bit I2C address of the power supply 88 * @param[in] driver - i2c driver name for power supply 89 * @param[in] gpioLineName - The gpio-line-name to read for presence. See 90 * https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md 91 * @param[in] callback - Get the power on status of the psu manager class 92 */ 93 PowerSupply(sdbusplus::bus_t& bus, const std::string& invpath, 94 std::uint8_t i2cbus, const std::uint16_t i2caddr, 95 const std::string& driver, const std::string& gpioLineName, 96 std::function<bool()>&& callback); 97 98 phosphor::pmbus::PMBusBase& getPMBus() 99 { 100 return *pmbusIntf; 101 } 102 103 GPIOInterfaceBase* getPresenceGPIO() 104 { 105 return presenceGPIO.get(); 106 } 107 108 std::string getPresenceGPIOName() const 109 { 110 if (presenceGPIO != nullptr) 111 { 112 return presenceGPIO->getName(); 113 } 114 else 115 { 116 return std::string(); 117 } 118 } 119 120 /** 121 * Power supply specific function to analyze for faults/errors. 122 * 123 * Various PMBus status bits will be checked for fault conditions. 124 * If a certain fault bits are on, the appropriate error will be 125 * committed. 126 */ 127 void analyze(); 128 129 /** 130 * Write PMBus ON_OFF_CONFIG 131 * 132 * This function will be called to cause the PMBus device driver to send the 133 * ON_OFF_CONFIG command. Takes one byte of data. 134 * 135 * @param[in] data - The ON_OFF_CONFIG data byte mask. 136 */ 137 void onOffConfig(uint8_t data); 138 139 /** 140 * Clears all the member variables that indicate if a fault bit was seen as 141 * on in the STATUS_WORD or STATUS_MFR_SPECIFIC response. 142 */ 143 void clearFaultFlags() 144 { 145 inputFault = 0; 146 mfrFault = 0; 147 statusMFR = 0; 148 vinUVFault = 0; 149 cmlFault = 0; 150 voutOVFault = 0; 151 ioutOCFault = 0; 152 voutUVFault = 0; 153 fanFault = 0; 154 tempFault = 0; 155 pgoodFault = 0; 156 psKillFault = 0; 157 ps12VcsFault = 0; 158 psCS12VFault = 0; 159 faultLogged = false; 160 } 161 162 /** 163 * @brief Function to specifically clear VIN_UV/OFF fault(s). 164 * 165 * The PMBus HWMON device driver has various alarm "files" to read out of 166 * sysfs. Reading those files will indicate if various alarms are active or 167 * not, and then specifically clear those faults that go with that alarm. 168 * 169 * The VIN_UV fault, indicated in STATUS_INPUT, goes with in1_lcrit_alarm. 170 * When a VIN_UV fault occurs, the "Unit Off For Insufficient Input Voltage" 171 * may also be active. Reading in1_lcrit_alarm should clear both fault bits, 172 * resulting in the corresponding fault bits in STATUS_WORD also clearing. 173 * 174 * See: https://www.kernel.org/doc/html/latest/hwmon/pmbus.html 175 */ 176 void clearVinUVFault(); 177 178 /** 179 * Write PMBus CLEAR_FAULTS 180 * 181 * This function will be called in various situations in order to clear 182 * any fault status bits that may have been set, in order to start over 183 * with a clean state. Presence changes and power state changes will 184 * want to clear any faults logged. 185 */ 186 void clearFaults(); 187 188 /** 189 * @brief Adds properties to the inventory. 190 * 191 * Reads the values from the device and writes them to the 192 * associated power supply D-Bus inventory object. 193 * 194 * This needs to be done on startup, and each time the presence 195 * state changes. 196 * 197 * Properties added: 198 * - Serial Number 199 * - Part Number 200 * - CCIN (Customer Card Identification Number) - added as the Model 201 * - Firmware version 202 */ 203 void updateInventory(); 204 205 /** 206 * @brief Accessor function to indicate present status 207 */ 208 bool isPresent() const 209 { 210 return present; 211 } 212 213 /** 214 * @brief Returns the last read value from STATUS_WORD. 215 */ 216 uint64_t getStatusWord() const 217 { 218 return statusWord; 219 } 220 221 /** 222 * @brief Returns the last read value from STATUS_INPUT. 223 */ 224 uint64_t getStatusInput() const 225 { 226 return statusInput; 227 } 228 229 /** 230 * @brief Returns the last read value from STATUS_MFR. 231 */ 232 uint64_t getMFRFault() const 233 { 234 return statusMFR; 235 } 236 237 /** 238 * @brief Returns the last read value from STATUS_CML. 239 */ 240 uint64_t getStatusCML() const 241 { 242 return statusCML; 243 } 244 245 /** 246 * @brief Returns the last read value from STATUS_VOUT. 247 */ 248 uint64_t getStatusVout() const 249 { 250 return statusVout; 251 } 252 253 /** 254 * @brief Returns the last value read from STATUS_IOUT. 255 */ 256 uint64_t getStatusIout() const 257 { 258 return statusIout; 259 } 260 261 /** 262 * @brief Returns the last value read from STATUS_FANS_1_2. 263 */ 264 uint64_t getStatusFans12() const 265 { 266 return statusFans12; 267 } 268 269 /** 270 * @brief Returns the last value read from STATUS_TEMPERATURE. 271 */ 272 uint64_t getStatusTemperature() const 273 { 274 return statusTemperature; 275 } 276 277 /** 278 * @brief Returns true if a fault was found. 279 */ 280 bool isFaulted() const 281 { 282 return (hasCommFault() || (vinUVFault >= DEGLITCH_LIMIT) || 283 (inputFault >= DEGLITCH_LIMIT) || 284 (voutOVFault >= DEGLITCH_LIMIT) || 285 (ioutOCFault >= DEGLITCH_LIMIT) || 286 (voutUVFault >= DEGLITCH_LIMIT) || 287 (fanFault >= DEGLITCH_LIMIT) || (tempFault >= DEGLITCH_LIMIT) || 288 (pgoodFault >= PGOOD_DEGLITCH_LIMIT) || 289 (mfrFault >= DEGLITCH_LIMIT)); 290 } 291 292 /** 293 * @brief Return whether a fault has been logged for this power supply 294 */ 295 bool isFaultLogged() const 296 { 297 return faultLogged; 298 } 299 300 /** 301 * @brief Called when a fault for this power supply has been logged. 302 */ 303 void setFaultLogged() 304 { 305 faultLogged = true; 306 } 307 308 /** 309 * @brief Returns true if INPUT fault occurred. 310 */ 311 bool hasInputFault() const 312 { 313 return (inputFault >= DEGLITCH_LIMIT); 314 } 315 316 /** 317 * @brief Returns true if MFRSPECIFIC occurred. 318 */ 319 bool hasMFRFault() const 320 { 321 return (mfrFault >= DEGLITCH_LIMIT); 322 } 323 324 /** 325 * @brief Returns true if VIN_UV_FAULT occurred. 326 */ 327 bool hasVINUVFault() const 328 { 329 return (vinUVFault >= DEGLITCH_LIMIT); 330 } 331 332 /** 333 * @brief Returns true if VOUT_OV_FAULT occurred. 334 */ 335 bool hasVoutOVFault() const 336 { 337 return (voutOVFault >= DEGLITCH_LIMIT); 338 } 339 340 /** 341 * @brief Returns true if IOUT_OC fault occurred (bit 4 STATUS_BYTE). 342 */ 343 bool hasIoutOCFault() const 344 { 345 return (ioutOCFault >= DEGLITCH_LIMIT); 346 } 347 348 /** 349 * @brief Returns true if VOUT_UV_FAULT occurred. 350 */ 351 bool hasVoutUVFault() const 352 { 353 return (voutUVFault >= DEGLITCH_LIMIT); 354 } 355 356 /** 357 *@brief Returns true if fan fault occurred. 358 */ 359 bool hasFanFault() const 360 { 361 return (fanFault >= DEGLITCH_LIMIT); 362 } 363 364 /** 365 * @brief Returns true if TEMPERATURE fault occurred. 366 */ 367 bool hasTempFault() const 368 { 369 return (tempFault >= DEGLITCH_LIMIT); 370 } 371 372 /** 373 * @brief Returns true if there is a PGood fault (PGOOD# inactive, or OFF 374 * bit on). 375 */ 376 bool hasPgoodFault() const 377 { 378 return (pgoodFault >= PGOOD_DEGLITCH_LIMIT); 379 } 380 381 /** 382 * @brief Return true if there is a PS_Kill fault. 383 */ 384 bool hasPSKillFault() const 385 { 386 return (psKillFault >= DEGLITCH_LIMIT); 387 } 388 389 /** 390 * @brief Returns true if there is a 12Vcs (standy power) fault. 391 */ 392 bool hasPS12VcsFault() const 393 { 394 return (ps12VcsFault >= DEGLITCH_LIMIT); 395 } 396 397 /** 398 * @brief Returns true if there is a 12V current-share fault. 399 */ 400 bool hasPSCS12VFault() const 401 { 402 return (psCS12VFault >= DEGLITCH_LIMIT); 403 } 404 405 /** 406 * @brief Returns true if an AC fault has occurred in the window of 407 * interest. 408 */ 409 bool hasACFault() const 410 { 411 return acFault != 0; 412 } 413 414 /** 415 * @brief Returns the device path 416 * 417 * This can be used for error call outs. 418 * Example: /sys/bus/i2c/devices/3-0068 419 */ 420 const std::string getDevicePath() const 421 { 422 return pmbusIntf->path(); 423 } 424 425 /** 426 * @brief Returns this power supply's inventory path. 427 * 428 * This can be used for error call outs. 429 * Example: 430 * /xyz/openbmc_project/inventory/system/chassis/motherboard/powersupply1 431 */ 432 const std::string& getInventoryPath() const 433 { 434 return inventoryPath; 435 } 436 437 /** 438 * @brief Returns the short name (last part of inventoryPath). 439 */ 440 const std::string& getShortName() const 441 { 442 return shortName; 443 } 444 445 /** 446 * @brief Returns the firmware revision version read from the power supply 447 */ 448 const std::string& getFWVersion() const 449 { 450 return fwVersion; 451 } 452 453 /** 454 * @brief Returns the model name of the power supply 455 */ 456 const std::string& getModelName() const 457 { 458 return modelName; 459 } 460 461 /** 462 * @brief Returns true if the number of failed reads exceeds limit 463 * TODO: or CML bit on. 464 */ 465 bool hasCommFault() const 466 { 467 return ((readFail >= LOG_LIMIT) || (cmlFault >= DEGLITCH_LIMIT)); 468 } 469 470 /** 471 * @brief Reads the pmbus input voltage and returns that actual voltage 472 * reading and the calculated input voltage based on thresholds. 473 * @param[out] actualInputVoltage - The actual voltage reading, in Volts. 474 * @param[out] inputVoltage - A rounded up/down value of the actual input 475 * voltage based on thresholds, in Volts. 476 */ 477 void getInputVoltage(double& actualInputVoltage, int& inputVoltage) const; 478 479 /** 480 * @brief Check if the PS is considered to be available or not 481 * 482 * It is unavailable if any of: 483 * - not present 484 * - input fault active 485 * - Vin UV fault active 486 * - PS KILL fault active 487 * - Iout OC fault active 488 * 489 * Other faults will, through creating error logs with callouts, already 490 * be setting the Functional property to false. 491 * 492 * On changes, the Available property is updated in the inventory. 493 */ 494 void checkAvailability(); 495 496 /** 497 * @brief Returns true when INPUT_HISTORY sync is required. 498 */ 499 bool isSyncHistoryRequired() const 500 { 501 return syncHistoryRequired; 502 } 503 504 /** 505 * @brief Clears the indicator that sync required for INPUT_HISTORY. 506 * 507 * Sets variable to false to indicate that the sync is no longer required. 508 * This can be used after the PSUManager has reacted to the need for the 509 * INPUT_HISTORY data to be synchronized. 510 */ 511 void clearSyncHistoryRequired() 512 { 513 syncHistoryRequired = false; 514 } 515 516 /** 517 * @brief Puts the input voltage rating on D-Bus. 518 * 519 * The rating is like 0, 110, 220. 520 */ 521 void setInputVoltageRating(); 522 523 /** 524 * @brief Returns the peak input power value if there is one, 525 * otherwise std::nullopt. 526 */ 527 std::optional<double> getPeakInputPower() const 528 { 529 std::optional<double> value; 530 if (peakInputPowerSensor) 531 { 532 value = peakInputPowerSensor->value(); 533 } 534 return value; 535 } 536 537 /** 538 * @brief Converts a Linear Format power number to an integer 539 * 540 * The PMBus spec describes a 2 byte Linear Format 541 * number that is composed of an exponent and mantissa 542 * in two's complement notation. 543 * 544 * Value = Mantissa * 2**Exponent 545 * 546 * @return double - The converted value 547 */ 548 static double linearToInteger(uint16_t data); 549 550 /** 551 * @brief Retrieve device driver name 552 */ 553 const std::string& getDriverName() const 554 { 555 return driverName; 556 } 557 558 /** 559 * @brief Set device driver name 560 * @param[in] newDriver - device driver name. 561 */ 562 void setDriverName(const std::string& newDriver) 563 { 564 driverName = newDriver; 565 } 566 567 private: 568 /** 569 * @brief Examine STATUS_WORD for CML (communication, memory, logic fault). 570 */ 571 void analyzeCMLFault(); 572 573 /** 574 * @brief Examine STATUS_WORD for INPUT bit on. 575 * 576 * "An input voltage, input current, or input power fault or warning has 577 * occurred." 578 */ 579 void analyzeInputFault(); 580 581 /** 582 * @brief Examine STATUS_WORD for VOUT being set. 583 * 584 * If VOUT is on, "An output voltage fault or warning has occurred.", and 585 * VOUT_OV_FAULT is on, there is an output over-voltage fault. 586 */ 587 void analyzeVoutOVFault(); 588 589 /** 590 * @brief Examine STATUS_WORD value read for IOUT_OC_FAULT. 591 * 592 * "An output overcurrent fault has occurred." If it is on, and fault not 593 * set, trace STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_IOUT values. 594 */ 595 void analyzeIoutOCFault(); 596 597 /** 598 * @brief Examines STATUS_WORD value read to see if there is a UV fault. 599 * 600 * Checks if the VOUT bit is on, indicating "An output voltage fault or 601 * warning has occurred", if it is on, but VOUT_OV_FAULT is off, it is 602 * determined to be an indication of an output under-voltage fault. 603 */ 604 void analyzeVoutUVFault(); 605 606 /** 607 * @brief Examine STATUS_WORD for the fan fault/warning bit. 608 * 609 * If fanFault is not on, trace that the bit now came on, include 610 * STATUS_WORD, STATUS_MFR_SPECIFIC, and STATUS_FANS_1_2 values as well, to 611 * help with understanding what may have caused it to be set. 612 */ 613 void analyzeFanFault(); 614 615 /** 616 * @brief Examine STATUS_WORD for temperature fault. 617 */ 618 void analyzeTemperatureFault(); 619 620 /** 621 * @brief Examine STATUS_WORD for pgood or unit off faults. 622 */ 623 void analyzePgoodFault(); 624 625 /** 626 * @brief Determine possible manufacturer-specific faults from bits in 627 * STATUS_MFR. 628 * 629 * The bits in the STATUS_MFR_SPECIFIC command response have "Manufacturer 630 * Defined" meanings. Determine which faults, if any, are present based on 631 * the power supply (device driver) type. 632 */ 633 void determineMFRFault(); 634 635 /** 636 * @brief Examine STATUS_WORD value read for MFRSPECIFIC bit on. 637 * 638 * "A manufacturer specific fault or warning has occurred." 639 * 640 * If it is on, call the determineMFRFault() helper function to examine the 641 * value read from STATUS_MFR_SPECIFIC. 642 */ 643 void analyzeMFRFault(); 644 645 /** 646 * @brief Analyzes the STATUS_WORD for a VIN_UV_FAULT indicator. 647 */ 648 void analyzeVinUVFault(); 649 650 /** 651 * @brief Given a full inventory path, returns the last node of the path as 652 * the "short name" 653 */ 654 std::string findShortName(const std::string& invPath) 655 { 656 const auto lastSlashPos = invPath.find_last_of('/'); 657 658 if ((lastSlashPos == std::string::npos) || 659 ((lastSlashPos + 1) == invPath.size())) 660 { 661 return invPath; 662 } 663 else 664 { 665 return invPath.substr(lastSlashPos + 1); 666 } 667 } 668 669 /** 670 * @brief Binds or unbinds the power supply device driver 671 * 672 * Called when a presence change is detected to either bind the device 673 * driver for the power supply when it is installed, or unbind the device 674 * driver when the power supply is removed. 675 * 676 * Note: 677 * Bind device when device present and i2cbus-i2caddr does not exist 678 * UnBind device when device not present and i2cbus-i2caddr exist 679 680 * Writes <device> to <path>/bind (or unbind) 681 * 682 * @param present - when true, will bind the device driver 683 * when false, will unbind the device driver 684 */ 685 void bindOrUnbindDriver(bool present); 686 687 /** 688 * @brief Updates the presence status by querying D-Bus 689 * 690 * The D-Bus inventory properties for this power supply will be read to 691 * determine if the power supply is present or not and update this 692 * object's present member variable to reflect current status. 693 **/ 694 void updatePresence(); 695 696 /** 697 * @brief Updates the power supply presence by reading the GPIO line. 698 */ 699 void updatePresenceGPIO(); 700 701 /** 702 * @brief Callback for inventory property changes 703 * 704 * Process change of Present property for power supply. 705 * 706 * This is used if we are watching the D-Bus properties instead of reading 707 * the GPIO presence line ourselves. 708 * 709 * @param[in] msg - Data associated with Present change signal 710 **/ 711 void inventoryChanged(sdbusplus::message_t& msg); 712 713 /** 714 * @brief Callback for inventory property added. 715 * 716 * Process add of the interface with the Present property for power supply. 717 * 718 * This is used if we are watching the D-Bus properties instead of reading 719 * the GPIO presence line ourselves. 720 * 721 * @param[in] msg - Data associated with Present add signal 722 **/ 723 void inventoryAdded(sdbusplus::message_t& msg); 724 725 /** 726 * @brief Reads the pmbus MFR_POUT_MAX value. 727 * 728 * "The MFR_POUT_MAX command sets or retrieves the maximum rated output 729 * power, in watts, that the unit is rated to supply." 730 * 731 * @return max_power_out value converted from string. 732 */ 733 auto getMaxPowerOut() const; 734 735 /** 736 * @brief Reads a VPD value from PMBus, correct size, and contents. 737 * 738 * If the VPD data read is not the passed in size, resize and fill with 739 * spaces. If the data contains a non-alphanumeric value, replace any of 740 * those values with spaces. 741 * 742 * @param[in] vpdName - The name of the sysfs "file" to read data from. 743 * @param[in] type - The HWMON file type to read from. 744 * @param[in] vpdSize - The expacted size of the data for this VPD/property 745 * 746 * @return A string containing the VPD data read, resized if necessary 747 */ 748 auto readVPDValue(const std::string& vpdName, 749 const phosphor::pmbus::Type& type, 750 const std::size_t& vpdSize); 751 752 /** 753 * @brief Retrieve PSU VPD keyword from D-Bus 754 * 755 * It retrieves PSU VPD keyword from D-Bus and assign the associated 756 * string to vpdStr. 757 * @param[in] keyword - The VPD search keyword 758 * @param[out] vpdStr - The VPD string associated with the keyword. 759 */ 760 void getPsuVpdFromDbus(const std::string& keyword, std::string& vpdStr); 761 762 /** 763 * @brief Creates the appropriate sensor D-Bus objects. 764 */ 765 void setupSensors(); 766 767 /** 768 * @brief Monitors sensor values and updates D-Bus. 769 * Called from analyze(). 770 */ 771 void monitorSensors(); 772 773 /** 774 * @brief Creates the peak input power sensor D-Bus object 775 * if the PS supports it. 776 */ 777 void setupInputPowerPeakSensor(); 778 779 /** 780 * @brief Monitors the peak input power sensor 781 */ 782 void monitorPeakInputPowerSensor(); 783 784 /** 785 * @brief Sets any sensor objects to Available = false on D-Bus. 786 */ 787 void setSensorsNotAvailable(); 788 789 /** 790 * @brief Returns the associations to create for a sensor on this 791 * power supply. 792 */ 793 std::vector<AssociationTuple> getSensorAssociations(); 794 795 /** 796 * @brief systemd bus member 797 */ 798 sdbusplus::bus_t& bus; 799 800 /** 801 * @brief D-Bus path to use for this power supply's inventory status. 802 **/ 803 std::string inventoryPath; 804 805 /** 806 * @brief The file system path used for binding the device driver. 807 */ 808 std::filesystem::path bindPath; 809 810 /** 811 * @brief Get the power on status of the psu manager class. 812 * 813 * This is a callback method used to get the power on status of the psu 814 * manager class. 815 */ 816 std::function<bool()> isPowerOn; 817 818 /** 819 * @brief Set to true when INPUT_HISTORY sync is required. 820 * 821 * A power supply will need to synchronize its INPUT_HISTORY data with the 822 * other power supplies installed in the system when it goes from missing to 823 * present. 824 */ 825 bool syncHistoryRequired{false}; 826 827 /** 828 * @brief Store the short name to avoid string processing. 829 * 830 * The short name will be something like powersupply1, the last part of the 831 * inventoryPath. 832 */ 833 std::string shortName; 834 835 /** 836 * @brief The libgpiod object for monitoring PSU presence 837 */ 838 std::unique_ptr<GPIOInterfaceBase> presenceGPIO = nullptr; 839 840 /** 841 * @brief True if the power supply is present. 842 */ 843 bool present = false; 844 845 /** 846 * @brief Power supply model name. 847 */ 848 std::string modelName; 849 850 /** 851 * @brief D-Bus match variable used to subscribe to Present property 852 * changes. 853 **/ 854 std::unique_ptr<sdbusplus::bus::match_t> presentMatch; 855 856 /** 857 * @brief D-Bus match variable used to subscribe for Present property 858 * interface added. 859 */ 860 std::unique_ptr<sdbusplus::bus::match_t> presentAddedMatch; 861 862 /** 863 * @brief Pointer to the PMBus interface 864 * 865 * Used to read or write to/from PMBus power supply devices. 866 */ 867 std::unique_ptr<phosphor::pmbus::PMBusBase> pmbusIntf = nullptr; 868 869 /** 870 * @brief Stored copy of the firmware version/revision string 871 */ 872 std::string fwVersion; 873 874 /** 875 * @brief The string to pass in for binding the device driver. 876 */ 877 std::string bindDevice; 878 879 /** 880 * @brief The result of the most recent availability check 881 * 882 * Saved on the object so changes can be detected. 883 */ 884 bool available = false; 885 886 /** 887 * @brief Will be updated to the latest/lastvalue read from STATUS_WORD. 888 */ 889 uint64_t statusWord = 0; 890 891 /** 892 * @brief Will be set to the last read value of STATUS_WORD. 893 */ 894 uint64_t statusWordOld = 0; 895 896 /** 897 * @brief Will be updated to the latest/lastvalue read from STATUS_INPUT. 898 */ 899 uint64_t statusInput = 0; 900 901 /** 902 * @brief Will be updated to the latest/lastvalue read from STATUS_MFR. 903 */ 904 uint64_t statusMFR = 0; 905 906 /** 907 * @brief Will be updated to the latest/last value read from STATUS_CML. 908 */ 909 uint64_t statusCML = 0; 910 911 /** 912 * @brief Will be updated to the latest/last value read from STATUS_VOUT. 913 */ 914 uint64_t statusVout = 0; 915 916 /** 917 * @brief Will be updated to the latest/last value read from STATUS_IOUT. 918 */ 919 uint64_t statusIout = 0; 920 921 /** 922 * @brief Will be updated to the latest/last value read from 923 * STATUS_FANS_1_2. 924 */ 925 uint64_t statusFans12 = 0; 926 927 /** 928 * @brief Will be updated to the latest/last value read from 929 * STATUS_TEMPERATURE. 930 */ 931 uint64_t statusTemperature = 0; 932 933 /** 934 * @brief Will be updated with latest converted value read from READ_VIN 935 */ 936 int inputVoltage = phosphor::pmbus::in_input::VIN_VOLTAGE_0; 937 938 /** 939 * @brief Will be updated with the actual voltage last read from READ_VIN 940 */ 941 double actualInputVoltage = 0; 942 943 /** 944 * @brief True if an error for a fault has already been logged. 945 */ 946 bool faultLogged = false; 947 948 /** 949 * @brief Incremented if bit 1 of STATUS_WORD low byte is on. 950 * 951 * Considered faulted if reaches DEGLITCH_LIMIT. 952 */ 953 size_t cmlFault = 0; 954 955 /** 956 * @brief Incremented if bit 5 of STATUS_WORD high byte is on. 957 * 958 * Considered faulted if reaches DEGLITCH_LIMIT. 959 */ 960 size_t inputFault = 0; 961 962 /** 963 * @brief Incremented if bit 4 of STATUS_WORD high byte is on. 964 * 965 * Considered faulted if reaches DEGLITCH_LIMIT. 966 */ 967 size_t mfrFault = 0; 968 969 /** 970 * @brief Incremented if bit 3 of STATUS_WORD low byte is on. 971 * 972 * Considered faulted if reaches DEGLITCH_LIMIT. 973 */ 974 size_t vinUVFault = 0; 975 976 /** 977 * @brief Incremented if bit 5 of STATUS_WORD low byte is on. 978 * 979 * Considered faulted if reaches DEGLITCH_LIMIT. 980 */ 981 size_t voutOVFault = 0; 982 983 /** 984 * @brief Incremented if bit 4 of STATUS_WORD low byte is on. 985 * 986 * Considered faulted if reaches DEGLITCH_LIMIT. 987 */ 988 size_t ioutOCFault = 0; 989 990 /** 991 * @brief Incremented if bit 7 of STATUS_WORD high byte is on and bit 5 992 * (VOUT_OV) of low byte is off. 993 * 994 * Considered faulted if reaches DEGLITCH_LIMIT. 995 */ 996 size_t voutUVFault = 0; 997 998 /** 999 * @brief Incremented if FANS fault/warn bit on in STATUS_WORD. 1000 * 1001 * Considered faulted if reaches DEGLITCH_LIMIT. 1002 */ 1003 size_t fanFault = 0; 1004 1005 /** 1006 * @brief Incremented if bit 2 of STATUS_WORD low byte is on. 1007 * 1008 * Considered faulted if reaches DEGLITCH_LIMIT. 1009 */ 1010 size_t tempFault = 0; 1011 1012 /** 1013 * @brief Incremented if bit 11 or 6 of STATUS_WORD is on. PGOOD# is 1014 * inactive, or the unit is off. 1015 * 1016 * Considered faulted if reaches DEGLITCH_LIMIT. 1017 */ 1018 size_t pgoodFault = 0; 1019 1020 /** 1021 * @brief Power Supply Kill fault. 1022 * 1023 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 1024 * bit 4 to indicate this fault. Considered faulted if it reaches 1025 * DEGLITCH_LIMIT. 1026 */ 1027 size_t psKillFault = 0; 1028 1029 /** 1030 * @brief Power Supply 12Vcs fault (standby power). 1031 * 1032 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 1033 * bit 6 to indicate this fault. Considered faulted if it reaches 1034 * DEGLITCH_LIMIT. 1035 */ 1036 size_t ps12VcsFault = 0; 1037 1038 /** 1039 * @brief Power Supply Current-Share fault in 12V domain. 1040 * 1041 * Incremented based on bits in STATUS_MFR_SPECIFIC. IBM power supplies use 1042 * bit 7 to indicate this fault. Considered faulted if it reaches 1043 * DEGLITCH_LIMIT. 1044 */ 1045 size_t psCS12VFault = 0; 1046 1047 /** 1048 * @brief Set to AC_FAULT_LIMIT when AC fault is detected, decremented when 1049 * AC fault has cleared. Effectively forms a timer since last AC failure. 1050 * Zero indicates being outside the window of concern. 1051 */ 1052 size_t acFault = 0; 1053 1054 /** 1055 * @brief Count of the number of read failures. 1056 */ 1057 size_t readFail = 0; 1058 1059 /** 1060 * @brief The D-Bus object for the input voltage rating 1061 * 1062 * It is updated at startup and power on. If a power supply is 1063 * added or removed after that, it does not need to be updated 1064 * again (though that could be done as a future improvement). 1065 */ 1066 std::unique_ptr<SensorObject> inputVoltageRatingIface; 1067 1068 /** 1069 * @brief The D-Bus object for the peak input power sensor. 1070 */ 1071 std::unique_ptr<PowerSensorObject> peakInputPowerSensor; 1072 1073 /** 1074 * @brief The device driver name 1075 */ 1076 std::string driverName; 1077 }; 1078 1079 } // namespace phosphor::power::psu 1080