blob: b9995c6a6a2b376cb8cff17d9966ccbf188673bb [file] [log] [blame]
Matt Spinlerf02daec2017-08-14 14:00:46 -05001/**
2 * Copyright © 2017 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <phosphor-logging/log.hpp>
Brandon Wymane0eb45c2017-10-06 12:58:42 -050017#include <org/open_power/Witherspoon/Fault/error.hpp>
Matt Spinler45a054a2017-08-22 15:07:07 -050018#include "config.h"
Matt Spinlerf02daec2017-08-14 14:00:46 -050019#include "elog-errors.hpp"
20#include "pgood_monitor.hpp"
21#include "utility.hpp"
22
23namespace witherspoon
24{
25namespace power
26{
27
28constexpr auto POWER_OBJ_PATH = "/org/openbmc/control/power0";
29constexpr auto POWER_INTERFACE = "org.openbmc.control.Power";
30
31using namespace phosphor::logging;
Brandon Wymane0eb45c2017-10-06 12:58:42 -050032using namespace sdbusplus::org::open_power::Witherspoon::Fault::Error;
Matt Spinlerf02daec2017-08-14 14:00:46 -050033
34bool PGOODMonitor::pgoodPending()
35{
36 bool pending = false;
37 int32_t state = 0;
38 int32_t pgood = 0;
39
40 auto service = util::getService(POWER_OBJ_PATH,
41 POWER_INTERFACE,
42 bus);
43
44 util::getProperty<int32_t>(POWER_INTERFACE,
45 "pgood",
46 POWER_OBJ_PATH,
47 service,
48 bus,
49 pgood);
50
51 //When state = 1, system was switched on
52 util::getProperty<int32_t>(POWER_INTERFACE,
53 "state",
54 POWER_OBJ_PATH,
55 service,
56 bus,
57 state);
58
59 //On but no PGOOD
60 if (state && !pgood)
61 {
62 pending = true;
63 }
64
65 return pending;
66}
67
68
Matt Spinlerf02daec2017-08-14 14:00:46 -050069void PGOODMonitor::analyze()
70{
71 //Timer callback.
72 //The timer expired before it was stopped.
73 //If PGOOD is still pending (it should be),
74 //then there is a real failure.
75
76 if (pgoodPending())
77 {
Matt Spinler45a054a2017-08-22 15:07:07 -050078#ifdef UCD90160_DEVICE_ACCESS
Matt Spinlerb2d72512017-08-22 09:07:01 -050079 device->onFailure();
Matt Spinler45a054a2017-08-22 15:07:07 -050080#endif
Matt Spinlerf02daec2017-08-14 14:00:46 -050081 report<PowerOnFailure>();
82 }
83
84 //The pgood-wait service (with a longer timeout)
85 //will handle powering off the system.
William A. Kennington IIIe5a8b472018-10-18 00:40:04 -070086 event.exit(EXIT_SUCCESS);
Matt Spinlerf02daec2017-08-14 14:00:46 -050087}
88
89void PGOODMonitor::propertyChanged()
90{
91 //Multiple properties could have changed here.
92 //Keep things simple and just recheck the important ones.
93 if (!pgoodPending())
94 {
95 //PGOOD is on, or system is off, so we are done.
William A. Kennington IIIe5a8b472018-10-18 00:40:04 -070096 event.exit(EXIT_SUCCESS);
Matt Spinlerf02daec2017-08-14 14:00:46 -050097 }
98}
99
100void PGOODMonitor::startListening()
101{
102 match = std::make_unique<sdbusplus::bus::match_t>(
103 bus,
104 sdbusplus::bus::match::rules::propertiesChanged(
105 POWER_OBJ_PATH,
106 POWER_INTERFACE),
107 [this](auto& msg){this->propertyChanged();});
108}
109
110int PGOODMonitor::run()
111{
112 try
113 {
114 startListening();
115
116 //If PGOOD came up before we got here, we're done.
117 //Otherwise if PGOOD doesn't get asserted before
118 //the timer expires, it's a failure.
119 if (!pgoodPending())
120 {
121 return EXIT_SUCCESS;
122 }
123
124 timer.start(interval);
William A. Kennington IIIe5a8b472018-10-18 00:40:04 -0700125 return event.loop();
Matt Spinlerf02daec2017-08-14 14:00:46 -0500126 }
127 catch (std::exception& e)
128 {
129 log<level::ERR>(e.what());
130 log<level::ERR>("Unexpected failure prevented PGOOD checking");
131 }
132
133 //Letting the service fail won't help anything, so don't do it.
134 return EXIT_SUCCESS;
135}
136
137
138}
139}