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