Enable dynamic presence detect of FRUs
This commit enables presence detect of FRUs at runtime.
Anytime any FRU can get attached or de-attached,
this code will detect it and will enable/disable the corresponding
output I2C pin respectively.
Right now we have only one FRU- op-panel, which is attachable or
de-attachable at runtime.
Test- Tested on Simics:
>> 2timers keep running, as part of vpd-manager-
./vpd-manager
keep checking for event occurance...
hasEventOccurred ?
keep checking for event occurance...
hasEventOccurred ?
>> changed signal at presence-pin of FRU2
keep checking for event occurance...
hasEventOccurred ?
keep checking for event occurance...
hasEventOccurred ?
Yes, togggle the gpio <---------------------event on 2nd timer
>> Again, changed signal at presence-pin of FRU2
keep checking for event occurance...
hasEventOccurred ?
keep checking for event occurance...
hasEventOccurred ?
Yes, togggle the gpio <---------------------event on 2nd timer
>> changed signal at presence-pin of FRU1
keep checking for event occurance...
hasEventOccurred ?
Yes, togggle the gpio <---------------------event on 1st timer
keep checking for event occurance...
hasEventOccurred ?
>> Again changed signal at presence-pin of FRU1
keep checking for event occurance...
hasEventOccurred ?
Yes, togggle the gpio <---------------------event on 1st timer
keep checking for event occurance...
hasEventOccurred ?
>> Noticed change on output gpio after every signal change.
As of now for testing, output gpio is same for both of these FRUs-
>> Effects on i2c-
i2cdetect -y 7
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: UU UU UU -- -- -- -- -- -- -- 5a -- -- -- -- --
60: UU UU UU -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- UU --
i2cdetect -y 7
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
50: UU 51 UU -- -- -- -- -- -- -- 5a -- -- -- -- --
60: UU UU UU -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- UU --
Also tested for write functionality, shouldn't be affected due to this change
It looks fine.
root@p10bmc:~# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard |grep PN
.PN property ay 7 48 50 87 71 54 55 56 emits-change writable
root@p10bmc:~# busctl call com.ibm.VPD.Manager /com/ibm/VPD/Manager com.ibm.VPD.Manager WriteKeyword ossay "/system/chassis/motherboard" "VINI" "PN" 1 80
root@p10bmc:~# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard |grep PN
.PN property ay 7 80 50 87 71 54 55 56 emits-change writable
root@p10bmc:~# busctl call com.ibm.VPD.Manager /com/ibm/VPD/Manager com.ibm.VPD.Manager WriteKeyword ossay "/system/chassis/motherboard" "VINI" "PN" 1 48
root@p10bmc:~# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard |grep PN
.PN property ay 7 48 50 87 71 54 55 56 emits-change writable
Change-Id: If7d311d36bf56ece751afe393a9ba2d83be5df11
Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
diff --git a/vpd-manager/gpioMonitor.hpp b/vpd-manager/gpioMonitor.hpp
new file mode 100644
index 0000000..66c049d
--- /dev/null
+++ b/vpd-manager/gpioMonitor.hpp
@@ -0,0 +1,137 @@
+#pragma once
+
+#include "manager.hpp"
+
+#include <sdeventplus/event.hpp>
+
+namespace openpower
+{
+namespace vpd
+{
+namespace manager
+{
+/** @class GpioEventHandler
+ * @brief Responsible for catching the event and handle it.
+ * This keeps checking for the FRU's presence.
+ * If any attachment or de-attachment found, it enables/disables that
+ * fru's output gpio and bind/unbind the driver, respectively.
+ */
+class GpioEventHandler
+{
+ public:
+ GpioEventHandler() = default;
+ ~GpioEventHandler() = default;
+ GpioEventHandler(const GpioEventHandler&) = default;
+ GpioEventHandler& operator=(const GpioEventHandler&) = delete;
+ GpioEventHandler(GpioEventHandler&&) = delete;
+ GpioEventHandler& operator=(GpioEventHandler&&) = delete;
+
+ GpioEventHandler(std::string& presPin, Byte& presValue, std::string& outPin,
+ Byte& outValue, std::string& devAddr, std::string& driver,
+ std::string& bus, std::string& objPath,
+ sdeventplus::Event& event) :
+ presencePin(presPin),
+ presenceValue(presValue), outputPin(outPin), outputValue(outValue),
+ devNameAddr(devAddr), driverType(driver), busType(bus),
+ objectPath(objPath)
+ {
+ doEventAndTimerSetup(event);
+ }
+
+ private:
+ /** @brief GPIO informations to get parsed from vpd json*/
+
+ // gpio pin indicates presence/absence of fru
+ const std::string presencePin;
+ // value which means fru is present
+ const Byte presenceValue;
+ // gpio pin to enable If fru is present
+ const std::string outputPin;
+ // Value to set, to enable the output pin
+ const Byte outputValue;
+
+ // FRU address on bus
+ const std::string devNameAddr;
+ // Driver type
+ const std::string driverType;
+ // Bus type
+ const std::string busType;
+ // object path of FRU
+ const std::string objectPath;
+
+ /** Preserves the GPIO pin value to compare it next time. Default init by
+ * false*/
+ bool prevPresPinValue = false;
+
+ /** @brief This is a helper function to read the
+ * current value of Presence GPIO
+ *
+ * @returns The GPIO value
+ */
+ bool getPresencePinValue();
+
+ /** @brief This function will toggle the output gpio as per the presence
+ * state of fru.
+ */
+ void toggleGpio();
+
+ /** @brief This function checks for fru's presence pin and detects change of
+ * value on that pin, (in case of fru gets attached or de-attached).
+ *
+ * @returns true if presence pin value changed
+ * false otherwise
+ */
+ inline bool hasEventOccurred()
+ {
+ return getPresencePinValue() != prevPresPinValue;
+ }
+
+ /** @brief This function runs a timer , which keeps checking for if an event
+ * happened, if event occured then takes action.
+ * @param[in] timer- Shared pointer of Timer to do event setup for each
+ * object.
+ * @param[in] event- Event which needs to be tagged with the timer.
+ */
+ void doEventAndTimerSetup(sdeventplus::Event& event);
+};
+
+/** @class GpioMonitor
+ * @brief Responsible for initialising the private variables containing gpio
+ * infos. These informations will be fetched from vpd json.
+ */
+class GpioMonitor
+{
+ public:
+ GpioMonitor() = delete;
+ ~GpioMonitor() = default;
+ GpioMonitor(const GpioMonitor&) = delete;
+ GpioMonitor& operator=(const GpioMonitor&) = delete;
+ GpioMonitor(GpioMonitor&&) = delete;
+ GpioMonitor& operator=(GpioMonitor&&) = delete;
+
+ GpioMonitor(nlohmann::json& js, sdeventplus::Event& event) : jsonFile(js)
+ {
+ initGpioInfos(event);
+ }
+
+ private:
+ // Json file to get the datas
+ nlohmann::json& jsonFile;
+ // Array of event handlers for all the attachable FRUs
+ std::vector<std::shared_ptr<GpioEventHandler>> gpioObjects;
+
+ /** @brief This function will extract the gpio informations from vpd json
+ * and store it in GpioEventHandler's private variables
+ * @param[in] gpioObj - shared object to initialise it's data and it's
+ * Timer setup
+ * @param[in] requestedGpioPin - Which GPIO's informations need to be
+ * stored
+ * @param[in] timer - shared object of timer to do the event setup
+ * @param[in] event - event to be tagged with timer.
+ */
+ void initGpioInfos(sdeventplus::Event& event);
+};
+
+} // namespace manager
+} // namespace vpd
+} // namespace openpower
\ No newline at end of file