blob: 37e5666e1e138cf1754bfee5910140efef42d7e9 [file] [log] [blame]
Brandon Wymanaed1f752019-11-25 18:10:52 -06001#include "power_supply.hpp"
2
3#include "types.hpp"
Brandon Wyman3f1242f2020-01-28 13:11:25 -06004#include "util.hpp"
Brandon Wymanaed1f752019-11-25 18:10:52 -06005
Brandon Wyman3f1242f2020-01-28 13:11:25 -06006#include <xyz/openbmc_project/Common/Device/error.hpp>
7
8namespace phosphor::power::psu
Brandon Wymanaed1f752019-11-25 18:10:52 -06009{
10
11using namespace phosphor::logging;
Brandon Wyman3f1242f2020-01-28 13:11:25 -060012using namespace sdbusplus::xyz::openbmc_project::Common::Device::Error;
Brandon Wymanaed1f752019-11-25 18:10:52 -060013
14void PowerSupply::updatePresence()
15{
16 try
17 {
Brandon Wyman3f1242f2020-01-28 13:11:25 -060018 present = getPresence(bus, inventoryPath);
Brandon Wymanaed1f752019-11-25 18:10:52 -060019 }
20 catch (const sdbusplus::exception::SdBusError& e)
21 {
22 // Relying on property change or interface added to retry.
23 // Log an informational trace to the journal.
24 log<level::INFO>("D-Bus property access failure exception");
25 }
26}
27
Brandon Wyman3f1242f2020-01-28 13:11:25 -060028void PowerSupply::analyze()
29{
30 using namespace phosphor::pmbus;
31
32 if (present)
33 {
34 try
35 {
36 auto statusWord{pmbusIntf->read(STATUS_WORD, Type::Debug)};
37
38 if (statusWord)
39 {
40 if (statusWord & status_word::INPUT_FAULT_WARN)
41 {
42 if (!inputFault)
43 {
44 log<level::INFO>(
45 "INPUT fault",
46 entry("STATUS_WORD=0x%04X",
47 static_cast<uint16_t>(statusWord)));
48 }
49
50 faultFound = true;
51 inputFault = true;
52 }
53
54 if (statusWord & status_word::MFR_SPECIFIC_FAULT)
55 {
56 if (!mfrFault)
57 {
58 log<level::INFO>(
59 "MFRSPECIFIC fault",
60 entry("STATUS_WORD=0x%04X",
61 static_cast<uint16_t>(statusWord)));
62 }
63 faultFound = true;
64 mfrFault = true;
65 }
66
67 if (statusWord & status_word::VIN_UV_FAULT)
68 {
69 if (!vinUVFault)
70 {
71 log<level::INFO>(
72 "VIN_UV fault",
73 entry("STATUS_WORD=0x%04X",
74 static_cast<uint16_t>(statusWord)));
75 }
76
77 faultFound = true;
78 vinUVFault = true;
79 }
80 }
81 else
82 {
83 faultFound = false;
84 inputFault = false;
85 mfrFault = false;
86 vinUVFault = false;
87 }
88 }
89 catch (ReadFailure& e)
90 {
91 phosphor::logging::commit<ReadFailure>();
92 }
93 }
94}
95
Brandon Wyman3c208462020-05-13 16:25:58 -050096void PowerSupply::clearFaults()
97{
98 faultFound = false;
99 inputFault = false;
100 mfrFault = false;
101 vinUVFault = false;
102
103 // The PMBus device driver does not allow for writing CLEAR_FAULTS
104 // directly. However, the pmbus hwmon device driver code will send a
105 // CLEAR_FAULTS after reading from any of the hwmon "files" in sysfs, so
106 // reading in1_input should result in clearing the fault bits in
107 // STATUS_BYTE/STATUS_WORD.
108 // I do not care what the return value is.
109 try
110 {
111 static_cast<void>(
112 pmbusIntf->read("in1_input", phosphor::pmbus::Type::Hwmon));
113 }
114 catch (ReadFailure& e)
115 {
116 // Since I do not care what the return value is, I really do not
117 // care much if it gets a ReadFailure either. However, this should not
118 // prevent the application from continuing to run, so catching the read
119 // failure.
120 }
121}
122
Brandon Wymanaed1f752019-11-25 18:10:52 -0600123void PowerSupply::inventoryChanged(sdbusplus::message::message& msg)
124{
125 std::string msgSensor;
Patrick Williamsabe49412020-05-13 17:59:47 -0500126 std::map<std::string, std::variant<uint32_t, bool>> msgData;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600127 msg.read(msgSensor, msgData);
128
129 // Check if it was the Present property that changed.
130 auto valPropMap = msgData.find(PRESENT_PROP);
131 if (valPropMap != msgData.end())
132 {
133 if (std::get<bool>(valPropMap->second))
134 {
135 present = true;
136 clearFaults();
137 }
138 else
139 {
140 present = false;
141
142 // Clear out the now outdated inventory properties
143 updateInventory();
144 }
145 }
146}
147
Brandon Wyman3f1242f2020-01-28 13:11:25 -0600148} // namespace phosphor::power::psu