diff --git a/cpu/nrf5x_common/periph/gpio.c b/cpu/nrf5x_common/periph/gpio.c
index e7d3f4d99e202476e3217a330ef6f0aca7c66c57..2dca44de7115e65593e93e40c8d843bbe513268b 100644
--- a/cpu/nrf5x_common/periph/gpio.c
+++ b/cpu/nrf5x_common/periph/gpio.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2015 Jan Wagner <mail@jwagner.eu>
  *               2015-2016 Freie Universität Berlin
+ *               2019 Inria
  *
  * This file is subject to the terms and conditions of the GNU Lesser
  * General Public License v2.1. See the file LICENSE in the top level
@@ -22,6 +23,7 @@
  * @author      Timo Ziegler <timo.ziegler@fu-berlin.de>
  * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
  * @author      Jan Wagner <mail@jwagner.eu>
+ * @author      Alexandre Abadie <alexandre.abadie@inria.fr>
  *
  * @}
  */
@@ -35,10 +37,30 @@
 #define PIN_MASK            (0x1f)
 
 #ifdef MODULE_PERIPH_GPIO_IRQ
+
+#if CPU_FAM_NRF51
+#define GPIOTE_CHAN_NUMOF     (4U)
+#else
+#define GPIOTE_CHAN_NUMOF     (8U)
+#endif
+
+/**
+ * @brief   Index of next interrupt in GPIOTE channel list.
+ *
+ * The index is incremented at the end of each call to gpio_init_int.
+ * The index cannot be greater or equal than GPIOTE_CHAN_NUMOF.
+ */
+static uint8_t _gpiote_next_index = 0;
+
+/**
+ * @brief   Array containing a mapping between GPIOTE channel and pin
+ */
+static gpio_t _exti_pins[GPIOTE_CHAN_NUMOF];
+
 /**
  * @brief   Place to store the interrupt context
  */
-static gpio_isr_ctx_t exti_chan;
+static gpio_isr_ctx_t exti_chan[GPIOTE_CHAN_NUMOF];
 #endif /* MODULE_PERIPH_GPIO_IRQ */
 
 /**
@@ -125,44 +147,76 @@ void gpio_write(gpio_t pin, int value)
 int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
                   gpio_cb_t cb, void *arg)
 {
-    /* disable external interrupt in case one is active */
-    NRF_GPIOTE->INTENSET &= ~(GPIOTE_INTENSET_IN0_Msk);
+    uint8_t _pin_index = 0xff;
+    /* Looking for already known pin in exti table */
+    for (unsigned int i = 0; i < _gpiote_next_index; i++) {
+        if (_exti_pins[i] == pin) {
+            _pin_index = i;
+            break;
+        }
+    }
+
+    /* New pin */
+    if (_pin_index == 0xff) {
+        assert(_gpiote_next_index < GPIOTE_CHAN_NUMOF);
+        _pin_index = _gpiote_next_index;
+        /* associate the current pin with channel index */
+        _exti_pins[_pin_index] = pin;
+        /* increase next index for next pin initialization */
+        _gpiote_next_index++;
+    }
+
     /* save callback */
-    exti_chan.cb = cb;
-    exti_chan.arg = arg;
+    exti_chan[_pin_index].cb = cb;
+    exti_chan[_pin_index].arg = arg;
     /* configure pin as input */
     gpio_init(pin, mode);
     /* set interrupt priority and enable global GPIOTE interrupt */
     NVIC_EnableIRQ(GPIOTE_IRQn);
     /* configure the GPIOTE channel: set even mode, pin and active flank */
-    NRF_GPIOTE->CONFIG[0] = (GPIOTE_CONFIG_MODE_Event |
+    NRF_GPIOTE->CONFIG[_pin_index] = (GPIOTE_CONFIG_MODE_Event |
                              (pin_num(pin) << GPIOTE_CONFIG_PSEL_Pos) |
 #ifdef CPU_MODEL_NRF52840XXAA
                              ((pin & PORT_BIT) << 8) |
 #endif
                              (flank << GPIOTE_CONFIG_POLARITY_Pos));
     /* enable external interrupt */
-    NRF_GPIOTE->INTENSET |= GPIOTE_INTENSET_IN0_Msk;
+    NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN0_Msk << _pin_index);
+
     return 0;
 }
 
 void gpio_irq_enable(gpio_t pin)
 {
-    (void) pin;
-    NRF_GPIOTE->INTENSET |= GPIOTE_INTENSET_IN0_Msk;
+    for (unsigned int i = 0; i < _gpiote_next_index; i++) {
+        if (_exti_pins[i] == pin) {
+            NRF_GPIOTE->CONFIG[i] |= GPIOTE_CONFIG_MODE_Event;
+            NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN0_Msk << i);
+            break;
+        }
+    }
 }
 
 void gpio_irq_disable(gpio_t pin)
 {
-    (void) pin;
-    NRF_GPIOTE->INTENCLR |= GPIOTE_INTENSET_IN0_Msk;
+    for (unsigned int i = 0; i < _gpiote_next_index; i++) {
+        if (_exti_pins[i] == pin) {
+            /* Clear mode configuration: 00 = Disabled */
+            NRF_GPIOTE->CONFIG[i] &= ~(GPIOTE_CONFIG_MODE_Msk);
+            NRF_GPIOTE->INTENCLR = (GPIOTE_INTENCLR_IN0_Msk << i);
+            break;
+        }
+    }
 }
 
 void isr_gpiote(void)
 {
-    if (NRF_GPIOTE->EVENTS_IN[0] == 1) {
-        NRF_GPIOTE->EVENTS_IN[0] = 0;
-        exti_chan.cb(exti_chan.arg);
+    for (unsigned int i = 0; i < _gpiote_next_index; ++i) {
+        if (NRF_GPIOTE->EVENTS_IN[i] == 1) {
+            NRF_GPIOTE->EVENTS_IN[i] = 0;
+            exti_chan[i].cb(exti_chan[i].arg);
+            break;
+        }
     }
     cortexm_isr_end();
 }