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