diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index eb4941e6b..c6ffa3205 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -52,6 +52,7 @@ #include "config.h" #endif +#include #include #include "bitbang.h" @@ -112,6 +113,7 @@ static void unexport_sysfs_gpio(int gpio) */ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) { + struct timeval timeout, now; char buf[40]; char gpiostr[5]; int ret; @@ -131,8 +133,19 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } } + gettimeofday(&timeout, NULL); + timeval_add_time(&timeout, 0, 500000); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + for (;;) { + ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't set direction for gpio %d", gpio); perror("sysfsgpio: "); @@ -141,7 +154,15 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + for (;;) { + ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't open value for gpio %d", gpio); perror("sysfsgpio: ");