From a091b418d9a3c07adb7f2d7719ed3976dd35ee3e Mon Sep 17 00:00:00 2001 From: Mike Choi Date: Mon, 16 Sep 2024 15:09:08 -0700 Subject: [PATCH] fan_service : Fan_service control logic to use either sysfs path or gpio, for detecting fan presence Summary: [FBOSS/Platform] fan_service : Fan_service control logic to use either sysfs path or gpio, for detecting fan presence Reviewed By: alandau, kimdo8736 Differential Revision: D62211922 fbshipit-source-id: d0fb8322da74a76ed47bf2e446096afeff88dddc --- cmake/PlatformFanService.cmake | 3 ++ fboss/platform/fan_service/BUCK | 4 +++ fboss/platform/fan_service/ControlLogic.cpp | 40 ++++++++++++++++----- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/cmake/PlatformFanService.cmake b/cmake/PlatformFanService.cmake index c8a38b9efe8d8..9b7db3618b773 100644 --- a/cmake/PlatformFanService.cmake +++ b/cmake/PlatformFanService.cmake @@ -41,6 +41,7 @@ target_link_libraries(fan_service_lib platform_name_lib platform_utils fan_service_config_types_cpp2 + gpiod_line sensor_service_cpp2 fan_service_cpp2 Folly::folly @@ -72,6 +73,8 @@ add_executable(fan_service_sw_test target_link_libraries(fan_service_sw_test fan_service_lib Folly::folly + ${LIBGPIOD} + gpiod_line ${GTEST} ${LIBGMOCK_LIBRARIES} ) diff --git a/fboss/platform/fan_service/BUCK b/fboss/platform/fan_service/BUCK index c9f13837f24f0..e836676810549 100644 --- a/fboss/platform/fan_service/BUCK +++ b/fboss/platform/fan_service/BUCK @@ -85,6 +85,7 @@ cpp_library( "//fboss/fsdb/if:fsdb_model", "//fboss/fsdb/if:fsdb_oper-cpp2-types", "//fboss/lib:common_file_utils", + "//fboss/lib:gpiod_line", "//fboss/platform/fan_service/if:fan_service-cpp2-services", "//fboss/platform/fan_service/if:fan_service-cpp2-types", "//fboss/platform/helpers:platform_utils", @@ -104,6 +105,9 @@ cpp_library( "//security/ca/lib:cert_path_picker", "//thrift/lib/cpp2/protocol:protocol", ], + exported_external_deps = [ + ("libgpiod", None, "gpiod"), + ], ) custom_unittest( diff --git a/fboss/platform/fan_service/ControlLogic.cpp b/fboss/platform/fan_service/ControlLogic.cpp index d701b2cefb27e..9a511615e546f 100644 --- a/fboss/platform/fan_service/ControlLogic.cpp +++ b/fboss/platform/fan_service/ControlLogic.cpp @@ -6,8 +6,10 @@ #include "fboss/platform/fan_service/ControlLogic.h" #include +#include #include "common/time/Time.h" +#include "fboss/lib/GpiodLine.h" #include "fboss/platform/fan_service/SensorData.h" #include "fboss/platform/fan_service/if/gen-cpp2/fan_service_config_constants.h" #include "fboss/platform/fan_service/if/gen-cpp2/fan_service_config_types.h" @@ -349,15 +351,35 @@ void ControlLogic::getOpticsUpdate() { bool ControlLogic::isFanPresentInDevice(const Fan& fan) { unsigned int readVal; bool readSuccessful = false; - try { - readVal = static_cast(pBsp_->readSysfs(*fan.presenceSysfsPath())); - readSuccessful = true; - } catch (std::exception&) { - XLOG(ERR) << "Failed to read sysfs " << *fan.presenceSysfsPath(); - } - auto fanPresent = (readSuccessful && readVal == *fan.fanPresentVal()); - if (!fanPresent) { - XLOG(INFO) << fmt::format("{}: is absent in the host", *fan.fanName()); + bool fanPresent = false; + if (fan.presenceSysfsPath()) { + try { + readVal = + static_cast(pBsp_->readSysfs(*fan.presenceSysfsPath())); + readSuccessful = true; + } catch (std::exception&) { + XLOG(ERR) << "Failed to read sysfs " << *fan.presenceSysfsPath(); + } + fanPresent = (readSuccessful && readVal == *fan.fanPresentVal()); + if (fanPresent) { + XLOG(INFO) << fmt::format( + "{}: is present in the host (through sysfs)", *fan.fanName()); + } else { + XLOG(INFO) << fmt::format( + "{}: is absent in the host (through sysfs)", *fan.fanName()); + } + } else if (fan.presenceGpio()) { + struct gpiod_chip* chip = + gpiod_chip_open(fan.presenceGpio()->path()->c_str()); + GpiodLine line(chip, *fan.presenceGpio()->lineIndex(), "gpioline"); + int16_t value = line.getValue(); + gpiod_chip_close(chip); + if (value == *fan.presenceGpio()->desiredValue()) { + fanPresent = true; + } else { + XLOG(INFO) << fmt::format( + "{}: is absent in the host (through gpio)", *fan.fanName()); + } } fb303::fbData->setCounter( fmt::format(kFanAbsent, *fan.fanName()), !fanPresent);