cpusensor: detect if cpu is available
Add CPU inventory item detection via gpio.
Tested: inventory item is exposed
Change-Id: Ia26a4bed5534edec6a7f5c7cf0965f84fa0fc23a
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/include/CPUSensor.hpp b/include/CPUSensor.hpp
index f66e655..1b25518 100644
--- a/include/CPUSensor.hpp
+++ b/include/CPUSensor.hpp
@@ -1,6 +1,12 @@
#pragma once
+#include "Utils.hpp"
+
#include <Thresholds.hpp>
+#include <boost/container/flat_map.hpp>
+#include <filesystem>
+#include <fstream>
+#include <gpiod.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sensor.hpp>
@@ -37,3 +43,77 @@
extern boost::container::flat_map<std::string, std::unique_ptr<CPUSensor>>
gCpuSensors;
+
+// this is added to cpusensor.hpp to avoid having every sensor have to link
+// against libgpiod, if another sensor needs it we may move it to utils
+inline bool hostIsPresent(size_t gpioNum)
+{
+ static boost::container::flat_map<size_t, bool> cpuPresence;
+
+ auto findIndex = cpuPresence.find(gpioNum);
+ if (findIndex != cpuPresence.end())
+ {
+ return findIndex->second;
+ }
+
+ constexpr size_t sgpioBase = 232;
+
+ // check if sysfs has device
+ bool sysfs = std::filesystem::exists(gpioPath + std::string("gpio") +
+ std::to_string(gpioNum));
+
+ // todo: delete this when we remove all sysfs code
+ if (sysfs)
+ {
+ // close it, we'll reopen it at the end
+ std::ofstream unexport(gpioPath + std::string("unexport"));
+ if (unexport.good())
+ {
+ unexport << gpioNum;
+ }
+ else
+ {
+ std::cerr << "Error cleaning up sysfs device\n";
+ }
+ }
+
+ size_t chipNum = (gpioNum - sgpioBase) / 8;
+ size_t index = (gpioNum - sgpioBase) % 8;
+ gpiod::chip chip("gpiochip" + std::to_string(chipNum));
+ auto line = chip.get_line(index);
+
+ if (!line)
+ {
+ std::cerr << "Error requesting gpio\n";
+ return true;
+ }
+
+ bool resp = true;
+ try
+ {
+ line.request({"adcsensor", gpiod::line_request::DIRECTION_INPUT});
+ resp = !line.get_value();
+ }
+ catch (std::system_error&)
+ {
+ std::cerr << "Error reading gpio\n";
+ return true;
+ }
+
+ // todo: delete this when we remove all sysfs code
+ if (sysfs)
+ {
+ // reopen it
+ std::ofstream populate(gpioPath + std::string("export"));
+ if (populate.good())
+ {
+ populate << gpioNum;
+ }
+ else
+ {
+ std::cerr << "Error cleaning up sysfs device\n";
+ }
+ }
+ cpuPresence[gpioNum] = resp;
+ return resp;
+}
\ No newline at end of file
diff --git a/include/TachSensor.hpp b/include/TachSensor.hpp
index b160a60..2a489dc 100644
--- a/include/TachSensor.hpp
+++ b/include/TachSensor.hpp
@@ -8,7 +8,6 @@
#include <sdbusplus/asio/object_server.hpp>
#include <sensor.hpp>
-constexpr const char* gpioPath = "/sys/class/gpio/";
class PresenceSensor
{
diff --git a/include/Utils.hpp b/include/Utils.hpp
index d65fb83..f3abc7f 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -9,9 +9,13 @@
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/message/types.hpp>
+constexpr const char* gpioPath = "/sys/class/gpio/";
const constexpr char* jsonStore = "/var/configuration/flattened.json";
const constexpr char* inventoryPath = "/xyz/openbmc_project/inventory";
const constexpr char* entityManagerName = "xyz.openbmc_project.EntityManager";
+
+constexpr const char* cpuInventoryPath =
+ "/xyz/openbmc_project/inventory/system/chassis/motherboard";
const std::regex illegalDbusRegex("[^A-Za-z0-9_]");
using BasicVariantType =