diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index ae7cbb7e78051c8028a12b530d52599673d2069a..f743a7304ea62ff89e588989d1c444cf3a7e3a7e 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -216,4 +216,17 @@ int sunxi_name_to_gpio_bank(const char *name);
 int sunxi_name_to_gpio(const char *name);
 #define name_to_gpio(name) sunxi_name_to_gpio(name)
 
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
+int axp_gpio_init(void);
+#else
+static inline int axp_gpio_init(void) { return 0; }
+#endif
+
+struct udevice;
+
+int axp_gpio_direction_input(struct udevice *dev, unsigned offset);
+int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val);
+int axp_gpio_get_value(struct udevice *dev, unsigned offset);
+int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);
+
 #endif /* _SUNXI_GPIO_H */
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index 64951871339d096b4fca67d65bd511ab25dd88c6..11e14d638e42ff32a57c12de3c44bb82f775bf23 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -340,6 +340,12 @@ config I2C4_ENABLE
 	See I2C0_ENABLE help text.
 endif
 
+config AXP_GPIO
+	boolean "Enable support for gpio-s on axp PMICs"
+	default n
+	---help---
+	Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+
 config VIDEO
 	boolean "Enable graphical uboot console on HDMI, LCD or VGA"
 	default y
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 9a486392b8fcf227998fc4b2e84406189a08c6db..50526104a5a633963494a05b0dee77aa313e01b3 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -80,7 +80,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /* add board specific code here */
 int board_init(void)
 {
-	int id_pfr1;
+	int id_pfr1, ret;
 
 	gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
 
@@ -93,6 +93,10 @@ int board_init(void)
 		asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(24000000));
 	}
 
+	ret = axp_gpio_init();
+	if (ret)
+		return ret;
+
 	/* Uses dm gpio code so do this here and not in i2c_init_board() */
 	return soft_i2c_board_init();
 }
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index b923d3e8acfb19721cf543a872f7b6cfa8a22b2d..ce94ba66d81d1c707f0ce8d00d1289991d06d68a 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -10,6 +10,7 @@ CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_AXP_GPIO=y
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
diff --git a/configs/Ainol_AW1_defconfig b/configs/Ainol_AW1_defconfig
index e5c2e21d2fdf85c931cc4ab022691b0025268125..5b3dd8b26f85e4bddc9202adbdf92a7e7c3c2834 100644
--- a/configs/Ainol_AW1_defconfig
+++ b/configs/Ainol_AW1_defconfig
@@ -10,6 +10,7 @@ CONFIG_MMC0_CD_PIN="PH1"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="PB9"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:40000,le:87,ri:112,up:38,lo:141,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="PH8"
 CONFIG_VIDEO_LCD_BL_EN="PH7"
diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig
index af7638d9edf3314099b19d2fc1696eecaf33468e..f4c7662e80306165a579fdde58335bc61d6b9bb6 100644
--- a/configs/Ampe_A76_defconfig
+++ b/configs/Ampe_A76_defconfig
@@ -9,6 +9,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_AXP_GPIO=y
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
diff --git a/configs/Astar_MID756_defconfig b/configs/Astar_MID756_defconfig
index 2634a27a68a91a0e9cbfc1bb0f51ec8ca4f5d261..2f3b71f97054aeae8eae213df534141f5f051614 100644
--- a/configs/Astar_MID756_defconfig
+++ b/configs/Astar_MID756_defconfig
@@ -8,6 +8,7 @@ CONFIG_FDTFILE="sun8i-a33-astar-mid756.dtb"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
index 52a390d1ff4db36eff1225a749135a843337df5a..b5d2f751f665a3ec82d1045efa9b10601597526c 100644
--- a/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
+++ b/configs/Ippo_q8h_v1_2_a33_1024x600_defconfig
@@ -6,6 +6,7 @@ CONFIG_FDTFILE="sun8i-a33-ippo-q8h-v1.2-lcd1024x600.dtb"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig
index d9455c8f35cceb7b15d6d0a61c5242a96388719b..5b0e82d3e42406be2cbbfad7597f7e2713c657a4 100644
--- a/configs/Ippo_q8h_v1_2_defconfig
+++ b/configs/Ippo_q8h_v1_2_defconfig
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v1.2.dtb"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig
index 4cc9a5e1eb795e91e6d2da6f42b22cde48ffa7c3..25cfb8e1607a5766cb5304962a85dc3804807794 100644
--- a/configs/Ippo_q8h_v5_defconfig
+++ b/configs/Ippo_q8h_v5_defconfig
@@ -4,6 +4,7 @@ CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v5.dtb"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_POWER="PH7"
diff --git a/configs/TZX-Q8-713B7_defconfig b/configs/TZX-Q8-713B7_defconfig
index 09535542811be97fa5845c46679bdc7f2eff6c4d..f22952694c92a279223b614763c462d22926bee1 100644
--- a/configs/TZX-Q8-713B7_defconfig
+++ b/configs/TZX-Q8-713B7_defconfig
@@ -9,6 +9,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_AXP_GPIO=y
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
diff --git a/configs/UTOO_P66_defconfig b/configs/UTOO_P66_defconfig
index 19ccd700d1a0b2e607affc78beef580050ba6ed1..7d97b3b9568bf2b56f8a16db725cf2bebdca21c3 100644
--- a/configs/UTOO_P66_defconfig
+++ b/configs/UTOO_P66_defconfig
@@ -11,6 +11,7 @@ CONFIG_VIDEO_LCD_RESET="PG11"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
 CONFIG_VIDEO_LCD_TL059WV5C0=y
+CONFIG_AXP_GPIO=y
 CONFIG_MMC_SUNXI_SLOT_EXTRA=2
 CONFIG_MMC0_CD_PIN="PG0"
 CONFIG_ARM=y
diff --git a/configs/Yones_Toptech_BD1078_defconfig b/configs/Yones_Toptech_BD1078_defconfig
index 00ede674ae9a7f72373b52bcfdd1d04f08ef598f..cc8e831990fef9da34b09fea6a7f5fd5b9a755b3 100644
--- a/configs/Yones_Toptech_BD1078_defconfig
+++ b/configs/Yones_Toptech_BD1078_defconfig
@@ -14,6 +14,7 @@ CONFIG_MMC1_PINS="PH"
 CONFIG_USB_MUSB_SUNXI=y
 CONFIG_USB0_VBUS_PIN="PB9"
 CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_AXP_GPIO=y
 CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:24,pclk_khz:63000,le:32,ri:287,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_DCLK_PHASE=0
 CONFIG_VIDEO_LCD_PANEL_LVDS=y
diff --git a/configs/forfun_q88db_defconfig b/configs/forfun_q88db_defconfig
index 8151eacb9b27a411a70b5f2d636d8e64aae70a33..2f2fa19ef4d37309458d703f10bf4ea9c34bac8a 100644
--- a/configs/forfun_q88db_defconfig
+++ b/configs/forfun_q88db_defconfig
@@ -8,6 +8,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_AXP_GPIO=y
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
diff --git a/configs/iNet_86VS_defconfig b/configs/iNet_86VS_defconfig
index e5c103f319f3484f70762e7e0d40a04a374f6b70..a5ac57fc090aa9c5ba081bfea1d130aa8620e132 100644
--- a/configs/iNet_86VS_defconfig
+++ b/configs/iNet_86VS_defconfig
@@ -8,6 +8,7 @@ CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo
 CONFIG_VIDEO_LCD_POWER="AXP0-0"
 CONFIG_VIDEO_LCD_BL_EN="AXP0-1"
 CONFIG_VIDEO_LCD_BL_PWM="PB2"
+CONFIG_AXP_GPIO=y
 CONFIG_ARM=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN5I=y
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fb40e09020b75cef7d52127cf3bb8da6a35ccc74..ba9efe8d541b2e7e74ae135df0ea9cb833d162da 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -7,6 +7,7 @@
 
 ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_DM_GPIO)		+= gpio-uclass.o
+obj-$(CONFIG_AXP_GPIO)		+= axp_gpio.o
 endif
 /* TODO(sjg@chromium.org): Only tegra supports driver model in SPL */
 ifdef CONFIG_TEGRA_GPIO
diff --git a/drivers/gpio/axp_gpio.c b/drivers/gpio/axp_gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..d04ec221ac0d672d9e0f7538850a995ce957482d
--- /dev/null
+++ b/drivers/gpio/axp_gpio.c
@@ -0,0 +1,147 @@
+/*
+ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * X-Powers AXP Power Management ICs gpio driver
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pmic_bus.h>
+#include <errno.h>
+
+#ifdef CONFIG_AXP152_POWER
+#include <axp152.h>
+#elif defined CONFIG_AXP209_POWER
+#include <axp209.h>
+#elif defined CONFIG_AXP221_POWER
+#include <axp221.h>
+#else
+#error Unknown AXP model
+#endif
+
+static u8 axp_get_gpio_ctrl_reg(unsigned pin)
+{
+	switch (pin) {
+	case 0: return AXP_GPIO0_CTRL;
+	case 1: return AXP_GPIO1_CTRL;
+#ifdef AXP_GPIO2_CTRL
+	case 2: return AXP_GPIO2_CTRL;
+#endif
+#ifdef AXP_GPIO3_CTRL
+	case 3: return AXP_GPIO3_CTRL;
+#endif
+	}
+	return 0;
+}
+
+int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
+{
+	u8 reg;
+
+	switch (pin) {
+#ifndef CONFIG_AXP152_POWER /* NA on axp152 */
+	case SUNXI_GPIO_AXP0_VBUS_DETECT:
+		return 0;
+#endif
+	default:
+		reg = axp_get_gpio_ctrl_reg(pin);
+		if (reg == 0)
+			return -EINVAL;
+
+		return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT);
+	}
+}
+
+int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val)
+{
+	__maybe_unused int ret;
+	u8 reg;
+
+	switch (pin) {
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+		ret = pmic_bus_clrbits(AXP221_MISC_CTRL,
+				       AXP221_MISC_CTRL_N_VBUSEN_FUNC);
+		if (ret)
+			return ret;
+
+		return axp_gpio_set_value(dev, pin, val);
+#endif
+	default:
+		reg = axp_get_gpio_ctrl_reg(pin);
+		if (reg == 0)
+			return -EINVAL;
+
+		return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
+						 AXP_GPIO_CTRL_OUTPUT_LOW);
+	}
+}
+
+int axp_gpio_get_value(struct udevice *dev, unsigned pin)
+{
+	u8 reg, val, mask;
+	int ret;
+
+	switch (pin) {
+#ifndef CONFIG_AXP152_POWER /* NA on axp152 */
+	case SUNXI_GPIO_AXP0_VBUS_DETECT:
+		ret = pmic_bus_read(AXP_POWER_STATUS, &val);
+		mask = AXP_POWER_STATUS_VBUS_PRESENT;
+		break;
+#endif
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+		ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val);
+		mask = AXP221_VBUS_IPSOUT_DRIVEBUS;
+		break;
+#endif
+	default:
+		reg = axp_get_gpio_ctrl_reg(pin);
+		if (reg == 0)
+			return -EINVAL;
+
+		ret = pmic_bus_read(AXP_GPIO_STATE, &val);
+		mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
+	}
+	if (ret)
+		return ret;
+
+	return (val & mask) ? 1 : 0;
+}
+
+int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
+{
+	u8 reg;
+
+	switch (pin) {
+#ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
+	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
+		if (val)
+			return pmic_bus_setbits(AXP221_VBUS_IPSOUT,
+						AXP221_VBUS_IPSOUT_DRIVEBUS);
+		else
+			return pmic_bus_clrbits(AXP221_VBUS_IPSOUT,
+						AXP221_VBUS_IPSOUT_DRIVEBUS);
+#endif
+	default:
+		reg = axp_get_gpio_ctrl_reg(pin);
+		if (reg == 0)
+			return -EINVAL;
+
+		return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
+						 AXP_GPIO_CTRL_OUTPUT_LOW);
+	}
+}
+
+int axp_gpio_init(void)
+{
+	int ret;
+
+	ret = pmic_bus_init();
+	if (ret)
+		return ret;
+
+	return 0;
+}
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 0774b709343fccfd7fedaae5fb71a4482f77178b..5a0b5e4aee0ae3a70e252b61b1c6e818282bbcba 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -15,15 +15,10 @@
 #include <errno.h>
 #include <fdtdec.h>
 #include <malloc.h>
+#include <asm/arch/gpio.h>
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
-#ifdef CONFIG_AXP209_POWER
-#include <axp209.h>
-#endif
-#ifdef CONFIG_AXP221_POWER
-#include <axp221.h>
-#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -79,7 +74,7 @@ int gpio_free(unsigned gpio)
 
 int gpio_direction_input(unsigned gpio)
 {
-#ifdef AXP_GPIO
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
 	if (gpio >= SUNXI_GPIO_AXP0_START)
 		return axp_gpio_direction_input(NULL, gpio - SUNXI_GPIO_AXP0_START);
 #endif
@@ -90,7 +85,7 @@ int gpio_direction_input(unsigned gpio)
 
 int gpio_direction_output(unsigned gpio, int value)
 {
-#ifdef AXP_GPIO
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
 	if (gpio >= SUNXI_GPIO_AXP0_START)
 		return axp_gpio_direction_output(NULL, gpio - SUNXI_GPIO_AXP0_START,
 						 value);
@@ -102,7 +97,7 @@ int gpio_direction_output(unsigned gpio, int value)
 
 int gpio_get_value(unsigned gpio)
 {
-#ifdef AXP_GPIO
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
 	if (gpio >= SUNXI_GPIO_AXP0_START)
 		return axp_gpio_get_value(NULL, gpio - SUNXI_GPIO_AXP0_START);
 #endif
@@ -111,7 +106,7 @@ int gpio_get_value(unsigned gpio)
 
 int gpio_set_value(unsigned gpio, int value)
 {
-#ifdef AXP_GPIO
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
 	if (gpio >= SUNXI_GPIO_AXP0_START)
 		return axp_gpio_set_value(NULL, gpio - SUNXI_GPIO_AXP0_START, value);
 #endif
@@ -125,7 +120,7 @@ int sunxi_name_to_gpio(const char *name)
 	long pin;
 	char *eptr;
 
-#ifdef AXP_GPIO
+#if !defined CONFIG_SPL_BUILD && defined CONFIG_AXP_GPIO
 	if (strncasecmp(name, "AXP0-", 5) == 0) {
 		name += 5;
 		if (strcmp(name, "VBUS-DETECT") == 0)
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index 98c214fa7ac6e783e5a0df8b16320263f8191d93..5161bc14729e2a6b83dd4f1caaac5fb13eab4543 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -155,67 +155,3 @@ int axp209_power_button(void)
 
 	return v & AXP209_IRQ5_PEK_DOWN;
 }
-
-static u8 axp209_get_gpio_ctrl_reg(unsigned int pin)
-{
-	switch (pin) {
-	case 0: return AXP209_GPIO0_CTRL;
-	case 1: return AXP209_GPIO1_CTRL;
-	case 2: return AXP209_GPIO2_CTRL;
-	case 3: return AXP209_GPIO3_CTRL;
-	}
-	return 0;
-}
-
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
-{
-	if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT)
-		return 0;
-
-	u8 reg = axp209_get_gpio_ctrl_reg(pin);
-	/* GPIO3 is "special" */
-	u8 val = (pin == 3) ? AXP209_GPIO3_INPUT : AXP209_GPIO_INPUT;
-
-	return axp209_write(reg, val);
-}
-
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val)
-{
-	u8 reg = axp209_get_gpio_ctrl_reg(pin);
-
-	if (val) {
-		val = (pin == 3) ? AXP209_GPIO3_OUTPUT_HIGH :
-				   AXP209_GPIO_OUTPUT_HIGH;
-	} else {
-		val = (pin == 3) ? AXP209_GPIO3_OUTPUT_LOW :
-				   AXP209_GPIO_OUTPUT_LOW;
-	}
-
-	return axp209_write(reg, val);
-}
-
-int axp_gpio_get_value(struct udevice *dev, unsigned pin)
-{
-	u8 val, mask;
-	int rc;
-
-	if (pin == SUNXI_GPIO_AXP0_VBUS_DETECT) {
-		rc = axp209_read(AXP209_POWER_STATUS, &val);
-		mask = AXP209_POWER_STATUS_VBUS_USABLE;
-	} else if (pin == 3) {
-		rc = axp209_read(AXP209_GPIO3_CTRL, &val);
-		mask = 1;
-	} else {
-		rc = axp209_read(AXP209_GPIO_STATE, &val);
-		mask = 1 << (pin + 4);
-	}
-	if (rc)
-		return rc;
-
-	return (val & mask) ? 1 : 0;
-}
-
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
-{
-	return axp_gpio_direction_output(dev, pin, val);
-}
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index d49de86e972b613211671f66c8d2200ba5f51a95..7bbaec87e455947788a66fcfedd665fb52217544 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -319,67 +319,3 @@ int axp221_get_sid(unsigned int *sid)
 
 	return 0;
 }
-
-int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
-{
-	switch (pin) {
-	case SUNXI_GPIO_AXP0_VBUS_DETECT:
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
-int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val)
-{
-	int ret;
-
-	switch (pin) {
-	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
-		ret = axp221_clrbits(AXP221_MISC_CTRL,
-				     AXP221_MISC_CTRL_N_VBUSEN_FUNC);
-		if (ret)
-			return ret;
-
-		return axp_gpio_set_value(dev, pin, val);
-	default:
-		return -EINVAL;
-	}
-}
-
-int axp_gpio_get_value(struct udevice *dev, unsigned pin)
-{
-	int ret;
-	u8 val;
-
-	switch (pin) {
-	case SUNXI_GPIO_AXP0_VBUS_DETECT:
-		ret = pmic_bus_read(AXP221_POWER_STATUS, &val);
-		if (ret)
-			return ret;
-
-		return !!(val & AXP221_POWER_STATUS_VBUS_AVAIL);
-	default:
-		return -EINVAL;
-	}
-}
-
-int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
-{
-	int ret;
-
-	switch (pin) {
-	case SUNXI_GPIO_AXP0_VBUS_ENABLE:
-		if (val)
-			ret = axp221_setbits(AXP221_VBUS_IPSOUT,
-					     AXP221_VBUS_IPSOUT_DRIVEBUS);
-		else
-			ret = axp221_clrbits(AXP221_VBUS_IPSOUT,
-					     AXP221_VBUS_IPSOUT_DRIVEBUS);
-
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
diff --git a/include/axp152.h b/include/axp152.h
index 9d205f8d3af5015c5c73f99d741633b5d68e0091..c3aef772104ce4342b047a4ebb080abacf1500d8 100644
--- a/include/axp152.h
+++ b/include/axp152.h
@@ -15,6 +15,17 @@ enum axp152_reg {
 
 #define AXP152_POWEROFF			(1 << 7)
 
+/* For axp_gpio.c */
+#define AXP_GPIO0_CTRL			0x90
+#define AXP_GPIO1_CTRL			0x91
+#define AXP_GPIO2_CTRL			0x92
+#define AXP_GPIO3_CTRL			0x93
+#define AXP_GPIO_CTRL_OUTPUT_LOW		0x00 /* Drive pin low */
+#define AXP_GPIO_CTRL_OUTPUT_HIGH		0x01 /* Drive pin high */
+#define AXP_GPIO_CTRL_INPUT			0x02 /* Input */
+#define AXP_GPIO_STATE			0x97
+#define AXP_GPIO_STATE_OFFSET			0
+
 int axp152_set_dcdc2(int mvolt);
 int axp152_set_dcdc3(int mvolt);
 int axp152_set_dcdc4(int mvolt);
diff --git a/include/axp209.h b/include/axp209.h
index fe4a1694b63add1d87f1ee4ebf6936c1ae757552..6170202b4c7b56156f82dc4a6a847dc035524d15 100644
--- a/include/axp209.h
+++ b/include/axp209.h
@@ -4,8 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-struct udevice;
-
 enum axp209_reg {
 	AXP209_POWER_STATUS = 0x00,
 	AXP209_CHIP_VERSION = 0x03,
@@ -20,11 +18,6 @@ enum axp209_reg {
 	AXP209_IRQ_ENABLE5 = 0x44,
 	AXP209_IRQ_STATUS5 = 0x4c,
 	AXP209_SHUTDOWN = 0x32,
-	AXP209_GPIO0_CTRL = 0x90,
-	AXP209_GPIO1_CTRL = 0x92,
-	AXP209_GPIO2_CTRL = 0x93,
-	AXP209_GPIO_STATE = 0x94,
-	AXP209_GPIO3_CTRL = 0x95,
 };
 
 #define AXP209_POWER_STATUS_ON_BY_DC	(1 << 0)
@@ -35,16 +28,17 @@ enum axp209_reg {
 
 #define AXP209_POWEROFF			(1 << 7)
 
-#define AXP209_GPIO_OUTPUT_LOW		0x00 /* Drive pin low */
-#define AXP209_GPIO_OUTPUT_HIGH		0x01 /* Drive pin high */
-#define AXP209_GPIO_INPUT		0x02 /* Float pin */
-
-/* GPIO3 is different from the others */
-#define AXP209_GPIO3_OUTPUT_LOW		0x00 /* Drive pin low, Output mode */
-#define AXP209_GPIO3_OUTPUT_HIGH	0x02 /* Float pin, Output mode */
-#define AXP209_GPIO3_INPUT		0x06 /* Float pin, Input mode */
-
-#define AXP_GPIO
+/* For axp_gpio.c */
+#define AXP_POWER_STATUS		0x00
+#define AXP_POWER_STATUS_VBUS_PRESENT		(1 << 5)
+#define AXP_GPIO0_CTRL			0x90
+#define AXP_GPIO1_CTRL			0x92
+#define AXP_GPIO2_CTRL			0x93
+#define AXP_GPIO_CTRL_OUTPUT_LOW		0x00 /* Drive pin low */
+#define AXP_GPIO_CTRL_OUTPUT_HIGH		0x01 /* Drive pin high */
+#define AXP_GPIO_CTRL_INPUT			0x02 /* Input */
+#define AXP_GPIO_STATE			0x94
+#define AXP_GPIO_STATE_OFFSET			4
 
 extern int axp209_set_dcdc2(int mvolt);
 extern int axp209_set_dcdc3(int mvolt);
@@ -54,8 +48,3 @@ extern int axp209_set_ldo4(int mvolt);
 extern int axp209_init(void);
 extern int axp209_poweron_by_dc(void);
 extern int axp209_power_button(void);
-
-extern int axp_gpio_direction_input(struct udevice *dev, unsigned offset);
-extern int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val);
-extern int axp_gpio_get_value(struct udevice *dev, unsigned offset);
-extern int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);
diff --git a/include/axp221.h b/include/axp221.h
index f62f7084babbc5dc9f6d3b954f227a25673df960..9c871623a87fbdbe5d2251dbce36311753bf4a46 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -6,12 +6,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-struct udevice;
-
 /* Page 0 addresses */
-#define AXP221_POWER_STATUS	0x00
-#define AXP221_POWER_STATUS_VBUS_AVAIL	(1 << 5)
-#define AXP221_POWER_STATUS_VBUS_USABLE	(1 << 4)
 #define AXP221_CHIP_ID		0x03
 #define AXP221_OUTPUT_CTRL1	0x10
 #define AXP221_OUTPUT_CTRL1_DCDC0_EN	(1 << 0)
@@ -57,7 +52,16 @@ struct udevice;
 /* Page 1 addresses */
 #define AXP221_SID		0x20
 
-#define AXP_GPIO
+/* For axp_gpio.c */
+#define AXP_POWER_STATUS		0x00
+#define AXP_POWER_STATUS_VBUS_PRESENT		(1 << 5)
+#define AXP_GPIO0_CTRL			0x90
+#define AXP_GPIO1_CTRL			0x92
+#define AXP_GPIO_CTRL_OUTPUT_LOW		0x00 /* Drive pin low */
+#define AXP_GPIO_CTRL_OUTPUT_HIGH		0x01 /* Drive pin high */
+#define AXP_GPIO_CTRL_INPUT			0x02 /* Input */
+#define AXP_GPIO_STATE			0x94
+#define AXP_GPIO_STATE_OFFSET			0
 
 int axp221_set_dcdc1(unsigned int mvolt);
 int axp221_set_dcdc2(unsigned int mvolt);
@@ -74,8 +78,3 @@ int axp221_set_aldo3(unsigned int mvolt);
 int axp221_set_eldo(int eldo_num, unsigned int mvolt);
 int axp221_init(void);
 int axp221_get_sid(unsigned int *sid);
-
-int axp_gpio_direction_input(struct udevice *dev, unsigned offset);
-int axp_gpio_direction_output(struct udevice *dev, unsigned offset, int val);
-int axp_gpio_get_value(struct udevice *dev, unsigned offset);
-int axp_gpio_set_value(struct udevice *dev, unsigned offset, int val);