diff --git a/ChangeLog b/ChangeLog
index 161e66d3..59bf56a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2021-11-27  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Submitted by Alex Sverdlin:
+	patch #10031: linuxspi: Support GPIO uAPI v2
+	* linuxspi.c (linuxspi_reset_mcu, linuxspi_open): Since Linux
+	v5.10 GPIO ABI Version 1 is optional and depends on
+	CONFIG_GPIO_CDEV_V1.
+
 2021-11-27  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Submitted by Alex Sverdlin:
diff --git a/NEWS b/NEWS
index e1e20885..a36bba70 100644
--- a/NEWS
+++ b/NEWS
@@ -121,6 +121,7 @@ Current:
     patch #10028: linuxspi: close() only when necessary
     patch #10029: linuxspi: Report GPIO_GET_LINEHANDLE_IOCTL errors
     patch #10030: linuxspi: Support inverted GPIO pin
+    patch #10031: linuxspi: Support GPIO uAPI v2
 
   * Internals:
     - New avrdude.conf keyword "family_id", used to verify SIB attributes
diff --git a/linuxspi.c b/linuxspi.c
index da2821f2..bbaf820d 100644
--- a/linuxspi.c
+++ b/linuxspi.c
@@ -109,6 +109,16 @@ static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
      */
     data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
     ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
+#ifdef GPIO_V2_LINE_SET_VALUES_IOCTL
+    if (ret == -1) {
+        struct gpio_v2_line_values val;
+
+        val.mask = 1;
+        val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
+
+        ret = ioctl(fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val);
+    }
+#endif
     if (ret == -1) {
         ret = -errno;
         avrdude_message(MSG_INFO, "%s error: Unable to set GPIO line %d value\n",
@@ -169,6 +179,27 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
     req.flags = GPIOHANDLE_REQUEST_OUTPUT;
 
     ret = ioctl(fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req);
+    if (ret != -1)
+        fd_linehandle = req.fd;
+#ifdef GPIO_V2_GET_LINE_IOCTL
+    if (ret == -1) {
+        struct gpio_v2_line_request reqv2;
+
+        memset(&reqv2, 0, sizeof(reqv2));
+        reqv2.offsets[0] = pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE;
+        strncpy(reqv2.consumer, progname, sizeof(reqv2.consumer) - 1);
+        reqv2.config.flags = GPIO_V2_LINE_FLAG_OUTPUT;
+        reqv2.config.num_attrs = 1;
+        reqv2.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
+        reqv2.config.attrs[0].attr.values = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
+        reqv2.config.attrs[0].mask = 1;
+        reqv2.num_lines = 1;
+
+        ret = ioctl(fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2);
+        if (ret != -1)
+            fd_linehandle = reqv2.fd;
+    }
+#endif
     if (ret == -1) {
         ret = -errno;
         avrdude_message(MSG_INFO, "%s error: Unable to get GPIO line %d\n",
@@ -176,8 +207,6 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
         goto close_gpiochip;
     }
 
-    fd_linehandle = req.fd;
-
     ret = linuxspi_reset_mcu(pgm, true);
     if (ret)
         goto close_out;