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