diff --git a/src/linuxgpio.c b/src/linuxgpio.c
index 86fefd76..36687612 100644
--- a/src/linuxgpio.c
+++ b/src/linuxgpio.c
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <sys/stat.h>
 
 #include "avrdude.h"
 #include "libavrdude.h"
@@ -108,7 +109,8 @@ static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
 
   fd = open(buf, O_WRONLY);
   if (fd < 0) {
-    perror("Can't open gpioX/direction");
+    snprintf(buf, sizeof(buf), "Can't open gpio%u/direction", gpio);
+    perror(buf);
     return fd;
   }
 
@@ -138,6 +140,11 @@ static int linuxgpio_dir_in(unsigned int gpio)
 
 #define N_GPIO (PIN_MAX + 1)
 
+/* Delay between checks for successful GPIO export (100ms) */
+#define GPIO_SYSFS_OPEN_DELAY      100000
+/* Number of retries to check for successful GPIO exports */
+#define GPIO_SYSFS_OPEN_RETRIES    10
+
 /*
 * an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins
 */
@@ -245,6 +252,8 @@ static void linuxgpio_powerdown(PROGRAMMER *pgm)
 static int linuxgpio_open(PROGRAMMER *pgm, char *port)
 {
   int r, i, pin;
+  char gpio_path[60];
+  struct stat stat_buf;
 
   if (bitbang_check_prerequisites(pgm) < 0)
     return -1;
@@ -272,13 +281,46 @@ static int linuxgpio_open(PROGRAMMER *pgm, char *port)
                     pin, strerror(errno));
             return r;
         }
-        if (i == PIN_AVR_MISO)
-            r=linuxgpio_dir_in(pin);
-        else
-            r=linuxgpio_dir_out(pin);
 
-        if (r < 0)
+        /* Wait until GPIO directory appears */
+        snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u", pin);
+        unsigned int retry_count;
+        for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) {
+            int ret = stat(gpio_path, &stat_buf);
+            if (ret == 0) {
+                break;
+            } else if (ret < 0 && errno != ENOENT) {
+                linuxgpio_unexport(pin);
+                return ret;
+            }
+
+            usleep(GPIO_SYSFS_OPEN_DELAY);
+        }
+
+        /* Write direction, looping in case of EACCES errors due to delayed
+         * udev permission rule application after export */
+        for (retry_count = GPIO_SYSFS_OPEN_RETRIES; retry_count > 0; retry_count--) {
+            usleep(GPIO_SYSFS_OPEN_DELAY);
+            if (i == PIN_AVR_MISO)
+                r=linuxgpio_dir_in(pin);
+            else
+                r=linuxgpio_dir_out(pin);
+
+            if (r >= 0) {
+                break;
+            } else if (errno != EACCES) {
+                linuxgpio_unexport(pin);
+                return r;
+            }
+            if (retry_count > 1) {
+                printf("Retrying...\n");
+            }
+        }
+
+        if (r < 0) {
+            linuxgpio_unexport(pin);
             return r;
+        }
 
         if ((linuxgpio_fds[pin]=linuxgpio_openfd(pin)) < 0)
             return linuxgpio_fds[pin];