warm-reboot: add cfam-reset capabilities
A cfam-reset is required when doing a warm reboot of a POWER based
processor.
This commit has dependencies on two other commits:
libgpiod dependency in the op-proc-control recipe:
https://gerrit.openbmc-project.xyz/c/openbmc/meta-openpower/+/29076
witherspoon device tree update to name cfam-reset gpio:
https://lists.ozlabs.org/pipermail/openbmc/2020-February/020425.html
Other systems which require this support will also need to have their
dts updated. This will happen as support is needed for warm reboot on
them.
Tested:
Built witherspoon image and verified new procedure runs without failure
within QEMU.
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I79b13e487dc4d8e1d08aa2444325c49c101cf6b0
diff --git a/Makefile.am b/Makefile.am
index 70a2552..6c434f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,7 +31,8 @@
openpower_proc_control_LDFLAGS = $(PHOSPHOR_LOGGING_LIBS) \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
$(SDBUSPLUS_LIBS) \
- -lstdc++fs
+ -lstdc++fs \
+ -lgpiodcxx
openpower_proc_control_CXXFLAGS = $(PHOSPHOR_LOGGING_CFLAGS) \
$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
diff --git a/procedures/common/cfam_reset.cpp b/procedures/common/cfam_reset.cpp
new file mode 100644
index 0000000..5558374
--- /dev/null
+++ b/procedures/common/cfam_reset.cpp
@@ -0,0 +1,51 @@
+#include <unistd.h>
+
+#include <chrono>
+#include <gpiod.hpp>
+#include <phosphor-logging/log.hpp>
+#include <registration.hpp>
+#include <system_error>
+#include <thread>
+
+namespace openpower
+{
+namespace misc
+{
+
+using namespace phosphor::logging;
+
+/**
+ * @brief Reset the CFAM using the appropriate GPIO
+ * @return void
+ */
+void cfamReset()
+{
+ const std::string cfamReset = {"cfam-reset"};
+ auto line = gpiod::find_line(cfamReset);
+ if (!line)
+ {
+ log<level::ERR>("failed to find cfam-reset line");
+ throw std::system_error(ENODEV, std::system_category());
+ }
+
+ // Configure this app to own the gpio while doing the reset
+ gpiod::line_request conf;
+ conf.consumer = "cfamReset";
+ conf.request_type = gpiod::line_request::DIRECTION_OUTPUT;
+ line.request(conf);
+
+ // Put chips into reset
+ line.set_value(0);
+
+ // Sleep one second to ensure reset processed
+ using namespace std::chrono_literals;
+ std::this_thread::sleep_for(1s);
+
+ // Take chips out of reset
+ line.set_value(1);
+}
+
+REGISTER_PROCEDURE("cfamReset", cfamReset);
+
+} // namespace misc
+} // namespace openpower