diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index a4ab06964e208c380edb412521dc5e41874f1729..1d41d485558d4b3f4df131d51d5b4eaf6f3a06c4 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -261,7 +261,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \
 	sun8i-h3-orangepi-pc.dtb \
 	sun8i-h3-orangepi-pc-plus.dtb \
 	sun8i-h3-orangepi-plus.dtb \
-	sun8i-h3-orangepi-plus2e.dtb
+	sun8i-h3-orangepi-plus2e.dtb \
+	sun8i-h3-nanopi-neo.dtb
 dtb-$(CONFIG_MACH_SUN50I) += \
 	sun50i-a64-pine64-plus.dtb \
 	sun50i-a64-pine64.dtb
diff --git a/arch/arm/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/dts/sun8i-h3-nanopi-neo.dts
new file mode 100644
index 0000000000000000000000000000000000000000..3d64cafc1e90973d53fcf004981068ff347ec39a
--- /dev/null
+++ b/arch/arm/dts/sun8i-h3-nanopi-neo.dts
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 James Pettigrew <james@innovum.com.au>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "FriendlyARM NanoPi NEO";
+	compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&leds_opc>, <&leds_r_opc>;
+
+		pwr {
+			label = "nanopi:green:pwr";
+			gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */
+			default-state = "on";
+		};
+
+		status {
+			label = "nanopi:blue:status";
+			gpios = <&pio 0 10 GPIO_ACTIVE_HIGH>; /* PA10 */
+		};
+	};
+};
+
+&ehci3 {
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci3 {
+	status = "okay";
+};
+
+&pio {
+	leds_opc: led-pins {
+		allwinner,pins = "PA10";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&r_pio {
+	leds_r_opc: led-pins {
+		allwinner,pins = "PL10";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usbphy {
+	/* USB VBUS is always on */
+	status = "okay";
+};
diff --git a/arch/arm/include/asm/arch-sunxi/usb_phy.h b/arch/arm/include/asm/arch-sunxi/usb_phy.h
index 6a14cad3ff393d4b9c0acf466e17683e82a13822..cef6c985bc8d46c74dd11cdaac712e1b45f7975f 100644
--- a/arch/arm/include/asm/arch-sunxi/usb_phy.h
+++ b/arch/arm/include/asm/arch-sunxi/usb_phy.h
@@ -16,7 +16,6 @@ void sunxi_usb_phy_init(int index);
 void sunxi_usb_phy_exit(int index);
 void sunxi_usb_phy_power_on(int index);
 void sunxi_usb_phy_power_off(int index);
-int sunxi_usb_phy_power_is_on(int index);
 int sunxi_usb_phy_vbus_detect(int index);
 int sunxi_usb_phy_id_detect(int index);
 void sunxi_usb_phy_enable_squelch_detect(int index, int enable);
diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c
index f9993d28755149717095e31a4b847c6a30f58cc7..bd1bbee410ba35bc6c17a539d4ae38422c82093f 100644
--- a/arch/arm/mach-sunxi/usb_phy.c
+++ b/arch/arm/mach-sunxi/usb_phy.c
@@ -296,13 +296,6 @@ void sunxi_usb_phy_power_off(int index)
 		gpio_set_value(phy->gpio_vbus, 0);
 }
 
-int sunxi_usb_phy_power_is_on(int index)
-{
-	struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
-
-	return phy->power_on_count > 0;
-}
-
 int sunxi_usb_phy_vbus_detect(int index)
 {
 	struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS
index 6f13cf68df47265ed908bf7ff1b41367669e280b..f7129b7d53a5bd668ea1ca7530df27570dded0e3 100644
--- a/board/sunxi/MAINTAINERS
+++ b/board/sunxi/MAINTAINERS
@@ -217,6 +217,11 @@ M:	Siarhei Siamashka <siarhei.siamashka@gmail.com>
 S:	Maintained
 F:	configs/MSI_Primo81_defconfig
 
+NANOPI-NEO BOARD
+M:	Jelle van der Waa <jelle@vdwaa.nl>
+S:	Maintained
+F:	configs/nanopi_neo_defconfig
+
 R16 EVB PARROT BOARD
 M:	Quentin Schulz <quentin.schulz@free-electrons.com>
 S:	Maintained
diff --git a/configs/Sinlinx_SinA33_defconfig b/configs/Sinlinx_SinA33_defconfig
index 013c35e1a83523fb0f96298ff441d17f4ff5d5a1..b41bf67965801e2d6f03436bdc6f43cb80ce3901 100644
--- a/configs/Sinlinx_SinA33_defconfig
+++ b/configs/Sinlinx_SinA33_defconfig
@@ -3,9 +3,19 @@ CONFIG_ARCH_SUNXI=y
 CONFIG_MACH_SUN8I_A33=y
 CONFIG_DRAM_CLK=552
 CONFIG_DRAM_ZQ=15291
+CONFIG_MMC0_CD_PIN="PB4"
+CONFIG_USB0_ID_DET="PH8"
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-sinlinx-sina33"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL=y
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_DFU=y
 # CONFIG_CMD_FPGA is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_G_DNL_MANUFACTURER="Allwinner Technology"
+CONFIG_G_DNL_VENDOR_NUM=0x1f3a
+CONFIG_G_DNL_PRODUCT_NUM=0x1010
diff --git a/configs/nanopi_neo_defconfig b/configs/nanopi_neo_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..536c9cd13a8c6609636c199b3c6923e978b032c9
--- /dev/null
+++ b/configs/nanopi_neo_defconfig
@@ -0,0 +1,16 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_MACH_SUN8I_H3=y
+CONFIG_DRAM_CLK=408
+CONFIG_DRAM_ZQ=3881979
+CONFIG_DRAM_ODT_EN=y
+CONFIG_MMC0_CD_PIN="PF6"
+# CONFIG_VIDEO is not set
+CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-neo"
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPL=y
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_SUN8I_EMAC=y
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
index fc162a149eb37d4edf1aa1d4ee911c3afb904f86..731b75e50a04924a1c61ce4dada402f2cca0f64e 100644
--- a/drivers/power/axp209.c
+++ b/drivers/power/axp209.c
@@ -167,6 +167,22 @@ int axp_init(void)
 			return rc;
 	}
 
+	/*
+	 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
+	 * from android these are sometimes on.
+	 */
+	rc = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
+	if (rc)
+		return rc;
+
+	rc = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
+	if (rc)
+		return rc;
+
+	rc = pmic_bus_write(AXP_GPIO2_CTRL, AXP_GPIO_CTRL_INPUT);
+	if (rc)
+		return rc;
+
 	return 0;
 }
 
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 727ab098068fe485d49e35d44549d402e06de3ef..109d3f468631d213e480c006f4796497c6df8680 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -223,6 +223,18 @@ int axp_init(void)
 	if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
 		return -ENODEV;
 
+	/*
+	 * Turn off LDOIO regulators / tri-state GPIO pins, when rebooting
+	 * from android these are sometimes on.
+	 */
+	ret = pmic_bus_write(AXP_GPIO0_CTRL, AXP_GPIO_CTRL_INPUT);
+	if (ret)
+		return ret;
+
+	ret = pmic_bus_write(AXP_GPIO1_CTRL, AXP_GPIO_CTRL_INPUT);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index c016a0bb544dd82a86a6a6dfe780d58c5bcc426f..469377fe4e6ddcdc98a277b2c6a81378732569c1 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -201,10 +201,11 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
 
 /* musb_core does not call enable / disable in a balanced manner <sigh> */
 static bool enabled = false;
-static struct musb *sunxi_musb;
 
 static int sunxi_musb_enable(struct musb *musb)
 {
+	int ret;
+
 	pr_debug("%s():\n", __func__);
 
 	musb_ep_select(musb->mregs, 0);
@@ -217,26 +218,17 @@ static int sunxi_musb_enable(struct musb *musb)
 	musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
 
 	if (is_host_enabled(musb)) {
-		int id = sunxi_usb_phy_id_detect(0);
-
-		if (id == 1 && sunxi_usb_phy_power_is_on(0))
-			sunxi_usb_phy_power_off(0);
-
-		if (!sunxi_usb_phy_power_is_on(0)) {
-			int vbus = sunxi_usb_phy_vbus_detect(0);
-			if (vbus == 1) {
-				printf("A charger is plugged into the OTG: ");
-				return -ENODEV;
-			}
+		ret = sunxi_usb_phy_vbus_detect(0);
+		if (ret == 1) {
+			printf("A charger is plugged into the OTG: ");
+			return -ENODEV;
 		}
-
-		if (id == 1) {
+		ret = sunxi_usb_phy_id_detect(0);
+		if (ret == 1) {
 			printf("No host cable detected: ");
 			return -ENODEV;
 		}
-
-		if (!sunxi_usb_phy_power_is_on(0))
-			sunxi_usb_phy_power_on(0);
+		sunxi_usb_phy_power_on(0); /* port power on */
 	}
 
 	USBC_ForceVbusValidToHigh(musb->mregs);
@@ -252,6 +244,9 @@ static void sunxi_musb_disable(struct musb *musb)
 	if (!enabled)
 		return;
 
+	if (is_host_enabled(musb))
+		sunxi_usb_phy_power_off(0); /* port power off */
+
 	USBC_ForceVbusValidToLow(musb->mregs);
 	mdelay(200); /* Wait for the current session to timeout */
 
@@ -313,7 +308,9 @@ static struct musb_hdrc_platform_data musb_plat = {
 };
 
 #ifdef CONFIG_USB_MUSB_HOST
-int musb_usb_probe(struct udevice *dev)
+static int musb_usb_remove(struct udevice *dev);
+
+static int musb_usb_probe(struct udevice *dev)
 {
 	struct musb_host_data *host = dev_get_priv(dev);
 	struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
@@ -321,23 +318,21 @@ int musb_usb_probe(struct udevice *dev)
 
 	priv->desc_before_addr = true;
 
-	if (!sunxi_musb) {
-		sunxi_musb = musb_init_controller(&musb_plat, NULL,
-						  (void *)SUNXI_USB0_BASE);
-	}
-
-	host->host = sunxi_musb;
+	host->host = musb_init_controller(&musb_plat, NULL,
+					  (void *)SUNXI_USB0_BASE);
 	if (!host->host)
 		return -EIO;
 
 	ret = musb_lowlevel_init(host);
 	if (ret == 0)
 		printf("MUSB OTG\n");
+	else
+		musb_usb_remove(dev);
 
 	return ret;
 }
 
-int musb_usb_remove(struct udevice *dev)
+static int musb_usb_remove(struct udevice *dev)
 {
 	struct musb_host_data *host = dev_get_priv(dev);
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
@@ -350,6 +345,9 @@ int musb_usb_remove(struct udevice *dev)
 #endif
 	clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
 
+	free(host->host);
+	host->host = NULL;
+
 	return 0;
 }