xref: /openbmc/openpower-hw-diags/attn/attn_monitor.cpp (revision a0c724d3d425032213dbd48247d93cc76d61a331)
1  #include <attn/attn_handler.hpp>
2  #include <attn/attn_monitor.hpp>
3  #include <util/trace.hpp>
4  
5  namespace attn
6  {
7  
8  /** @brief Register a callback for gpio event */
scheduleGPIOEvent()9  void AttnMonitor::scheduleGPIOEvent()
10  {
11      // Register async callback, note that callback is a
12      // lambda function with "this" pointer captured
13      iv_gpioEventDescriptor.async_wait(
14          boost::asio::posix::stream_descriptor::wait_read,
15          [this](const boost::system::error_code& ec) {
16              if (ec)
17              {
18                  trace::err("GPIO Async wait error: %s", ec.message().c_str());
19              }
20              else
21              {
22                  trace::inf("Attention GPIO active");
23                  handleGPIOEvent(); // gpio trigger detected
24              }
25              return;
26          }); // register async callback
27  }
28  
29  /** @brief Handle the GPIO state change event */
handleGPIOEvent()30  void AttnMonitor::handleGPIOEvent()
31  {
32      gpiod_line_event gpioEvent;
33  
34      if (gpiod_line_event_read_fd(iv_gpioEventDescriptor.native_handle(),
35                                   &gpioEvent) < 0)
36      {
37          trace::err("GPIO line read failed");
38      }
39      else
40      {
41          switch (gpiod_line_get_value(iv_gpioLine))
42          {
43              // active attention when gpio == 0
44              case 0:
45                  attnHandler(iv_config);
46                  break;
47  
48              // gpio == 1, GPIO handler should not be executing
49              case 1:
50                  trace::inf("GPIO handler out of sync");
51                  break;
52  
53              // unexpected value
54              default:
55                  trace::inf("GPIO line unexpected value");
56          }
57      }
58      scheduleGPIOEvent(); // continue monitoring gpio
59  }
60  
61  /** @brief Request a GPIO line for monitoring attention events */
requestGPIOEvent()62  void AttnMonitor::requestGPIOEvent()
63  {
64      if (0 != gpiod_line_request(iv_gpioLine, &iv_gpioConfig, 0))
65      {
66          trace::err("failed request for GPIO");
67      }
68      else
69      {
70          int gpioLineFd;
71  
72          gpioLineFd = gpiod_line_event_get_fd(iv_gpioLine);
73          if (gpioLineFd < 0)
74          {
75              trace::err("failed to get file descriptor");
76          }
77          else
78          {
79              // Register file descriptor for monitoring
80              iv_gpioEventDescriptor.assign(gpioLineFd);
81  
82              // Start monitoring
83              scheduleGPIOEvent();
84          }
85      }
86  }
87  
88  } // namespace attn
89