diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c
index 0a94b84c67fd5..f7c57156361ec 100644
--- a/drivers/gpio/gpio_nrfx.c
+++ b/drivers/gpio/gpio_nrfx.c
@@ -20,6 +20,26 @@
 #include <nrf/gpd.h>
 #endif
 
+#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance)
+#define GPIOTE_PROP(idx, prop)     DT_PROP(GPIOTE(idx), prop)
+
+#define IS_NO_PORT_INSTANCE(id) DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ||
+#define IS_FIXED_CH_INSTANCE(id) DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ||
+
+#if DT_INST_FOREACH_STATUS_OKAY(IS_NO_PORT_INSTANCE) 0
+#define GPIOTE_NO_PORT_EVT_SUPPORT 1
+#endif
+
+#if DT_INST_FOREACH_STATUS_OKAY(IS_FIXED_CH_INSTANCE) 0
+#define GPIOTE_FIXED_CH_SUPPORT 1
+#endif
+
+#if defined(GPIOTE_NO_PORT_EVT_SUPPORT) || defined(GPIOTE_FIXED_CH_SUPPORT)
+#define GPIOTE_FEATURE_FLAG 1
+#define GPIOTE_FLAG_NO_PORT_EVT BIT(0)
+#define GPIOTE_FLAG_FIXED_CHAN  BIT(1)
+#endif
+
 struct gpio_nrfx_data {
 	/* gpio_driver_data needs to be first */
 	struct gpio_driver_data common;
@@ -33,6 +53,9 @@ struct gpio_nrfx_cfg {
 	uint32_t edge_sense;
 	uint8_t port_num;
 	nrfx_gpiote_t gpiote;
+#if defined(GPIOTE_FEATURE_FLAG)
+	uint32_t flags;
+#endif
 #ifdef CONFIG_SOC_NRF54H20_GPD
 	uint8_t pad_pd;
 #endif
@@ -180,6 +203,7 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
 				abs_pin, &input_pin_config);
 			if (err != NRFX_SUCCESS) {
 				ret = -EINVAL;
+
 				goto end;
 			}
 		}
@@ -211,13 +235,21 @@ static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin,
 	}
 
 	if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT) && free_ch) {
+#ifdef GPIOTE_FEATURE_FLAG
+		/* Fixed channel was used, no need to free. */
+		if (cfg->flags & GPIOTE_FLAG_FIXED_CHAN) {
+			goto end;
+		}
+#endif
 		err = nrfx_gpiote_channel_free(&cfg->gpiote, ch);
 		__ASSERT_NO_MSG(err == NRFX_SUCCESS);
 	}
 
 end:
 	gpio_nrfx_gpd_retain_set(port, BIT(pin));
-	return pm_device_runtime_put(port);
+	int pm_ret = pm_device_runtime_put(port);
+
+	return (ret != 0) ? ret : pm_ret;
 }
 
 #ifdef CONFIG_GPIO_GET_CONFIG
@@ -393,6 +425,37 @@ static nrfx_gpiote_trigger_t get_trigger(enum gpio_int_mode mode,
 					    NRFX_GPIOTE_TRIGGER_LOTOHI;
 }
 
+static nrfx_err_t chan_alloc(const struct gpio_nrfx_cfg *cfg, gpio_pin_t pin, uint8_t *ch)
+{
+#ifdef GPIOTE_FEATURE_FLAG
+	if (cfg->flags & GPIOTE_FLAG_FIXED_CHAN) {
+		/* Currently fixed channel relation is only present in one instance (GPIOTE0 on
+		 * cpurad). The rules are following:
+		 * - GPIOTE0 can only be used with P1 (pins 4-11) and P2 (pins (0-11))
+		 * - P1: channel => pin - 4, e.g. P1.4 => channel 0, P1.5 => channel 1
+		 * - P2: channel => pin % 8, e.g. P2.0 => channel 0, P2.8 => channel 0
+		 */
+		nrfx_err_t err = NRFX_SUCCESS;
+
+		if (cfg->port_num == 1) {
+			if (pin < 4) {
+				err = NRFX_ERROR_INVALID_PARAM;
+			} else {
+				*ch = pin - 4;
+			}
+		} else if (cfg->port_num == 2) {
+			*ch = pin & 0x7;
+		} else {
+			err = NRFX_ERROR_INVALID_PARAM;
+		}
+
+		return err;
+	}
+#endif
+
+	return nrfx_gpiote_channel_alloc(&cfg->gpiote, ch);
+}
+
 static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
 					     gpio_pin_t pin,
 					     enum gpio_int_mode mode,
@@ -428,7 +491,7 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
 	    (nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) {
 		err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch);
 		if (err == NRFX_ERROR_INVALID_PARAM) {
-			err = nrfx_gpiote_channel_alloc(&cfg->gpiote, &ch);
+			err = chan_alloc(cfg, pin, &ch);
 			if (err != NRFX_SUCCESS) {
 				return -ENOMEM;
 			}
@@ -436,6 +499,11 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port,
 
 		trigger_config.p_in_channel = &ch;
 	} else {
+#ifdef GPIOTE_FEATURE_FLAG
+		if (cfg->flags & GPIOTE_FLAG_NO_PORT_EVT) {
+			return -ENOTSUP;
+		}
+#endif
 		/* If edge mode with channel was previously used and we are changing to sense or
 		 * level triggered, we must free the channel.
 		 */
@@ -641,7 +709,6 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
 #endif
 };
 
-#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance)
 #define GPIOTE_INST(id)    DT_PROP(GPIOTE_PHANDLE(id), instance)
 
 #define GPIOTE_INSTANCE(id)                                     \
@@ -668,30 +735,37 @@ static DEVICE_API(gpio, gpio_nrfx_drv_api_funcs) = {
 #define PAD_PD(inst)
 #endif
 
-#define GPIO_NRF_DEVICE(id)						\
-	GPIOTE_CHECK(id);						\
-	static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = {	\
-		.common = {						\
-			.port_pin_mask =				\
-			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),		\
-		},							\
-		.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)),		\
-		.port_num = DT_INST_PROP(id, port),			\
-		.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0),	\
-		.gpiote = GPIOTE_INSTANCE(id),				\
-		PAD_PD(id)						\
-	};								\
-									\
-	static struct gpio_nrfx_data gpio_nrfx_p##id##_data;		\
-									\
-	PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook);		\
-									\
-	DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init,			\
-			 PM_DEVICE_DT_INST_GET(id),			\
-			 &gpio_nrfx_p##id##_data,			\
-			 &gpio_nrfx_p##id##_cfg,			\
-			 PRE_KERNEL_1,					\
-			 CONFIG_GPIO_INIT_PRIORITY,			\
+#define GPIO_NRF_DEVICE(id)								\
+	GPIOTE_CHECK(id);								\
+	static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = {			\
+		.common = {								\
+			.port_pin_mask =						\
+			GPIO_PORT_PIN_MASK_FROM_DT_INST(id),				\
+		},									\
+		.port = _CONCAT(NRF_P, DT_INST_PROP(id, port)),				\
+		.port_num = DT_INST_PROP(id, port),					\
+		.edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0),			\
+		.gpiote = GPIOTE_INSTANCE(id),						\
+		IF_ENABLED(GPIOTE_FEATURE_FLAG,						\
+			(.flags =							\
+			 (DT_PROP_OR(GPIOTE_PHANDLE(id), no_port_event, 0) ?		\
+			    GPIOTE_FLAG_NO_PORT_EVT : 0) |				\
+			 (DT_PROP_OR(GPIOTE_PHANDLE(id), fixed_channels_supported, 0) ?	\
+			  GPIOTE_FLAG_FIXED_CHAN : 0),)					\
+			)								\
+		PAD_PD(id)								\
+	};										\
+											\
+	static struct gpio_nrfx_data gpio_nrfx_p##id##_data;				\
+											\
+	PM_DEVICE_DT_INST_DEFINE(id, gpio_nrfx_pm_hook);				\
+											\
+	DEVICE_DT_INST_DEFINE(id, gpio_nrfx_init,					\
+			 PM_DEVICE_DT_INST_GET(id),					\
+			 &gpio_nrfx_p##id##_data,					\
+			 &gpio_nrfx_p##id##_cfg,					\
+			 PRE_KERNEL_1,							\
+			 CONFIG_GPIO_INIT_PRIORITY,					\
 			 &gpio_nrfx_drv_api_funcs);
 
 DT_INST_FOREACH_STATUS_OKAY(GPIO_NRF_DEVICE)
diff --git a/dts/bindings/gpio/nordic,nrf-gpiote.yaml b/dts/bindings/gpio/nordic,nrf-gpiote.yaml
index b9180857e44f4..90914c712d204 100644
--- a/dts/bindings/gpio/nordic,nrf-gpiote.yaml
+++ b/dts/bindings/gpio/nordic,nrf-gpiote.yaml
@@ -8,6 +8,7 @@ compatible: "nordic,nrf-gpiote"
 include:
   - base.yaml
   - nordic,split-channels.yaml
+  - pinctrl-device.yaml
 
 properties:
   reg:
@@ -16,6 +17,17 @@ properties:
   interrupts:
     required: true
 
+  no-port-event:
+    type: boolean
+    description: |
+      Indicates that the GPIOTE instance does not support PORT event.
+
+  fixed-channels-supported:
+    type: boolean
+    description: |
+      Indicates that the GPIOTE instance has fixed connection between pins and TE channels.
+      It means that a specific TE channel must be used for a given pin.
+
   instance:
     type: int
     required: true
diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi
index 21b8056ff040f..05ae6df5d0f6a 100644
--- a/dts/vendor/nordic/nrf54h20.dtsi
+++ b/dts/vendor/nordic/nrf54h20.dtsi
@@ -379,6 +379,16 @@
 				interrupts = <37 NRF_DEFAULT_IRQ_PRIORITY>;
 			};
 
+			gpiote0: gpiote@27000 {
+				compatible = "nordic,nrf-gpiote";
+				reg = <0x27000 0x1000>;
+				status = "disabled";
+				interrupts = <39 NRF_DEFAULT_IRQ_PRIORITY>;
+				instance = <0>;
+				no-port-event;
+				fixed-channels-supported;
+			};
+
 			timer020: timer@28000 {
 				compatible = "nordic,nrf-timer";
 				reg = <0x28000 0x1000>;
diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt
index 11c28246828b8..b6f3528641231 100644
--- a/modules/hal_nordic/CMakeLists.txt
+++ b/modules/hal_nordic/CMakeLists.txt
@@ -12,7 +12,7 @@ if(CONFIG_NRF_REGTOOL_GENERATE_UICR)
   list(APPEND nrf_regtool_components GENERATE:UICR)
 endif()
 if(DEFINED nrf_regtool_components)
-  find_package(nrf-regtool 9.1.0
+  find_package(nrf-regtool 9.2.0
     COMPONENTS ${nrf_regtool_components}
     PATHS ${CMAKE_CURRENT_LIST_DIR}/nrf-regtool
     NO_CMAKE_PATH
diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig
index 4293adceb5fbb..080dc5ae2d9f0 100644
--- a/modules/hal_nordic/nrfx/Kconfig
+++ b/modules/hal_nordic/nrfx/Kconfig
@@ -226,6 +226,10 @@ config NRFX_GPIOTE131
 	depends on $(dt_nodelabel_exists,gpiote131)
 	select NRFX_GPIOTE
 
+config NRFX_GPIOTE_NONUNIFORM_INSTANCES
+	def_bool $(dt_nodelabel_enabled,gpiote0)
+	depends on $(dt_nodelabel_bool_prop,gpiote0,fixed-channels-supported)
+
 config NRFX_GPIOTE_NUM_OF_EVT_HANDLERS
 	int "Number of event handlers"
 	depends on NRFX_GPIOTE
diff --git a/modules/hal_nordic/nrfx/nrfx_kconfig.h b/modules/hal_nordic/nrfx/nrfx_kconfig.h
index 6816aebed1168..bd7aa7ae1da18 100644
--- a/modules/hal_nordic/nrfx/nrfx_kconfig.h
+++ b/modules/hal_nordic/nrfx/nrfx_kconfig.h
@@ -207,6 +207,9 @@
 #ifdef CONFIG_NRFX_GPIOTE131
 #define NRFX_GPIOTE131_ENABLED 1
 #endif
+#ifdef CONFIG_NRFX_GPIOTE_NONUNIFORM_INSTANCES
+#define NRFX_GPIOTE_CONFIG_NONUNIFORM_INSTANCES 1
+#endif
 
 #ifdef CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS
 #define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS
diff --git a/tests/drivers/gpio/gpio_basic_api/boards/nrf54h20dk_nrf54h20_cpurad_gpiote0.overlay b/tests/drivers/gpio/gpio_basic_api/boards/nrf54h20dk_nrf54h20_cpurad_gpiote0.overlay
new file mode 100644
index 0000000000000..0c8f7dbe06c98
--- /dev/null
+++ b/tests/drivers/gpio/gpio_basic_api/boards/nrf54h20dk_nrf54h20_cpurad_gpiote0.overlay
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+
+&pinctrl {
+	gpiote0_default_alt: gpiote0_default_alt {
+		group1 {
+			psels = <NRF_PSEL(SPIM_SCK, 1, 4)>;
+		};
+	};
+};
+
+/ {
+	resources {
+		compatible = "test-gpio-basic-api";
+		out-gpios = <&gpio1 5 0>;
+		in-gpios = <&gpio1 4 0>;
+	};
+};
+
+&gpio1 {
+	status = "okay";
+	gpiote-instance = <&gpiote0>;
+};
+
+&gpiote0 {
+	status = "okay";
+	pinctrl-0 = <&gpiote0_default_alt>;
+	pinctrl-names = "default";
+};
diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c b/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c
index 4c521c8e2a0ed..d302e99303244 100644
--- a/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c
+++ b/tests/drivers/gpio/gpio_basic_api/src/test_callback_manage.c
@@ -66,16 +66,19 @@ static int init_callback(const struct device *dev_in, const struct device *dev_o
 static void trigger_callback(const struct device *dev_in, const struct device *dev_out,
 			     int enable_cb)
 {
+	int rc;
+
 	gpio_pin_set(dev_out, PIN_OUT, 0);
 	k_sleep(K_MSEC(100));
 
 	cb_cnt[0] = 0;
 	cb_cnt[1] = 0;
 	if (enable_cb == 1) {
-		gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_EDGE_RISING);
+		rc = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_EDGE_RISING);
 	} else {
-		gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_DISABLE);
+		rc = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_DISABLE);
 	}
+	zassert_equal(rc, 0);
 	k_sleep(K_MSEC(100));
 	gpio_pin_set(dev_out, PIN_OUT, 1);
 	k_sleep(K_MSEC(1000));
diff --git a/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c b/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c
index e96a9599e145e..0f9f7ced04a32 100644
--- a/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c
+++ b/tests/drivers/gpio/gpio_basic_api/src/test_config_trigger.c
@@ -73,6 +73,9 @@ ZTEST(after_flash_gpio_config_trigger, test_gpio_config_twice_trigger)
 	k_sleep(K_MSEC(10));
 	zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt);
 
+	ret = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_DISABLE);
+	zassert_ok(ret, "interrupt disabling failed");
+
 	gpio_remove_callback(dev_in, &drv_data->gpio_cb);
 }
 
@@ -125,5 +128,8 @@ ZTEST(after_flash_gpio_config_trigger, test_gpio_config_trigger)
 	k_sleep(K_MSEC(10));
 	zassert_between_inclusive(cb_cnt, 0, 1, "Got %d interrupts", cb_cnt);
 
+	ret = gpio_pin_interrupt_configure(dev_in, PIN_IN, GPIO_INT_DISABLE);
+	zassert_ok(ret, "interrupt disabling failed");
+
 	gpio_remove_callback(dev_in, &drv_data->gpio_cb);
 }
diff --git a/tests/drivers/gpio/gpio_basic_api/testcase.yaml b/tests/drivers/gpio/gpio_basic_api/testcase.yaml
index 97083a30feff1..8dcb4cecf9669 100644
--- a/tests/drivers/gpio/gpio_basic_api/testcase.yaml
+++ b/tests/drivers/gpio/gpio_basic_api/testcase.yaml
@@ -114,3 +114,10 @@ tests:
     platform_allow:
       - siwx917_rb4338a
     extra_args: "DTC_OVERLAY_FILE=boards/siwx917_rb4338a-uulp.overlay"
+  drivers.gpio.2pin.nrf54h20_cpurad_gpiote0:
+    harness_config:
+      fixture: i2s_loopback # Loopback includes the pin pair needed for that test
+    platform_allow:
+      - nrf54h20dk/nrf54h20/cpurad
+    extra_args:
+      - DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpurad_gpiote0.overlay"