blob: d1a80c2512f55da21e69079ecf58811de55edef3 [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 */
Matt Spinler45a054a2017-08-22 15:07:07 -050016#include "config.h"
Matt Spinlerf0f02b92018-10-25 16:12:43 -050017
Matt Spinlerf02daec2017-08-14 14:00:46 -050018#include "pgood_monitor.hpp"
Matt Spinlerf0f02b92018-10-25 16:12:43 -050019
20#include "elog-errors.hpp"
Matt Spinlerf02daec2017-08-14 14:00:46 -050021#include "utility.hpp"
22
Matt Spinlerf0f02b92018-10-25 16:12:43 -050023#include <org/open_power/Witherspoon/Fault/error.hpp>
Anwaar Hadi1f0193f2025-05-13 21:05:12 +000024#include <phosphor-logging/lg2.hpp>
Matt Spinlerf0f02b92018-10-25 16:12:43 -050025
Lei YUab093322019-10-09 16:43:22 +080026namespace phosphor
Matt Spinlerf02daec2017-08-14 14:00:46 -050027{
28namespace power
29{
30
31constexpr auto POWER_OBJ_PATH = "/org/openbmc/control/power0";
32constexpr auto POWER_INTERFACE = "org.openbmc.control.Power";
33
Brandon Wymane0eb45c2017-10-06 12:58:42 -050034using namespace sdbusplus::org::open_power::Witherspoon::Fault::Error;
Matt Spinlerf02daec2017-08-14 14:00:46 -050035
36bool PGOODMonitor::pgoodPending()
37{
38 bool pending = false;
39 int32_t state = 0;
40 int32_t pgood = 0;
41
Matt Spinlerf0f02b92018-10-25 16:12:43 -050042 auto service = util::getService(POWER_OBJ_PATH, POWER_INTERFACE, bus);
Matt Spinlerf02daec2017-08-14 14:00:46 -050043
Matt Spinlerf0f02b92018-10-25 16:12:43 -050044 util::getProperty<int32_t>(POWER_INTERFACE, "pgood", POWER_OBJ_PATH,
45 service, bus, pgood);
Matt Spinlerf02daec2017-08-14 14:00:46 -050046
Matt Spinlerf0f02b92018-10-25 16:12:43 -050047 // When state = 1, system was switched on
48 util::getProperty<int32_t>(POWER_INTERFACE, "state", POWER_OBJ_PATH,
49 service, bus, state);
Matt Spinlerf02daec2017-08-14 14:00:46 -050050
Matt Spinlerf0f02b92018-10-25 16:12:43 -050051 // On but no PGOOD
Matt Spinlerf02daec2017-08-14 14:00:46 -050052 if (state && !pgood)
53 {
54 pending = true;
55 }
56
57 return pending;
58}
59
Matt Spinlerf02daec2017-08-14 14:00:46 -050060void PGOODMonitor::analyze()
61{
Matt Spinlerf0f02b92018-10-25 16:12:43 -050062 // Timer callback.
63 // The timer expired before it was stopped.
64 // If PGOOD is still pending (it should be),
65 // then there is a real failure.
Matt Spinlerf02daec2017-08-14 14:00:46 -050066
67 if (pgoodPending())
68 {
Andy YF Wang40247cc2019-09-06 18:30:56 +080069#ifdef DEVICE_ACCESS
Matt Spinlerb2d72512017-08-22 09:07:01 -050070 device->onFailure();
Matt Spinler45a054a2017-08-22 15:07:07 -050071#endif
Anwaar Hadif8e8bc12025-06-05 21:08:06 +000072 phosphor::logging::report<PowerOnFailure>();
Matt Spinlerf02daec2017-08-14 14:00:46 -050073 }
74
Matt Spinlerf0f02b92018-10-25 16:12:43 -050075 // The pgood-wait service (with a longer timeout)
76 // will handle powering off the system.
William A. Kennington III1a0c9172018-10-18 17:57:49 -070077 timer.get_event().exit(EXIT_SUCCESS);
Matt Spinlerf02daec2017-08-14 14:00:46 -050078}
79
80void PGOODMonitor::propertyChanged()
81{
Matt Spinlerf0f02b92018-10-25 16:12:43 -050082 // Multiple properties could have changed here.
83 // Keep things simple and just recheck the important ones.
Matt Spinlerf02daec2017-08-14 14:00:46 -050084 if (!pgoodPending())
85 {
Matt Spinlerf0f02b92018-10-25 16:12:43 -050086 // PGOOD is on, or system is off, so we are done.
William A. Kennington III1a0c9172018-10-18 17:57:49 -070087 timer.get_event().exit(EXIT_SUCCESS);
Matt Spinlerf02daec2017-08-14 14:00:46 -050088 }
89}
90
91void PGOODMonitor::startListening()
92{
93 match = std::make_unique<sdbusplus::bus::match_t>(
Matt Spinlerf0f02b92018-10-25 16:12:43 -050094 bus,
95 sdbusplus::bus::match::rules::propertiesChanged(POWER_OBJ_PATH,
96 POWER_INTERFACE),
Brad Bishop11cb6722019-09-03 14:30:06 -040097 [this](auto&) { this->propertyChanged(); });
Matt Spinlerf02daec2017-08-14 14:00:46 -050098}
99
100int PGOODMonitor::run()
101{
102 try
103 {
104 startListening();
105
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500106 // If PGOOD came up before we got here, we're done.
107 // Otherwise if PGOOD doesn't get asserted before
108 // the timer expires, it's a failure.
Matt Spinlerf02daec2017-08-14 14:00:46 -0500109 if (!pgoodPending())
110 {
111 return EXIT_SUCCESS;
112 }
113
William A. Kennington III1a0c9172018-10-18 17:57:49 -0700114 return timer.get_event().loop();
Matt Spinlerf02daec2017-08-14 14:00:46 -0500115 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500116 catch (const std::exception& e)
Matt Spinlerf02daec2017-08-14 14:00:46 -0500117 {
Anwaar Hadi1f0193f2025-05-13 21:05:12 +0000118 lg2::error("Unexpected failure prevented PGOOD checking: {ERROR}",
119 "ERROR", e);
Matt Spinlerf02daec2017-08-14 14:00:46 -0500120 }
121
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500122 // Letting the service fail won't help anything, so don't do it.
Matt Spinlerf02daec2017-08-14 14:00:46 -0500123 return EXIT_SUCCESS;
124}
125
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500126} // namespace power
Lei YUab093322019-10-09 16:43:22 +0800127} // namespace phosphor