cpusensor: refine CPU detection logic

This commit refines CPU detection logic using gpio line name based
handling.

Tested: Worked well with new SGPIO kernel driver and updated
platform configuration.

Change-Id: I5dae2b7497b6b5291b56e73d2175ca8cbb0580d4
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
diff --git a/include/CPUSensor.hpp b/include/CPUSensor.hpp
index 5f48674..7a2819f 100644
--- a/include/CPUSensor.hpp
+++ b/include/CPUSensor.hpp
@@ -49,74 +49,57 @@
 
 // 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)
+inline bool cpuIsPresent(
+    const boost::container::flat_map<std::string, BasicVariantType>& gpioConfig)
 {
-    static boost::container::flat_map<size_t, bool> cpuPresence;
+    static boost::container::flat_map<std::string, bool> cpuPresence;
 
-    auto findIndex = cpuPresence.find(gpioNum);
+    auto findName = gpioConfig.find("Name");
+    if (findName == gpioConfig.end())
+    {
+        return false;
+    }
+    std::string gpioName =
+        std::visit(VariantToStringVisitor(), findName->second);
+
+    auto findIndex = cpuPresence.find(gpioName);
     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)
+    bool activeHigh = true;
+    auto findPolarity = gpioConfig.find("Polarity");
+    if (findPolarity != gpioConfig.end())
     {
-        // close it, we'll reopen it at the end
-        std::ofstream unexport(gpioPath + std::string("unexport"));
-        if (unexport.good())
+        if (std::string("Low") ==
+            std::visit(VariantToStringVisitor(), findPolarity->second))
         {
-            unexport << gpioNum;
-        }
-        else
-        {
-            std::cerr << "Error cleaning up sysfs device\n";
+            activeHigh = false;
         }
     }
 
-    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);
-
+    auto line = gpiod::find_line(gpioName);
     if (!line)
     {
-        std::cerr << "Error requesting gpio\n";
-        return true;
+        std::cerr << "Error requesting gpio: " << gpioName << "\n";
+        return false;
     }
 
-    bool resp = true;
+    bool resp;
     try
     {
-        line.request({"adcsensor", gpiod::line_request::DIRECTION_INPUT, 0});
-        resp = !line.get_value();
+        line.request({"cpusensor", gpiod::line_request::DIRECTION_INPUT,
+                      activeHigh ? 0 : gpiod::line_request::FLAG_ACTIVE_LOW});
+        resp = line.get_value();
     }
     catch (std::system_error&)
     {
-        std::cerr << "Error reading gpio\n";
-        return true;
+        std::cerr << "Error reading gpio: " << gpioName << "\n";
+        return false;
     }
 
-    // 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;
+    cpuPresence[gpioName] = resp;
+
     return resp;
 }
diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
index 2588221..2a3ff16 100644
--- a/src/CPUSensorMain.cpp
+++ b/src/CPUSensorMain.cpp
@@ -182,9 +182,7 @@
         std::string sensorType;
         const SensorData* sensorData = nullptr;
         const std::string* interfacePath = nullptr;
-        const std::pair<std::string, boost::container::flat_map<
-                                         std::string, BasicVariantType>>*
-            baseConfiguration = nullptr;
+        const SensorBaseConfiguration* baseConfiguration = nullptr;
 
         for (const std::pair<sdbusplus::message::object_path, SensorData>&
                  sensor : sensorConfigs)
@@ -554,17 +552,14 @@
         useCache = true;
     }
 
-    // check PECI client addresses and DT overlay names from CPU configuration
+    // check PECI client addresses and names from CPU configuration
     // before starting ping operation
     for (const char* type : sensorTypes)
     {
         for (const std::pair<sdbusplus::message::object_path, SensorData>&
                  sensor : sensorConfigs)
         {
-            for (const std::pair<
-                     std::string,
-                     boost::container::flat_map<std::string, BasicVariantType>>&
-                     config : sensor.second)
+            for (const SensorBaseConfiguration& config : sensor.second)
             {
                 if ((configPrefix + std::string(type)) != config.first)
                 {
@@ -581,26 +576,30 @@
                 std::string name =
                     std::regex_replace(nameRaw, illegalDbusRegex, "_");
 
-                auto findCpuGpio = config.second.find("PresenceGpio");
-                if (findCpuGpio != config.second.end())
+                bool present = true;
+                for (const SensorBaseConfiguration& suppConfig : sensor.second)
                 {
-                    size_t gpio = std::visit(VariantToUnsignedIntVisitor(),
-                                             findCpuGpio->second);
-                    bool present = hostIsPresent(gpio);
-                    if (inventoryIfaces.find(name) == inventoryIfaces.end())
+                    if (suppConfig.first.find("PresenceGpio") !=
+                        std::string::npos)
                     {
-                        auto iface = objectServer.add_interface(
-                            cpuInventoryPath + std::string("/") + name,
-                            "xyz.openbmc_project.Inventory.Item");
-                        iface->register_property("PrettyName", name);
-                        iface->register_property("Present", present);
-                        iface->initialize();
-                        inventoryIfaces[name] = std::move(iface);
+                        present = cpuIsPresent(suppConfig.second);
+                        break;
                     }
-                    if (!present)
-                    {
-                        continue; // no reason to look for non present cpu
-                    }
+                }
+
+                if (inventoryIfaces.find(name) == inventoryIfaces.end())
+                {
+                    auto iface = objectServer.add_interface(
+                        cpuInventoryPath + std::string("/") + name,
+                        "xyz.openbmc_project.Inventory.Item");
+                    iface->register_property("PrettyName", name);
+                    iface->register_property("Present", present);
+                    iface->initialize();
+                    inventoryIfaces[name] = std::move(iface);
+                }
+                if (!present)
+                {
+                    continue; // no reason to look for non present cpu
                 }
 
                 auto findBus = config.second.find("Bus");