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