1a9d39e30SKuiying Wang /* 2a9d39e30SKuiying Wang // Copyright (c) 2018 Intel Corporation 3a9d39e30SKuiying Wang // 4a9d39e30SKuiying Wang // Licensed under the Apache License, Version 2.0 (the "License"); 5a9d39e30SKuiying Wang // you may not use this file except in compliance with the License. 6a9d39e30SKuiying Wang // You may obtain a copy of the License at 7a9d39e30SKuiying Wang // 8a9d39e30SKuiying Wang // http://www.apache.org/licenses/LICENSE-2.0 9a9d39e30SKuiying Wang // 10a9d39e30SKuiying Wang // Unless required by applicable law or agreed to in writing, software 11a9d39e30SKuiying Wang // distributed under the License is distributed on an "AS IS" BASIS, 12a9d39e30SKuiying Wang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9d39e30SKuiying Wang // See the License for the specific language governing permissions and 14a9d39e30SKuiying Wang // limitations under the License. 15a9d39e30SKuiying Wang */ 16a9d39e30SKuiying Wang 17a9d39e30SKuiying Wang #pragma once 18a9d39e30SKuiying Wang #include "common.hpp" 19a9d39e30SKuiying Wang #include "gpio.hpp" 20*0d9377d2SPatrick Venture #include "xyz/openbmc_project/Chassis/Buttons/Reset/server.hpp" 21*0d9377d2SPatrick Venture #include "xyz/openbmc_project/Chassis/Common/error.hpp" 22*0d9377d2SPatrick Venture 23*0d9377d2SPatrick Venture #include <unistd.h> 24*0d9377d2SPatrick Venture 25*0d9377d2SPatrick Venture #include <phosphor-logging/elog-errors.hpp> 26a9d39e30SKuiying Wang 27a9d39e30SKuiying Wang const static constexpr char* RESET_BUTTON = "RESET_BUTTON"; 28a9d39e30SKuiying Wang 29a9d39e30SKuiying Wang struct ResetButton 30a9d39e30SKuiying Wang : sdbusplus::server::object::object< 31a9d39e30SKuiying Wang sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset> 32a9d39e30SKuiying Wang { 33a9d39e30SKuiying Wang 34*0d9377d2SPatrick Venture ResetButton(sdbusplus::bus::bus& bus, const char* path, EventPtr& event, 35a9d39e30SKuiying Wang sd_event_io_handler_t handler = ResetButton::EventHandler) : 36a9d39e30SKuiying Wang sdbusplus::server::object::object< 37a9d39e30SKuiying Wang sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset>( 38a9d39e30SKuiying Wang bus, path), 39a9d39e30SKuiying Wang fd(-1), bus(bus), event(event), callbackHandler(handler) 40a9d39e30SKuiying Wang { 41a9d39e30SKuiying Wang 42a9d39e30SKuiying Wang int ret = -1; 43a9d39e30SKuiying Wang 44a9d39e30SKuiying Wang // config gpio 45a9d39e30SKuiying Wang ret = ::configGpio(RESET_BUTTON, &fd, bus); 46a9d39e30SKuiying Wang if (ret < 0) 47a9d39e30SKuiying Wang { 48a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 49a9d39e30SKuiying Wang "RESET_BUTTON: failed to config GPIO"); 50*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 51*0d9377d2SPatrick Venture IOError(); 52a9d39e30SKuiying Wang } 53a9d39e30SKuiying Wang 54a9d39e30SKuiying Wang ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI, 55a9d39e30SKuiying Wang callbackHandler, this); 56a9d39e30SKuiying Wang if (ret < 0) 57a9d39e30SKuiying Wang { 58a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 59a9d39e30SKuiying Wang "RESET_BUTTON: failed to add to event loop"); 60a9d39e30SKuiying Wang ::closeGpio(fd); 61*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 62*0d9377d2SPatrick Venture IOError(); 63a9d39e30SKuiying Wang } 64a9d39e30SKuiying Wang } 65a9d39e30SKuiying Wang 66a9d39e30SKuiying Wang ~ResetButton() 67a9d39e30SKuiying Wang { 68a9d39e30SKuiying Wang ::closeGpio(fd); 69a9d39e30SKuiying Wang } 70a9d39e30SKuiying Wang 71a9d39e30SKuiying Wang void simPress() override; 72a9d39e30SKuiying Wang 73*0d9377d2SPatrick Venture static int EventHandler(sd_event_source* es, int fd, uint32_t revents, 74*0d9377d2SPatrick Venture void* userdata) 75a9d39e30SKuiying Wang { 76a9d39e30SKuiying Wang 77a9d39e30SKuiying Wang int n = -1; 78a9d39e30SKuiying Wang char buf = '0'; 79a9d39e30SKuiying Wang 80a9d39e30SKuiying Wang if (!userdata) 81a9d39e30SKuiying Wang { 82a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 83a9d39e30SKuiying Wang "RESET_BUTTON: userdata null!"); 84*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 85*0d9377d2SPatrick Venture IOError(); 86a9d39e30SKuiying Wang } 87a9d39e30SKuiying Wang 88a9d39e30SKuiying Wang ResetButton* resetButton = static_cast<ResetButton*>(userdata); 89a9d39e30SKuiying Wang 90a9d39e30SKuiying Wang if (!resetButton) 91a9d39e30SKuiying Wang { 92a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 93a9d39e30SKuiying Wang "RESET_BUTTON: null pointer!"); 94*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 95*0d9377d2SPatrick Venture IOError(); 96a9d39e30SKuiying Wang } 97a9d39e30SKuiying Wang 98a9d39e30SKuiying Wang n = ::lseek(fd, 0, SEEK_SET); 99a9d39e30SKuiying Wang 100a9d39e30SKuiying Wang if (n < 0) 101a9d39e30SKuiying Wang { 102a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 103a9d39e30SKuiying Wang "RESET_BUTTON: lseek error!"); 104*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 105*0d9377d2SPatrick Venture IOError(); 106a9d39e30SKuiying Wang } 107a9d39e30SKuiying Wang 108a9d39e30SKuiying Wang n = ::read(fd, &buf, sizeof(buf)); 109a9d39e30SKuiying Wang if (n < 0) 110a9d39e30SKuiying Wang { 111a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::ERR>( 112a9d39e30SKuiying Wang "RESET_BUTTON: read error!"); 113*0d9377d2SPatrick Venture throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 114*0d9377d2SPatrick Venture IOError(); 115a9d39e30SKuiying Wang } 116a9d39e30SKuiying Wang 117a9d39e30SKuiying Wang if (buf == '0') 118a9d39e30SKuiying Wang { 119a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::DEBUG>( 120a9d39e30SKuiying Wang "RESET_BUTTON: pressed"); 121a9d39e30SKuiying Wang // emit pressed signal 122a9d39e30SKuiying Wang resetButton->pressed(); 123a9d39e30SKuiying Wang } 124a9d39e30SKuiying Wang else 125a9d39e30SKuiying Wang { 126a9d39e30SKuiying Wang phosphor::logging::log<phosphor::logging::level::DEBUG>( 127a9d39e30SKuiying Wang "RESET_BUTTON: released"); 128a9d39e30SKuiying Wang // released 129a9d39e30SKuiying Wang resetButton->released(); 130a9d39e30SKuiying Wang } 131a9d39e30SKuiying Wang 132a9d39e30SKuiying Wang return 0; 133a9d39e30SKuiying Wang } 134a9d39e30SKuiying Wang 135a9d39e30SKuiying Wang private: 136a9d39e30SKuiying Wang int fd; 137a9d39e30SKuiying Wang sdbusplus::bus::bus& bus; 138a9d39e30SKuiying Wang EventPtr& event; 139a9d39e30SKuiying Wang sd_event_io_handler_t callbackHandler; 140a9d39e30SKuiying Wang }; 141