diff options
author | Yong Li <yong.b.li@linux.intel.com> | 2018-05-02 12:52:35 +0300 |
---|---|---|
committer | The Jenkins Build Agent <jenkins@openbmc-staging.jf.intel.com> | 2018-05-04 00:05:23 +0300 |
commit | 08abc3d5a84e45f713e036c4bf050eb8bdbee913 (patch) | |
tree | 98894559f094b1b82011932b0945e5de1d1459db /services | |
parent | da6a71d6a0d061d9ef5195b683506794a8300980 (diff) | |
download | provingground-08abc3d5a84e45f713e036c4bf050eb8bdbee913.tar.xz |
Add power on/off support
Implement power on/off logic by using gpio/i2c control
Change-Id: Idfde9507749fe9661509e84890c1720a908fb35f
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Diffstat (limited to 'services')
-rw-r--r-- | services/chassis/Buttons/CMakeLists.txt | 4 | ||||
-rw-r--r-- | services/chassis/CMakeLists.txt | 2 | ||||
-rw-r--r-- | services/chassis/Gpio/src/Gpio.cpp | 10 | ||||
-rw-r--r-- | services/chassis/I2c/.clang-format | 85 | ||||
-rw-r--r-- | services/chassis/I2c/CMakeLists.txt | 14 | ||||
-rw-r--r-- | services/chassis/I2c/inc/I2c.hpp | 4 | ||||
-rw-r--r-- | services/chassis/I2c/src/I2c.cpp | 83 | ||||
-rw-r--r-- | services/chassis/PowerControl/CMakeLists.txt | 6 | ||||
-rw-r--r-- | services/chassis/PowerControl/inc/PowerControl.hpp | 108 | ||||
-rw-r--r-- | services/chassis/PowerControl/src/PowerControl.cpp | 87 | ||||
-rw-r--r-- | services/chassis/PowerControl/src/main.cpp | 13 | ||||
-rw-r--r-- | services/chassis/PowerControl/src/timer.cpp | 192 |
12 files changed, 466 insertions, 142 deletions
diff --git a/services/chassis/Buttons/CMakeLists.txt b/services/chassis/Buttons/CMakeLists.txt index 8ce6728..a26c637 100644 --- a/services/chassis/Buttons/CMakeLists.txt +++ b/services/chassis/Buttons/CMakeLists.txt @@ -17,9 +17,9 @@ set(POWER_DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Buttons.Power") set(RESET_DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Buttons/Reset") set(RESET_DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Buttons.Reset") -add_definitions(-DPOWER_DBUS_OBJECT_NAME="/${POWER_DBUS_OBJECT_NAME}") +add_definitions(-DPOWER_DBUS_OBJECT_NAME="/${POWER_DBUS_OBJECT_NAME}0") -add_definitions(-DRESET_DBUS_OBJECT_NAME="/${RESET_DBUS_OBJECT_NAME}") +add_definitions(-DRESET_DBUS_OBJECT_NAME="/${RESET_DBUS_OBJECT_NAME}0") set(SRC_FILES src/PowerButton.cpp diff --git a/services/chassis/CMakeLists.txt b/services/chassis/CMakeLists.txt index 2325c81..f46dc63 100644 --- a/services/chassis/CMakeLists.txt +++ b/services/chassis/CMakeLists.txt @@ -3,8 +3,10 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Gpio/inc) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/I2c/inc) add_subdirectory(Gpio) +add_subdirectory(I2c) add_subdirectory(Buttons) add_subdirectory(ChassisControl) add_subdirectory(PowerControl) diff --git a/services/chassis/Gpio/src/Gpio.cpp b/services/chassis/Gpio/src/Gpio.cpp index ef1490c..3d74d96 100644 --- a/services/chassis/Gpio/src/Gpio.cpp +++ b/services/chassis/Gpio/src/Gpio.cpp @@ -1,13 +1,7 @@ #include <experimental/filesystem> #include <fcntl.h> #include <fstream> -#include <iostream> #include <phosphor-logging/elog-errors.hpp> -#include <phosphor-logging/elog.hpp> -#include <phosphor-logging/log.hpp> -#include <sys/stat.h> -#include <sys/types.h> -#include <systemd/sd-event.h> #include <unistd.h> #include <xyz/openbmc_project/Common/error.hpp> #include "Gpio.hpp" @@ -60,7 +54,9 @@ int configGpio(const char *gpioName, int *fd, sdbusplus::bus::bus &bus) if (std::experimental::filesystem::exists(fullPath)) { - phosphor::logging::log<phosphor::logging::level::INFO>("GPIO exported"); + phosphor::logging::log<phosphor::logging::level::INFO>( + "GPIO exported", + phosphor::logging::entry("PATH=%s", devPath.c_str())); } else { diff --git a/services/chassis/I2c/.clang-format b/services/chassis/I2c/.clang-format new file mode 100644 index 0000000..bbc1bb1 --- /dev/null +++ b/services/chassis/I2c/.clang-format @@ -0,0 +1,85 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/services/chassis/I2c/CMakeLists.txt b/services/chassis/I2c/CMakeLists.txt new file mode 100644 index 0000000..4d950db --- /dev/null +++ b/services/chassis/I2c/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR) +project(chassisi2c CXX) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include(GNUInstallDirs) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) + +add_library(${PROJECT_NAME} SHARED src/I2c.cpp) + +set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "0.1.0") +set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION "0") + +install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/services/chassis/I2c/inc/I2c.hpp b/services/chassis/I2c/inc/I2c.hpp new file mode 100644 index 0000000..6298786 --- /dev/null +++ b/services/chassis/I2c/inc/I2c.hpp @@ -0,0 +1,4 @@ +#pragma once +#include <cstdint> +#include <linux/i2c-dev-user.h> +int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value);
\ No newline at end of file diff --git a/services/chassis/I2c/src/I2c.cpp b/services/chassis/I2c/src/I2c.cpp new file mode 100644 index 0000000..315e35d --- /dev/null +++ b/services/chassis/I2c/src/I2c.cpp @@ -0,0 +1,83 @@ +#include <experimental/filesystem> +#include <fcntl.h> +#include <phosphor-logging/elog-errors.hpp> +#include <unistd.h> +#include <xyz/openbmc_project/Common/error.hpp> +#include "I2c.hpp" + +int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value) +{ + unsigned long funcs; + std::string devPath = "/dev/i2c-" + std::to_string(bus); + std::experimental::filesystem::path fullPath(devPath); + + if (!std::experimental::filesystem::exists(fullPath)) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "i2c bus des not exist!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + return -1; + } + + int fd = ::open(devPath.c_str(), O_RDWR); + if (fd < 0) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error in open!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + return -1; + } + + if (::ioctl(fd, I2C_FUNCS, &funcs) < 0) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error in I2C_FUNCS!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + + ::close(fd); + return -1; + } + + if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) + { + + phosphor::logging::log<phosphor::logging::level::ERR>( + "i2c bus des not support write!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + ::close(fd); + return -1; + } + + if (::ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error in I2C_SLAVE_FORCE!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + ::close(fd); + return -1; + } + + if (::i2c_smbus_write_byte_data(fd, regAddr, value) < 0) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Error in i2c write!", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=%d", slaveAddr)); + ::close(fd); + return -1; + } + + phosphor::logging::log<phosphor::logging::level::DEBUG>( + "i2cset successfully", + phosphor::logging::entry("PATH=%s", devPath.c_str()), + phosphor::logging::entry("slaveAddr=0x%x", slaveAddr), + phosphor::logging::entry("regAddr=0x%x", regAddr), + phosphor::logging::entry("value=0x%x", value)); + ::close(fd); + return 0; +}
\ No newline at end of file diff --git a/services/chassis/PowerControl/CMakeLists.txt b/services/chassis/PowerControl/CMakeLists.txt index 24d1cd9..4f08070 100644 --- a/services/chassis/PowerControl/CMakeLists.txt +++ b/services/chassis/PowerControl/CMakeLists.txt @@ -13,7 +13,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Control/Power") set(DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Control.Power") -add_definitions(-DDBUS_OBJECT_NAME="/${DBUS_OBJECT_NAME}") +add_definitions(-DDBUS_OBJECT_NAME="/${DBUS_OBJECT_NAME}0") add_definitions(-DDBUS_INTF_NAME="${DBUS_INTF_NAME}") set(SRC_FILES src/PowerControl.cpp @@ -90,8 +90,8 @@ set_source_files_properties( PROPERTIES GENERATED TRUE) add_executable(${PROJECT_NAME} ${SRC_FILES} ${GENERATED_SRC_FILES}) -target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES}) -target_link_libraries(${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES} gpio chassisi2c) +target_link_libraries(${PROJECT_NAME} "${SDBUSPLUSPLUS_LIBRARIES} -lstdc++fs") target_link_libraries(${PROJECT_NAME} ${DBUSINTERFACE_LIBRARIES}) install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/services/chassis/PowerControl/inc/PowerControl.hpp b/services/chassis/PowerControl/inc/PowerControl.hpp index c7ccfb9..cfaa3e7 100644 --- a/services/chassis/PowerControl/inc/PowerControl.hpp +++ b/services/chassis/PowerControl/inc/PowerControl.hpp @@ -1,33 +1,74 @@ #pragma once +#include <unistd.h> #include <phosphor-logging/elog-errors.hpp> -#include <phosphor-logging/elog.hpp> -#include <phosphor-logging/log.hpp> #include <xyz/openbmc_project/Chassis/Control/Power/error.hpp> #include <xyz/openbmc_project/Chassis/Control/Power/server.hpp> #include <xyz/openbmc_project/Common/error.hpp> -#include <iostream> +#include "Gpio.hpp" +#include "I2c.hpp" #include "timer.hpp" static constexpr size_t POLLING_INTERVAL_MS = 500; + +const static constexpr char* PGOOD_PIN = "PGOOD"; +const static constexpr char* POWER_UP_PIN = "POWER_UP_PIN"; + +const static constexpr size_t PCH_DEVICE_BUS_ADDRESS = 3; +const static constexpr size_t PCH_DEVICE_SLAVE_ADDRESS = 0x44; +const static constexpr size_t PCH_CMD_REGISTER = 0; +const static constexpr size_t PCH_POWER_DOWN_CMD = 0x02; + +const static constexpr size_t POWER_ON_PULSE_TIME_MS = 200; +const static constexpr size_t POWER_OFF_PULSE_TIME_MS = 4000; + using pwr_control = sdbusplus::xyz::openbmc_project::Chassis::Control::server::Power; struct PowerControl : sdbusplus::server::object_t<pwr_control> { PowerControl(sdbusplus::bus::bus& bus, const char* path, - phosphor::watchdog::EventPtr event) + phosphor::watchdog::EventPtr event, + sd_event_io_handler_t handler = PowerControl::EventHandler) : sdbusplus::server::object_t<pwr_control>(bus, path), bus(bus), + callbackHandler(handler), timer(event, std::bind(&PowerControl::timeOutHandler, this)) { + int ret; + char buf; + + // config gpio + ret = configGpio(PGOOD_PIN, &pgood_fd, bus); + if (ret < 0) { + throw std::runtime_error("failed to config GPIO"); + return; + } + + ret = configGpio(POWER_UP_PIN, &power_up_fd, bus); + if (ret < 0) { + throw std::runtime_error("failed to config GPIO"); + closeGpio(pgood_fd); + return; + } + + ret = sd_event_add_io(event.get(), nullptr, pgood_fd, EPOLLPRI, + callbackHandler, this); + if (ret < 0) { + closeGpio(pgood_fd); + closeGpio(power_up_fd); + throw std::runtime_error("failed to add to event loop"); + } + timer.start(std::chrono::duration_cast<std::chrono::microseconds>( std::chrono::milliseconds(POLLING_INTERVAL_MS))); timer.setEnabled<std::true_type>(); phosphor::logging::log<phosphor::logging::level::DEBUG>("Enable timer"); } - void timeOutHandler() { - phosphor::logging::log<phosphor::logging::level::DEBUG>( - "timeOutHandler..."); + ~PowerControl() { + closeGpio(pgood_fd); + closeGpio(power_up_fd); + } + void timeOutHandler() { // TODO polling acpi status this->timer.start(std::chrono::duration_cast<std::chrono::microseconds>( @@ -35,11 +76,64 @@ struct PowerControl : sdbusplus::server::object_t<pwr_control> { this->timer.setEnabled<std::true_type>(); } + static int EventHandler(sd_event_source* es, int fd, uint32_t revents, + void* userdata) { + // For the first event, only set the initial status, do not emit signal + // since is it not triggered by the real gpio change + + static bool first_event = true; + int n; + char buf; + + PowerControl* powercontrol = static_cast<PowerControl*>(userdata); + + if (!powercontrol) { + phosphor::logging::log<phosphor::logging::level::ERR>("null pointer!"); + return -1; + } + + n = ::lseek(fd, 0, SEEK_SET); + if (n < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>("lseek error!"); + return n; + } + + n = ::read(fd, &buf, 1); + if (n < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>("read error!"); + return n; + } + + if (buf == '0') { + powercontrol->state(0); + powercontrol->pgood(0); + + if (first_event) { + first_event = false; + } else { + powercontrol->gotoSystemState(std::string("HOST_POWERED_OFF")); + } + } else { + powercontrol->state(1); + powercontrol->pgood(1); + if (first_event) { + first_event = false; + } else { + powercontrol->gotoSystemState(std::string("HOST_POWERED_ON")); + } + } + + return 0; + } + int32_t forcePowerOff() override; int32_t setPowerState(int32_t newState) override; int32_t getPowerState() override; private: + int power_up_fd; + int pgood_fd; phosphor::watchdog::Timer timer; sdbusplus::bus::bus& bus; + sd_event_io_handler_t callbackHandler; }; diff --git a/services/chassis/PowerControl/src/PowerControl.cpp b/services/chassis/PowerControl/src/PowerControl.cpp index b6bf5e1..3784c28 100644 --- a/services/chassis/PowerControl/src/PowerControl.cpp +++ b/services/chassis/PowerControl/src/PowerControl.cpp @@ -16,15 +16,94 @@ #include "PowerControl.hpp" int32_t PowerControl::forcePowerOff() { - // TODO - throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: - UnsupportedCommand(); + int ret = 0; + ret = i2cSet(PCH_DEVICE_BUS_ADDRESS, PCH_DEVICE_SLAVE_ADDRESS, + PCH_CMD_REGISTER, PCH_POWER_DOWN_CMD); + + if (ret < 0) { + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: + IOError(); + } return 0; } int32_t PowerControl::setPowerState(int32_t newState) { - // TODO + int ret = 0; + int count = 0; + char buf; + + phosphor::logging::log<phosphor::logging::level::DEBUG>( + "setPowerState", phosphor::logging::entry("newState=%d", newState)); + + if (state() == newState) { + phosphor::logging::log<phosphor::logging::level::DEBUG>( + "Same powerstate", phosphor::logging::entry("newState=%d", newState)); + } + + if (newState == 1) { + gotoSystemState(std::string("HOST_POWERING_ON")); + } else { + gotoSystemState(std::string("HOST_POWERING_OFF")); + } + state(newState); + + ret = ::lseek(power_up_fd, 0, SEEK_SET); + if (ret < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>("lseek error!"); + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: + IOError(); + return ret; + } + + buf = '0'; + ret = ::write(power_up_fd, &buf, 1); + if (ret < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>("write error!"); + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: + IOError(); + return ret; + } + + if (1 == newState) { // start power on + std::this_thread::sleep_for( + std::chrono::milliseconds(POWER_ON_PULSE_TIME_MS)); + } else { // start power off + std::this_thread::sleep_for( + std::chrono::milliseconds(POWER_OFF_PULSE_TIME_MS)); + } + + buf = '1'; + ret = ::write(power_up_fd, &buf, 1); + if (ret < 0) { + phosphor::logging::log<phosphor::logging::level::ERR>("write error!"); + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power::Error:: + IOError(); + return ret; + } + + if (0 == newState) { + // For power off, currently there is a known issue, the “long-press” power + // button cannot power off the host, a workaround is perform force power off + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + if (1 == pgood()) { // still on, force off! + phosphor::logging::log<phosphor::logging::level::DEBUG>( + "Perform force power off"); + count = 0; + do { + if (count++ > 5) { + phosphor::logging::log<phosphor::logging::level::ERR>( + "forcePowerOff error!"); + throw sdbusplus::xyz::openbmc_project::Chassis::Control::Power:: + Error::IOError(); + return ret; + } + ret = forcePowerOff(); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } while (ret != 0); + } + } + return 0; } diff --git a/services/chassis/PowerControl/src/main.cpp b/services/chassis/PowerControl/src/main.cpp index f9216d8..eb9c4cc 100644 --- a/services/chassis/PowerControl/src/main.cpp +++ b/services/chassis/PowerControl/src/main.cpp @@ -13,19 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. */ -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <systemd/sd-event.h> -#include <unistd.h> -#include <phosphor-logging/elog-errors.hpp> -#include <phosphor-logging/elog.hpp> -#include <phosphor-logging/log.hpp> -#include <xyz/openbmc_project/Common/error.hpp> -#include <chrono> -#include <experimental/filesystem> -#include <fstream> -#include <iostream> #include "PowerControl.hpp" int main(int argc, char* argv[]) { diff --git a/services/chassis/PowerControl/src/timer.cpp b/services/chassis/PowerControl/src/timer.cpp index f562f92..d20f646 100644 --- a/services/chassis/PowerControl/src/timer.cpp +++ b/services/chassis/PowerControl/src/timer.cpp @@ -13,137 +13,117 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <chrono> +#include "timer.hpp" #include <systemd/sd-event.h> -#include <phosphor-logging/log.hpp> -#include <phosphor-logging/elog.hpp> #include <phosphor-logging/elog-errors.hpp> +#include <phosphor-logging/elog.hpp> +#include <phosphor-logging/log.hpp> #include <xyz/openbmc_project/Common/error.hpp> -#include "timer.hpp" -namespace phosphor -{ -namespace watchdog -{ +#include <chrono> +namespace phosphor { +namespace watchdog { // For throwing exception using namespace phosphor::logging; -using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: - Error::InternalFailure; +using InternalFailure = + sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; // Initializes the timer object -void Timer::initialize() -{ - // This can not be called more than once. - if (eventSource.get()) - { - log<level::ERR>("Timer already initialized"); - elog<InternalFailure>(); - } - - // Add infinite expiration time - decltype(eventSource.get()) sourcePtr = nullptr; - auto r = sd_event_add_time(event.get(), - &sourcePtr, - CLOCK_MONOTONIC, // Time base - UINT64_MAX, // Expire time - way long time - 0, // Use default event accuracy - timeoutHandler, // Callback handler on timeout - this); // User data - eventSource.reset(sourcePtr); - - if (r < 0) - { - log<level::ERR>("Timer initialization failed"); - elog<InternalFailure>(); - } - - // Disable the timer for now - setEnabled<std::false_type>(); +void Timer::initialize() { + // This can not be called more than once. + if (eventSource.get()) { + log<level::ERR>("Timer already initialized"); + elog<InternalFailure>(); + } + + // Add infinite expiration time + decltype(eventSource.get()) sourcePtr = nullptr; + auto r = sd_event_add_time(event.get(), &sourcePtr, + CLOCK_MONOTONIC, // Time base + UINT64_MAX, // Expire time - way long time + 0, // Use default event accuracy + timeoutHandler, // Callback handler on timeout + this); // User data + eventSource.reset(sourcePtr); + + if (r < 0) { + log<level::ERR>("Timer initialization failed"); + elog<InternalFailure>(); + } + + // Disable the timer for now + setEnabled<std::false_type>(); } // callback handler on timeout -int Timer::timeoutHandler(sd_event_source* eventSource, - uint64_t usec, void* userData) -{ - using namespace phosphor::logging; - - log<level::INFO>("Timer Expired"); - - auto timer = static_cast<Timer*>(userData); - timer->expire = true; - - // Call an optional callback function - if(timer->userCallBack) - { - timer->userCallBack(); - } - return 0; +int Timer::timeoutHandler(sd_event_source* eventSource, uint64_t usec, + void* userData) { + using namespace phosphor::logging; + + auto timer = static_cast<Timer*>(userData); + timer->expire = true; + + // Call an optional callback function + if (timer->userCallBack) { + timer->userCallBack(); + } + return 0; } // Gets the time from steady_clock -std::chrono::microseconds Timer::getCurrentTime() -{ - using namespace std::chrono; - auto usec = steady_clock::now().time_since_epoch(); - return duration_cast<microseconds>(usec); +std::chrono::microseconds Timer::getCurrentTime() { + using namespace std::chrono; + auto usec = steady_clock::now().time_since_epoch(); + return duration_cast<microseconds>(usec); } // Sets the expiration time and arms the timer -void Timer::start(std::chrono::microseconds usec) -{ - using namespace std::chrono; - - // Get the current MONOTONIC time and add the delta - auto expireTime = getCurrentTime() + usec; - - // Set the time - auto r = sd_event_source_set_time(eventSource.get(), - expireTime.count()); - if (r < 0) - { - log<level::ERR>("Error setting the expiration time", - entry("MSEC=%llu",duration_cast<milliseconds>(usec).count())); - elog<InternalFailure>(); - } +void Timer::start(std::chrono::microseconds usec) { + using namespace std::chrono; + + // Get the current MONOTONIC time and add the delta + auto expireTime = getCurrentTime() + usec; + + // Set the time + auto r = sd_event_source_set_time(eventSource.get(), expireTime.count()); + if (r < 0) { + log<level::ERR>( + "Error setting the expiration time", + entry("MSEC=%llu", duration_cast<milliseconds>(usec).count())); + elog<InternalFailure>(); + } } // Returns current timer enablement type -int Timer::getEnabled() const -{ - int enabled{}; - auto r = sd_event_source_get_enabled(eventSource.get(), &enabled); - if (r < 0) - { - log<level::ERR>("Error geting current timer type enablement state"); - elog<InternalFailure>(); - } - return enabled; +int Timer::getEnabled() const { + int enabled{}; + auto r = sd_event_source_get_enabled(eventSource.get(), &enabled); + if (r < 0) { + log<level::ERR>("Error geting current timer type enablement state"); + elog<InternalFailure>(); + } + return enabled; } // Enables / disables the timer -void Timer::setEnabled(int type) -{ - auto r = sd_event_source_set_enabled(eventSource.get(), type); - if (r < 0) - { - log<level::ERR>("Error setting the timer type", - entry("TYPE=%d",type)); - elog<InternalFailure>(); - } +void Timer::setEnabled(int type) { + auto r = sd_event_source_set_enabled(eventSource.get(), type); + if (r < 0) { + log<level::ERR>("Error setting the timer type", entry("TYPE=%d", type)); + elog<InternalFailure>(); + } } // Returns time remaining before expiration -std::chrono::microseconds Timer::getRemaining() const -{ - uint64_t next = 0; - auto r = sd_event_source_get_time(eventSource.get(), &next); - if (r < 0) - { - log<level::ERR>("Error fetching remaining time to expire"); - elog<InternalFailure>(); - } - return std::chrono::microseconds(next); +std::chrono::microseconds Timer::getRemaining() const { + uint64_t next = 0; + auto r = sd_event_source_get_time(eventSource.get(), &next); + if (r < 0) { + log<level::ERR>("Error fetching remaining time to expire"); + elog<InternalFailure>(); + } + return std::chrono::microseconds(next); } -} // namespace watchdog -} // namespace phosphor +} // namespace watchdog +} // namespace phosphor |