summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2018-08-07 14:32:58 -0500
committerMatt Spinler <spinler@us.ibm.com>2018-08-14 15:42:00 -0500
commite2cd39d8585dce09c8acddf07fd5ed2b0a619ebc (patch)
treed8aa43d382132fbfac6d91d6ac8a41d75856cbab
parent8428d4422258a3f0eb33e561aaf2d3eae2ba85d9 (diff)
downloadtalos-skeleton-e2cd39d8585dce09c8acddf07fd5ed2b0a619ebc.tar.gz
talos-skeleton-e2cd39d8585dce09c8acddf07fd5ed2b0a619ebc.zip
Fill in the function that finds the GPIO base
Finds the GPIO base value to use in the GPIO number calculation. This is most likely specific to ASPEED BMCs, though as with the calling code additional support can be added in the future if required. Change-Id: Ie0d2b87286ab4bf6b05b61245bd821ab2a9d602a Signed-off-by: Matt Spinler <spinler@us.ibm.com>
-rw-r--r--libopenbmc_intf/gpio.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c
index 2fe1421..a33348b 100644
--- a/libopenbmc_intf/gpio.c
+++ b/libopenbmc_intf/gpio.c
@@ -9,6 +9,7 @@
#include <argp.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <dirent.h>
#include "openbmc_intf.h"
#include "gpio.h"
#include "gpio_json.h"
@@ -106,10 +107,97 @@ int gpio_clock_cycle(GPIO* gpio, int num_clks) {
return r;
}
+/**
+ * Determine the GPIO base number for the system. It is found in
+ * the 'base' file in the /sys/class/gpio/gpiochipX/ directory where the
+ * /sys/class/gpio/gpiochipX/label file has a '1e780000.gpio' in it.
+ *
+ * Note: This method is ASPEED specific. Could add support for
+ * additional SOCs in the future.
+ *
+ * @return int - the GPIO base number, or < 0 if not found
+ */
int get_gpio_base()
{
- /* TODO */
- return 0;
+ int gpio_base = -1;
+
+ DIR* dir = opendir(GPIO_BASE_PATH);
+ if (dir == NULL)
+ {
+ fprintf(stderr, "Unable to open directory %s\n",
+ GPIO_BASE_PATH);
+ return -1;
+ }
+
+ struct dirent* entry;
+ while ((entry = readdir(dir)) != NULL)
+ {
+ /* Look in the gpiochip<X> directories for a file called 'label' */
+ /* that contains '1e780000.gpio', then in that directory read */
+ /* the GPIO base out of the 'base' file. */
+
+ if (strncmp(entry->d_name, "gpiochip", 8) != 0)
+ {
+ continue;
+ }
+
+ gboolean is_bmc = FALSE;
+ char* label_name;
+ asprintf(&label_name, "%s/%s/label",
+ GPIO_BASE_PATH, entry->d_name);
+
+ FILE* fd = fopen(label_name, "r");
+ free(label_name);
+
+ if (!fd)
+ {
+ continue;
+ }
+
+ char label[14];
+ if (fgets(label, 14, fd) != NULL)
+ {
+ if (strcmp(label, "1e780000.gpio") == 0)
+ {
+ is_bmc = TRUE;
+ }
+ }
+ fclose(fd);
+
+ if (!is_bmc)
+ {
+ continue;
+ }
+
+ char* base_name;
+ asprintf(&base_name, "%s/%s/base",
+ GPIO_BASE_PATH, entry->d_name);
+
+ fd = fopen(base_name, "r");
+ free(base_name);
+
+ if (!fd)
+ {
+ continue;
+ }
+
+ if (fscanf(fd, "%d", &gpio_base) != 1)
+ {
+ gpio_base = -1;
+ }
+ fclose(fd);
+
+ /* We found the right file. No need to continue. */
+ break;
+ }
+ closedir(dir);
+
+ if (gpio_base == -1)
+ {
+ fprintf(stderr, "Could not find GPIO base\n");
+ }
+
+ return gpio_base;
}
/**
OpenPOWER on IntegriCloud