From c0c74e7cca35179a9c4496a49f64e00db4c47870 Mon Sep 17 00:00:00 2001 From: Anthony Wilson Date: Wed, 6 Mar 2019 10:54:58 -0600 Subject: skeleton: Use ioctl gpio handling Now that chassiskill is a standalone app and is using ioctl gpio handling (through the gpioplus library), the gpio libraries here need to use ioctl as well for chassiskill to be compatible. Tested: Verified chassiskill works as intended and checked that nothing else broke. Change-Id: I67c431027d31e87c332c3e1771fc2d3423f56652 Signed-off-by: Anthony Wilson --- libopenbmc_intf/gpio.c | 249 ++++++++++-------------------------------- libopenbmc_intf/gpio.h | 8 +- op-pwrctl/power_control_obj.c | 50 +++++---- 3 files changed, 90 insertions(+), 217 deletions(-) diff --git a/libopenbmc_intf/gpio.c b/libopenbmc_intf/gpio.c index 33a9ffe..afa0914 100644 --- a/libopenbmc_intf/gpio.c +++ b/libopenbmc_intf/gpio.c @@ -14,97 +14,53 @@ #include "gpio.h" #include "gpio_json.h" +#include +#include + #define GPIO_PORT_OFFSET 8 #define GPIO_BASE_PATH "/sys/class/gpio" cJSON* gpio_json = NULL; -int gpio_writec(GPIO* gpio, char value) +int gpio_write(GPIO* gpio, uint8_t value) { g_assert (gpio != NULL); - int rc = GPIO_OK; - char buf[1]; - buf[0] = value; + struct gpiohandle_data data; + memset(&data, 0, sizeof(data)); + data.values[0] = value; - if (lseek(gpio->fd, 0, SEEK_SET) == -1) + if (gpio->fd <= 0) { return GPIO_ERROR; } - if (write(gpio->fd, buf, 1) != 1) + if (ioctl(gpio->fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data) < 0) { - rc = GPIO_WRITE_ERROR; + return GPIO_WRITE_ERROR; } - return rc; + + return GPIO_OK; } -int gpio_write(GPIO* gpio, uint8_t value) +int gpio_read(GPIO* gpio, uint8_t *value) { g_assert (gpio != NULL); - int rc = GPIO_OK; - char buf[1]; - buf[0] = '0'; - if (value==1) - { - buf[0]='1'; - } + struct gpiohandle_data data; + memset(&data, 0, sizeof(data)); - if (lseek(gpio->fd, 0, SEEK_SET) == -1) + if (gpio->fd <= 0) { return GPIO_ERROR; } - if (write(gpio->fd, buf, 1) != 1) + if (ioctl(gpio->fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data) < 0) { - rc = GPIO_WRITE_ERROR; + return GPIO_READ_ERROR; } - return rc; -} -int gpio_read(GPIO* gpio, uint8_t *value) -{ - g_assert (gpio != NULL); - char buf[1]; - int r = GPIO_OK; - if (gpio->fd <= 0) - { - r = GPIO_ERROR; - } - else - { - if (lseek(gpio->fd, 0, SEEK_SET) == -1) - { - return GPIO_ERROR; - } + *value = data.values[0]; - if (read(gpio->fd,&buf,1) != 1) - { - r = GPIO_READ_ERROR; - } else { - if (buf[0]=='1') { - *value = 1; - } else { - *value = 0; - } - } - } - return r; -} -int gpio_clock_cycle(GPIO* gpio, int num_clks) { - g_assert (gpio != NULL); - int i=0; - int r=GPIO_OK; - for (i=0;ichip_id = 0; return GPIO_OK; } -// Gets the gpio device path from gpio manager object -int gpio_init(GPIO* gpio) +int gpio_open(GPIO* gpio, uint8_t default_value) { - int rc = gpio_get_params(gpio); - if (rc != GPIO_OK) - { - return rc; - } - - g_print("GPIO Lookup: %s = %d,%s\n",gpio->name,gpio->num,gpio->direction); - - //export and set direction - char dev[254]; - char data[4]; - int fd; - do { - struct stat st; - - sprintf(dev,"%s/gpio%d/value",gpio->dev,gpio->num); - //check if gpio is exported, if not export - int result = stat(dev, &st); - if (result) - { - sprintf(dev,"%s/export",gpio->dev); - fd = open(dev, O_WRONLY); - if (fd == GPIO_ERROR) { - rc = GPIO_OPEN_ERROR; - break; - } - sprintf(data,"%d",gpio->num); - rc = write(fd,data,strlen(data)); - close(fd); - if (rc != strlen(data)) { - rc = GPIO_WRITE_ERROR; - break; - } - } - const char* file = "edge"; - const char* direction = gpio->direction; - if (strcmp(direction, "in") == 0) - { - file = "direction"; - } - else if (strcmp(direction, "out") == 0) - { - file = "direction"; - - // Read current value, so we can set 'high' or 'low'. - // Setting direction directly to 'out' is the same as - // setting to 'low' which can change the value in the - // GPIO. - uint8_t value = 0; - rc = gpio_open(gpio); - if (rc) break; - rc = gpio_read(gpio, &value); - if (rc) break; - gpio_close(gpio); - - direction = (value ? "high" : "low"); - } - sprintf(dev,"%s/gpio%d/%s",gpio->dev,gpio->num,file); - fd = open(dev,O_WRONLY); - if (fd == GPIO_ERROR) { - rc = GPIO_WRITE_ERROR; - break; - } - rc = write(fd,direction,strlen(direction)); - if (rc != strlen(direction)) { - rc = GPIO_WRITE_ERROR; - break; - } - - close(fd); - rc = GPIO_OK; - } while(0); - - return rc; -} - - - - -char* get_gpio_dev(GPIO* gpio) -{ - char* buf; - asprintf(&buf, "%s/gpio%d/value", gpio->dev, gpio->num); - return buf; -} + g_assert (gpio != NULL); -int gpio_open_interrupt(GPIO* gpio, GIOFunc func, gpointer user_data) -{ - int rc = GPIO_OK; char buf[255]; - sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); - gpio->fd = open(buf, O_RDONLY | O_NONBLOCK ); - gpio->irq_inited = false; + sprintf(buf, "/dev/gpiochip%d", gpio->chip_id); + gpio->fd = open(buf, 0); if (gpio->fd == -1) { - rc = GPIO_OPEN_ERROR; - } - else - { - GIOChannel* channel = g_io_channel_unix_new( gpio->fd); - guint id = g_io_add_watch( channel, G_IO_PRI, func, user_data ); + return GPIO_OPEN_ERROR; } - return rc; -} -int gpio_open(GPIO* gpio) -{ - g_assert (gpio != NULL); + struct gpiohandle_request req; + memset(&req, 0, sizeof(req)); + strncpy(req.consumer_label, "skeleton-gpio", sizeof(req.consumer_label)); + // open gpio for writing or reading - char buf[254]; - int rc = 0; - gpio->fd = -1; - if (gpio->direction == NULL) { + if (gpio->direction == NULL) + { + gpio_close(gpio); return GPIO_OPEN_ERROR; } - if (strcmp(gpio->direction,"in")==0) + req.flags = (strcmp(gpio->direction,"in") == 0) ? GPIOHANDLE_REQUEST_INPUT + : GPIOHANDLE_REQUEST_OUTPUT; + + req.lineoffsets[0] = gpio->num; + req.lines = 1; + + if (strcmp(gpio->direction,"out") == 0) { - sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); - gpio->fd = open(buf, O_RDONLY); + req.default_values[0] = default_value; } - else - { - sprintf(buf, "%s/gpio%d/value", gpio->dev, gpio->num); - gpio->fd = open(buf, O_RDWR); - } - if (gpio->fd == -1) { + int rc = ioctl(gpio->fd, GPIO_GET_LINEHANDLE_IOCTL, &req); + if (rc < 0) + { + gpio_close(gpio); return GPIO_OPEN_ERROR; } + gpio_close(gpio); + gpio->fd = req.fd; + return GPIO_OK; } void gpio_close(GPIO* gpio) { + if(gpio->fd < 0) + return; + close(gpio->fd); + gpio->fd = -1; } diff --git a/libopenbmc_intf/gpio.h b/libopenbmc_intf/gpio.h index dc439c8..54ff6af 100644 --- a/libopenbmc_intf/gpio.h +++ b/libopenbmc_intf/gpio.h @@ -9,6 +9,7 @@ typedef struct { gchar* name; gchar* dev; uint16_t num; + uint16_t chip_id; gchar* direction; int fd; bool irq_inited; @@ -24,13 +25,10 @@ typedef struct { #define GPIO_WRITE_ERROR 0x10 #define GPIO_LOOKUP_ERROR 0x20 -int gpio_init(GPIO*); void gpio_close(GPIO*); -int gpio_open(GPIO*); -int gpio_open_interrupt(GPIO*, GIOFunc, gpointer); +int gpio_open(GPIO*, uint8_t); int gpio_write(GPIO*, uint8_t); -int gpio_writec(GPIO*, char); -int gpio_clock_cycle(GPIO*, int); +int gpio_get_params(GPIO*); int gpio_read(GPIO*,uint8_t*); void gpio_inits_done(); diff --git a/op-pwrctl/power_control_obj.c b/op-pwrctl/power_control_obj.c index dedcbe2..ada9b3b 100644 --- a/op-pwrctl/power_control_obj.c +++ b/op-pwrctl/power_control_obj.c @@ -52,8 +52,9 @@ poll_pgood(gpointer user_data) } uint8_t pgood_state; - int rc = gpio_open(&g_gpio_configs.power_gpio.power_good_in); + int rc = gpio_open(&g_gpio_configs.power_gpio.power_good_in, 0); if(rc != GPIO_OK) { + gpio_close(&g_gpio_configs.power_gpio.power_good_in); g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", g_gpio_configs.power_gpio.power_good_in.name, rc); return FALSE; @@ -81,15 +82,16 @@ poll_pgood(gpointer user_data) for(i = 0; i < g_gpio_configs.power_gpio.num_reset_outs; i++) { GPIO *reset_out = &g_gpio_configs.power_gpio.reset_outs[i]; - rc = gpio_open(reset_out); + reset_state = pgood_state ^ g_gpio_configs.power_gpio.reset_pols[i]; + rc = gpio_open(reset_out, reset_state); if(rc != GPIO_OK) { + gpio_close(reset_out); g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", reset_out->name, rc); continue; } - reset_state = pgood_state ^ g_gpio_configs.power_gpio.reset_pols[i]; g_print("PowerControl: pgood: %d, setting reset %s to %d\n", (int)pgood_state, reset_out->name, (int)reset_state); gpio_write(reset_out, reset_state); @@ -111,15 +113,16 @@ poll_pgood(gpointer user_data) continue; } } - rc = gpio_open(pci_reset_out); + reset_state = pgood_state ^ g_gpio_configs.power_gpio.pci_reset_pols[i]; + rc = gpio_open(pci_reset_out, reset_state); if(rc != GPIO_OK) { + gpio_close(pci_reset_out); g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", pci_reset_out->name, rc); continue; } - reset_state = pgood_state ^ g_gpio_configs.power_gpio.pci_reset_pols[i]; g_print("PowerControl: pgood: %d, setting pci reset %s to %d\n", (int)pgood_state, pci_reset_out->name, (int)reset_state); gpio_write(pci_reset_out, reset_state); @@ -202,9 +205,10 @@ on_boot_progress(GDBusConnection *connection, if (ignore) return; - rc = gpio_open(&g_gpio_configs.power_gpio.power_good_in); + rc = gpio_open(&g_gpio_configs.power_gpio.power_good_in, 0); if(rc != GPIO_OK) { + gpio_close(&g_gpio_configs.power_gpio.power_good_in); g_print("ERROR PowerControl: on_boot_progress(): GPIO open error (gpio=%s,rc=%d)\n", g_gpio_configs.power_gpio.power_good_in.name, rc); return; @@ -220,15 +224,16 @@ on_boot_progress(GDBusConnection *connection, if(!g_gpio_configs.power_gpio.pci_reset_holds[i]) continue; - rc = gpio_open(pci_reset_out); + reset_state = pgood_state ^ g_gpio_configs.power_gpio.pci_reset_pols[i]; + rc = gpio_open(pci_reset_out, reset_state); if(rc != GPIO_OK) { + gpio_close(pci_reset_out); g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", pci_reset_out->name, rc); continue; } - reset_state = pgood_state ^ g_gpio_configs.power_gpio.pci_reset_pols[i]; g_print("PowerControl: pgood: %d, setting pci reset %s to %d\n", (int)pgood_state, pci_reset_out->name, (int)reset_state); gpio_write(pci_reset_out, reset_state); @@ -267,17 +272,19 @@ on_set_power_state(ControlPower *pwr, uint8_t power_up_out; for (i = 0; i < power_gpio->num_power_up_outs; i++) { GPIO *power_pin = &power_gpio->power_up_outs[i]; - error = gpio_open(power_pin); + power_up_out = state ^ !power_gpio->power_up_pols[i]; + error = gpio_open(power_pin, power_up_out); if(error != GPIO_OK) { + gpio_close(power_pin); g_print("ERROR PowerControl: GPIO open error (gpio=%s,rc=%d)\n", power_gpio->power_up_outs[i].name, error); continue; } - power_up_out = state ^ !power_gpio->power_up_pols[i]; g_print("PowerControl: setting power up %s to %d\n", power_gpio->power_up_outs[i].name, (int)power_up_out); error = gpio_write(power_pin, power_up_out); if(error != GPIO_OK) { + gpio_close(power_pin); continue; } gpio_close(power_pin); @@ -294,16 +301,17 @@ on_set_power_state(ControlPower *pwr, * power pins' states. This commits the changes to the latch states. */ if (power_gpio->latch_out.name != NULL) { int rc; - uint8_t latch_value = 0; - rc = gpio_open(&power_gpio->latch_out); + uint8_t latch_value = 1; + rc = gpio_open(&power_gpio->latch_out, latch_value); if (rc != GPIO_OK) { /* Failures are non-fatal. */ + gpio_close(&power_gpio->latch_out); g_print("PowerControl ERROR failed to open latch %s rc=%d\n", power_gpio->latch_out.name, rc); return TRUE; } /* Make the latch transparent for as brief of a time as possible. */ - rc = gpio_write(&power_gpio->latch_out, 1); + rc = gpio_write(&power_gpio->latch_out, latch_value--); if (rc != GPIO_OK) { g_print("PowerControl ERROR failed to assert latch %s rc=%d\n", power_gpio->latch_out.name, rc); @@ -311,7 +319,7 @@ on_set_power_state(ControlPower *pwr, g_print("PowerControl asserted latch %s\n", power_gpio->latch_out.name); } - rc = gpio_write(&power_gpio->latch_out, 0); + rc = gpio_write(&power_gpio->latch_out, latch_value); if (rc != GPIO_OK) { g_print("PowerControl ERROR failed to clear latch %s rc=%d\n", power_gpio->latch_out.name, rc); @@ -355,29 +363,29 @@ set_up_gpio(PowerGpio *power_gpio, ControlPower* control_power) // get gpio device paths if(power_gpio->latch_out.name != NULL) { /* latch is optional */ - rc = gpio_init(&power_gpio->latch_out); + rc = gpio_get_params(&power_gpio->latch_out); if(rc != GPIO_OK) { error = rc; } } - rc = gpio_init(&power_gpio->power_good_in); + rc = gpio_get_params(&power_gpio->power_good_in); if(rc != GPIO_OK) { error = rc; } for(int i = 0; i < power_gpio->num_power_up_outs; i++) { - rc = gpio_init(&power_gpio->power_up_outs[i]); + rc = gpio_get_params(&power_gpio->power_up_outs[i]); if(rc != GPIO_OK) { error = rc; } } for(int i = 0; i < power_gpio->num_reset_outs; i++) { - rc = gpio_init(&power_gpio->reset_outs[i]); + rc = gpio_get_params(&power_gpio->reset_outs[i]); if(rc != GPIO_OK) { error = rc; } } for(int i = 0; i < power_gpio->num_pci_reset_outs; i++) { - rc = gpio_init(&power_gpio->pci_reset_outs[i]); + rc = gpio_get_params(&power_gpio->pci_reset_outs[i]); if(rc != GPIO_OK) { error = rc; } @@ -385,12 +393,14 @@ set_up_gpio(PowerGpio *power_gpio, ControlPower* control_power) gpio_inits_done(); - rc = gpio_open(&power_gpio->power_good_in); + rc = gpio_open(&power_gpio->power_good_in, 0); if(rc != GPIO_OK) { + gpio_close(&power_gpio->power_good_in); return rc; } rc = gpio_read(&power_gpio->power_good_in, &pgood_state); if(rc != GPIO_OK) { + gpio_close(&power_gpio->power_good_in); return rc; } gpio_close(&power_gpio->power_good_in); -- cgit v1.2.1