diff --git a/target/linux/bcm53xx/patches-3.18/180-bcma_set_gpio_base.patch b/target/linux/bcm53xx/patches-3.18/180-bcma_set_gpio_base.patch
deleted file mode 100644
index de1dd0914dee1f71b27d1ab40a0fe3c7fa954434..0000000000000000000000000000000000000000
--- a/target/linux/bcm53xx/patches-3.18/180-bcma_set_gpio_base.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Subject: [PATCH] bcma: set gpio chip->base for CONFIG_ARCH_BCM_5301X like on 47xx
-
-This makes system GPIOs easier to deal with, e.g. for user space scripts.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
---- a/drivers/bcma/driver_gpio.c
-+++ b/drivers/bcma/driver_gpio.c
-@@ -240,7 +240,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
- 	 * relative (per chip) numbers.
- 	 * So let's use predictable base for BCM47XX and "random" for all other.
- 	 */
--#if IS_BUILTIN(CONFIG_BCM47XX)
-+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
- 	chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
- #else
- 	chip->base		= -1;
diff --git a/target/linux/bcm53xx/patches-3.18/181-bcma-ngpio-bcm4707.patch b/target/linux/bcm53xx/patches-3.18/181-bcma-ngpio-bcm4707.patch
deleted file mode 100644
index 79cb6df7f15f35f18018dfbca6b57d7297bc8cea..0000000000000000000000000000000000000000
--- a/target/linux/bcm53xx/patches-3.18/181-bcma-ngpio-bcm4707.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-From: Felix Fietkau <nbd@openwrt.org>
-Subject: [PATCH] bcma: enable 32 GPIO pins for BCM4707+
-
-At least one BCM4709 device uses GPIO pins > 16.
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
----
---- a/drivers/bcma/driver_gpio.c
-+++ b/drivers/bcma/driver_gpio.c
-@@ -226,6 +226,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
- 		chip->of_node	= cc->core->dev.of_node;
- #endif
- 	switch (bus->chipinfo.id) {
-+	case BCMA_CHIP_ID_BCM4707:
- 	case BCMA_CHIP_ID_BCM5357:
- 	case BCMA_CHIP_ID_BCM53572:
- 		chip->ngpio	= 32;
diff --git a/target/linux/generic/patches-3.18/028-bcma-from-4.2.patch b/target/linux/generic/patches-3.18/028-bcma-from-4.2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1a9f472a4a7b5c9f8c8ae7f4864430809b25fd8d
--- /dev/null
+++ b/target/linux/generic/patches-3.18/028-bcma-from-4.2.patch
@@ -0,0 +1,37 @@
+--- a/drivers/bcma/driver_gpio.c
++++ b/drivers/bcma/driver_gpio.c
+@@ -226,6 +226,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+ 		chip->of_node	= cc->core->dev.of_node;
+ #endif
+ 	switch (bus->chipinfo.id) {
++	case BCMA_CHIP_ID_BCM4707:
+ 	case BCMA_CHIP_ID_BCM5357:
+ 	case BCMA_CHIP_ID_BCM53572:
+ 		chip->ngpio	= 32;
+@@ -235,16 +236,17 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+ 	}
+ 
+ 	/*
+-	 * On MIPS we register GPIO devices (LEDs, buttons) using absolute GPIO
+-	 * pin numbers. We don't have Device Tree there and we can't really use
+-	 * relative (per chip) numbers.
+-	 * So let's use predictable base for BCM47XX and "random" for all other.
++	 * Register SoC GPIO devices with absolute GPIO pin base.
++	 * On MIPS, we don't have Device Tree and we can't use relative (per chip)
++	 * GPIO numbers.
++	 * On some ARM devices, user space may want to access some system GPIO
++	 * pins directly, which is easier to do with a predictable GPIO base.
+ 	 */
+-#if IS_BUILTIN(CONFIG_BCM47XX)
+-	chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
+-#else
+-	chip->base		= -1;
+-#endif
++	if (IS_BUILTIN(CONFIG_BCM47XX) ||
++	    cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
++		chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
++	else
++		chip->base		= -1;
+ 
+ 	err = bcma_gpio_irq_domain_init(cc);
+ 	if (err)
diff --git a/target/linux/generic/patches-4.0/022-bcma-from-4.2.patch b/target/linux/generic/patches-4.0/022-bcma-from-4.2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1a9f472a4a7b5c9f8c8ae7f4864430809b25fd8d
--- /dev/null
+++ b/target/linux/generic/patches-4.0/022-bcma-from-4.2.patch
@@ -0,0 +1,37 @@
+--- a/drivers/bcma/driver_gpio.c
++++ b/drivers/bcma/driver_gpio.c
+@@ -226,6 +226,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+ 		chip->of_node	= cc->core->dev.of_node;
+ #endif
+ 	switch (bus->chipinfo.id) {
++	case BCMA_CHIP_ID_BCM4707:
+ 	case BCMA_CHIP_ID_BCM5357:
+ 	case BCMA_CHIP_ID_BCM53572:
+ 		chip->ngpio	= 32;
+@@ -235,16 +236,17 @@ int bcma_gpio_init(struct bcma_drv_cc *c
+ 	}
+ 
+ 	/*
+-	 * On MIPS we register GPIO devices (LEDs, buttons) using absolute GPIO
+-	 * pin numbers. We don't have Device Tree there and we can't really use
+-	 * relative (per chip) numbers.
+-	 * So let's use predictable base for BCM47XX and "random" for all other.
++	 * Register SoC GPIO devices with absolute GPIO pin base.
++	 * On MIPS, we don't have Device Tree and we can't use relative (per chip)
++	 * GPIO numbers.
++	 * On some ARM devices, user space may want to access some system GPIO
++	 * pins directly, which is easier to do with a predictable GPIO base.
+ 	 */
+-#if IS_BUILTIN(CONFIG_BCM47XX)
+-	chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
+-#else
+-	chip->base		= -1;
+-#endif
++	if (IS_BUILTIN(CONFIG_BCM47XX) ||
++	    cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
++		chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
++	else
++		chip->base		= -1;
+ 
+ 	err = bcma_gpio_irq_domain_init(cc);
+ 	if (err)