diff --git a/config/kernel/linux-sun50i-dev.config b/config/kernel/linux-sun50i-dev.config
index f854136f3..3817be67e 100644
--- a/config/kernel/linux-sun50i-dev.config
+++ b/config/kernel/linux-sun50i-dev.config
@@ -1,6 +1,6 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Linux/arm64 4.10.0 Kernel Configuration
+# Linux/arm64 4.11.0 Kernel Configuration
 #
 CONFIG_ARM64=y
 CONFIG_64BIT=y
@@ -231,6 +231,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_CONTIGUOUS=y
 CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
 CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
@@ -315,6 +316,7 @@ CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_MSDOS_PARTITION=y
 CONFIG_EFI_PARTITION=y
 CONFIG_BLOCK_COMPAT=y
+CONFIG_BLK_MQ_VIRTIO=y
 
 #
 # IO Schedulers
@@ -328,13 +330,6 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_MQ_IOSCHED_DEADLINE=y
-CONFIG_MQ_IOSCHED_NONE=y
-# CONFIG_DEFAULT_SQ_DEADLINE is not set
-CONFIG_DEFAULT_SQ_NONE=y
-CONFIG_DEFAULT_SQ_IOSCHED="none"
-# CONFIG_DEFAULT_MQ_DEADLINE is not set
-CONFIG_DEFAULT_MQ_NONE=y
-CONFIG_DEFAULT_MQ_IOSCHED="none"
 CONFIG_PADATA=y
 CONFIG_ASN1=y
 CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
@@ -388,6 +383,10 @@ CONFIG_ARCH_SUNXI=y
 # CONFIG_PCI_DOMAINS_GENERIC is not set
 # CONFIG_PCI_SYSCALL is not set
 
+#
+# DesignWare PCI Core Support
+#
+
 #
 # Kernel Features
 #
@@ -407,6 +406,7 @@ CONFIG_ARM64_ERRATUM_843419=y
 # CONFIG_CAVIUM_ERRATUM_27456 is not set
 # CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
 # CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
+# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
 CONFIG_ARM64_4K_PAGES=y
 # CONFIG_ARM64_16K_PAGES is not set
 # CONFIG_ARM64_64K_PAGES is not set
@@ -519,6 +519,7 @@ CONFIG_BINFMT_MISC=y
 CONFIG_COREDUMP=y
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
+CONFIG_KEYS_COMPAT=y
 
 #
 # Power management options
@@ -2160,7 +2161,6 @@ CONFIG_PINCTRL_SUNXI=y
 # CONFIG_PINCTRL_SUN4I_A10 is not set
 # CONFIG_PINCTRL_SUN5I is not set
 # CONFIG_PINCTRL_SUN6I_A31 is not set
-# CONFIG_PINCTRL_SUN6I_A31S is not set
 # CONFIG_PINCTRL_SUN6I_A31_R is not set
 # CONFIG_PINCTRL_SUN7I_A20 is not set
 # CONFIG_PINCTRL_SUN8I_A23 is not set
@@ -2175,7 +2175,6 @@ CONFIG_PINCTRL_SUN8I_H3_R=y
 CONFIG_PINCTRL_SUN50I_A64=y
 CONFIG_PINCTRL_SUN50I_A64_R=y
 CONFIG_PINCTRL_SUN50I_H5=y
-# CONFIG_PINCTRL_TI_IODELAY is not set
 CONFIG_GPIOLIB=y
 CONFIG_OF_GPIO=y
 # CONFIG_DEBUG_GPIO is not set
@@ -2443,7 +2442,6 @@ CONFIG_THERMAL_EMULATION=y
 #
 # ACPI INT340X thermal drivers
 #
-CONFIG_SUN8I_THS=y
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_CORE=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -2625,13 +2623,77 @@ CONFIG_REGULATOR_QCOM_SPMI=y
 # CONFIG_REGULATOR_S2MPA01 is not set
 CONFIG_REGULATOR_S2MPS11=y
 # CONFIG_REGULATOR_S5M8767 is not set
-CONFIG_REGULATOR_SY8106A=y
 # CONFIG_REGULATOR_TPS51632 is not set
 # CONFIG_REGULATOR_TPS62360 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
 # CONFIG_REGULATOR_TPS6507X is not set
 # CONFIG_REGULATOR_TPS6524X is not set
-# CONFIG_MEDIA_SUPPORT is not set
+CONFIG_MEDIA_SUPPORT=m
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CAMERA_SUPPORT is not set
+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
+# CONFIG_MEDIA_RADIO_SUPPORT is not set
+# CONFIG_MEDIA_SDR_SUPPORT is not set
+CONFIG_MEDIA_RC_SUPPORT=y
+# CONFIG_MEDIA_CEC_SUPPORT is not set
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Media drivers
+#
+CONFIG_RC_CORE=m
+CONFIG_RC_MAP=m
+CONFIG_RC_DECODERS=y
+CONFIG_LIRC=m
+CONFIG_IR_LIRC_CODEC=m
+CONFIG_IR_NEC_DECODER=m
+CONFIG_IR_RC5_DECODER=m
+CONFIG_IR_RC6_DECODER=m
+CONFIG_IR_JVC_DECODER=m
+CONFIG_IR_SONY_DECODER=m
+CONFIG_IR_SANYO_DECODER=m
+CONFIG_IR_SHARP_DECODER=m
+CONFIG_IR_MCE_KBD_DECODER=m
+CONFIG_IR_XMP_DECODER=m
+CONFIG_RC_DEVICES=y
+# CONFIG_RC_ATI_REMOTE is not set
+# CONFIG_IR_HIX5HD2 is not set
+# CONFIG_IR_IMON is not set
+# CONFIG_IR_MCEUSB is not set
+# CONFIG_IR_REDRAT3 is not set
+# CONFIG_IR_SPI is not set
+# CONFIG_IR_STREAMZAP is not set
+# CONFIG_IR_IGORPLUGUSB is not set
+# CONFIG_IR_IGUANA is not set
+# CONFIG_IR_TTUSBIR is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_IR_GPIO_CIR is not set
+CONFIG_IR_SUNXI=m
+# CONFIG_IR_SERIAL is not set
+# CONFIG_MEDIA_USB_SUPPORT is not set
+
+#
+# Supported MMC/SDIO adapters
+#
+# CONFIG_CYPRESS_FIRMWARE is not set
+
+#
+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends)
+#
+
+#
+# Customise DVB Frontends
+#
+
+#
+# Tools to develop new frontends
+#
 
 #
 # Graphics support
@@ -2830,7 +2892,8 @@ CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_CS42XX8_I2C is not set
 # CONFIG_SND_SOC_CS4349 is not set
 # CONFIG_SND_SOC_CS53L30 is not set
-# CONFIG_SND_SOC_ES8328 is not set
+# CONFIG_SND_SOC_ES8328_I2C is not set
+# CONFIG_SND_SOC_ES8328_SPI is not set
 # CONFIG_SND_SOC_GTM601 is not set
 # CONFIG_SND_SOC_INNO_RK3036 is not set
 # CONFIG_SND_SOC_MAX98504 is not set
@@ -3549,7 +3612,7 @@ CONFIG_SUN50I_A64_CCU=y
 # CONFIG_SUN6I_A31_CCU is not set
 # CONFIG_SUN8I_A23_CCU is not set
 # CONFIG_SUN8I_A33_CCU is not set
-CONFIG_SUNXI_H3_H5_CCU=y
+CONFIG_SUN8I_H3_CCU=y
 # CONFIG_SUN8I_V3S_CCU is not set
 # CONFIG_SUN9I_A80_CCU is not set
 CONFIG_SUN8I_R_CCU=y
@@ -3566,7 +3629,9 @@ CONFIG_CLKSRC_PROBE=y
 CONFIG_CLKSRC_MMIO=y
 CONFIG_ARM_ARCH_TIMER=y
 CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
+CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
 CONFIG_FSL_ERRATUM_A008585=y
+# CONFIG_HISILICON_ERRATUM_161010101 is not set
 CONFIG_ARM_TIMER_SP804=y
 # CONFIG_ATMEL_PIT is not set
 # CONFIG_SH_TIMER_CMT is not set
@@ -4028,6 +4093,7 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_PAGE_EXTENSION is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_PAGE_POISONING is not set
+# CONFIG_DEBUG_RODATA_TEST is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
@@ -4064,7 +4130,6 @@ CONFIG_SCHED_INFO=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_SCHED_STACK_END_CHECK is not set
 # CONFIG_DEBUG_TIMEKEEPING is not set
-# CONFIG_TIMER_STATS is not set
 
 #
 # Lock Debugging (spinlocks, mutexes, etc...)
@@ -4348,7 +4413,6 @@ CONFIG_CRYPTO_USER_API_AEAD=y
 #
 # Certificates for signature checking
 #
-# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
 CONFIG_ARM64_CRYPTO=y
 CONFIG_CRYPTO_SHA256_ARM64=y
 CONFIG_CRYPTO_SHA512_ARM64=y
@@ -4426,6 +4490,8 @@ CONFIG_RADIX_TREE_MULTIORDER=y
 CONFIG_ASSOCIATIVE_ARRAY=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_DMA=y
+# CONFIG_DMA_NOOP_OPS is not set
+# CONFIG_DMA_VIRT_OPS is not set
 CONFIG_CPU_RMAP=y
 CONFIG_DQL=y
 CONFIG_GLOB=y
@@ -4446,5 +4512,3 @@ CONFIG_FONT_8x16=y
 CONFIG_SG_POOL=y
 CONFIG_ARCH_HAS_SG_CHAIN=y
 CONFIG_SBITMAP=y
-# CONFIG_PARMAN is not set
-CONFIG_PRIME_NUMBERS=m
diff --git a/config/sources/sunxi64_common.inc b/config/sources/sunxi64_common.inc
index 66a8bef97..951feba57 100644
--- a/config/sources/sunxi64_common.inc
+++ b/config/sources/sunxi64_common.inc
@@ -13,9 +13,10 @@ case $BRANCH in
 	BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd'
 
 	KERNELSOURCE='https://github.com/Icenowy/linux/'
-	KERNELBRANCH='branch:sunxi64-next-20170216'
+	KERNELBRANCH='branch:sunxi64-4.11.y'
 	KERNELDIR='linux-sun50i-dev'
 	KERNEL_USE_GCC='> 6.1'
 	LINUXCONFIG='linux-sun50i-dev'
+	KERNELPATCHDIR='sun50i-dev'
 	;;
 esac
diff --git a/patch/kernel/sun50iw1-dev/add-mtd-spi-nor-dts.patch.disabled b/patch/kernel/sun50i-dev/add-mtd-spi-nor-dts.patch.disabled
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add-mtd-spi-nor-dts.patch.disabled
rename to patch/kernel/sun50i-dev/add-mtd-spi-nor-dts.patch.disabled
diff --git a/patch/kernel/sun50iw1-dev/add-overlay-compilation-support.patch b/patch/kernel/sun50i-dev/add-overlay-compilation-support.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add-overlay-compilation-support.patch
rename to patch/kernel/sun50i-dev/add-overlay-compilation-support.patch
diff --git a/patch/kernel/sun50iw2-dev/add-spi-flash-pc2.patch b/patch/kernel/sun50i-dev/add-spi-flash-pc2.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add-spi-flash-pc2.patch
rename to patch/kernel/sun50i-dev/add-spi-flash-pc2.patch
diff --git a/patch/kernel/sun50iw1-dev/add_BergMicro_flashes_to_SPI-NOR.patch b/patch/kernel/sun50i-dev/add_BergMicro_flashes_to_SPI-NOR.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add_BergMicro_flashes_to_SPI-NOR.patch
rename to patch/kernel/sun50i-dev/add_BergMicro_flashes_to_SPI-NOR.patch
diff --git a/patch/kernel/sun50iw1-dev/add_configfs_overlay_for_v4.10.x.patch b/patch/kernel/sun50i-dev/add_configfs_overlay_for_v4.10.x.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add_configfs_overlay_for_v4.10.x.patch
rename to patch/kernel/sun50i-dev/add_configfs_overlay_for_v4.10.x.patch
diff --git a/patch/kernel/sun50iw1-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch b/patch/kernel/sun50i-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch
rename to patch/kernel/sun50i-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch
diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_spi.patch b/patch/kernel/sun50i-dev/add_sun50i_a64_spi.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_sun50i_a64_spi.patch
rename to patch/kernel/sun50i-dev/add_sun50i_a64_spi.patch
diff --git a/patch/kernel/sun50iw1-dev/enable-fsl-timer-errata.patch b/patch/kernel/sun50i-dev/enable-fsl-timer-errata.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/enable-fsl-timer-errata.patch
rename to patch/kernel/sun50i-dev/enable-fsl-timer-errata.patch
diff --git a/patch/kernel/sun50iw2-dev/packaging-4.x-DEV-with-postinstall-scripts.patch b/patch/kernel/sun50i-dev/packaging-4.x-DEV-with-postinstall-scripts.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/packaging-4.x-DEV-with-postinstall-scripts.patch
rename to patch/kernel/sun50i-dev/packaging-4.x-DEV-with-postinstall-scripts.patch
diff --git a/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch b/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch
new file mode 100644
index 000000000..89d2a2adc
--- /dev/null
+++ b/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch
@@ -0,0 +1,3046 @@
+diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
+index 3d18e453..5adfc8f5 100644
+--- a/scripts/dtc/checks.c
++++ b/scripts/dtc/checks.c
+@@ -72,17 +72,16 @@ struct check {
+ #define CHECK(_nm, _fn, _d, ...) \
+ 	CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
+ 
+-#ifdef __GNUC__
+-static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
+-#endif
+-static inline void check_msg(struct check *c, const char *fmt, ...)
++static inline void  PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
++					   const char *fmt, ...)
+ {
+ 	va_list ap;
+ 	va_start(ap, fmt);
+ 
+ 	if ((c->warn && (quiet < 1))
+ 	    || (c->error && (quiet < 2))) {
+-		fprintf(stderr, "%s (%s): ",
++		fprintf(stderr, "%s: %s (%s): ",
++			strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
+ 			(c->error) ? "ERROR" : "Warning", c->name);
+ 		vfprintf(stderr, fmt, ap);
+ 		fprintf(stderr, "\n");
+@@ -90,11 +89,11 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
+ 	va_end(ap);
+ }
+ 
+-#define FAIL(c, ...) \
+-	do { \
+-		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
+-		(c)->status = FAILED; \
+-		check_msg((c), __VA_ARGS__); \
++#define FAIL(c, dti, ...)						\
++	do {								\
++		TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__);	\
++		(c)->status = FAILED;					\
++		check_msg((c), dti, __VA_ARGS__);			\
+ 	} while (0)
+ 
+ static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
+@@ -127,7 +126,7 @@ static bool run_check(struct check *c, struct dt_info *dti)
+ 		error = error || run_check(prq, dti);
+ 		if (prq->status != PASSED) {
+ 			c->status = PREREQ;
+-			check_msg(c, "Failed prerequisite '%s'",
++			check_msg(c, dti, "Failed prerequisite '%s'",
+ 				  c->prereq[i]->name);
+ 		}
+ 	}
+@@ -157,7 +156,7 @@ static bool run_check(struct check *c, struct dt_info *dti)
+ static inline void check_always_fail(struct check *c, struct dt_info *dti,
+ 				     struct node *node)
+ {
+-	FAIL(c, "always_fail check");
++	FAIL(c, dti, "always_fail check");
+ }
+ CHECK(always_fail, check_always_fail, NULL);
+ 
+@@ -172,7 +171,7 @@ static void check_is_string(struct check *c, struct dt_info *dti,
+ 		return; /* Not present, assumed ok */
+ 
+ 	if (!data_is_one_string(prop->val))
+-		FAIL(c, "\"%s\" property in %s is not a string",
++		FAIL(c, dti, "\"%s\" property in %s is not a string",
+ 		     propname, node->fullpath);
+ }
+ #define WARNING_IF_NOT_STRING(nm, propname) \
+@@ -191,7 +190,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti,
+ 		return; /* Not present, assumed ok */
+ 
+ 	if (prop->val.len != sizeof(cell_t))
+-		FAIL(c, "\"%s\" property in %s is not a single cell",
++		FAIL(c, dti, "\"%s\" property in %s is not a single cell",
+ 		     propname, node->fullpath);
+ }
+ #define WARNING_IF_NOT_CELL(nm, propname) \
+@@ -213,7 +212,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
+ 		     child2;
+ 		     child2 = child2->next_sibling)
+ 			if (streq(child->name, child2->name))
+-				FAIL(c, "Duplicate node name %s",
++				FAIL(c, dti, "Duplicate node name %s",
+ 				     child->fullpath);
+ }
+ ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
+@@ -228,7 +227,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
+ 			if (prop2->deleted)
+ 				continue;
+ 			if (streq(prop->name, prop2->name))
+-				FAIL(c, "Duplicate property name %s in %s",
++				FAIL(c, dti, "Duplicate property name %s in %s",
+ 				     prop->name, node->fullpath);
+ 		}
+ 	}
+@@ -239,6 +238,7 @@ ERROR(duplicate_property_names, check_duplicate_property_names, NULL);
+ #define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ #define DIGITS		"0123456789"
+ #define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
++#define PROPNODECHARSSTRICT	LOWERCASE UPPERCASE DIGITS ",-"
+ 
+ static void check_node_name_chars(struct check *c, struct dt_info *dti,
+ 				  struct node *node)
+@@ -246,16 +246,27 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti,
+ 	int n = strspn(node->name, c->data);
+ 
+ 	if (n < strlen(node->name))
+-		FAIL(c, "Bad character '%c' in node %s",
++		FAIL(c, dti, "Bad character '%c' in node %s",
+ 		     node->name[n], node->fullpath);
+ }
+ ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
+ 
++static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
++					 struct node *node)
++{
++	int n = strspn(node->name, c->data);
++
++	if (n < node->basenamelen)
++		FAIL(c, dti, "Character '%c' not recommended in node %s",
++		     node->name[n], node->fullpath);
++}
++CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
++
+ static void check_node_name_format(struct check *c, struct dt_info *dti,
+ 				   struct node *node)
+ {
+ 	if (strchr(get_unitname(node), '@'))
+-		FAIL(c, "Node %s has multiple '@' characters in name",
++		FAIL(c, dti, "Node %s has multiple '@' characters in name",
+ 		     node->fullpath);
+ }
+ ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
+@@ -274,11 +285,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
+ 
+ 	if (prop) {
+ 		if (!unitname[0])
+-			FAIL(c, "Node %s has a reg or ranges property, but no unit name",
++			FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name",
+ 			    node->fullpath);
+ 	} else {
+ 		if (unitname[0])
+-			FAIL(c, "Node %s has a unit name, but no reg property",
++			FAIL(c, dti, "Node %s has a unit name, but no reg property",
+ 			    node->fullpath);
+ 	}
+ }
+@@ -293,12 +304,44 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti,
+ 		int n = strspn(prop->name, c->data);
+ 
+ 		if (n < strlen(prop->name))
+-			FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
++			FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s",
+ 			     prop->name[n], prop->name, node->fullpath);
+ 	}
+ }
+ ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
+ 
++static void check_property_name_chars_strict(struct check *c,
++					     struct dt_info *dti,
++					     struct node *node)
++{
++	struct property *prop;
++
++	for_each_property(node, prop) {
++		const char *name = prop->name;
++		int n = strspn(name, c->data);
++
++		if (n == strlen(prop->name))
++			continue;
++
++		/* Certain names are whitelisted */
++		if (streq(name, "device_type"))
++			continue;
++
++		/*
++		 * # is only allowed at the beginning of property names not counting
++		 * the vendor prefix.
++		 */
++		if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) {
++			name += n + 1;
++			n = strspn(name, c->data);
++		}
++		if (n < strlen(name))
++			FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s",
++			     name[n], prop->name, node->fullpath);
++	}
++}
++CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
++
+ #define DESCLABEL_FMT	"%s%s%s%s%s"
+ #define DESCLABEL_ARGS(node,prop,mark)		\
+ 	((mark) ? "value of " : ""),		\
+@@ -327,7 +370,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti,
+ 		return;
+ 
+ 	if ((othernode != node) || (otherprop != prop) || (othermark != mark))
+-		FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
++		FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT
+ 		     " and " DESCLABEL_FMT,
+ 		     label, DESCLABEL_ARGS(node, prop, mark),
+ 		     DESCLABEL_ARGS(othernode, otherprop, othermark));
+@@ -367,7 +410,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
+ 		return 0;
+ 
+ 	if (prop->val.len != sizeof(cell_t)) {
+-		FAIL(c, "%s has bad length (%d) %s property",
++		FAIL(c, dti, "%s has bad length (%d) %s property",
+ 		     node->fullpath, prop->val.len, prop->name);
+ 		return 0;
+ 	}
+@@ -379,7 +422,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
+ 			/* "Set this node's phandle equal to some
+ 			 * other node's phandle".  That's nonsensical
+ 			 * by construction. */ {
+-			FAIL(c, "%s in %s is a reference to another node",
++			FAIL(c, dti, "%s in %s is a reference to another node",
+ 			     prop->name, node->fullpath);
+ 		}
+ 		/* But setting this node's phandle equal to its own
+@@ -393,7 +436,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
+ 	phandle = propval_cell(prop);
+ 
+ 	if ((phandle == 0) || (phandle == -1)) {
+-		FAIL(c, "%s has bad value (0x%x) in %s property",
++		FAIL(c, dti, "%s has bad value (0x%x) in %s property",
+ 		     node->fullpath, phandle, prop->name);
+ 		return 0;
+ 	}
+@@ -420,7 +463,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti,
+ 		return;
+ 
+ 	if (linux_phandle && phandle && (phandle != linux_phandle))
+-		FAIL(c, "%s has mismatching 'phandle' and 'linux,phandle'"
++		FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'"
+ 		     " properties", node->fullpath);
+ 
+ 	if (linux_phandle && !phandle)
+@@ -428,7 +471,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti,
+ 
+ 	other = get_node_by_phandle(root, phandle);
+ 	if (other && (other != node)) {
+-		FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
++		FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)",
+ 		     node->fullpath, phandle, other->fullpath);
+ 		return;
+ 	}
+@@ -453,7 +496,7 @@ static void check_name_properties(struct check *c, struct dt_info *dti,
+ 
+ 	if ((prop->val.len != node->basenamelen+1)
+ 	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
+-		FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
++		FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead"
+ 		     " of base node name)", node->fullpath, prop->val.val);
+ 	} else {
+ 		/* The name property is correct, and therefore redundant.
+@@ -488,16 +531,16 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
+ 			refnode = get_node_by_ref(dt, m->ref);
+ 			if (! refnode) {
+ 				if (!(dti->dtsflags & DTSF_PLUGIN))
+-					FAIL(c, "Reference to non-existent node or "
++					FAIL(c, dti, "Reference to non-existent node or "
+ 							"label \"%s\"\n", m->ref);
+ 				else /* mark the entry as unresolved */
+-					*((cell_t *)(prop->val.val + m->offset)) =
++					*((fdt32_t *)(prop->val.val + m->offset)) =
+ 						cpu_to_fdt32(0xffffffff);
+ 				continue;
+ 			}
+ 
+ 			phandle = get_node_phandle(dt, refnode);
+-			*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
++			*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
+ 		}
+ 	}
+ }
+@@ -520,7 +563,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
+ 
+ 			refnode = get_node_by_ref(dt, m->ref);
+ 			if (!refnode) {
+-				FAIL(c, "Reference to non-existent node or label \"%s\"\n",
++				FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n",
+ 				     m->ref);
+ 				continue;
+ 			}
+@@ -579,19 +622,19 @@ static void check_reg_format(struct check *c, struct dt_info *dti,
+ 		return; /* No "reg", that's fine */
+ 
+ 	if (!node->parent) {
+-		FAIL(c, "Root node has a \"reg\" property");
++		FAIL(c, dti, "Root node has a \"reg\" property");
+ 		return;
+ 	}
+ 
+ 	if (prop->val.len == 0)
+-		FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
++		FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath);
+ 
+ 	addr_cells = node_addr_cells(node->parent);
+ 	size_cells = node_size_cells(node->parent);
+ 	entrylen = (addr_cells + size_cells) * sizeof(cell_t);
+ 
+ 	if (!entrylen || (prop->val.len % entrylen) != 0)
+-		FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
++		FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) "
+ 		     "(#address-cells == %d, #size-cells == %d)",
+ 		     node->fullpath, prop->val.len, addr_cells, size_cells);
+ }
+@@ -608,7 +651,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
+ 		return;
+ 
+ 	if (!node->parent) {
+-		FAIL(c, "Root node has a \"ranges\" property");
++		FAIL(c, dti, "Root node has a \"ranges\" property");
+ 		return;
+ 	}
+ 
+@@ -620,17 +663,17 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
+ 
+ 	if (prop->val.len == 0) {
+ 		if (p_addr_cells != c_addr_cells)
+-			FAIL(c, "%s has empty \"ranges\" property but its "
++			FAIL(c, dti, "%s has empty \"ranges\" property but its "
+ 			     "#address-cells (%d) differs from %s (%d)",
+ 			     node->fullpath, c_addr_cells, node->parent->fullpath,
+ 			     p_addr_cells);
+ 		if (p_size_cells != c_size_cells)
+-			FAIL(c, "%s has empty \"ranges\" property but its "
++			FAIL(c, dti, "%s has empty \"ranges\" property but its "
+ 			     "#size-cells (%d) differs from %s (%d)",
+ 			     node->fullpath, c_size_cells, node->parent->fullpath,
+ 			     p_size_cells);
+ 	} else if ((prop->val.len % entrylen) != 0) {
+-		FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
++		FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) "
+ 		     "(parent #address-cells == %d, child #address-cells == %d, "
+ 		     "#size-cells == %d)", node->fullpath, prop->val.len,
+ 		     p_addr_cells, c_addr_cells, c_size_cells);
+@@ -638,6 +681,229 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
+ }
+ WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
+ 
++static const struct bus_type pci_bus = {
++	.name = "PCI",
++};
++
++static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node)
++{
++	struct property *prop;
++	cell_t *cells;
++
++	prop = get_property(node, "device_type");
++	if (!prop || !streq(prop->val.val, "pci"))
++		return;
++
++	node->bus = &pci_bus;
++
++	if (!strneq(node->name, "pci", node->basenamelen) &&
++	    !strneq(node->name, "pcie", node->basenamelen))
++		FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"",
++			     node->fullpath);
++
++	prop = get_property(node, "ranges");
++	if (!prop)
++		FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)",
++			     node->fullpath);
++
++	if (node_addr_cells(node) != 3)
++		FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge",
++			     node->fullpath);
++	if (node_size_cells(node) != 2)
++		FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge",
++			     node->fullpath);
++
++	prop = get_property(node, "bus-range");
++	if (!prop) {
++		FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
++			     node->fullpath);
++		return;
++	}
++	if (prop->val.len != (sizeof(cell_t) * 2)) {
++		FAIL(c, dti, "Node %s bus-range must be 2 cells",
++			     node->fullpath);
++		return;
++	}
++	cells = (cell_t *)prop->val.val;
++	if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
++		FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell",
++			     node->fullpath);
++	if (fdt32_to_cpu(cells[1]) > 0xff)
++		FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256",
++			     node->fullpath);
++}
++WARNING(pci_bridge, check_pci_bridge, NULL,
++	&device_type_is_string, &addr_size_cells);
++
++static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node)
++{
++	struct property *prop;
++	unsigned int bus_num, min_bus, max_bus;
++	cell_t *cells;
++
++	if (!node->parent || (node->parent->bus != &pci_bus))
++		return;
++
++	prop = get_property(node, "reg");
++	if (!prop)
++		return;
++
++	cells = (cell_t *)prop->val.val;
++	bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16;
++
++	prop = get_property(node->parent, "bus-range");
++	if (!prop) {
++		min_bus = max_bus = 0;
++	} else {
++		cells = (cell_t *)prop->val.val;
++		min_bus = fdt32_to_cpu(cells[0]);
++		max_bus = fdt32_to_cpu(cells[0]);
++	}
++	if ((bus_num < min_bus) || (bus_num > max_bus))
++		FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)",
++		     node->fullpath, bus_num, min_bus, max_bus);
++}
++WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
++
++static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node)
++{
++	struct property *prop;
++	const char *unitname = get_unitname(node);
++	char unit_addr[5];
++	unsigned int dev, func, reg;
++	cell_t *cells;
++
++	if (!node->parent || (node->parent->bus != &pci_bus))
++		return;
++
++	prop = get_property(node, "reg");
++	if (!prop) {
++		FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath);
++		return;
++	}
++
++	cells = (cell_t *)prop->val.val;
++	if (cells[1] || cells[2])
++		FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0",
++			     node->fullpath);
++
++	reg = fdt32_to_cpu(cells[0]);
++	dev = (reg & 0xf800) >> 11;
++	func = (reg & 0x700) >> 8;
++
++	if (reg & 0xff000000)
++		FAIL(c, dti, "Node %s PCI reg address is not configuration space",
++			     node->fullpath);
++	if (reg & 0x000000ff)
++		FAIL(c, dti, "Node %s PCI reg config space address register number must be 0",
++			     node->fullpath);
++
++	if (func == 0) {
++		snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
++		if (streq(unitname, unit_addr))
++			return;
++	}
++
++	snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func);
++	if (streq(unitname, unit_addr))
++		return;
++
++	FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"",
++	     node->fullpath, unit_addr);
++}
++WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
++
++static const struct bus_type simple_bus = {
++	.name = "simple-bus",
++};
++
++static bool node_is_compatible(struct node *node, const char *compat)
++{
++	struct property *prop;
++	const char *str, *end;
++
++	prop = get_property(node, "compatible");
++	if (!prop)
++		return false;
++
++	for (str = prop->val.val, end = str + prop->val.len; str < end;
++	     str += strnlen(str, end - str) + 1) {
++		if (strneq(str, compat, end - str))
++			return true;
++	}
++	return false;
++}
++
++static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
++{
++	if (node_is_compatible(node, "simple-bus"))
++		node->bus = &simple_bus;
++}
++WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
++
++static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
++{
++	struct property *prop;
++	const char *unitname = get_unitname(node);
++	char unit_addr[17];
++	unsigned int size;
++	uint64_t reg = 0;
++	cell_t *cells = NULL;
++
++	if (!node->parent || (node->parent->bus != &simple_bus))
++		return;
++
++	prop = get_property(node, "reg");
++	if (prop)
++		cells = (cell_t *)prop->val.val;
++	else {
++		prop = get_property(node, "ranges");
++		if (prop && prop->val.len)
++			/* skip of child address */
++			cells = ((cell_t *)prop->val.val) + node_addr_cells(node);
++	}
++
++	if (!cells) {
++		if (node->parent->parent && !(node->bus == &simple_bus))
++			FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
++		return;
++	}
++
++	size = node_addr_cells(node->parent);
++	while (size--)
++		reg = (reg << 32) | fdt32_to_cpu(*(cells++));
++
++	snprintf(unit_addr, sizeof(unit_addr), "%lx", reg);
++	if (!streq(unitname, unit_addr))
++		FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
++		     node->fullpath, unit_addr);
++}
++WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
++
++static void check_unit_address_format(struct check *c, struct dt_info *dti,
++				      struct node *node)
++{
++	const char *unitname = get_unitname(node);
++
++	if (node->parent && node->parent->bus)
++		return;
++
++	if (!unitname[0])
++		return;
++
++	if (!strncmp(unitname, "0x", 2)) {
++		FAIL(c, dti, "Node %s unit name should not have leading \"0x\"",
++		    node->fullpath);
++		/* skip over 0x for next test */
++		unitname += 2;
++	}
++	if (unitname[0] == '0' && isxdigit(unitname[1]))
++		FAIL(c, dti, "Node %s unit name should not have leading 0s",
++		    node->fullpath);
++}
++WARNING(unit_address_format, check_unit_address_format, NULL,
++	&node_name_format, &pci_bridge, &simple_bus_bridge);
++
+ /*
+  * Style checks
+  */
+@@ -656,11 +922,11 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
+ 		return;
+ 
+ 	if (node->parent->addr_cells == -1)
+-		FAIL(c, "Relying on default #address-cells value for %s",
++		FAIL(c, dti, "Relying on default #address-cells value for %s",
+ 		     node->fullpath);
+ 
+ 	if (node->parent->size_cells == -1)
+-		FAIL(c, "Relying on default #size-cells value for %s",
++		FAIL(c, dti, "Relying on default #size-cells value for %s",
+ 		     node->fullpath);
+ }
+ WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
+@@ -684,7 +950,7 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
+ 
+ 	prop = get_property(chosen, "interrupt-controller");
+ 	if (prop)
+-		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
++		FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" "
+ 		     "property");
+ }
+ WARNING(obsolete_chosen_interrupt_controller,
+@@ -703,9 +969,20 @@ static struct check *check_table[] = {
+ 	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
+ 	&device_type_is_string, &model_is_string, &status_is_string,
+ 
++	&property_name_chars_strict,
++	&node_name_chars_strict,
++
+ 	&addr_size_cells, &reg_format, &ranges_format,
+ 
+ 	&unit_address_vs_reg,
++	&unit_address_format,
++
++	&pci_bridge,
++	&pci_device_reg,
++	&pci_device_bus_num,
++
++	&simple_bus_bridge,
++	&simple_bus_reg,
+ 
+ 	&avoid_default_addr_size,
+ 	&obsolete_chosen_interrupt_controller,
+diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c
+index 8cae2374..aa37a16c 100644
+--- a/scripts/dtc/data.c
++++ b/scripts/dtc/data.c
+@@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2)
+ struct data data_append_integer(struct data d, uint64_t value, int bits)
+ {
+ 	uint8_t value_8;
+-	uint16_t value_16;
+-	uint32_t value_32;
+-	uint64_t value_64;
++	fdt16_t value_16;
++	fdt32_t value_32;
++	fdt64_t value_64;
+ 
+ 	switch (bits) {
+ 	case 8:
+@@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits)
+ 	}
+ }
+ 
+-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
++struct data data_append_re(struct data d, uint64_t address, uint64_t size)
+ {
+-	struct fdt_reserve_entry bere;
++	struct fdt_reserve_entry re;
+ 
+-	bere.address = cpu_to_fdt64(re->address);
+-	bere.size = cpu_to_fdt64(re->size);
++	re.address = cpu_to_fdt64(address);
++	re.size = cpu_to_fdt64(size);
+ 
+-	return data_append_data(d, &bere, sizeof(bere));
++	return data_append_data(d, &re, sizeof(re));
+ }
+ 
+ struct data data_append_cell(struct data d, cell_t word)
+diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
+index c6006030..fd825ebb 100644
+--- a/scripts/dtc/dtc-lexer.l
++++ b/scripts/dtc/dtc-lexer.l
+@@ -62,7 +62,8 @@ static int dts_version = 1;
+ 
+ static void push_input_file(const char *filename);
+ static bool pop_input_file(void);
+-static void lexical_error(const char *fmt, ...);
++static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
++
+ %}
+ 
+ %%
+diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
+index 2c862bc8..6b016dba 100644
+--- a/scripts/dtc/dtc-lexer.lex.c_shipped
++++ b/scripts/dtc/dtc-lexer.lex.c_shipped
+@@ -9,7 +9,7 @@
+ #define FLEX_SCANNER
+ #define YY_FLEX_MAJOR_VERSION 2
+ #define YY_FLEX_MINOR_VERSION 6
+-#define YY_FLEX_SUBMINOR_VERSION 1
++#define YY_FLEX_SUBMINOR_VERSION 0
+ #if YY_FLEX_SUBMINOR_VERSION > 0
+ #define FLEX_BETA
+ #endif
+@@ -88,13 +88,25 @@ typedef unsigned int flex_uint32_t;
+ 
+ #endif /* ! FLEXINT_H */
+ 
+-/* TODO: this is always defined, so inline it */
+-#define yyconst const
++#ifdef __cplusplus
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 3
+-#define yynoreturn __attribute__((__noreturn__))
++/* The "const" storage-class-modifier is valid. */
++#define YY_USE_CONST
++
++#else	/* ! __cplusplus */
++
++/* C99 requires __STDC__ to be defined as 1. */
++#if defined (__STDC__)
++
++#define YY_USE_CONST
++
++#endif	/* defined (__STDC__) */
++#endif	/* ! __cplusplus */
++
++#ifdef YY_USE_CONST
++#define yyconst const
+ #else
+-#define yynoreturn
++#define yyconst
+ #endif
+ 
+ /* Returned upon end-of-file. */
+@@ -155,7 +167,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
+ typedef size_t yy_size_t;
+ #endif
+ 
+-extern int yyleng;
++extern yy_size_t yyleng;
+ 
+ extern FILE *yyin, *yyout;
+ 
+@@ -194,7 +206,7 @@ struct yy_buffer_state
+ 	/* Size of input buffer in bytes, not including room for EOB
+ 	 * characters.
+ 	 */
+-	int yy_buf_size;
++	yy_size_t yy_buf_size;
+ 
+ 	/* Number of characters read into yy_ch_buf, not including EOB
+ 	 * characters.
+@@ -222,7 +234,7 @@ struct yy_buffer_state
+ 
+     int yy_bs_lineno; /**< The line count. */
+     int yy_bs_column; /**< The column count. */
+-
++    
+ 	/* Whether to try to fill the input buffer when we reach the
+ 	 * end of it.
+ 	 */
+@@ -250,7 +262,7 @@ struct yy_buffer_state
+ /* Stack of input buffers. */
+ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
++static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+ 
+ /* We provide macros for accessing buffer states in case in the
+  * future we want to put the buffer states in a more general
+@@ -270,10 +282,10 @@ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+ /* yy_hold_char holds the character lost when yytext is formed. */
+ static char yy_hold_char;
+ static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+-int yyleng;
++yy_size_t yyleng;
+ 
+ /* Points to current character in buffer. */
+-static char *yy_c_buf_p = NULL;
++static char *yy_c_buf_p = (char *) 0;
+ static int yy_init = 0;		/* whether we need to initialize */
+ static int yy_start = 0;	/* start state number */
+ 
+@@ -298,7 +310,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+ 
+ YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+ YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len  );
+ 
+ void *yyalloc (yy_size_t  );
+ void *yyrealloc (void *,yy_size_t  );
+@@ -335,7 +347,7 @@ void yyfree (void *  );
+ 
+ typedef unsigned char YY_CHAR;
+ 
+-FILE *yyin = NULL, *yyout = NULL;
++FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+ 
+ typedef int yy_state_type;
+ 
+@@ -352,14 +364,17 @@ extern char *yytext;
+ static yy_state_type yy_get_previous_state (void );
+ static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+ static int yy_get_next_buffer (void );
+-static void yynoreturn yy_fatal_error (yyconst char* msg  );
++#if defined(__GNUC__) && __GNUC__ >= 3
++__attribute__((__noreturn__))
++#endif
++static void yy_fatal_error (yyconst char msg[]  );
+ 
+ /* Done after the current pattern has been matched and before the
+  * corresponding action - sets up yytext.
+  */
+ #define YY_DO_BEFORE_ACTION \
+ 	(yytext_ptr) = yy_bp; \
+-	yyleng = (int) (yy_cp - yy_bp); \
++	yyleng = (size_t) (yy_cp - yy_bp); \
+ 	(yy_hold_char) = *yy_cp; \
+ 	*yy_cp = '\0'; \
+ 	(yy_c_buf_p) = yy_cp;
+@@ -655,8 +670,9 @@ static int dts_version = 1;
+ 
+ static void push_input_file(const char *filename);
+ static bool pop_input_file(void);
+-static void lexical_error(const char *fmt, ...);
+-#line 660 "dtc-lexer.lex.c"
++static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
++
++#line 676 "dtc-lexer.lex.c"
+ 
+ #define INITIAL 0
+ #define BYTESTRING 1
+@@ -698,7 +714,7 @@ FILE *yyget_out (void );
+ 
+ void yyset_out  (FILE * _out_str  );
+ 
+-			int yyget_leng (void );
++yy_size_t yyget_leng (void );
+ 
+ char *yyget_text (void );
+ 
+@@ -755,7 +771,7 @@ static int input (void );
+ /* This used to be an fputs(), but since the string might contain NUL's,
+  * we now use fwrite().
+  */
+-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
++#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+ #endif
+ 
+ /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+@@ -779,7 +795,7 @@ static int input (void );
+ 	else \
+ 		{ \
+ 		errno=0; \
+-		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
++		while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ 			{ \
+ 			if( errno != EINTR) \
+ 				{ \
+@@ -878,9 +894,9 @@ YY_DECL
+ 		}
+ 
+ 	{
+-#line 68 "dtc-lexer.l"
++#line 69 "dtc-lexer.l"
+ 
+-#line 884 "dtc-lexer.lex.c"
++#line 900 "dtc-lexer.lex.c"
+ 
+ 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
+ 		{
+@@ -911,7 +927,7 @@ yy_match:
+ 				if ( yy_current_state >= 166 )
+ 					yy_c = yy_meta[(unsigned int) yy_c];
+ 				}
+-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ 			++yy_cp;
+ 			}
+ 		while ( yy_current_state != 165 );
+@@ -937,7 +953,7 @@ do_action:	/* This label is used only to access EOF actions. */
+ case 1:
+ /* rule 1 can match eol */
+ YY_RULE_SETUP
+-#line 69 "dtc-lexer.l"
++#line 70 "dtc-lexer.l"
+ {
+ 			char *name = strchr(yytext, '\"') + 1;
+ 			yytext[yyleng-1] = '\0';
+@@ -947,7 +963,7 @@ YY_RULE_SETUP
+ case 2:
+ /* rule 2 can match eol */
+ YY_RULE_SETUP
+-#line 75 "dtc-lexer.l"
++#line 76 "dtc-lexer.l"
+ {
+ 			char *line, *fnstart, *fnend;
+ 			struct data fn;
+@@ -981,7 +997,7 @@ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(BYTESTRING):
+ case YY_STATE_EOF(PROPNODENAME):
+ case YY_STATE_EOF(V1):
+-#line 104 "dtc-lexer.l"
++#line 105 "dtc-lexer.l"
+ {
+ 			if (!pop_input_file()) {
+ 				yyterminate();
+@@ -991,7 +1007,7 @@ case YY_STATE_EOF(V1):
+ case 3:
+ /* rule 3 can match eol */
+ YY_RULE_SETUP
+-#line 110 "dtc-lexer.l"
++#line 111 "dtc-lexer.l"
+ {
+ 			DPRINT("String: %s\n", yytext);
+ 			yylval.data = data_copy_escape_string(yytext+1,
+@@ -1001,7 +1017,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 4:
+ YY_RULE_SETUP
+-#line 117 "dtc-lexer.l"
++#line 118 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /dts-v1/\n");
+ 			dts_version = 1;
+@@ -1011,7 +1027,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 5:
+ YY_RULE_SETUP
+-#line 124 "dtc-lexer.l"
++#line 125 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /plugin/\n");
+ 			return DT_PLUGIN;
+@@ -1019,7 +1035,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 6:
+ YY_RULE_SETUP
+-#line 129 "dtc-lexer.l"
++#line 130 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /memreserve/\n");
+ 			BEGIN_DEFAULT();
+@@ -1028,7 +1044,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 7:
+ YY_RULE_SETUP
+-#line 135 "dtc-lexer.l"
++#line 136 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /bits/\n");
+ 			BEGIN_DEFAULT();
+@@ -1037,7 +1053,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 8:
+ YY_RULE_SETUP
+-#line 141 "dtc-lexer.l"
++#line 142 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /delete-property/\n");
+ 			DPRINT("<PROPNODENAME>\n");
+@@ -1047,7 +1063,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 9:
+ YY_RULE_SETUP
+-#line 148 "dtc-lexer.l"
++#line 149 "dtc-lexer.l"
+ {
+ 			DPRINT("Keyword: /delete-node/\n");
+ 			DPRINT("<PROPNODENAME>\n");
+@@ -1057,7 +1073,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 10:
+ YY_RULE_SETUP
+-#line 155 "dtc-lexer.l"
++#line 156 "dtc-lexer.l"
+ {
+ 			DPRINT("Label: %s\n", yytext);
+ 			yylval.labelref = xstrdup(yytext);
+@@ -1067,7 +1083,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 11:
+ YY_RULE_SETUP
+-#line 162 "dtc-lexer.l"
++#line 163 "dtc-lexer.l"
+ {
+ 			char *e;
+ 			DPRINT("Integer Literal: '%s'\n", yytext);
+@@ -1093,7 +1109,7 @@ YY_RULE_SETUP
+ case 12:
+ /* rule 12 can match eol */
+ YY_RULE_SETUP
+-#line 184 "dtc-lexer.l"
++#line 185 "dtc-lexer.l"
+ {
+ 			struct data d;
+ 			DPRINT("Character literal: %s\n", yytext);
+@@ -1117,7 +1133,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 13:
+ YY_RULE_SETUP
+-#line 205 "dtc-lexer.l"
++#line 206 "dtc-lexer.l"
+ {	/* label reference */
+ 			DPRINT("Ref: %s\n", yytext+1);
+ 			yylval.labelref = xstrdup(yytext+1);
+@@ -1126,7 +1142,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 14:
+ YY_RULE_SETUP
+-#line 211 "dtc-lexer.l"
++#line 212 "dtc-lexer.l"
+ {	/* new-style path reference */
+ 			yytext[yyleng-1] = '\0';
+ 			DPRINT("Ref: %s\n", yytext+2);
+@@ -1136,7 +1152,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 15:
+ YY_RULE_SETUP
+-#line 218 "dtc-lexer.l"
++#line 219 "dtc-lexer.l"
+ {
+ 			yylval.byte = strtol(yytext, NULL, 16);
+ 			DPRINT("Byte: %02x\n", (int)yylval.byte);
+@@ -1145,7 +1161,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 16:
+ YY_RULE_SETUP
+-#line 224 "dtc-lexer.l"
++#line 225 "dtc-lexer.l"
+ {
+ 			DPRINT("/BYTESTRING\n");
+ 			BEGIN_DEFAULT();
+@@ -1154,7 +1170,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 17:
+ YY_RULE_SETUP
+-#line 230 "dtc-lexer.l"
++#line 231 "dtc-lexer.l"
+ {
+ 			DPRINT("PropNodeName: %s\n", yytext);
+ 			yylval.propnodename = xstrdup((yytext[0] == '\\') ?
+@@ -1165,7 +1181,7 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 18:
+ YY_RULE_SETUP
+-#line 238 "dtc-lexer.l"
++#line 239 "dtc-lexer.l"
+ {
+ 			DPRINT("Binary Include\n");
+ 			return DT_INCBIN;
+@@ -1174,64 +1190,64 @@ YY_RULE_SETUP
+ case 19:
+ /* rule 19 can match eol */
+ YY_RULE_SETUP
+-#line 243 "dtc-lexer.l"
++#line 244 "dtc-lexer.l"
+ /* eat whitespace */
+ 	YY_BREAK
+ case 20:
+ /* rule 20 can match eol */
+ YY_RULE_SETUP
+-#line 244 "dtc-lexer.l"
++#line 245 "dtc-lexer.l"
+ /* eat C-style comments */
+ 	YY_BREAK
+ case 21:
+ /* rule 21 can match eol */
+ YY_RULE_SETUP
+-#line 245 "dtc-lexer.l"
++#line 246 "dtc-lexer.l"
+ /* eat C++-style comments */
+ 	YY_BREAK
+ case 22:
+ YY_RULE_SETUP
+-#line 247 "dtc-lexer.l"
++#line 248 "dtc-lexer.l"
+ { return DT_LSHIFT; };
+ 	YY_BREAK
+ case 23:
+ YY_RULE_SETUP
+-#line 248 "dtc-lexer.l"
++#line 249 "dtc-lexer.l"
+ { return DT_RSHIFT; };
+ 	YY_BREAK
+ case 24:
+ YY_RULE_SETUP
+-#line 249 "dtc-lexer.l"
++#line 250 "dtc-lexer.l"
+ { return DT_LE; };
+ 	YY_BREAK
+ case 25:
+ YY_RULE_SETUP
+-#line 250 "dtc-lexer.l"
++#line 251 "dtc-lexer.l"
+ { return DT_GE; };
+ 	YY_BREAK
+ case 26:
+ YY_RULE_SETUP
+-#line 251 "dtc-lexer.l"
++#line 252 "dtc-lexer.l"
+ { return DT_EQ; };
+ 	YY_BREAK
+ case 27:
+ YY_RULE_SETUP
+-#line 252 "dtc-lexer.l"
++#line 253 "dtc-lexer.l"
+ { return DT_NE; };
+ 	YY_BREAK
+ case 28:
+ YY_RULE_SETUP
+-#line 253 "dtc-lexer.l"
++#line 254 "dtc-lexer.l"
+ { return DT_AND; };
+ 	YY_BREAK
+ case 29:
+ YY_RULE_SETUP
+-#line 254 "dtc-lexer.l"
++#line 255 "dtc-lexer.l"
+ { return DT_OR; };
+ 	YY_BREAK
+ case 30:
+ YY_RULE_SETUP
+-#line 256 "dtc-lexer.l"
++#line 257 "dtc-lexer.l"
+ {
+ 			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
+ 				(unsigned)yytext[0]);
+@@ -1249,10 +1265,10 @@ YY_RULE_SETUP
+ 	YY_BREAK
+ case 31:
+ YY_RULE_SETUP
+-#line 271 "dtc-lexer.l"
++#line 272 "dtc-lexer.l"
+ ECHO;
+ 	YY_BREAK
+-#line 1256 "dtc-lexer.lex.c"
++#line 1272 "dtc-lexer.lex.c"
+ 
+ 	case YY_END_OF_BUFFER:
+ 		{
+@@ -1438,7 +1454,7 @@ static int yy_get_next_buffer (void)
+ 
+ 	else
+ 		{
+-			int num_to_read =
++			yy_size_t num_to_read =
+ 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+ 
+ 		while ( num_to_read <= 0 )
+@@ -1452,7 +1468,7 @@ static int yy_get_next_buffer (void)
+ 
+ 			if ( b->yy_is_our_buffer )
+ 				{
+-				int new_size = b->yy_buf_size * 2;
++				yy_size_t new_size = b->yy_buf_size * 2;
+ 
+ 				if ( new_size <= 0 )
+ 					b->yy_buf_size += b->yy_buf_size / 8;
+@@ -1465,7 +1481,7 @@ static int yy_get_next_buffer (void)
+ 				}
+ 			else
+ 				/* Can't grow it, we don't own it. */
+-				b->yy_ch_buf = NULL;
++				b->yy_ch_buf = 0;
+ 
+ 			if ( ! b->yy_ch_buf )
+ 				YY_FATAL_ERROR(
+@@ -1548,7 +1564,7 @@ static int yy_get_next_buffer (void)
+ 			if ( yy_current_state >= 166 )
+ 				yy_c = yy_meta[(unsigned int) yy_c];
+ 			}
+-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ 		}
+ 
+ 	return yy_current_state;
+@@ -1576,7 +1592,7 @@ static int yy_get_next_buffer (void)
+ 		if ( yy_current_state >= 166 )
+ 			yy_c = yy_meta[(unsigned int) yy_c];
+ 		}
+-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
++	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ 	yy_is_jam = (yy_current_state == 165);
+ 
+ 		return yy_is_jam ? 0 : yy_current_state;
+@@ -1610,7 +1626,7 @@ static int yy_get_next_buffer (void)
+ 
+ 		else
+ 			{ /* need more input */
+-			int offset = (yy_c_buf_p) - (yytext_ptr);
++			yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ 			++(yy_c_buf_p);
+ 
+ 			switch ( yy_get_next_buffer(  ) )
+@@ -1634,7 +1650,7 @@ static int yy_get_next_buffer (void)
+ 				case EOB_ACT_END_OF_FILE:
+ 					{
+ 					if ( yywrap( ) )
+-						return 0;
++						return EOF;
+ 
+ 					if ( ! (yy_did_buffer_switch_on_eof) )
+ 						YY_NEW_FILE;
+@@ -1884,7 +1900,7 @@ void yypop_buffer_state (void)
+  */
+ static void yyensure_buffer_stack (void)
+ {
+-	int num_to_alloc;
++	yy_size_t num_to_alloc;
+     
+ 	if (!(yy_buffer_stack)) {
+ 
+@@ -1892,15 +1908,15 @@ static void yyensure_buffer_stack (void)
+ 		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ 		 * immediate realloc on the next call.
+          */
+-      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
++		num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ 		(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ 								(num_to_alloc * sizeof(struct yy_buffer_state*)
+ 								);
+ 		if ( ! (yy_buffer_stack) )
+ 			YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+-
++								  
+ 		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+-
++				
+ 		(yy_buffer_stack_max) = num_to_alloc;
+ 		(yy_buffer_stack_top) = 0;
+ 		return;
+@@ -1929,7 +1945,7 @@ static void yyensure_buffer_stack (void)
+  * @param base the character buffer
+  * @param size the size in bytes of the character buffer
+  * 
+- * @return the newly allocated buffer state object.
++ * @return the newly allocated buffer state object. 
+  */
+ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+ {
+@@ -1939,7 +1955,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+ 	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ 	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+ 		/* They forgot to leave room for the EOB's. */
+-		return NULL;
++		return 0;
+ 
+ 	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+ 	if ( ! b )
+@@ -1948,7 +1964,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+ 	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+ 	b->yy_buf_pos = b->yy_ch_buf = base;
+ 	b->yy_is_our_buffer = 0;
+-	b->yy_input_file = NULL;
++	b->yy_input_file = 0;
+ 	b->yy_n_chars = b->yy_buf_size;
+ 	b->yy_is_interactive = 0;
+ 	b->yy_at_bol = 1;
+@@ -1971,7 +1987,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+ {
+     
+-	return yy_scan_bytes(yystr,(int) strlen(yystr) );
++	return yy_scan_bytes(yystr,strlen(yystr) );
+ }
+ 
+ /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+@@ -1981,7 +1997,7 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+  * 
+  * @return the newly allocated buffer state object.
+  */
+-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
++YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len )
+ {
+ 	YY_BUFFER_STATE b;
+ 	char *buf;
+@@ -1989,7 +2005,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+ 	yy_size_t i;
+     
+ 	/* Get memory for full buffer, including space for trailing EOB's. */
+-	n = (yy_size_t) _yybytes_len + 2;
++	n = _yybytes_len + 2;
+ 	buf = (char *) yyalloc(n  );
+ 	if ( ! buf )
+ 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+@@ -2015,7 +2031,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+ #define YY_EXIT_FAILURE 2
+ #endif
+ 
+-static void yynoreturn yy_fatal_error (yyconst char* msg )
++static void yy_fatal_error (yyconst char* msg )
+ {
+ 			(void) fprintf( stderr, "%s\n", msg );
+ 	exit( YY_EXIT_FAILURE );
+@@ -2045,7 +2061,7 @@ static void yynoreturn yy_fatal_error (yyconst char* msg )
+  */
+ int yyget_lineno  (void)
+ {
+-    
++        
+     return yylineno;
+ }
+ 
+@@ -2068,7 +2084,7 @@ FILE *yyget_out  (void)
+ /** Get the length of the current token.
+  * 
+  */
+-int yyget_leng  (void)
++yy_size_t yyget_leng  (void)
+ {
+         return yyleng;
+ }
+@@ -2124,10 +2140,10 @@ static int yy_init_globals (void)
+      * This function is called from yylex_destroy(), so don't allocate here.
+      */
+ 
+-    (yy_buffer_stack) = NULL;
++    (yy_buffer_stack) = 0;
+     (yy_buffer_stack_top) = 0;
+     (yy_buffer_stack_max) = 0;
+-    (yy_c_buf_p) = NULL;
++    (yy_c_buf_p) = (char *) 0;
+     (yy_init) = 0;
+     (yy_start) = 0;
+ 
+@@ -2136,8 +2152,8 @@ static int yy_init_globals (void)
+     yyin = stdin;
+     yyout = stdout;
+ #else
+-    yyin = NULL;
+-    yyout = NULL;
++    yyin = (FILE *) 0;
++    yyout = (FILE *) 0;
+ #endif
+ 
+     /* For future reference: Set errno on error, since we are called by
+@@ -2195,7 +2211,7 @@ static int yy_flex_strlen (yyconst char * s )
+ 
+ void *yyalloc (yy_size_t  size )
+ {
+-			return malloc(size);
++			return (void *) malloc( size );
+ }
+ 
+ void *yyrealloc  (void * ptr, yy_size_t  size )
+@@ -2208,7 +2224,7 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
+ 	 * any pointer type to void*, and deal with argument conversions
+ 	 * as though doing an assignment.
+ 	 */
+-	return realloc(ptr, size);
++	return (void *) realloc( (char *) ptr, size );
+ }
+ 
+ void yyfree (void * ptr )
+@@ -2218,7 +2234,7 @@ void yyfree (void * ptr )
+ 
+ #define YYTABLES_NAME "yytables"
+ 
+-#line 271 "dtc-lexer.l"
++#line 272 "dtc-lexer.l"
+ 
+ 
+ 
+diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
+index 2965227a..0a7a5ed8 100644
+--- a/scripts/dtc/dtc-parser.tab.c_shipped
++++ b/scripts/dtc/dtc-parser.tab.c_shipped
+@@ -1557,10 +1557,10 @@ yyreduce:
+     {
+ 			struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref));
+ 
+-			add_label(&target->labels, (yyvsp[-2].labelref));
+-			if (target)
++			if (target) {
++				add_label(&target->labels, (yyvsp[-2].labelref));
+ 				merge_nodes(target, (yyvsp[0].node));
+-			else
++			} else
+ 				ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref));
+ 			(yyval.node) = (yyvsp[-3].node);
+ 		}
+diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
+index b2fd4d15..ca3f5003 100644
+--- a/scripts/dtc/dtc-parser.y
++++ b/scripts/dtc/dtc-parser.y
+@@ -171,10 +171,10 @@ devicetree:
+ 		{
+ 			struct node *target = get_node_by_ref($1, $3);
+ 
+-			add_label(&target->labels, $2);
+-			if (target)
++			if (target) {
++				add_label(&target->labels, $2);
+ 				merge_nodes(target, $4);
+-			else
++			} else
+ 				ERROR(&@3, "Label or path %s not found", $3);
+ 			$$ = $1;
+ 		}
+diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
+index a4edf4c7..f5eed9d7 100644
+--- a/scripts/dtc/dtc.c
++++ b/scripts/dtc/dtc.c
+@@ -138,7 +138,7 @@ static const char *guess_type_by_name(const char *fname, const char *fallback)
+ static const char *guess_input_format(const char *fname, const char *fallback)
+ {
+ 	struct stat statbuf;
+-	uint32_t magic;
++	fdt32_t magic;
+ 	FILE *f;
+ 
+ 	if (stat(fname, &statbuf) != 0)
+@@ -159,8 +159,7 @@ static const char *guess_input_format(const char *fname, const char *fallback)
+ 	}
+ 	fclose(f);
+ 
+-	magic = fdt32_to_cpu(magic);
+-	if (magic == FDT_MAGIC)
++	if (fdt32_to_cpu(magic) == FDT_MAGIC)
+ 		return "dtb";
+ 
+ 	return guess_type_by_name(fname, fallback);
+@@ -216,7 +215,7 @@ int main(int argc, char *argv[])
+ 			alignsize = strtol(optarg, NULL, 0);
+ 			if (!is_power_of_2(alignsize))
+ 				die("Invalid argument \"%d\" to -a option\n",
+-				    optarg);
++				    alignsize);
+ 			break;
+ 		case 'f':
+ 			force = true;
+@@ -309,6 +308,8 @@ int main(int argc, char *argv[])
+ 	else
+ 		die("Unknown input format \"%s\"\n", inform);
+ 
++	dti->outname = outname;
++
+ 	if (depfile) {
+ 		fputc('\n', depfile);
+ 		fclose(depfile);
+diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
+index c6f125c6..fc24e175 100644
+--- a/scripts/dtc/dtc.h
++++ b/scripts/dtc/dtc.h
+@@ -43,7 +43,6 @@
+ #define debug(...)
+ #endif
+ 
+-
+ #define DEFAULT_FDT_VERSION	17
+ 
+ /*
+@@ -114,7 +113,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
+ struct data data_merge(struct data d1, struct data d2);
+ struct data data_append_cell(struct data d, cell_t word);
+ struct data data_append_integer(struct data d, uint64_t word, int bits);
+-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
++struct data data_append_re(struct data d, uint64_t address, uint64_t size);
+ struct data data_append_addr(struct data d, uint64_t addr);
+ struct data data_append_byte(struct data d, uint8_t byte);
+ struct data data_append_zeroes(struct data d, int len);
+@@ -136,6 +135,10 @@ struct label {
+ 	struct label *next;
+ };
+ 
++struct bus_type {
++	const char *name;
++};
++
+ struct property {
+ 	bool deleted;
+ 	char *name;
+@@ -162,6 +165,7 @@ struct node {
+ 	int addr_cells, size_cells;
+ 
+ 	struct label *labels;
++	const struct bus_type *bus;
+ };
+ 
+ #define for_each_label_withdel(l0, l) \
+@@ -227,7 +231,7 @@ uint32_t guess_boot_cpuid(struct node *tree);
+ /* Boot info (tree plus memreserve information */
+ 
+ struct reserve_info {
+-	struct fdt_reserve_entry re;
++	uint64_t address, size;
+ 
+ 	struct reserve_info *next;
+ 
+@@ -246,6 +250,7 @@ struct dt_info {
+ 	struct reserve_info *reservelist;
+ 	uint32_t boot_cpuid_phys;
+ 	struct node *dt;		/* the device tree */
++	const char *outname;		/* filename being written to, "-" for stdout */
+ };
+ 
+ /* DTS version flags definitions */
+diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
+index ebac548b..fcf71541 100644
+--- a/scripts/dtc/flattree.c
++++ b/scripts/dtc/flattree.c
+@@ -49,7 +49,7 @@ static struct version_info {
+ 
+ struct emitter {
+ 	void (*cell)(void *, cell_t);
+-	void (*string)(void *, char *, int);
++	void (*string)(void *, const char *, int);
+ 	void (*align)(void *, int);
+ 	void (*data)(void *, struct data);
+ 	void (*beginnode)(void *, struct label *labels);
+@@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val)
+ 	*dtbuf = data_append_cell(*dtbuf, val);
+ }
+ 
+-static void bin_emit_string(void *e, char *str, int len)
++static void bin_emit_string(void *e, const char *str, int len)
+ {
+ 	struct data *dtbuf = e;
+ 
+@@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val)
+ 		(val >> 8) & 0xff, val & 0xff);
+ }
+ 
+-static void asm_emit_string(void *e, char *str, int len)
++static void asm_emit_string(void *e, const char *str, int len)
+ {
+ 	FILE *f = e;
+-	char c = 0;
+ 
+-	if (len != 0) {
+-		/* XXX: ewww */
+-		c = str[len];
+-		str[len] = '\0';
+-	}
+-
+-	fprintf(f, "\t.string\t\"%s\"\n", str);
+-
+-	if (len != 0) {
+-		str[len] = c;
+-	}
++	if (len != 0)
++		fprintf(f, "\t.string\t\"%.*s\"\n", len, str);
++	else
++		fprintf(f, "\t.string\t\"%s\"\n", str);
+ }
+ 
+ static void asm_emit_align(void *e, int a)
+@@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d)
+ 		emit_offset_label(f, m->ref, m->offset);
+ 
+ 	while ((d.len - off) >= sizeof(uint32_t)) {
+-		asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off))));
++		asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off))));
+ 		off += sizeof(uint32_t);
+ 	}
+ 
+@@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist,
+ {
+ 	struct reserve_info *re;
+ 	struct data d = empty_data;
+-	static struct fdt_reserve_entry null_re = {0,0};
+ 	int    j;
+ 
+ 	for (re = reservelist; re; re = re->next) {
+-		d = data_append_re(d, &re->re);
++		d = data_append_re(d, re->address, re->size);
+ 	}
+ 	/*
+ 	 * Add additional reserved slots if the user asked for them.
+ 	 */
+ 	for (j = 0; j < reservenum; j++) {
+-		d = data_append_re(d, &null_re);
++		d = data_append_re(d, 0, 0);
+ 	}
+ 
+ 	return d;
+@@ -544,11 +535,11 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
+ 			fprintf(f, "\t.globl\t%s\n", l->label);
+ 			fprintf(f, "%s:\n", l->label);
+ 		}
+-		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32));
++		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32));
+ 		ASM_EMIT_BELONG(f, "0x%08x",
+-				(unsigned int)(re->re.address & 0xffffffff));
+-		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32));
+-		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff));
++				(unsigned int)(re->address & 0xffffffff));
++		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32));
++		ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff));
+ 	}
+ 	for (i = 0; i < reservenum; i++) {
+ 		fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
+@@ -609,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len)
+ 
+ static uint32_t flat_read_word(struct inbuf *inb)
+ {
+-	uint32_t val;
++	fdt32_t val;
+ 
+ 	assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
+ 
+@@ -718,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
+ 	 * First pass, count entries.
+ 	 */
+ 	while (1) {
++		uint64_t address, size;
++
+ 		flat_read_chunk(inb, &re, sizeof(re));
+-		re.address  = fdt64_to_cpu(re.address);
+-		re.size = fdt64_to_cpu(re.size);
+-		if (re.size == 0)
++		address  = fdt64_to_cpu(re.address);
++		size = fdt64_to_cpu(re.size);
++		if (size == 0)
+ 			break;
+ 
+-		new = build_reserve_entry(re.address, re.size);
++		new = build_reserve_entry(address, size);
+ 		reservelist = add_reserve_entry(reservelist, new);
+ 	}
+ 
+@@ -817,6 +810,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
+ struct dt_info *dt_from_blob(const char *fname)
+ {
+ 	FILE *f;
++	fdt32_t magic_buf, totalsize_buf;
+ 	uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
+ 	uint32_t off_dt, off_str, off_mem_rsvmap;
+ 	int rc;
+@@ -833,7 +827,7 @@ struct dt_info *dt_from_blob(const char *fname)
+ 
+ 	f = srcfile_relative_open(fname, NULL);
+ 
+-	rc = fread(&magic, sizeof(magic), 1, f);
++	rc = fread(&magic_buf, sizeof(magic_buf), 1, f);
+ 	if (ferror(f))
+ 		die("Error reading DT blob magic number: %s\n",
+ 		    strerror(errno));
+@@ -844,11 +838,11 @@ struct dt_info *dt_from_blob(const char *fname)
+ 			die("Mysterious short read reading magic number\n");
+ 	}
+ 
+-	magic = fdt32_to_cpu(magic);
++	magic = fdt32_to_cpu(magic_buf);
+ 	if (magic != FDT_MAGIC)
+ 		die("Blob has incorrect magic number\n");
+ 
+-	rc = fread(&totalsize, sizeof(totalsize), 1, f);
++	rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f);
+ 	if (ferror(f))
+ 		die("Error reading DT blob size: %s\n", strerror(errno));
+ 	if (rc < 1) {
+@@ -858,7 +852,7 @@ struct dt_info *dt_from_blob(const char *fname)
+ 			die("Mysterious short read reading blob size\n");
+ 	}
+ 
+-	totalsize = fdt32_to_cpu(totalsize);
++	totalsize = fdt32_to_cpu(totalsize_buf);
+ 	if (totalsize < FDT_V1_SIZE)
+ 		die("DT blob size (%d) is too small\n", totalsize);
+ 
+diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c
+new file mode 100644
+index 00000000..eff4dbcc
+--- /dev/null
++++ b/scripts/dtc/libfdt/fdt_addresses.c
+@@ -0,0 +1,96 @@
++/*
++ * libfdt - Flat Device Tree manipulation
++ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
++ *
++ * libfdt is dual licensed: you can use it either under the terms of
++ * the GPL, or the BSD license, at your option.
++ *
++ *  a) This library 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 library 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.
++ *
++ *     You should have received a copy of the GNU General Public
++ *     License along with this library; if not, write to the Free
++ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ *     MA 02110-1301 USA
++ *
++ * Alternatively,
++ *
++ *  b) Redistribution and use in source and binary forms, with or
++ *     without modification, are permitted provided that the following
++ *     conditions are met:
++ *
++ *     1. Redistributions of source code must retain the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer.
++ *     2. Redistributions in binary form must reproduce the above
++ *        copyright notice, this list of conditions and the following
++ *        disclaimer in the documentation and/or other materials
++ *        provided with the distribution.
++ *
++ *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
++ *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
++ *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
++ *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++ *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
++ *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++int fdt_address_cells(const void *fdt, int nodeoffset)
++{
++	const fdt32_t *ac;
++	int val;
++	int len;
++
++	ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
++	if (!ac)
++		return 2;
++
++	if (len != sizeof(*ac))
++		return -FDT_ERR_BADNCELLS;
++
++	val = fdt32_to_cpu(*ac);
++	if ((val <= 0) || (val > FDT_MAX_NCELLS))
++		return -FDT_ERR_BADNCELLS;
++
++	return val;
++}
++
++int fdt_size_cells(const void *fdt, int nodeoffset)
++{
++	const fdt32_t *sc;
++	int val;
++	int len;
++
++	sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
++	if (!sc)
++		return 2;
++
++	if (len != sizeof(*sc))
++		return -FDT_ERR_BADNCELLS;
++
++	val = fdt32_to_cpu(*sc);
++	if ((val < 0) || (val > FDT_MAX_NCELLS))
++		return -FDT_ERR_BADNCELLS;
++
++	return val;
++}
+diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c
+index f72d13b1..f2ae9b77 100644
+--- a/scripts/dtc/libfdt/fdt_empty_tree.c
++++ b/scripts/dtc/libfdt/fdt_empty_tree.c
+@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize)
+ 
+ 	return fdt_open_into(buf, buf, bufsize);
+ }
+-
+diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c
+new file mode 100644
+index 00000000..ceb96878
+--- /dev/null
++++ b/scripts/dtc/libfdt/fdt_overlay.c
+@@ -0,0 +1,677 @@
++#include "libfdt_env.h"
++
++#include <fdt.h>
++#include <libfdt.h>
++
++#include "libfdt_internal.h"
++
++/**
++ * overlay_get_target_phandle - retrieves the target phandle of a fragment
++ * @fdto: pointer to the device tree overlay blob
++ * @fragment: node offset of the fragment in the overlay
++ *
++ * overlay_get_target_phandle() retrieves the target phandle of an
++ * overlay fragment when that fragment uses a phandle (target
++ * property) instead of a path (target-path property).
++ *
++ * returns:
++ *      the phandle pointed by the target property
++ *      0, if the phandle was not found
++ *	-1, if the phandle was malformed
++ */
++static uint32_t overlay_get_target_phandle(const void *fdto, int fragment)
++{
++	const fdt32_t *val;
++	int len;
++
++	val = fdt_getprop(fdto, fragment, "target", &len);
++	if (!val)
++		return 0;
++
++	if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1))
++		return (uint32_t)-1;
++
++	return fdt32_to_cpu(*val);
++}
++
++/**
++ * overlay_get_target - retrieves the offset of a fragment's target
++ * @fdt: Base device tree blob
++ * @fdto: Device tree overlay blob
++ * @fragment: node offset of the fragment in the overlay
++ *
++ * overlay_get_target() retrieves the target offset in the base
++ * device tree of a fragment, no matter how the actual targetting is
++ * done (through a phandle or a path)
++ *
++ * returns:
++ *      the targetted node offset in the base device tree
++ *      Negative error code on error
++ */
++static int overlay_get_target(const void *fdt, const void *fdto,
++			      int fragment)
++{
++	uint32_t phandle;
++	const char *path;
++	int path_len;
++
++	/* Try first to do a phandle based lookup */
++	phandle = overlay_get_target_phandle(fdto, fragment);
++	if (phandle == (uint32_t)-1)
++		return -FDT_ERR_BADPHANDLE;
++
++	if (phandle)
++		return fdt_node_offset_by_phandle(fdt, phandle);
++
++	/* And then a path based lookup */
++	path = fdt_getprop(fdto, fragment, "target-path", &path_len);
++	if (!path) {
++		/*
++		 * If we haven't found either a target or a
++		 * target-path property in a node that contains a
++		 * __overlay__ subnode (we wouldn't be called
++		 * otherwise), consider it a improperly written
++		 * overlay
++		 */
++		if (path_len == -FDT_ERR_NOTFOUND)
++			return -FDT_ERR_BADOVERLAY;
++
++		return path_len;
++	}
++
++	return fdt_path_offset(fdt, path);
++}
++
++/**
++ * overlay_phandle_add_offset - Increases a phandle by an offset
++ * @fdt: Base device tree blob
++ * @node: Device tree overlay blob
++ * @name: Name of the property to modify (phandle or linux,phandle)
++ * @delta: offset to apply
++ *
++ * overlay_phandle_add_offset() increments a node phandle by a given
++ * offset.
++ *
++ * returns:
++ *      0 on success.
++ *      Negative error code on error
++ */
++static int overlay_phandle_add_offset(void *fdt, int node,
++				      const char *name, uint32_t delta)
++{
++	const fdt32_t *val;
++	uint32_t adj_val;
++	int len;
++
++	val = fdt_getprop(fdt, node, name, &len);
++	if (!val)
++		return len;
++
++	if (len != sizeof(*val))
++		return -FDT_ERR_BADPHANDLE;
++
++	adj_val = fdt32_to_cpu(*val);
++	if ((adj_val + delta) < adj_val)
++		return -FDT_ERR_NOPHANDLES;
++
++	adj_val += delta;
++	if (adj_val == (uint32_t)-1)
++		return -FDT_ERR_NOPHANDLES;
++
++	return fdt_setprop_inplace_u32(fdt, node, name, adj_val);
++}
++
++/**
++ * overlay_adjust_node_phandles - Offsets the phandles of a node
++ * @fdto: Device tree overlay blob
++ * @node: Offset of the node we want to adjust
++ * @delta: Offset to shift the phandles of
++ *
++ * overlay_adjust_node_phandles() adds a constant to all the phandles
++ * of a given node. This is mainly use as part of the overlay
++ * application process, when we want to update all the overlay
++ * phandles to not conflict with the overlays of the base device tree.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_adjust_node_phandles(void *fdto, int node,
++					uint32_t delta)
++{
++	int child;
++	int ret;
++
++	ret = overlay_phandle_add_offset(fdto, node, "phandle", delta);
++	if (ret && ret != -FDT_ERR_NOTFOUND)
++		return ret;
++
++	ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta);
++	if (ret && ret != -FDT_ERR_NOTFOUND)
++		return ret;
++
++	fdt_for_each_subnode(child, fdto, node) {
++		ret = overlay_adjust_node_phandles(fdto, child, delta);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++/**
++ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay
++ * @fdto: Device tree overlay blob
++ * @delta: Offset to shift the phandles of
++ *
++ * overlay_adjust_local_phandles() adds a constant to all the
++ * phandles of an overlay. This is mainly use as part of the overlay
++ * application process, when we want to update all the overlay
++ * phandles to not conflict with the overlays of the base device tree.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_adjust_local_phandles(void *fdto, uint32_t delta)
++{
++	/*
++	 * Start adjusting the phandles from the overlay root
++	 */
++	return overlay_adjust_node_phandles(fdto, 0, delta);
++}
++
++/**
++ * overlay_update_local_node_references - Adjust the overlay references
++ * @fdto: Device tree overlay blob
++ * @tree_node: Node offset of the node to operate on
++ * @fixup_node: Node offset of the matching local fixups node
++ * @delta: Offset to shift the phandles of
++ *
++ * overlay_update_local_nodes_references() update the phandles
++ * pointing to a node within the device tree overlay by adding a
++ * constant delta.
++ *
++ * This is mainly used as part of a device tree application process,
++ * where you want the device tree overlays phandles to not conflict
++ * with the ones from the base device tree before merging them.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_update_local_node_references(void *fdto,
++						int tree_node,
++						int fixup_node,
++						uint32_t delta)
++{
++	int fixup_prop;
++	int fixup_child;
++	int ret;
++
++	fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) {
++		const fdt32_t *fixup_val;
++		const char *tree_val;
++		const char *name;
++		int fixup_len;
++		int tree_len;
++		int i;
++
++		fixup_val = fdt_getprop_by_offset(fdto, fixup_prop,
++						  &name, &fixup_len);
++		if (!fixup_val)
++			return fixup_len;
++
++		if (fixup_len % sizeof(uint32_t))
++			return -FDT_ERR_BADOVERLAY;
++
++		tree_val = fdt_getprop(fdto, tree_node, name, &tree_len);
++		if (!tree_val) {
++			if (tree_len == -FDT_ERR_NOTFOUND)
++				return -FDT_ERR_BADOVERLAY;
++
++			return tree_len;
++		}
++
++		for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) {
++			fdt32_t adj_val;
++			uint32_t poffset;
++
++			poffset = fdt32_to_cpu(fixup_val[i]);
++
++			/*
++			 * phandles to fixup can be unaligned.
++			 *
++			 * Use a memcpy for the architectures that do
++			 * not support unaligned accesses.
++			 */
++			memcpy(&adj_val, tree_val + poffset, sizeof(adj_val));
++
++			adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta);
++
++			ret = fdt_setprop_inplace_namelen_partial(fdto,
++								  tree_node,
++								  name,
++								  strlen(name),
++								  poffset,
++								  &adj_val,
++								  sizeof(adj_val));
++			if (ret == -FDT_ERR_NOSPACE)
++				return -FDT_ERR_BADOVERLAY;
++
++			if (ret)
++				return ret;
++		}
++	}
++
++	fdt_for_each_subnode(fixup_child, fdto, fixup_node) {
++		const char *fixup_child_name = fdt_get_name(fdto, fixup_child,
++							    NULL);
++		int tree_child;
++
++		tree_child = fdt_subnode_offset(fdto, tree_node,
++						fixup_child_name);
++		if (tree_child == -FDT_ERR_NOTFOUND)
++			return -FDT_ERR_BADOVERLAY;
++		if (tree_child < 0)
++			return tree_child;
++
++		ret = overlay_update_local_node_references(fdto,
++							   tree_child,
++							   fixup_child,
++							   delta);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++/**
++ * overlay_update_local_references - Adjust the overlay references
++ * @fdto: Device tree overlay blob
++ * @delta: Offset to shift the phandles of
++ *
++ * overlay_update_local_references() update all the phandles pointing
++ * to a node within the device tree overlay by adding a constant
++ * delta to not conflict with the base overlay.
++ *
++ * This is mainly used as part of a device tree application process,
++ * where you want the device tree overlays phandles to not conflict
++ * with the ones from the base device tree before merging them.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_update_local_references(void *fdto, uint32_t delta)
++{
++	int fixups;
++
++	fixups = fdt_path_offset(fdto, "/__local_fixups__");
++	if (fixups < 0) {
++		/* There's no local phandles to adjust, bail out */
++		if (fixups == -FDT_ERR_NOTFOUND)
++			return 0;
++
++		return fixups;
++	}
++
++	/*
++	 * Update our local references from the root of the tree
++	 */
++	return overlay_update_local_node_references(fdto, 0, fixups,
++						    delta);
++}
++
++/**
++ * overlay_fixup_one_phandle - Set an overlay phandle to the base one
++ * @fdt: Base Device Tree blob
++ * @fdto: Device tree overlay blob
++ * @symbols_off: Node offset of the symbols node in the base device tree
++ * @path: Path to a node holding a phandle in the overlay
++ * @path_len: number of path characters to consider
++ * @name: Name of the property holding the phandle reference in the overlay
++ * @name_len: number of name characters to consider
++ * @poffset: Offset within the overlay property where the phandle is stored
++ * @label: Label of the node referenced by the phandle
++ *
++ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to
++ * a node in the base device tree.
++ *
++ * This is part of the device tree overlay application process, when
++ * you want all the phandles in the overlay to point to the actual
++ * base dt nodes.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_fixup_one_phandle(void *fdt, void *fdto,
++				     int symbols_off,
++				     const char *path, uint32_t path_len,
++				     const char *name, uint32_t name_len,
++				     int poffset, const char *label)
++{
++	const char *symbol_path;
++	uint32_t phandle;
++	fdt32_t phandle_prop;
++	int symbol_off, fixup_off;
++	int prop_len;
++
++	if (symbols_off < 0)
++		return symbols_off;
++
++	symbol_path = fdt_getprop(fdt, symbols_off, label,
++				  &prop_len);
++	if (!symbol_path)
++		return prop_len;
++
++	symbol_off = fdt_path_offset(fdt, symbol_path);
++	if (symbol_off < 0)
++		return symbol_off;
++
++	phandle = fdt_get_phandle(fdt, symbol_off);
++	if (!phandle)
++		return -FDT_ERR_NOTFOUND;
++
++	fixup_off = fdt_path_offset_namelen(fdto, path, path_len);
++	if (fixup_off == -FDT_ERR_NOTFOUND)
++		return -FDT_ERR_BADOVERLAY;
++	if (fixup_off < 0)
++		return fixup_off;
++
++	phandle_prop = cpu_to_fdt32(phandle);
++	return fdt_setprop_inplace_namelen_partial(fdto, fixup_off,
++						   name, name_len, poffset,
++						   &phandle_prop,
++						   sizeof(phandle_prop));
++};
++
++/**
++ * overlay_fixup_phandle - Set an overlay phandle to the base one
++ * @fdt: Base Device Tree blob
++ * @fdto: Device tree overlay blob
++ * @symbols_off: Node offset of the symbols node in the base device tree
++ * @property: Property offset in the overlay holding the list of fixups
++ *
++ * overlay_fixup_phandle() resolves all the overlay phandles pointed
++ * to in a __fixups__ property, and updates them to match the phandles
++ * in use in the base device tree.
++ *
++ * This is part of the device tree overlay application process, when
++ * you want all the phandles in the overlay to point to the actual
++ * base dt nodes.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off,
++				 int property)
++{
++	const char *value;
++	const char *label;
++	int len;
++
++	value = fdt_getprop_by_offset(fdto, property,
++				      &label, &len);
++	if (!value) {
++		if (len == -FDT_ERR_NOTFOUND)
++			return -FDT_ERR_INTERNAL;
++
++		return len;
++	}
++
++	do {
++		const char *path, *name, *fixup_end;
++		const char *fixup_str = value;
++		uint32_t path_len, name_len;
++		uint32_t fixup_len;
++		char *sep, *endptr;
++		int poffset, ret;
++
++		fixup_end = memchr(value, '\0', len);
++		if (!fixup_end)
++			return -FDT_ERR_BADOVERLAY;
++		fixup_len = fixup_end - fixup_str;
++
++		len -= fixup_len + 1;
++		value += fixup_len + 1;
++
++		path = fixup_str;
++		sep = memchr(fixup_str, ':', fixup_len);
++		if (!sep || *sep != ':')
++			return -FDT_ERR_BADOVERLAY;
++
++		path_len = sep - path;
++		if (path_len == (fixup_len - 1))
++			return -FDT_ERR_BADOVERLAY;
++
++		fixup_len -= path_len + 1;
++		name = sep + 1;
++		sep = memchr(name, ':', fixup_len);
++		if (!sep || *sep != ':')
++			return -FDT_ERR_BADOVERLAY;
++
++		name_len = sep - name;
++		if (!name_len)
++			return -FDT_ERR_BADOVERLAY;
++
++		poffset = strtoul(sep + 1, &endptr, 10);
++		if ((*endptr != '\0') || (endptr <= (sep + 1)))
++			return -FDT_ERR_BADOVERLAY;
++
++		ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off,
++						path, path_len, name, name_len,
++						poffset, label);
++		if (ret)
++			return ret;
++	} while (len > 0);
++
++	return 0;
++}
++
++/**
++ * overlay_fixup_phandles - Resolve the overlay phandles to the base
++ *                          device tree
++ * @fdt: Base Device Tree blob
++ * @fdto: Device tree overlay blob
++ *
++ * overlay_fixup_phandles() resolves all the overlay phandles pointing
++ * to nodes in the base device tree.
++ *
++ * This is one of the steps of the device tree overlay application
++ * process, when you want all the phandles in the overlay to point to
++ * the actual base dt nodes.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_fixup_phandles(void *fdt, void *fdto)
++{
++	int fixups_off, symbols_off;
++	int property;
++
++	/* We can have overlays without any fixups */
++	fixups_off = fdt_path_offset(fdto, "/__fixups__");
++	if (fixups_off == -FDT_ERR_NOTFOUND)
++		return 0; /* nothing to do */
++	if (fixups_off < 0)
++		return fixups_off;
++
++	/* And base DTs without symbols */
++	symbols_off = fdt_path_offset(fdt, "/__symbols__");
++	if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND)))
++		return symbols_off;
++
++	fdt_for_each_property_offset(property, fdto, fixups_off) {
++		int ret;
++
++		ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++/**
++ * overlay_apply_node - Merges a node into the base device tree
++ * @fdt: Base Device Tree blob
++ * @target: Node offset in the base device tree to apply the fragment to
++ * @fdto: Device tree overlay blob
++ * @node: Node offset in the overlay holding the changes to merge
++ *
++ * overlay_apply_node() merges a node into a target base device tree
++ * node pointed.
++ *
++ * This is part of the final step in the device tree overlay
++ * application process, when all the phandles have been adjusted and
++ * resolved and you just have to merge overlay into the base device
++ * tree.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_apply_node(void *fdt, int target,
++			      void *fdto, int node)
++{
++	int property;
++	int subnode;
++
++	fdt_for_each_property_offset(property, fdto, node) {
++		const char *name;
++		const void *prop;
++		int prop_len;
++		int ret;
++
++		prop = fdt_getprop_by_offset(fdto, property, &name,
++					     &prop_len);
++		if (prop_len == -FDT_ERR_NOTFOUND)
++			return -FDT_ERR_INTERNAL;
++		if (prop_len < 0)
++			return prop_len;
++
++		ret = fdt_setprop(fdt, target, name, prop, prop_len);
++		if (ret)
++			return ret;
++	}
++
++	fdt_for_each_subnode(subnode, fdto, node) {
++		const char *name = fdt_get_name(fdto, subnode, NULL);
++		int nnode;
++		int ret;
++
++		nnode = fdt_add_subnode(fdt, target, name);
++		if (nnode == -FDT_ERR_EXISTS) {
++			nnode = fdt_subnode_offset(fdt, target, name);
++			if (nnode == -FDT_ERR_NOTFOUND)
++				return -FDT_ERR_INTERNAL;
++		}
++
++		if (nnode < 0)
++			return nnode;
++
++		ret = overlay_apply_node(fdt, nnode, fdto, subnode);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++/**
++ * overlay_merge - Merge an overlay into its base device tree
++ * @fdt: Base Device Tree blob
++ * @fdto: Device tree overlay blob
++ *
++ * overlay_merge() merges an overlay into its base device tree.
++ *
++ * This is the final step in the device tree overlay application
++ * process, when all the phandles have been adjusted and resolved and
++ * you just have to merge overlay into the base device tree.
++ *
++ * returns:
++ *      0 on success
++ *      Negative error code on failure
++ */
++static int overlay_merge(void *fdt, void *fdto)
++{
++	int fragment;
++
++	fdt_for_each_subnode(fragment, fdto, 0) {
++		int overlay;
++		int target;
++		int ret;
++
++		/*
++		 * Each fragments will have an __overlay__ node. If
++		 * they don't, it's not supposed to be merged
++		 */
++		overlay = fdt_subnode_offset(fdto, fragment, "__overlay__");
++		if (overlay == -FDT_ERR_NOTFOUND)
++			continue;
++
++		if (overlay < 0)
++			return overlay;
++
++		target = overlay_get_target(fdt, fdto, fragment);
++		if (target < 0)
++			return target;
++
++		ret = overlay_apply_node(fdt, target, fdto, overlay);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++int fdt_overlay_apply(void *fdt, void *fdto)
++{
++	uint32_t delta = fdt_get_max_phandle(fdt);
++	int ret;
++
++	FDT_CHECK_HEADER(fdt);
++	FDT_CHECK_HEADER(fdto);
++
++	ret = overlay_adjust_local_phandles(fdto, delta);
++	if (ret)
++		goto err;
++
++	ret = overlay_update_local_references(fdto, delta);
++	if (ret)
++		goto err;
++
++	ret = overlay_fixup_phandles(fdt, fdto);
++	if (ret)
++		goto err;
++
++	ret = overlay_merge(fdt, fdto);
++	if (ret)
++		goto err;
++
++	/*
++	 * The overlay has been damaged, erase its magic.
++	 */
++	fdt_set_magic(fdto, ~0);
++
++	return 0;
++
++err:
++	/*
++	 * The overlay might have been damaged, erase its magic.
++	 */
++	fdt_set_magic(fdto, ~0);
++
++	/*
++	 * The base device tree might have been damaged, erase its
++	 * magic.
++	 */
++	fdt_set_magic(fdt, ~0);
++
++	return ret;
++}
+diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
+index 3d00d2ee..08de2cce 100644
+--- a/scripts/dtc/libfdt/fdt_ro.c
++++ b/scripts/dtc/libfdt/fdt_ro.c
+@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset,
+ {
+ 	const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
+ 
+-	if (! p)
++	if (!p)
+ 		/* short match */
+ 		return 0;
+ 
+@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ 	const struct fdt_property *prop;
+ 
+ 	prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
+-	if (! prop)
++	if (!prop)
+ 		return NULL;
+ 
+ 	return prop->data;
+diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
+index 2eed4f58..8b487f6c 100644
+--- a/scripts/dtc/libfdt/fdt_rw.c
++++ b/scripts/dtc/libfdt/fdt_rw.c
+@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
+ 	int err;
+ 
+ 	*prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
+-	if (! (*prop))
++	if (!*prop)
+ 		return oldlen;
+ 
+ 	if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
+@@ -283,7 +283,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name,
+ 	if (err)
+ 		return err;
+ 
+-	memcpy(prop->data, val, len);
++	if (len)
++		memcpy(prop->data, val, len);
+ 	return 0;
+ }
+ 
+@@ -322,7 +323,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
+ 	FDT_RW_CHECK_HEADER(fdt);
+ 
+ 	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+-	if (! prop)
++	if (!prop)
+ 		return len;
+ 
+ 	proplen = sizeof(*prop) + FDT_TAGALIGN(len);
+diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c
+index 6a804859..2bd15e7a 100644
+--- a/scripts/dtc/libfdt/fdt_sw.c
++++ b/scripts/dtc/libfdt/fdt_sw.c
+@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s)
+ 	return offset;
+ }
+ 
+-int fdt_property(void *fdt, const char *name, const void *val, int len)
++int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp)
+ {
+ 	struct fdt_property *prop;
+ 	int nameoff;
+@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
+ 	prop->tag = cpu_to_fdt32(FDT_PROP);
+ 	prop->nameoff = cpu_to_fdt32(nameoff);
+ 	prop->len = cpu_to_fdt32(len);
+-	memcpy(prop->data, val, len);
++	*valp = prop->data;
++	return 0;
++}
++
++int fdt_property(void *fdt, const char *name, const void *val, int len)
++{
++	void *ptr;
++	int ret;
++
++	ret = fdt_property_placeholder(fdt, name, len, &ptr);
++	if (ret)
++		return ret;
++	memcpy(ptr, val, len);
+ 	return 0;
+ }
+ 
+diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c
+index 6aaab399..5e859198 100644
+--- a/scripts/dtc/libfdt/fdt_wip.c
++++ b/scripts/dtc/libfdt/fdt_wip.c
+@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ 	int proplen;
+ 
+ 	propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
+-	if (! propval)
++	if (!propval)
+ 		return proplen;
+ 
+ 	if (proplen != len)
+@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
+ 	int len;
+ 
+ 	prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
+-	if (! prop)
++	if (!prop)
+ 		return len;
+ 
+ 	_fdt_nop_region(prop, len + sizeof(*prop));
+diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h
+index b842b156..707b5069 100644
+--- a/scripts/dtc/libfdt/libfdt.h
++++ b/scripts/dtc/libfdt/libfdt.h
+@@ -143,7 +143,9 @@
+ /* Low-level functions (you probably don't need these)                */
+ /**********************************************************************/
+ 
++#ifndef SWIG /* This function is not useful in Python */
+ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen);
++#endif
+ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
+ {
+ 	return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
+@@ -210,7 +212,6 @@ int fdt_next_subnode(const void *fdt, int offset);
+ /**********************************************************************/
+ /* General functions                                                  */
+ /**********************************************************************/
+-
+ #define fdt_get_header(fdt, field) \
+ 	(fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
+ #define fdt_magic(fdt)			(fdt_get_header(fdt, magic))
+@@ -354,8 +355,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
+  * useful for finding subnodes based on a portion of a larger string,
+  * such as a full path.
+  */
++#ifndef SWIG /* Not available in Python */
+ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
+ 			       const char *name, int namelen);
++#endif
+ /**
+  * fdt_subnode_offset - find a subnode of a given node
+  * @fdt: pointer to the device tree blob
+@@ -391,7 +394,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
+  * Identical to fdt_path_offset(), but only consider the first namelen
+  * characters of path as the path name.
+  */
++#ifndef SWIG /* Not available in Python */
+ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen);
++#endif
+ 
+ /**
+  * fdt_path_offset - find a tree node by its full path
+@@ -550,10 +555,12 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
+  * Identical to fdt_get_property(), but only examine the first namelen
+  * characters of name for matching the property name.
+  */
++#ifndef SWIG /* Not available in Python */
+ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+ 						    int nodeoffset,
+ 						    const char *name,
+ 						    int namelen, int *lenp);
++#endif
+ 
+ /**
+  * fdt_get_property - find a given property in a given node
+@@ -624,8 +631,10 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
+  *		-FDT_ERR_BADSTRUCTURE,
+  *		-FDT_ERR_TRUNCATED, standard meanings
+  */
++#ifndef SWIG /* This function is not useful in Python */
+ const void *fdt_getprop_by_offset(const void *fdt, int offset,
+ 				  const char **namep, int *lenp);
++#endif
+ 
+ /**
+  * fdt_getprop_namelen - get property value based on substring
+@@ -638,6 +647,7 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
+  * Identical to fdt_getprop(), but only examine the first namelen
+  * characters of name for matching the property name.
+  */
++#ifndef SWIG /* Not available in Python */
+ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+ 				const char *name, int namelen, int *lenp);
+ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
+@@ -647,6 +657,7 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset,
+ 	return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name,
+ 						      namelen, lenp);
+ }
++#endif
+ 
+ /**
+  * fdt_getprop - retrieve the value of a given property
+@@ -707,8 +718,10 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
+  * Identical to fdt_get_alias(), but only examine the first namelen
+  * characters of name for matching the alias name.
+  */
++#ifndef SWIG /* Not available in Python */
+ const char *fdt_get_alias_namelen(const void *fdt,
+ 				  const char *name, int namelen);
++#endif
+ 
+ /**
+  * fdt_get_alias - retrieve the path referenced by a given alias
+@@ -1106,10 +1119,12 @@ int fdt_size_cells(const void *fdt, int nodeoffset);
+  * of the name. It is useful when you want to manipulate only one value of
+  * an array and you have a string that doesn't end with \0.
+  */
++#ifndef SWIG /* Not available in Python */
+ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+ 					const char *name, int namelen,
+ 					uint32_t idx, const void *val,
+ 					int len);
++#endif
+ 
+ /**
+  * fdt_setprop_inplace - change a property's value, but not its size
+@@ -1139,8 +1154,10 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset,
+  *	-FDT_ERR_BADSTRUCTURE,
+  *	-FDT_ERR_TRUNCATED, standard meanings
+  */
++#ifndef SWIG /* Not available in Python */
+ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
+ 			const void *val, int len);
++#endif
+ 
+ /**
+  * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property
+@@ -1297,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
+ {
+ 	return fdt_property_u32(fdt, name, val);
+ }
++
++/**
++ * fdt_property_placeholder - add a new property and return a ptr to its value
++ *
++ * @fdt: pointer to the device tree blob
++ * @name: name of property to add
++ * @len: length of property value in bytes
++ * @valp: returns a pointer to where where the value should be placed
++ *
++ * returns:
++ *	0, on success
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_NOSPACE, standard meanings
++ */
++int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp);
++
+ #define fdt_property_string(fdt, name, str) \
+ 	fdt_property(fdt, name, str, strlen(str)+1)
+ int fdt_end_node(void *fdt);
+@@ -1527,6 +1560,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
+ #define fdt_setprop_string(fdt, nodeoffset, name, str) \
+ 	fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
+ 
++
++/**
++ * fdt_setprop_empty - set a property to an empty value
++ * @fdt: pointer to the device tree blob
++ * @nodeoffset: offset of the node whose property to change
++ * @name: name of the property to change
++ *
++ * fdt_setprop_empty() sets the value of the named property in the
++ * given node to an empty (zero length) value, or creates a new empty
++ * property if it does not already exist.
++ *
++ * This function may insert or delete data from the blob, and will
++ * therefore change the offsets of some existing nodes.
++ *
++ * returns:
++ *	0, on success
++ *	-FDT_ERR_NOSPACE, there is insufficient free space in the blob to
++ *		contain the new property value
++ *	-FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
++ *	-FDT_ERR_BADLAYOUT,
++ *	-FDT_ERR_BADMAGIC,
++ *	-FDT_ERR_BADVERSION,
++ *	-FDT_ERR_BADSTATE,
++ *	-FDT_ERR_BADSTRUCTURE,
++ *	-FDT_ERR_BADLAYOUT,
++ *	-FDT_ERR_TRUNCATED, standard meanings
++ */
++#define fdt_setprop_empty(fdt, nodeoffset, name) \
++	fdt_setprop((fdt), (nodeoffset), (name), NULL, 0)
++
+ /**
+  * fdt_appendprop - append to or create a property
+  * @fdt: pointer to the device tree blob
+@@ -1704,8 +1767,10 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name);
+  * creating subnodes based on a portion of a larger string, such as a
+  * full path.
+  */
++#ifndef SWIG /* Not available in Python */
+ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
+ 			    const char *name, int namelen);
++#endif
+ 
+ /**
+  * fdt_add_subnode - creates a new node
+diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h
+index 99f936da..952056cd 100644
+--- a/scripts/dtc/libfdt/libfdt_env.h
++++ b/scripts/dtc/libfdt/libfdt_env.h
+@@ -58,16 +58,16 @@
+ #include <string.h>
+ 
+ #ifdef __CHECKER__
+-#define __force __attribute__((force))
+-#define __bitwise __attribute__((bitwise))
++#define FDT_FORCE __attribute__((force))
++#define FDT_BITWISE __attribute__((bitwise))
+ #else
+-#define __force
+-#define __bitwise
++#define FDT_FORCE
++#define FDT_BITWISE
+ #endif
+ 
+-typedef uint16_t __bitwise fdt16_t;
+-typedef uint32_t __bitwise fdt32_t;
+-typedef uint64_t __bitwise fdt64_t;
++typedef uint16_t FDT_BITWISE fdt16_t;
++typedef uint32_t FDT_BITWISE fdt32_t;
++typedef uint64_t FDT_BITWISE fdt64_t;
+ 
+ #define EXTRACT_BYTE(x, n)	((unsigned long long)((uint8_t *)&x)[n])
+ #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1))
+@@ -80,29 +80,29 @@ typedef uint64_t __bitwise fdt64_t;
+ 
+ static inline uint16_t fdt16_to_cpu(fdt16_t x)
+ {
+-	return (__force uint16_t)CPU_TO_FDT16(x);
++	return (FDT_FORCE uint16_t)CPU_TO_FDT16(x);
+ }
+ static inline fdt16_t cpu_to_fdt16(uint16_t x)
+ {
+-	return (__force fdt16_t)CPU_TO_FDT16(x);
++	return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x);
+ }
+ 
+ static inline uint32_t fdt32_to_cpu(fdt32_t x)
+ {
+-	return (__force uint32_t)CPU_TO_FDT32(x);
++	return (FDT_FORCE uint32_t)CPU_TO_FDT32(x);
+ }
+ static inline fdt32_t cpu_to_fdt32(uint32_t x)
+ {
+-	return (__force fdt32_t)CPU_TO_FDT32(x);
++	return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x);
+ }
+ 
+ static inline uint64_t fdt64_to_cpu(fdt64_t x)
+ {
+-	return (__force uint64_t)CPU_TO_FDT64(x);
++	return (FDT_FORCE uint64_t)CPU_TO_FDT64(x);
+ }
+ static inline fdt64_t cpu_to_fdt64(uint64_t x)
+ {
+-	return (__force fdt64_t)CPU_TO_FDT64(x);
++	return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x);
+ }
+ #undef CPU_TO_FDT64
+ #undef CPU_TO_FDT32
+diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
+index afa2f67b..aecd2787 100644
+--- a/scripts/dtc/livetree.c
++++ b/scripts/dtc/livetree.c
+@@ -242,7 +242,7 @@ void delete_property_by_name(struct node *node, char *name)
+ 	struct property *prop = node->proplist;
+ 
+ 	while (prop) {
+-		if (!strcmp(prop->name, name)) {
++		if (streq(prop->name, name)) {
+ 			delete_property(prop);
+ 			return;
+ 		}
+@@ -275,7 +275,7 @@ void delete_node_by_name(struct node *parent, char *name)
+ 	struct node *node = parent->children;
+ 
+ 	while (node) {
+-		if (!strcmp(node->name, name)) {
++		if (streq(node->name, name)) {
+ 			delete_node(node);
+ 			return;
+ 		}
+@@ -319,8 +319,8 @@ struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
+ 
+ 	memset(new, 0, sizeof(*new));
+ 
+-	new->re.address = address;
+-	new->re.size = size;
++	new->address = address;
++	new->size = size;
+ 
+ 	return new;
+ }
+@@ -393,7 +393,7 @@ struct property *get_property(struct node *node, const char *propname)
+ cell_t propval_cell(struct property *prop)
+ {
+ 	assert(prop->val.len == sizeof(cell_t));
+-	return fdt32_to_cpu(*((cell_t *)prop->val.val));
++	return fdt32_to_cpu(*((fdt32_t *)prop->val.val));
+ }
+ 
+ struct property *get_property_by_label(struct node *tree, const char *label,
+@@ -478,7 +478,8 @@ struct node *get_node_by_path(struct node *tree, const char *path)
+ 	p = strchr(path, '/');
+ 
+ 	for_each_child(tree, child) {
+-		if (p && strneq(path, child->name, p-path))
++		if (p && (strlen(child->name) == p-path) &&
++				strneq(path, child->name, p-path))
+ 			return get_node_by_path(child, p+1);
+ 		else if (!p && streq(path, child->name))
+ 			return child;
+@@ -599,13 +600,13 @@ static int cmp_reserve_info(const void *ax, const void *bx)
+ 	a = *((const struct reserve_info * const *)ax);
+ 	b = *((const struct reserve_info * const *)bx);
+ 
+-	if (a->re.address < b->re.address)
++	if (a->address < b->address)
+ 		return -1;
+-	else if (a->re.address > b->re.address)
++	else if (a->address > b->address)
+ 		return 1;
+-	else if (a->re.size < b->re.size)
++	else if (a->size < b->size)
+ 		return -1;
+-	else if (a->re.size > b->re.size)
++	else if (a->size > b->size)
+ 		return 1;
+ 	else
+ 		return 0;
+@@ -847,6 +848,8 @@ static void add_fixup_entry(struct dt_info *dti, struct node *fn,
+ 	xasprintf(&entry, "%s:%s:%u",
+ 			node->fullpath, prop->name, m->offset);
+ 	append_to_property(fn, m->ref, entry, strlen(entry) + 1);
++
++	free(entry);
+ }
+ 
+ static void generate_fixups_tree_internal(struct dt_info *dti,
+@@ -900,7 +903,7 @@ static void add_local_fixup_entry(struct dt_info *dti,
+ 		struct node *refnode)
+ {
+ 	struct node *wn, *nwn;	/* local fixup node, walk node, new */
+-	uint32_t value_32;
++	fdt32_t value_32;
+ 	char **compp;
+ 	int i, depth;
+ 
+diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
+index aa3aad04..9d384599 100644
+--- a/scripts/dtc/srcpos.c
++++ b/scripts/dtc/srcpos.c
+@@ -252,7 +252,7 @@ srcpos_string(struct srcpos *pos)
+ 	const char *fname = "<no-file>";
+ 	char *pos_str;
+ 
+-	if (pos)
++	if (pos->file && pos->file->name)
+ 		fname = pos->file->name;
+ 
+ 
+diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
+index 2cdfcd82..7caca825 100644
+--- a/scripts/dtc/srcpos.h
++++ b/scripts/dtc/srcpos.h
+@@ -22,6 +22,7 @@
+ 
+ #include <stdio.h>
+ #include <stdbool.h>
++#include "util.h"
+ 
+ struct srcfile_state {
+ 	FILE *f;
+@@ -106,12 +107,10 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len);
+ extern struct srcpos *srcpos_copy(struct srcpos *pos);
+ extern char *srcpos_string(struct srcpos *pos);
+ 
+-extern void srcpos_verror(struct srcpos *pos, const char *prefix,
+-			  const char *fmt, va_list va)
+-	__attribute__((format(printf, 3, 0)));
+-extern void srcpos_error(struct srcpos *pos, const char *prefix,
+-			 const char *fmt, ...)
+-	__attribute__((format(printf, 3, 4)));
++extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
++					const char *fmt, va_list va);
++extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix,
++				      const char *fmt, ...);
+ 
+ extern void srcpos_set_line(char *f, int l);
+ 
+diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
+index c9d89679..2461a3d0 100644
+--- a/scripts/dtc/treesource.c
++++ b/scripts/dtc/treesource.c
+@@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val)
+ static void write_propval_cells(FILE *f, struct data val)
+ {
+ 	void *propend = val.val + val.len;
+-	cell_t *cp = (cell_t *)val.val;
++	fdt32_t *cp = (fdt32_t *)val.val;
+ 	struct marker *m = val.markers;
+ 
+ 	fprintf(f, "<");
+@@ -275,8 +275,8 @@ void dt_to_source(FILE *f, struct dt_info *dti)
+ 		for_each_label(re->labels, l)
+ 			fprintf(f, "%s: ", l->label);
+ 		fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
+-			(unsigned long long)re->re.address,
+-			(unsigned long long)re->re.size);
++			(unsigned long long)re->address,
++			(unsigned long long)re->size);
+ 	}
+ 
+ 	write_tree_source_node(f, dti->dt, 0);
+diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c
+index 3550f86b..9953c32a 100644
+--- a/scripts/dtc/util.c
++++ b/scripts/dtc/util.c
+@@ -396,7 +396,7 @@ void utilfdt_print_data(const char *data, int len)
+ 		} while (s < data + len);
+ 
+ 	} else if ((len % 4) == 0) {
+-		const uint32_t *cell = (const uint32_t *)data;
++		const fdt32_t *cell = (const fdt32_t *)data;
+ 
+ 		printf(" = <");
+ 		for (i = 0, len /= 4; i < len; i++)
+@@ -412,15 +412,16 @@ void utilfdt_print_data(const char *data, int len)
+ 	}
+ }
+ 
+-void util_version(void)
++void NORETURN util_version(void)
+ {
+ 	printf("Version: %s\n", DTC_VERSION);
+ 	exit(0);
+ }
+ 
+-void util_usage(const char *errmsg, const char *synopsis,
+-		const char *short_opts, struct option const long_opts[],
+-		const char * const opts_help[])
++void NORETURN util_usage(const char *errmsg, const char *synopsis,
++			 const char *short_opts,
++			 struct option const long_opts[],
++			 const char * const opts_help[])
+ {
+ 	FILE *fp = errmsg ? stderr : stdout;
+ 	const char a_arg[] = "<arg>";
+diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h
+index f5c4f1b5..ad5f4119 100644
+--- a/scripts/dtc/util.h
++++ b/scripts/dtc/util.h
+@@ -25,9 +25,17 @@
+  *                                                                   USA
+  */
+ 
++#ifdef __GNUC__
++#define PRINTF(i, j)	__attribute__((format (printf, i, j)))
++#define NORETURN	__attribute__((noreturn))
++#else
++#define PRINTF(i, j)
++#define NORETURN
++#endif
++
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+ 
+-static inline void __attribute__((noreturn)) die(const char *str, ...)
++static inline void NORETURN PRINTF(1, 2) die(const char *str, ...)
+ {
+ 	va_list ap;
+ 
+@@ -53,13 +61,14 @@ static inline void *xrealloc(void *p, size_t len)
+ 	void *new = realloc(p, len);
+ 
+ 	if (!new)
+-		die("realloc() failed (len=%d)\n", len);
++		die("realloc() failed (len=%zd)\n", len);
+ 
+ 	return new;
+ }
+ 
+ extern char *xstrdup(const char *s);
+-extern int xasprintf(char **strp, const char *fmt, ...);
++
++extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...);
+ extern char *join_path(const char *path, const char *name);
+ 
+ /**
+@@ -188,7 +197,7 @@ void utilfdt_print_data(const char *data, int len);
+ /**
+  * Show source version and exit
+  */
+-void util_version(void) __attribute__((noreturn));
++void NORETURN util_version(void);
+ 
+ /**
+  * Show usage and exit
+@@ -202,9 +211,10 @@ void util_version(void) __attribute__((noreturn));
+  * @param long_opts	The structure of long options
+  * @param opts_help	An array of help strings (should align with long_opts)
+  */
+-void util_usage(const char *errmsg, const char *synopsis,
+-		const char *short_opts, struct option const long_opts[],
+-		const char * const opts_help[]) __attribute__((noreturn));
++void NORETURN util_usage(const char *errmsg, const char *synopsis,
++			 const char *short_opts,
++			 struct option const long_opts[],
++			 const char * const opts_help[]);
+ 
+ /**
+  * Show usage and exit
diff --git a/patch/kernel/sun50iw1-dev/spi-sun6i-allow-large-transfers.patch b/patch/kernel/sun50i-dev/spi-sun6i-allow-large-transfers.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/spi-sun6i-allow-large-transfers.patch
rename to patch/kernel/sun50i-dev/spi-sun6i-allow-large-transfers.patch
diff --git a/patch/kernel/sun50iw1-dev/spidev-remove-warnings.patch b/patch/kernel/sun50i-dev/spidev-remove-warnings.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/spidev-remove-warnings.patch
rename to patch/kernel/sun50i-dev/spidev-remove-warnings.patch
diff --git a/patch/kernel/sun50iw2-dev/add-DVFS-and-THS-DT-H5.patch b/patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-DT-H5.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add-DVFS-and-THS-DT-H5.patch
rename to patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-DT-H5.patch
diff --git a/patch/kernel/sun50iw2-dev/add-DVFS-and-THS-drivers-H5.patch b/patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-drivers-H5.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add-DVFS-and-THS-drivers-H5.patch
rename to patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-drivers-H5.patch
diff --git a/patch/kernel/sun50iw1-dev/add-h5-a64-simplefb.patch b/patch/kernel/sun50i-dev/unresolved/add-h5-a64-simplefb.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add-h5-a64-simplefb.patch
rename to patch/kernel/sun50i-dev/unresolved/add-h5-a64-simplefb.patch
diff --git a/patch/kernel/sun50iw1-dev/add-sun50i-a64-overlays.patch b/patch/kernel/sun50i-dev/unresolved/add-sun50i-a64-overlays.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/add-sun50i-a64-overlays.patch
rename to patch/kernel/sun50i-dev/unresolved/add-sun50i-a64-overlays.patch
diff --git a/patch/kernel/sun50iw2-dev/add-sun50i-h5-overlays.patch b/patch/kernel/sun50i-dev/unresolved/add-sun50i-h5-overlays.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add-sun50i-h5-overlays.patch
rename to patch/kernel/sun50i-dev/unresolved/add-sun50i-h5-overlays.patch
diff --git a/patch/kernel/sun50iw2-dev/add_nanopim1plus2_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_nanopim1plus2_dts.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_nanopim1plus2_dts.patch
rename to patch/kernel/sun50i-dev/unresolved/add_nanopim1plus2_dts.patch
diff --git a/patch/kernel/sun50iw2-dev/add_nanopineo2.patch b/patch/kernel/sun50i-dev/unresolved/add_nanopineo2.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_nanopineo2.patch
rename to patch/kernel/sun50i-dev/unresolved/add_nanopineo2.patch
diff --git a/patch/kernel/sun50iw2-dev/add_orangepi-zero-plus-h5.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepi-zero-plus-h5.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_orangepi-zero-plus-h5.patch
rename to patch/kernel/sun50i-dev/unresolved/add_orangepi-zero-plus-h5.patch
diff --git a/patch/kernel/sun50iw2-dev/add_orangepiprime_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepiprime_dts.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_orangepiprime_dts.patch
rename to patch/kernel/sun50i-dev/unresolved/add_orangepiprime_dts.patch
diff --git a/patch/kernel/sun50iw2-dev/add_orangepiwin_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepiwin_dts.patch
similarity index 100%
rename from patch/kernel/sun50iw2-dev/add_orangepiwin_dts.patch
rename to patch/kernel/sun50i-dev/unresolved/add_orangepiwin_dts.patch
diff --git a/patch/kernel/sun50iw1-dev/spi-patch-for-A64-4.10.x.patch b/patch/kernel/sun50i-dev/unresolved/spi-patch-for-A64-4.10.x.patch
similarity index 100%
rename from patch/kernel/sun50iw1-dev/spi-patch-for-A64-4.10.x.patch
rename to patch/kernel/sun50i-dev/unresolved/spi-patch-for-A64-4.10.x.patch
diff --git a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch b/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch
deleted file mode 100644
index 1ad041f64..000000000
--- a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch
+++ /dev/null
@@ -1,404 +0,0 @@
-diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
-index 8af8f4be8e3b..fbd3f8cd5c22 100644
---- a/drivers/clk/sunxi-ng/Kconfig
-+++ b/drivers/clk/sunxi-ng/Kconfig
-@@ -151,4 +151,10 @@  config SUN9I_A80_CCU
- 	default MACH_SUN9I
- 	depends on MACH_SUN9I || COMPILE_TEST
- 
-+config SUN8I_R_CCU
-+	bool "Support for Allwinner SoCs' PRCM CCUs"
-+	select SUNXI_CCU_DIV
-+	select SUNXI_CCU_GATE
-+	default MACH_SUN8I || (ARCH_SUNXI && ARM64)
-+
- endif
-diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
-index 6feaac0c5600..0ec02fe14c50 100644
---- a/drivers/clk/sunxi-ng/Makefile
-+++ b/drivers/clk/sunxi-ng/Makefile
-@@ -25,6 +25,7 @@  obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
- obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
- obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
- obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
-+obj-$(CONFIG_SUN8I_R_CCU)	+= ccu-sun8i-r.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-de.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-usb.o
-diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
-new file mode 100644
-index 000000000000..0d027d53dbdf
---- /dev/null
-+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
-@@ -0,0 +1,213 @@ 
-+/*
-+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program 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.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+
-+#include "ccu_common.h"
-+#include "ccu_reset.h"
-+
-+#include "ccu_div.h"
-+#include "ccu_gate.h"
-+#include "ccu_mp.h"
-+#include "ccu_nm.h"
-+
-+#include "ccu-sun8i-r.h"
-+
-+static const char * const ar100_parents[] = { "osc32k", "osc24M",
-+					     "pll-periph0", "iosc" };
-+
-+static struct ccu_div ar100_clk = {
-+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
-+
-+	.mux		= {
-+		.shift	= 16,
-+		.width	= 2,
-+
-+		.variable_prediv	= {
-+			.index	= 2,
-+			.shift	= 8,
-+			.width	= 5,
-+		},
-+	},
-+
-+	.common		= {
-+		.reg		= 0x00,
-+		.features	= CCU_FEATURE_VARIABLE_PREDIV,
-+		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
-+						      ar100_parents,
-+						      &ccu_div_ops,
-+						      0),
-+	},
-+};
-+
-+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
-+
-+static struct ccu_div apb0_clk = {
-+	.div		= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
-+
-+	.common		= {
-+		.reg		= 0x0c,
-+		.hw.init	= CLK_HW_INIT("apb0",
-+					      "ahb0",
-+					      &ccu_div_ops,
-+					      0),
-+	},
-+};
-+
-+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
-+		      0x28, BIT(0), 0);
-+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
-+		      0x28, BIT(1), 0);
-+static SUNXI_CCU_GATE(apb0_timer_clk,	"apb0-timer",	"apb0",
-+		      0x28, BIT(2), 0);
-+static SUNXI_CCU_GATE(apb0_rsb_clk,	"apb0-rsb",	"apb0",
-+		      0x28, BIT(3), 0);
-+static SUNXI_CCU_GATE(apb0_uart_clk,	"apb0-uart",	"apb0",
-+		      0x28, BIT(4), 0);
-+static SUNXI_CCU_GATE(apb0_i2c_clk,	"apb0-i2c",	"apb0",
-+		      0x28, BIT(6), 0);
-+static SUNXI_CCU_GATE(apb0_twd_clk,	"apb0-twd",	"apb0",
-+		      0x28, BIT(7), 0);
-+
-+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" };
-+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
-+				  r_mod0_default_parents, 0x54,
-+				  0, 4,		/* M */
-+				  16, 2,	/* P */
-+				  24, 2,	/* mux */
-+				  BIT(31),	/* gate */
-+				  0);
-+
-+static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
-+	&ar100_clk.common,
-+	&apb0_clk.common,
-+	&apb0_pio_clk.common,
-+	&apb0_ir_clk.common,
-+	&apb0_timer_clk.common,
-+	&apb0_uart_clk.common,
-+	&apb0_i2c_clk.common,
-+	&apb0_twd_clk.common,
-+	&ir_clk.common,
-+};
-+
-+static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
-+	&ar100_clk.common,
-+	&apb0_clk.common,
-+	&apb0_pio_clk.common,
-+	&apb0_ir_clk.common,
-+	&apb0_timer_clk.common,
-+	&apb0_rsb_clk.common,
-+	&apb0_uart_clk.common,
-+	&apb0_i2c_clk.common,
-+	&apb0_twd_clk.common,
-+	&ir_clk.common,
-+};
-+
-+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
-+	.hws	= {
-+		[CLK_AR100]		= &ar100_clk.common.hw,
-+		[CLK_AHB0]		= &ahb0_clk.hw,
-+		[CLK_APB0]		= &apb0_clk.common.hw,
-+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
-+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
-+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
-+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
-+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
-+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
-+		[CLK_IR]		= &ir_clk.common.hw,
-+	},
-+	.num	= CLK_NUMBER,
-+};
-+
-+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
-+	.hws	= {
-+		[CLK_AR100]		= &ar100_clk.common.hw,
-+		[CLK_AHB0]		= &ahb0_clk.hw,
-+		[CLK_APB0]		= &apb0_clk.common.hw,
-+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
-+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
-+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
-+		[CLK_APB0_RSB]		= &apb0_rsb_clk.common.hw,
-+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
-+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
-+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
-+		[CLK_IR]		= &ir_clk.common.hw,
-+	},
-+	.num	= CLK_NUMBER,
-+};
-+
-+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
-+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
-+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
-+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
-+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
-+};
-+
-+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
-+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
-+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
-+	[RST_APB0_RSB]		=  { 0xb0, BIT(3) },
-+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
-+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
-+};
-+
-+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
-+	.ccu_clks	= sun8i_h3_r_ccu_clks,
-+	.num_ccu_clks	= ARRAY_SIZE(sun8i_h3_r_ccu_clks),
-+
-+	.hw_clks	= &sun8i_h3_r_hw_clks,
-+
-+	.resets		= sun8i_h3_r_ccu_resets,
-+	.num_resets	= ARRAY_SIZE(sun8i_h3_r_ccu_resets),
-+};
-+
-+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
-+	.ccu_clks	= sun50i_a64_r_ccu_clks,
-+	.num_ccu_clks	= ARRAY_SIZE(sun50i_a64_r_ccu_clks),
-+
-+	.hw_clks	= &sun50i_a64_r_hw_clks,
-+
-+	.resets		= sun50i_a64_r_ccu_resets,
-+	.num_resets	= ARRAY_SIZE(sun50i_a64_r_ccu_resets),
-+};
-+
-+static void __init sunxi_r_ccu_init(struct device_node *node,
-+				    const struct sunxi_ccu_desc *desc)
-+{
-+	void __iomem *reg;
-+
-+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-+	if (IS_ERR(reg)) {
-+		pr_err("%s: Could not map the clock registers\n",
-+		       of_node_full_name(node));
-+		return;
-+	}
-+
-+	sunxi_ccu_probe(node, reg, desc);
-+}
-+
-+static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
-+{
-+	sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
-+}
-+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
-+	       sun8i_h3_r_ccu_setup);
-+
-+static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
-+{
-+	sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
-+}
-+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
-+	       sun50i_a64_r_ccu_setup);
-diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
-new file mode 100644
-index 000000000000..eaa431fd1d8f
---- /dev/null
-+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
-@@ -0,0 +1,27 @@ 
-+/*
-+ * Copyright 2016 Icenowy <icenowy@aosc.xyz>
-+ *
-+ * This program 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 program 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.
-+ */
-+
-+#ifndef _CCU_SUN8I_R_H
-+#define _CCU_SUN8I_R_H_
-+
-+#include <dt-bindings/clock/sun8i-r-ccu.h>
-+#include <dt-bindings/reset/sun8i-r-ccu.h>
-+
-+/* AHB/APB bus clocks are not exported */
-+#define CLK_AHB0	1
-+#define CLK_APB0	2
-+
-+#define CLK_NUMBER	(CLK_APB0_TWD + 1)
-+
-+#endif /* _CCU_SUN8I_R_H */
-diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h
-new file mode 100644
-index 000000000000..779d20aa0d05
---- /dev/null
-+++ b/include/dt-bindings/clock/sun8i-r-ccu.h
-@@ -0,0 +1,59 @@ 
-+/*
-+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
-+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
-+
-+#define CLK_AR100		0
-+
-+#define CLK_APB0_PIO		3
-+#define CLK_APB0_IR		4
-+#define CLK_APB0_TIMER		5
-+#define CLK_APB0_RSB		6
-+#define CLK_APB0_UART		7
-+/* 8 is reserved for CLK_APB0_W1 on A31 */
-+#define CLK_APB0_I2C		9
-+#define CLK_APB0_TWD		10
-+
-+#define CLK_IR			11
-+
-+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */
-diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h
-new file mode 100644
-index 000000000000..4ba64f3d6fc9
---- /dev/null
-+++ b/include/dt-bindings/reset/sun8i-r-ccu.h
-@@ -0,0 +1,53 @@ 
-+/*
-+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_
-+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_
-+
-+#define RST_APB0_IR		0
-+#define RST_APB0_TIMER		1
-+#define RST_APB0_RSB		2
-+#define RST_APB0_UART		3
-+/* 4 is reserved for RST_APB0_W1 on A31 */
-+#define RST_APB0_I2C		5
-+
-+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */
-
diff --git a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch b/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch
deleted file mode 100644
index 428807bd8..000000000
--- a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
-index 81f0d61..18ff031 100644
---- a/arch/arm64/Kconfig.platforms
-+++ b/arch/arm64/Kconfig.platforms
-@@ -5,6 +5,7 @@ config ARCH_SUNXI
- 	select GENERIC_IRQ_CHIP
- 	select PINCTRL
- 	select PINCTRL_SUN50I_A64
-+	select PINCTRL_SUN50I_A64_R
- 	select PINCTRL_SUN50I_H5
- 	select PINCTRL_SUN8I_H3_R
- 	help
-diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
-index a84bfa7f3c05..a0c419ac2a3b 100644
---- a/drivers/pinctrl/sunxi/Kconfig
-+++ b/drivers/pinctrl/sunxi/Kconfig
-@@ -68,6 +68,10 @@  config PINCTRL_SUN50I_A64
- 	def_bool ARM64 && ARCH_SUNXI
- 	select PINCTRL_SUNXI
- 
-+config PINCTRL_SUN50I_A64_R
-+	def_bool ARM64 && ARCH_SUNXI
-+	select PINCTRL_SUNXI
-+
- config PINCTRL_SUN50I_H5
- 	def_bool ARM64 && ARCH_SUNXI
- 	select PINCTRL_SUNXI
-diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
-index 04ccb88ebd5f..df4ccd6cd44c 100644
---- a/drivers/pinctrl/sunxi/Makefile
-+++ b/drivers/pinctrl/sunxi/Makefile
-@@ -11,6 +11,7 @@  obj-$(CONFIG_PINCTRL_SUN8I_A23)		+= pinctrl-sun8i-a23.o
- obj-$(CONFIG_PINCTRL_SUN8I_A23_R)	+= pinctrl-sun8i-a23-r.o
- obj-$(CONFIG_PINCTRL_SUN8I_A33)		+= pinctrl-sun8i-a33.o
- obj-$(CONFIG_PINCTRL_SUN50I_A64)	+= pinctrl-sun50i-a64.o
-+obj-$(CONFIG_PINCTRL_SUN50I_A64_R)	+= pinctrl-sun50i-a64-r.o
- obj-$(CONFIG_PINCTRL_SUN8I_A83T)	+= pinctrl-sun8i-a83t.o
- obj-$(CONFIG_PINCTRL_SUN8I_H3)		+= pinctrl-sun8i-h3.o
- obj-$(CONFIG_PINCTRL_SUN8I_H3_R)	+= pinctrl-sun8i-h3-r.o
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c
-new file mode 100644
-index 000000000000..415870e82cbf
---- /dev/null
-+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c
-@@ -0,0 +1,125 @@ 
-+/*
-+ * Allwinner A64 SoCs special pins pinctrl driver.
-+ *
-+ * Based on pinctrl-sun8i-a23-r.c
-+ *
-+ * Copyright (C) 2016 Icenowy Zheng
-+ * Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * Copyright (C) 2014 Chen-Yu Tsai
-+ * Chen-Yu Tsai <wens@csie.org>
-+ *
-+ * Copyright (C) 2014 Boris Brezillon
-+ * Boris Brezillon <boris.brezillon@free-electrons.com>
-+ *
-+ * Copyright (C) 2014 Maxime Ripard
-+ * Maxime Ripard <maxime.ripard@free-electrons.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2.  This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+#include "pinctrl-sunxi.h"
-+
-+static const struct sunxi_desc_pin sun50i_a64_r_pins[] = {
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_rsb"),		/* SCK */
-+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SCK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PL_EINT0 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_rsb"),		/* SDA */
-+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SDA */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PL_EINT1 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PL_EINT2 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PL_EINT3 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* MS */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PL_EINT4 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* CK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PL_EINT5 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* DO */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PL_EINT6 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* DI */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PL_EINT7 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PL_EINT8 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PL_EINT9 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_pwm"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)),	/* PL_EINT10 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_cir_rx"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)),	/* PL_EINT11 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)),	/* PL_EINT12 */
-+};
-+
-+static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = {
-+	.pins = sun50i_a64_r_pins,
-+	.npins = ARRAY_SIZE(sun50i_a64_r_pins),
-+	.pin_base = PL_BASE,
-+	.irq_banks = 1,
-+};
-+
-+static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev)
-+{
-+	return sunxi_pinctrl_init(pdev,
-+				  &sun50i_a64_r_pinctrl_data);
-+}
-+
-+static const struct of_device_id sun50i_a64_r_pinctrl_match[] = {
-+	{ .compatible = "allwinner,sun50i-a64-r-pinctrl", },
-+	{}
-+};
-+
-+static struct platform_driver sun50i_a64_r_pinctrl_driver = {
-+	.probe	= sun50i_a64_r_pinctrl_probe,
-+	.driver	= {
-+		.name		= "sun50i-a64-r-pinctrl",
-+		.of_match_table	= sun50i_a64_r_pinctrl_match,
-+	},
-+};
-+builtin_platform_driver(sun50i_a64_r_pinctrl_driver);
-diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-index 02c0385..c0773d8 100644
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-@@ -43,8 +43,10 @@
-  */
- 
- #include <dt-bindings/clock/sun50i-a64-ccu.h>
-+#include <dt-bindings/clock/sun8i-r-ccu.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/reset/sun50i-a64-ccu.h>
-+#include <dt-bindings/reset/sun8i-r-ccu.h>
- 
- / {
- 	interrupt-parent = <&gic>;
-@@ -98,6 +100,13 @@
- 		clock-output-names = "osc32k";
- 	};
- 
-+	osc32000: osc32000_clk {
-+		#clock-cells = <0>;
-+		compatible = "fixed-clock";
-+		clock-frequency = <32000>;
-+		clock-output-names = "osc32000";
-+	};
-+
- 	psci {
- 		compatible = "arm,psci-0.2";
- 		method = "smc";
-@@ -306,6 +315,27 @@
- 			};
- 		};
- 
-+		r_ccu: clock@1f01400 {
-+			compatible = "allwinner,sun50i-a64-r-ccu";
-+			reg = <0x01f01400 0x100>;
-+			clocks = <&osc24M>, <&osc32k>, <&osc32000>;
-+			clock-names = "hosc", "losc", "iosc";
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+		};
-+
-+		r_pio: pinctrl@1f02c00 {
-+			compatible = "allwinner,sun50i-a64-r-pinctrl";
-+			reg = <0x01f02c00 0x400>;
-+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-+			clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
-+			clock-names = "apb", "hosc", "losc";
-+			gpio-controller;
-+			#gpio-cells = <3>;
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+		};
-+
- 		uart0: serial@1c28000 {
- 			compatible = "snps,dw-apb-uart";
- 			reg = <0x01c28000 0x400>;
diff --git a/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch b/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch
deleted file mode 100644
index 68c734bab..000000000
--- a/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-diff --git a/scripts/package/builddeb b/scripts/package/builddeb
-index 8ea9fd2b..9f17b825 100755
---- a/scripts/package/builddeb
-+++ b/scripts/package/builddeb
-@@ -29,6 +29,28 @@ create_package() {
- 	# in case we are in a restrictive umask environment like 0077
- 	chmod -R a+rX "$pdir"
- 
-+	# Create preinstall and post install script to remove dtb
-+	if [[ "$1" == *dtb* ]]; then
-+		echo "if [ -d /boot/dtb-$version ]; then mv /boot/dtb-$version /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/preinst
-+		echo "if [ -d /boot/dtb.old ]; then rm -rf /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
-+		echo "if [ -d /dtb ]; then mv /dtb /dtb.old; fi" >> $pdir/DEBIAN/preinst
-+		echo "if [ -d /boot/dtb ]; then mv /boot/dtb /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
-+		echo "exit 0" >> $pdir/DEBIAN/preinst
-+		chmod 775 $pdir/DEBIAN/preinst
-+		#
-+		echo "if [ -d /boot/dtb-$version.old ]; then rm -rf /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/postinst
-+		echo "ln -sf dtb-$version /boot/dtb > /dev/null 2>&1 || mv /boot/dtb-$version /boot/dtb" >> $pdir/DEBIAN/postinst
-+		echo "exit 0" >> $pdir/DEBIAN/postinst
-+		chmod 775 $pdir/DEBIAN/postinst
-+	fi
-+	
-+	# Create postinstall script for headers
-+	if [[ "$1" == *headers* ]]; then
-+		echo "cd /usr/src/linux-headers-$version; echo \"Compiling headers - please wait ...\"; make -s scripts >/dev/null 2>&1" >> $pdir/DEBIAN/postinst
-+		echo "exit 0" >> $pdir/DEBIAN/postinst
-+		chmod 775 $pdir/DEBIAN/postinst
-+	fi
-+	
- 	# Create the package
- 	dpkg-gencontrol $forcearch -Vkernel:debarch="${debarch}" -p$pname -P"$pdir"
- 	dpkg --build "$pdir" ..
-@@ -95,11 +117,13 @@ tmpdir="$objtree/debian/tmp"
- fwdir="$objtree/debian/fwtmp"
- kernel_headers_dir="$objtree/debian/hdrtmp"
- libc_headers_dir="$objtree/debian/headertmp"
-+dtb_dir="$objtree/debian/dtbtmp"
- dbg_dir="$objtree/debian/dbgtmp"
--packagename=linux-image-$version
--fwpackagename=linux-firmware-image-$version
--kernel_headers_packagename=linux-headers-$version
--libc_headers_packagename=linux-libc-dev
-+packagename=linux-image-dev"$LOCALVERSION"
-+fwpackagename=linux-firmware-image-dev"$LOCALVERSION"
-+kernel_headers_packagename=linux-headers-dev"$LOCALVERSION"
-+dtb_packagename=linux-dtb-dev"$LOCALVERSION"
-+libc_headers_packagename=linux-libc-dev-dev"$LOCALVERSION"
- dbg_packagename=$packagename-dbg
- debarch=
- forcearch=
-@@ -119,6 +143,9 @@ um)
- parisc|mips|powerpc)
- 	installed_image_path="boot/vmlinux-$version"
- 	;;
-+arm64)
-+	installed_image_path="boot/Image-$version"
-+	;;
- *)
- 	installed_image_path="boot/vmlinuz-$version"
- esac
-@@ -126,7 +153,9 @@ esac
- BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
- 
- # Setup the directory structure
--rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
-+rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" "$dtb_dir" $objtree/debian/files
-+mkdir -m 755 -p "$dtb_dir/DEBIAN"
-+mkdir -p "$dtb_dir/boot/dtb-$version" "$dtb_dir/usr/share/doc/$dtb_packagename"
- mkdir -m 755 -p "$tmpdir/DEBIAN"
- mkdir -p "$tmpdir/lib" "$tmpdir/boot"
- mkdir -p "$fwdir/lib/firmware/$version/"
-@@ -143,12 +172,7 @@ else
- 	cp System.map "$tmpdir/boot/System.map-$version"
- 	cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version"
- fi
--# Not all arches include the boot path in KBUILD_IMAGE
--if [ -e $KBUILD_IMAGE ]; then
--	cp $KBUILD_IMAGE "$tmpdir/$installed_image_path"
--else
--	cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/$installed_image_path"
--fi
-+cp arch/$ARCH/boot/Image "$tmpdir/$installed_image_path"
- 
- if grep -q "^CONFIG_OF=y" $KCONFIG_CONFIG ; then
- 	# Only some architectures with OF support have this target
-@@ -185,6 +209,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then
- 	fi
- fi
- 
-+if grep -q '^CONFIG_OF=y' $KCONFIG_CONFIG ; then
-+	#mkdir -p "$tmpdir/boot/dtb"
-+	INSTALL_DTBS_PATH="$dtb_dir/boot/dtb-$version" $MAKE KBUILD_SRC= dtbs_install
-+fi
-+
- if [ "$ARCH" != "um" ]; then
- 	$MAKE headers_check KBUILD_SRC=
- 	$MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr"
-@@ -209,9 +238,11 @@ for script in postinst postrm preinst prerm ; do
- set -e
- 
- # Pass maintainer script parameters to hook scripts
-+
- export DEB_MAINT_PARAMS="\$*"
- 
- # Tell initramfs builder whether it's wanted
-+
- export INITRD=$want_initrd
- 
- test -d $debhookdir/$script.d && run-parts --arg="$version" --arg="/$installed_image_path" $debhookdir/$script.d
-@@ -220,6 +251,17 @@ EOF
- 	chmod 755 "$tmpdir/DEBIAN/$script"
- done
- 
-+##
-+## Create sym link to kernel image
-+##
-+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/postinst
-+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/postinst
-+cat >> $tmpdir/DEBIAN/postinst <<EOT 
-+ln -sf $(basename $installed_image_path) /boot/Image > /dev/null 2>&1 || mv /$installed_image_path /boot/Image
-+touch /boot/.next
-+exit 0
-+EOT
-+
- # Try to determine maintainer and email values
- if [ -n "$DEBEMAIL" ]; then
-        email=$DEBEMAIL
-@@ -337,16 +379,24 @@ if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then
- fi
- destdir=$kernel_headers_dir/usr/src/linux-headers-$version
- mkdir -p "$destdir"
-+######################## headers patch
-+ZACNI=$(pwd)
-+cd $destdir
-+patch -p1 < /tmp/headers-debian-byteshift.patch
-+cd $ZACNI
-+######################## headers patch
- (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
- (cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -)
- (cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be
- ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
- rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
- 
-+(cd "$destdir"; make M=scripts clean)
-+
- cat <<EOF >> debian/control
- 
- Package: $kernel_headers_packagename
--Provides: linux-headers, linux-headers-2.6
-+Provides: linux-headers
- Architecture: any
- Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch}
-  This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch}
-@@ -372,6 +422,16 @@ fi
- 
- cat <<EOF >> debian/control
- 
-+Package: $dtb_packagename
-+Architecture: any
-+Description: Linux DTB, version $version
-+ This package contains device blobs from the Linux kernel, version $version.
-+EOF
-+
-+create_package "$dtb_packagename" "$dtb_dir"
-+
-+cat <<EOF >> debian/control
-+
- Package: $libc_headers_packagename
- Section: devel
- Provides: linux-kernel-headers
-@@ -383,7 +443,7 @@ EOF
- 
- if [ "$ARCH" != "um" ]; then
- 	create_package "$kernel_headers_packagename" "$kernel_headers_dir"
--	create_package "$libc_headers_packagename" "$libc_headers_dir"
-+#	create_package "$libc_headers_packagename" "$libc_headers_dir"
- fi
- 
- create_package "$packagename" "$tmpdir"
diff --git a/patch/kernel/sun50iw1-dev/remove-localversion.patch b/patch/kernel/sun50iw1-dev/remove-localversion.patch
deleted file mode 100644
index 8083ac142..000000000
--- a/patch/kernel/sun50iw1-dev/remove-localversion.patch
+++ /dev/null
@@ -1,7 +0,0 @@
-diff --git a/localversion-next b/localversion-next
-deleted file mode 100644
-index 299f8119..00000000
---- a/localversion-next
-+++ /dev/null
-@@ -1 +0,0 @@
---next-20170216
diff --git a/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch b/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch
deleted file mode 100644
index bc3f71600..000000000
--- a/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
-index ddf83d0..a0fb9e3 100644
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -275,7 +275,11 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
-
- # DTC
- # ---------------------------------------------------------------------------
-+ifeq ($(CONFIG_OF_CONFIGFS),y)
-+DTC ?= $(objtree)/scripts/dtc/dtc -@
-+else
- DTC ?= $(objtree)/scripts/dtc/dtc
-+endif
-
- # Generate an assembly file to wrap the output of the device tree compiler
- quiet_cmd_dt_S_dtb= DTB     $@
diff --git a/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch b/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch
deleted file mode 100644
index 0e1eb6837..000000000
--- a/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
-index 495edf5f..c0edd5c2 100644
---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
-@@ -45,6 +45,22 @@
- / {
- 	interrupt-parent = <&gic>;
- 
-+        chosen {
-+                #address-cells = <1>;
-+                #size-cells = <1>;
-+                ranges;
-+
-+                simplefb_hdmi: framebuffer@0 {
-+                        compatible = "allwinner,simple-framebuffer",
-+                                     "simple-framebuffer";
-+                        allwinner,pipeline = "de0-lcd0-hdmi";
-+                        clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_BUS_DE>,
-+                                 <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>,
-+                                 <&ccu CLK_TCON0>, <&ccu CLK_HDMI>;
-+                        status = "disabled";
-+                };
-+        };
-+
- 	cpus {
- 		#address-cells = <1>;
- 		#size-cells = <0>;
-diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-index 100e9b49..e208e005 100644
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-@@ -52,6 +52,22 @@
- 	#address-cells = <1>;
- 	#size-cells = <1>;
- 
-+        chosen {
-+                #address-cells = <1>;
-+                #size-cells = <1>;
-+                ranges;
-+
-+                simplefb_hdmi: framebuffer@0 {
-+                        compatible = "allwinner,simple-framebuffer",
-+                                     "simple-framebuffer";
-+                        allwinner,pipeline = "de0-lcd0-hdmi";
-+                        clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_BUS_DE>,
-+                                 <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>,
-+                                 <&ccu CLK_TCON1>, <&ccu CLK_HDMI>;
-+                        status = "disabled";
-+                };
-+        };
-+
- 	cpus {
- 		#address-cells = <1>;
- 		#size-cells = <0>;
diff --git a/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch b/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch
deleted file mode 100644
index 361e9f86a..000000000
--- a/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-diff --git a/arch/arm/Makefile b/arch/arm/Makefile
-index ab30cc63..cc176797 100644
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -339,6 +339,12 @@ $(INSTALL_TARGETS):
- %.dtb: | scripts
- 	$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
- 
-+%.dtbo: | scripts
-+	$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
-+
-+%.scr: | scripts
-+	$(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@
-+
- PHONY += dtbs dtbs_install
- 
- dtbs: prepare scripts
-diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
-index 3c79f859..eaaeb17e 100644
---- a/arch/arm/boot/.gitignore
-+++ b/arch/arm/boot/.gitignore
-@@ -3,4 +3,5 @@ zImage
- xipImage
- bootpImage
- uImage
--*.dtb
-+*.dtb*
-+*.scr
-diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
-index b9a4a934..54e3c38d 100644
---- a/arch/arm64/Makefile
-+++ b/arch/arm64/Makefile
-@@ -119,6 +119,12 @@ zinstall install:
- %.dtb: scripts
- 	$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
- 
-+%.dtbo: | scripts
-+	$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
-+
-+%.scr: | scripts
-+	$(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@
-+
- PHONY += dtbs dtbs_install
- 
- dtbs: prepare scripts
-diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore
-index b60ed208..5d65b54b 100644
---- a/arch/arm64/boot/dts/.gitignore
-+++ b/arch/arm64/boot/dts/.gitignore
-@@ -1 +1,2 @@
--*.dtb
-+*.dtb*
-+*.scr
-diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst
-index a1be75d0..ad8dc1c9 100644
---- a/scripts/Makefile.dtbinst
-+++ b/scripts/Makefile.dtbinst
-@@ -27,6 +27,9 @@ ifeq ("$(dtbinst-root)", "$(obj)")
- endif
- 
- dtbinst-files	:= $(dtb-y)
-+dtboinst-files	:= $(dtbo-y)
-+script-files	:= $(scr-y)
-+readme-files	:= $(dtbotxt-y)
- dtbinst-dirs	:= $(dts-dirs)
- 
- # Helper targets for Installing DTBs into the boot directory
-@@ -35,15 +38,24 @@ quiet_cmd_dtb_install =	INSTALL $<
- 
- install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj))
- 
--$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep
-+$(dtbinst-files) $(dtboinst-files) $(readme-files) $(script-files) $(dtbinst-dirs): | __dtbs_install_prep
- 
- $(dtbinst-files): %.dtb: $(obj)/%.dtb
- 	$(call cmd,dtb_install,$(install-dir))
- 
-+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo
-+	$(call cmd,dtb_install,$(install-dir))
-+
-+$(script-files): %.scr: $(obj)/%.scr
-+	$(call cmd,dtb_install,$(install-dir))
-+
-+$(readme-files): %: $(src)/%
-+	$(call cmd,dtb_install,$(install-dir))
-+
- $(dtbinst-dirs):
- 	$(Q)$(MAKE) $(dtbinst)=$(obj)/$@
- 
--PHONY += $(dtbinst-files) $(dtbinst-dirs)
--__dtbs_install: $(dtbinst-files) $(dtbinst-dirs)
-+PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
-+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
- 
- .PHONY: $(PHONY)
-diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
-index 0a07f901..5ccd3490 100644
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -312,6 +312,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
- $(obj)/%.dtb: $(src)/%.dts FORCE
- 	$(call if_changed_dep,dtc)
- 
-+quiet_cmd_dtco = DTCO    $@
-+cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \
-+	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
-+	$(DTC) -O dtb -o $@ -b 0 \
-+		-i $(dir $<) $(DTC_FLAGS) \
-+		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
-+	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
-+
-+$(obj)/%.dtbo: $(src)/%.dts FORCE
-+	$(call if_changed_dep,dtco)
-+
-+quiet_cmd_scr = MKIMAGE $@
-+cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@
-+
-+$(obj)/%.scr: $(src)/%.scr-cmd FORCE
-+	$(call if_changed,scr)
-+
- dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
- 
- # Bzip2
diff --git a/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch b/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch
deleted file mode 100644
index 87d97f508..000000000
--- a/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
-index d0fc165..4510c2d 100644
---- a/drivers/mtd/spi-nor/spi-nor.c
-+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -809,6 +809,13 @@ static const struct flash_info spi_nor_ids[] = {
- 
- 	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
- 
-+	/* BergMicro Flashes */
-+	{ "bg25q80", INFO(0xe04014, 0, 64 * 1024,  16, SECT_4K) },
-+	{ "bg25q16", INFO(0xe04015, 0, 64 * 1024,  32, SECT_4K) },
-+	{ "bg25q32", INFO(0xe04016, 0, 64 * 1024,  64, SECT_4K) },
-+	{ "bg25q64", INFO(0xe04017, 0, 64 * 1024, 128, SECT_4K) },
-+	{ "bg25q128", INFO(0xe04018, 0, 64 * 1024, 256, SECT_4K) },
-+
- 	/* EON -- en25xxx */
- 	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
- 	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
diff --git a/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch b/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch
deleted file mode 100644
index 006766a22..000000000
--- a/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch
+++ /dev/null
@@ -1,360 +0,0 @@
-diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
-index bc07ad3..e9da9cf 100644
---- a/drivers/of/Kconfig
-+++ b/drivers/of/Kconfig
-@@ -113,6 +113,13 @@ config OF_OVERLAY
- 	  While this option is selected automatically when needed, you can
- 	  enable it manually to improve device tree unit test coverage.
- 
-+config OF_CONFIGFS
-+        bool "Device Tree Overlay ConfigFS interface"
-+        select CONFIGFS_FS
-+        depends on OF_OVERLAY
-+        help
-+          Enable a simple user-space driven DT overlay interface.
-+
- config OF_NUMA
- 	bool
- 
-diff --git a/drivers/of/Makefile b/drivers/of/Makefile
-index d7efd9d..a06cc35 100644
---- a/drivers/of/Makefile
-+++ b/drivers/of/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
- obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
- obj-$(CONFIG_OF_RESOLVE)  += resolver.o
- obj-$(CONFIG_OF_OVERLAY) += overlay.o
-+obj-$(CONFIG_OF_CONFIGFS) += configfs.o
- obj-$(CONFIG_OF_NUMA) += of_numa.o
- 
- obj-$(CONFIG_OF_UNITTEST) += unittest-data/
-diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c
-new file mode 100644
-index 0000000..68f889d
---- /dev/null
-+++ b/drivers/of/configfs.c
-@@ -0,0 +1,311 @@
-+/*
-+ * Configfs entries for device-tree
-+ *
-+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
-+ *
-+ * This program 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.
-+ */
-+#include <linux/ctype.h>
-+#include <linux/cpu.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/of_fdt.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/configfs.h>
-+#include <linux/types.h>
-+#include <linux/stat.h>
-+#include <linux/limits.h>
-+#include <linux/file.h>
-+#include <linux/vmalloc.h>
-+#include <linux/firmware.h>
-+#include <linux/sizes.h>
-+
-+#include "of_private.h"
-+
-+struct cfs_overlay_item {
-+	struct config_item	item;
-+
-+	char			path[PATH_MAX];
-+
-+	const struct firmware	*fw;
-+	struct device_node	*overlay;
-+	int			ov_id;
-+
-+	void			*dtbo;
-+	int			dtbo_size;
-+};
-+
-+static int create_overlay(struct cfs_overlay_item *overlay, void *blob)
-+{
-+	int err;
-+
-+	/* unflatten the tree */
-+	of_fdt_unflatten_tree(blob, NULL, &overlay->overlay);
-+	if (overlay->overlay == NULL) {
-+		pr_err("%s: failed to unflatten tree\n", __func__);
-+		err = -EINVAL;
-+		goto out_err;
-+	}
-+	pr_debug("%s: unflattened OK\n", __func__);
-+
-+	/* mark it as detached */
-+	of_node_set_flag(overlay->overlay, OF_DETACHED);
-+
-+	/* perform resolution */
-+	err = of_resolve_phandles(overlay->overlay);
-+	if (err != 0) {
-+		pr_err("%s: Failed to resolve tree\n", __func__);
-+		goto out_err;
-+	}
-+	pr_debug("%s: resolved OK\n", __func__);
-+
-+	err = of_overlay_create(overlay->overlay);
-+	if (err < 0) {
-+		pr_err("%s: Failed to create overlay (err=%d)\n",
-+				__func__, err);
-+		goto out_err;
-+	}
-+	overlay->ov_id = err;
-+
-+out_err:
-+	return err;
-+}
-+
-+static inline struct cfs_overlay_item *to_cfs_overlay_item(
-+		struct config_item *item)
-+{
-+	return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
-+}
-+
-+static ssize_t cfs_overlay_item_path_show(struct config_item *item,
-+		char *page)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+	return sprintf(page, "%s\n", overlay->path);
-+}
-+
-+static ssize_t cfs_overlay_item_path_store(struct config_item *item,
-+		const char *page, size_t count)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+	const char *p = page;
-+	char *s;
-+	int err;
-+
-+	/* if it's set do not allow changes */
-+	if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
-+		return -EPERM;
-+
-+	/* copy to path buffer (and make sure it's always zero terminated */
-+	count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
-+	overlay->path[sizeof(overlay->path) - 1] = '\0';
-+
-+	/* strip trailing newlines */
-+	s = overlay->path + strlen(overlay->path);
-+	while (s > overlay->path && *--s == '\n')
-+		*s = '\0';
-+
-+	pr_debug("%s: path is '%s'\n", __func__, overlay->path);
-+
-+	err = request_firmware(&overlay->fw, overlay->path, NULL);
-+	if (err != 0)
-+		goto out_err;
-+
-+	err = create_overlay(overlay, (void *)overlay->fw->data);
-+	if (err != 0)
-+		goto out_err;
-+
-+	return count;
-+
-+out_err:
-+
-+	release_firmware(overlay->fw);
-+	overlay->fw = NULL;
-+
-+	overlay->path[0] = '\0';
-+	return err;
-+}
-+
-+static ssize_t cfs_overlay_item_status_show(struct config_item *item,
-+		char *page)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+
-+	return sprintf(page, "%s\n",
-+			overlay->ov_id >= 0 ? "applied" : "unapplied");
-+}
-+
-+CONFIGFS_ATTR(cfs_overlay_item_, path);
-+CONFIGFS_ATTR_RO(cfs_overlay_item_, status);
-+
-+static struct configfs_attribute *cfs_overlay_attrs[] = {
-+	&cfs_overlay_item_attr_path,
-+	&cfs_overlay_item_attr_status,
-+	NULL,
-+};
-+
-+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
-+		void *buf, size_t max_count)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+
-+	pr_debug("%s: buf=%p max_count=%zu\n", __func__,
-+			buf, max_count);
-+
-+	if (overlay->dtbo == NULL)
-+		return 0;
-+
-+	/* copy if buffer provided */
-+	if (buf != NULL) {
-+		/* the buffer must be large enough */
-+		if (overlay->dtbo_size > max_count)
-+			return -ENOSPC;
-+
-+		memcpy(buf, overlay->dtbo, overlay->dtbo_size);
-+	}
-+
-+	return overlay->dtbo_size;
-+}
-+
-+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
-+		const void *buf, size_t count)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+	int err;
-+
-+	/* if it's set do not allow changes */
-+	if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
-+		return -EPERM;
-+
-+	/* copy the contents */
-+	overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
-+	if (overlay->dtbo == NULL)
-+		return -ENOMEM;
-+
-+	overlay->dtbo_size = count;
-+
-+	err = create_overlay(overlay, overlay->dtbo);
-+	if (err != 0)
-+		goto out_err;
-+
-+	return count;
-+
-+out_err:
-+	kfree(overlay->dtbo);
-+	overlay->dtbo = NULL;
-+	overlay->dtbo_size = 0;
-+
-+	return err;
-+}
-+
-+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M);
-+
-+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = {
-+	&cfs_overlay_item_attr_dtbo,
-+	NULL,
-+};
-+
-+static void cfs_overlay_release(struct config_item *item)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+
-+	if (overlay->ov_id >= 0)
-+		of_overlay_destroy(overlay->ov_id);
-+	if (overlay->fw)
-+		release_firmware(overlay->fw);
-+	/* kfree with NULL is safe */
-+	kfree(overlay->dtbo);
-+	kfree(overlay);
-+}
-+
-+static struct configfs_item_operations cfs_overlay_item_ops = {
-+	.release	= cfs_overlay_release,
-+};
-+
-+static struct config_item_type cfs_overlay_type = {
-+	.ct_item_ops	= &cfs_overlay_item_ops,
-+	.ct_attrs	= cfs_overlay_attrs,
-+	.ct_bin_attrs	= cfs_overlay_bin_attrs,
-+	.ct_owner	= THIS_MODULE,
-+};
-+
-+static struct config_item *cfs_overlay_group_make_item(
-+		struct config_group *group, const char *name)
-+{
-+	struct cfs_overlay_item *overlay;
-+
-+	overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
-+	if (!overlay)
-+		return ERR_PTR(-ENOMEM);
-+	overlay->ov_id = -1;
-+
-+	config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
-+	return &overlay->item;
-+}
-+
-+static void cfs_overlay_group_drop_item(struct config_group *group,
-+		struct config_item *item)
-+{
-+	struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
-+
-+	config_item_put(&overlay->item);
-+}
-+
-+static struct configfs_group_operations overlays_ops = {
-+	.make_item	= cfs_overlay_group_make_item,
-+	.drop_item	= cfs_overlay_group_drop_item,
-+};
-+
-+static struct config_item_type overlays_type = {
-+	.ct_group_ops   = &overlays_ops,
-+	.ct_owner       = THIS_MODULE,
-+};
-+
-+static struct configfs_group_operations of_cfs_ops = {
-+	/* empty - we don't allow anything to be created */
-+};
-+
-+static struct config_item_type of_cfs_type = {
-+	.ct_group_ops   = &of_cfs_ops,
-+	.ct_owner       = THIS_MODULE,
-+};
-+
-+struct config_group of_cfs_overlay_group;
-+
-+static struct configfs_subsystem of_cfs_subsys = {
-+	.su_group = {
-+		.cg_item = {
-+			.ci_namebuf = "device-tree",
-+			.ci_type = &of_cfs_type,
-+		},
-+	},
-+	.su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
-+};
-+
-+static int __init of_cfs_init(void)
-+{
-+	int ret;
-+
-+	pr_info("%s\n", __func__);
-+
-+	config_group_init(&of_cfs_subsys.su_group);
-+	config_group_init_type_name(&of_cfs_overlay_group, "overlays",
-+			&overlays_type);
-+	configfs_add_default_group(&of_cfs_overlay_group,
-+			&of_cfs_subsys.su_group);
-+
-+	ret = configfs_register_subsystem(&of_cfs_subsys);
-+	if (ret != 0) {
-+		pr_err("%s: failed to register subsys\n", __func__);
-+		goto out;
-+	}
-+	pr_info("%s: OK\n", __func__);
-+out:
-+	return ret;
-+}
-+late_initcall(of_cfs_init);
-diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c
-index dca8f9b..ec7e167 100644
---- a/drivers/of/fdt_address.c
-+++ b/drivers/of/fdt_address.c
-@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent,
-  * that can be mapped to a cpu physical address). This is not really specified
-  * that way, but this is traditionally the way IBM at least do things
-  */
--static u64 __init fdt_translate_address(const void *blob, int node_offset)
-+u64 __init fdt_translate_address(const void *blob, int node_offset)
- {
- 	int parent, len;
- 	const struct of_bus *bus, *pbus;
diff --git a/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch b/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch
deleted file mode 100644
index 49338fb4b..000000000
--- a/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
-index b3d5b3e..9520280 100644
---- a/arch/arm64/kernel/cpuinfo.c
-+++ b/arch/arm64/kernel/cpuinfo.c
-@@ -118,6 +118,8 @@ static int c_show(struct seq_file *m, void *v)
- 		 * "processor".  Give glibc what it expects.
- 		 */
- 		seq_printf(m, "processor\t: %d\n", i);
-+                seq_printf(m, "Processor\t: AArch64 Processor rev %d (aarch64)\n", MIDR_REVISION(midr));
-+                seq_printf(m, "Hardware\t: sun50iw1p1\n");
- 		if (compat)
- 			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
- 				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch
deleted file mode 100644
index afbf6308b..000000000
--- a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch
+++ /dev/null
@@ -1,404 +0,0 @@
-diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
-index 8af8f4be8e3b..fbd3f8cd5c22 100644
---- a/drivers/clk/sunxi-ng/Kconfig
-+++ b/drivers/clk/sunxi-ng/Kconfig
-@@ -151,4 +151,10 @@  config SUN9I_A80_CCU
- 	default MACH_SUN9I
- 	depends on MACH_SUN9I || COMPILE_TEST
- 
-+config SUN8I_R_CCU
-+	bool "Support for Allwinner SoCs' PRCM CCUs"
-+	select SUNXI_CCU_DIV
-+	select SUNXI_CCU_GATE
-+	default MACH_SUN8I || (ARCH_SUNXI && ARM64)
-+
- endif
-diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
-index 6feaac0c5600..0ec02fe14c50 100644
---- a/drivers/clk/sunxi-ng/Makefile
-+++ b/drivers/clk/sunxi-ng/Makefile
-@@ -25,6 +25,7 @@  obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
- obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
- obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
- obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
-+obj-$(CONFIG_SUN8I_R_CCU)	+= ccu-sun8i-r.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-de.o
- obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-usb.o
-diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
-new file mode 100644
-index 000000000000..0d027d53dbdf
---- /dev/null
-+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c
-@@ -0,0 +1,213 @@ 
-+/*
-+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program 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.
-+ */
-+
-+#include <linux/clk-provider.h>
-+#include <linux/of_address.h>
-+#include <linux/platform_device.h>
-+
-+#include "ccu_common.h"
-+#include "ccu_reset.h"
-+
-+#include "ccu_div.h"
-+#include "ccu_gate.h"
-+#include "ccu_mp.h"
-+#include "ccu_nm.h"
-+
-+#include "ccu-sun8i-r.h"
-+
-+static const char * const ar100_parents[] = { "osc32K", "osc24M",
-+					     "pll-periph0", "iosc" };
-+
-+static struct ccu_div ar100_clk = {
-+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
-+
-+	.mux		= {
-+		.shift	= 16,
-+		.width	= 2,
-+
-+		.variable_prediv	= {
-+			.index	= 2,
-+			.shift	= 8,
-+			.width	= 5,
-+		},
-+	},
-+
-+	.common		= {
-+		.reg		= 0x00,
-+		.features	= CCU_FEATURE_VARIABLE_PREDIV,
-+		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
-+						      ar100_parents,
-+						      &ccu_div_ops,
-+						      0),
-+	},
-+};
-+
-+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
-+
-+static struct ccu_div apb0_clk = {
-+	.div		= _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
-+
-+	.common		= {
-+		.reg		= 0x0c,
-+		.hw.init	= CLK_HW_INIT("apb0",
-+					      "ahb0",
-+					      &ccu_div_ops,
-+					      0),
-+	},
-+};
-+
-+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
-+		      0x28, BIT(0), 0);
-+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
-+		      0x28, BIT(1), 0);
-+static SUNXI_CCU_GATE(apb0_timer_clk,	"apb0-timer",	"apb0",
-+		      0x28, BIT(2), 0);
-+static SUNXI_CCU_GATE(apb0_rsb_clk,	"apb0-rsb",	"apb0",
-+		      0x28, BIT(3), 0);
-+static SUNXI_CCU_GATE(apb0_uart_clk,	"apb0-uart",	"apb0",
-+		      0x28, BIT(4), 0);
-+static SUNXI_CCU_GATE(apb0_i2c_clk,	"apb0-i2c",	"apb0",
-+		      0x28, BIT(6), 0);
-+static SUNXI_CCU_GATE(apb0_twd_clk,	"apb0-twd",	"apb0",
-+		      0x28, BIT(7), 0);
-+
-+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" };
-+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
-+				  r_mod0_default_parents, 0x54,
-+				  0, 4,		/* M */
-+				  16, 2,	/* P */
-+				  24, 2,	/* mux */
-+				  BIT(31),	/* gate */
-+				  0);
-+
-+static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
-+	&ar100_clk.common,
-+	&apb0_clk.common,
-+	&apb0_pio_clk.common,
-+	&apb0_ir_clk.common,
-+	&apb0_timer_clk.common,
-+	&apb0_uart_clk.common,
-+	&apb0_i2c_clk.common,
-+	&apb0_twd_clk.common,
-+	&ir_clk.common,
-+};
-+
-+static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
-+	&ar100_clk.common,
-+	&apb0_clk.common,
-+	&apb0_pio_clk.common,
-+	&apb0_ir_clk.common,
-+	&apb0_timer_clk.common,
-+	&apb0_rsb_clk.common,
-+	&apb0_uart_clk.common,
-+	&apb0_i2c_clk.common,
-+	&apb0_twd_clk.common,
-+	&ir_clk.common,
-+};
-+
-+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
-+	.hws	= {
-+		[CLK_AR100]		= &ar100_clk.common.hw,
-+		[CLK_AHB0]		= &ahb0_clk.hw,
-+		[CLK_APB0]		= &apb0_clk.common.hw,
-+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
-+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
-+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
-+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
-+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
-+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
-+		[CLK_IR]		= &ir_clk.common.hw,
-+	},
-+	.num	= CLK_NUMBER,
-+};
-+
-+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
-+	.hws	= {
-+		[CLK_AR100]		= &ar100_clk.common.hw,
-+		[CLK_AHB0]		= &ahb0_clk.hw,
-+		[CLK_APB0]		= &apb0_clk.common.hw,
-+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
-+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
-+		[CLK_APB0_TIMER]	= &apb0_timer_clk.common.hw,
-+		[CLK_APB0_RSB]		= &apb0_rsb_clk.common.hw,
-+		[CLK_APB0_UART]		= &apb0_uart_clk.common.hw,
-+		[CLK_APB0_I2C]		= &apb0_i2c_clk.common.hw,
-+		[CLK_APB0_TWD]		= &apb0_twd_clk.common.hw,
-+		[CLK_IR]		= &ir_clk.common.hw,
-+	},
-+	.num	= CLK_NUMBER,
-+};
-+
-+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
-+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
-+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
-+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
-+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
-+};
-+
-+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
-+	[RST_APB0_IR]		=  { 0xb0, BIT(1) },
-+	[RST_APB0_TIMER]	=  { 0xb0, BIT(2) },
-+	[RST_APB0_RSB]		=  { 0xb0, BIT(3) },
-+	[RST_APB0_UART]		=  { 0xb0, BIT(4) },
-+	[RST_APB0_I2C]		=  { 0xb0, BIT(6) },
-+};
-+
-+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
-+	.ccu_clks	= sun8i_h3_r_ccu_clks,
-+	.num_ccu_clks	= ARRAY_SIZE(sun8i_h3_r_ccu_clks),
-+
-+	.hw_clks	= &sun8i_h3_r_hw_clks,
-+
-+	.resets		= sun8i_h3_r_ccu_resets,
-+	.num_resets	= ARRAY_SIZE(sun8i_h3_r_ccu_resets),
-+};
-+
-+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
-+	.ccu_clks	= sun50i_a64_r_ccu_clks,
-+	.num_ccu_clks	= ARRAY_SIZE(sun50i_a64_r_ccu_clks),
-+
-+	.hw_clks	= &sun50i_a64_r_hw_clks,
-+
-+	.resets		= sun50i_a64_r_ccu_resets,
-+	.num_resets	= ARRAY_SIZE(sun50i_a64_r_ccu_resets),
-+};
-+
-+static void __init sunxi_r_ccu_init(struct device_node *node,
-+				    const struct sunxi_ccu_desc *desc)
-+{
-+	void __iomem *reg;
-+
-+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-+	if (IS_ERR(reg)) {
-+		pr_err("%s: Could not map the clock registers\n",
-+		       of_node_full_name(node));
-+		return;
-+	}
-+
-+	sunxi_ccu_probe(node, reg, desc);
-+}
-+
-+static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
-+{
-+	sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
-+}
-+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
-+	       sun8i_h3_r_ccu_setup);
-+
-+static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
-+{
-+	sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
-+}
-+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
-+	       sun50i_a64_r_ccu_setup);
-diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
-new file mode 100644
-index 000000000000..eaa431fd1d8f
---- /dev/null
-+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h
-@@ -0,0 +1,27 @@ 
-+/*
-+ * Copyright 2016 Icenowy <icenowy@aosc.xyz>
-+ *
-+ * This program 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 program 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.
-+ */
-+
-+#ifndef _CCU_SUN8I_R_H
-+#define _CCU_SUN8I_R_H_
-+
-+#include <dt-bindings/clock/sun8i-r-ccu.h>
-+#include <dt-bindings/reset/sun8i-r-ccu.h>
-+
-+/* AHB/APB bus clocks are not exported */
-+#define CLK_AHB0	1
-+#define CLK_APB0	2
-+
-+#define CLK_NUMBER	(CLK_IR + 1)
-+
-+#endif /* _CCU_SUN8I_R_H */
-diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h
-new file mode 100644
-index 000000000000..779d20aa0d05
---- /dev/null
-+++ b/include/dt-bindings/clock/sun8i-r-ccu.h
-@@ -0,0 +1,59 @@ 
-+/*
-+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
-+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_
-+
-+#define CLK_AR100		0
-+
-+#define CLK_APB0_PIO		3
-+#define CLK_APB0_IR		4
-+#define CLK_APB0_TIMER		5
-+#define CLK_APB0_RSB		6
-+#define CLK_APB0_UART		7
-+/* 8 is reserved for CLK_APB0_W1 on A31 */
-+#define CLK_APB0_I2C		9
-+#define CLK_APB0_TWD		10
-+
-+#define CLK_IR			11
-+
-+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */
-diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h
-new file mode 100644
-index 000000000000..4ba64f3d6fc9
---- /dev/null
-+++ b/include/dt-bindings/reset/sun8i-r-ccu.h
-@@ -0,0 +1,53 @@ 
-+/*
-+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * 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.
-+ */
-+
-+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_
-+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_
-+
-+#define RST_APB0_IR		0
-+#define RST_APB0_TIMER		1
-+#define RST_APB0_RSB		2
-+#define RST_APB0_UART		3
-+/* 4 is reserved for RST_APB0_W1 on A31 */
-+#define RST_APB0_I2C		5
-+
-+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */
-
diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch
deleted file mode 100644
index 428807bd8..000000000
--- a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
-index 81f0d61..18ff031 100644
---- a/arch/arm64/Kconfig.platforms
-+++ b/arch/arm64/Kconfig.platforms
-@@ -5,6 +5,7 @@ config ARCH_SUNXI
- 	select GENERIC_IRQ_CHIP
- 	select PINCTRL
- 	select PINCTRL_SUN50I_A64
-+	select PINCTRL_SUN50I_A64_R
- 	select PINCTRL_SUN50I_H5
- 	select PINCTRL_SUN8I_H3_R
- 	help
-diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
-index a84bfa7f3c05..a0c419ac2a3b 100644
---- a/drivers/pinctrl/sunxi/Kconfig
-+++ b/drivers/pinctrl/sunxi/Kconfig
-@@ -68,6 +68,10 @@  config PINCTRL_SUN50I_A64
- 	def_bool ARM64 && ARCH_SUNXI
- 	select PINCTRL_SUNXI
- 
-+config PINCTRL_SUN50I_A64_R
-+	def_bool ARM64 && ARCH_SUNXI
-+	select PINCTRL_SUNXI
-+
- config PINCTRL_SUN50I_H5
- 	def_bool ARM64 && ARCH_SUNXI
- 	select PINCTRL_SUNXI
-diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
-index 04ccb88ebd5f..df4ccd6cd44c 100644
---- a/drivers/pinctrl/sunxi/Makefile
-+++ b/drivers/pinctrl/sunxi/Makefile
-@@ -11,6 +11,7 @@  obj-$(CONFIG_PINCTRL_SUN8I_A23)		+= pinctrl-sun8i-a23.o
- obj-$(CONFIG_PINCTRL_SUN8I_A23_R)	+= pinctrl-sun8i-a23-r.o
- obj-$(CONFIG_PINCTRL_SUN8I_A33)		+= pinctrl-sun8i-a33.o
- obj-$(CONFIG_PINCTRL_SUN50I_A64)	+= pinctrl-sun50i-a64.o
-+obj-$(CONFIG_PINCTRL_SUN50I_A64_R)	+= pinctrl-sun50i-a64-r.o
- obj-$(CONFIG_PINCTRL_SUN8I_A83T)	+= pinctrl-sun8i-a83t.o
- obj-$(CONFIG_PINCTRL_SUN8I_H3)		+= pinctrl-sun8i-h3.o
- obj-$(CONFIG_PINCTRL_SUN8I_H3_R)	+= pinctrl-sun8i-h3-r.o
-diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c
-new file mode 100644
-index 000000000000..415870e82cbf
---- /dev/null
-+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c
-@@ -0,0 +1,125 @@ 
-+/*
-+ * Allwinner A64 SoCs special pins pinctrl driver.
-+ *
-+ * Based on pinctrl-sun8i-a23-r.c
-+ *
-+ * Copyright (C) 2016 Icenowy Zheng
-+ * Icenowy Zheng <icenowy@aosc.xyz>
-+ *
-+ * Copyright (C) 2014 Chen-Yu Tsai
-+ * Chen-Yu Tsai <wens@csie.org>
-+ *
-+ * Copyright (C) 2014 Boris Brezillon
-+ * Boris Brezillon <boris.brezillon@free-electrons.com>
-+ *
-+ * Copyright (C) 2014 Maxime Ripard
-+ * Maxime Ripard <maxime.ripard@free-electrons.com>
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2.  This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#include <linux/of.h>
-+#include <linux/of_device.h>
-+#include <linux/pinctrl/pinctrl.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+#include "pinctrl-sunxi.h"
-+
-+static const struct sunxi_desc_pin sun50i_a64_r_pins[] = {
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_rsb"),		/* SCK */
-+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SCK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PL_EINT0 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_rsb"),		/* SDA */
-+		  SUNXI_FUNCTION(0x3, "s_i2c"),		/* SDA */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PL_EINT1 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* TX */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PL_EINT2 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_uart"),	/* RX */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PL_EINT3 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* MS */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PL_EINT4 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* CK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PL_EINT5 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* DO */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PL_EINT6 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_jtag"),	/* DI */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PL_EINT7 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SCK */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PL_EINT8 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_i2c"),		/* SDA */
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PL_EINT9 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_pwm"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)),	/* PL_EINT10 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION(0x2, "s_cir_rx"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)),	/* PL_EINT11 */
-+	SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12),
-+		  SUNXI_FUNCTION(0x0, "gpio_in"),
-+		  SUNXI_FUNCTION(0x1, "gpio_out"),
-+		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)),	/* PL_EINT12 */
-+};
-+
-+static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = {
-+	.pins = sun50i_a64_r_pins,
-+	.npins = ARRAY_SIZE(sun50i_a64_r_pins),
-+	.pin_base = PL_BASE,
-+	.irq_banks = 1,
-+};
-+
-+static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev)
-+{
-+	return sunxi_pinctrl_init(pdev,
-+				  &sun50i_a64_r_pinctrl_data);
-+}
-+
-+static const struct of_device_id sun50i_a64_r_pinctrl_match[] = {
-+	{ .compatible = "allwinner,sun50i-a64-r-pinctrl", },
-+	{}
-+};
-+
-+static struct platform_driver sun50i_a64_r_pinctrl_driver = {
-+	.probe	= sun50i_a64_r_pinctrl_probe,
-+	.driver	= {
-+		.name		= "sun50i-a64-r-pinctrl",
-+		.of_match_table	= sun50i_a64_r_pinctrl_match,
-+	},
-+};
-+builtin_platform_driver(sun50i_a64_r_pinctrl_driver);
-diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-index 02c0385..c0773d8 100644
---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
-@@ -43,8 +43,10 @@
-  */
- 
- #include <dt-bindings/clock/sun50i-a64-ccu.h>
-+#include <dt-bindings/clock/sun8i-r-ccu.h>
- #include <dt-bindings/interrupt-controller/arm-gic.h>
- #include <dt-bindings/reset/sun50i-a64-ccu.h>
-+#include <dt-bindings/reset/sun8i-r-ccu.h>
- 
- / {
- 	interrupt-parent = <&gic>;
-@@ -98,6 +100,13 @@
- 		clock-output-names = "osc32k";
- 	};
- 
-+	osc32000: osc32000_clk {
-+		#clock-cells = <0>;
-+		compatible = "fixed-clock";
-+		clock-frequency = <32000>;
-+		clock-output-names = "osc32000";
-+	};
-+
- 	psci {
- 		compatible = "arm,psci-0.2";
- 		method = "smc";
-@@ -306,6 +315,27 @@
- 			};
- 		};
- 
-+		r_ccu: clock@1f01400 {
-+			compatible = "allwinner,sun50i-a64-r-ccu";
-+			reg = <0x01f01400 0x100>;
-+			clocks = <&osc24M>, <&osc32k>, <&osc32000>;
-+			clock-names = "hosc", "losc", "iosc";
-+			#clock-cells = <1>;
-+			#reset-cells = <1>;
-+		};
-+
-+		r_pio: pinctrl@1f02c00 {
-+			compatible = "allwinner,sun50i-a64-r-pinctrl";
-+			reg = <0x01f02c00 0x400>;
-+			interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
-+			clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
-+			clock-names = "apb", "hosc", "losc";
-+			gpio-controller;
-+			#gpio-cells = <3>;
-+			interrupt-controller;
-+			#interrupt-cells = <3>;
-+		};
-+
- 		uart0: serial@1c28000 {
- 			compatible = "snps,dw-apb-uart";
- 			reg = <0x01c28000 0x400>;
diff --git a/patch/kernel/sun50iw2-dev/remove-localversion.patch b/patch/kernel/sun50iw2-dev/remove-localversion.patch
deleted file mode 100644
index 8083ac142..000000000
--- a/patch/kernel/sun50iw2-dev/remove-localversion.patch
+++ /dev/null
@@ -1,7 +0,0 @@
-diff --git a/localversion-next b/localversion-next
-deleted file mode 100644
-index 299f8119..00000000
---- a/localversion-next
-+++ /dev/null
-@@ -1 +0,0 @@
---next-20170216
diff --git a/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch b/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch
deleted file mode 100644
index bc3f71600..000000000
--- a/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
-index ddf83d0..a0fb9e3 100644
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -275,7 +275,11 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
-
- # DTC
- # ---------------------------------------------------------------------------
-+ifeq ($(CONFIG_OF_CONFIGFS),y)
-+DTC ?= $(objtree)/scripts/dtc/dtc -@
-+else
- DTC ?= $(objtree)/scripts/dtc/dtc
-+endif
-
- # Generate an assembly file to wrap the output of the device tree compiler
- quiet_cmd_dt_S_dtb= DTB     $@
diff --git a/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch b/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch
deleted file mode 100644
index 4dbf46ad8..000000000
--- a/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch
+++ /dev/null
@@ -1,190 +0,0 @@
-diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
-index e3114832..03a773a9 100644
---- a/drivers/spi/spi-sun6i.c
-+++ b/drivers/spi/spi-sun6i.c
-@@ -46,13 +46,19 @@
- #define SUN6I_TFR_CTL_XCH			BIT(31)
- 
- #define SUN6I_INT_CTL_REG		0x10
-+#define SUN6I_INT_CTL_RF_RDY			BIT(0)
-+#define SUN6I_INT_CTL_TF_ERQ			BIT(4)
- #define SUN6I_INT_CTL_RF_OVF			BIT(8)
- #define SUN6I_INT_CTL_TC			BIT(12)
- 
- #define SUN6I_INT_STA_REG		0x14
- 
- #define SUN6I_FIFO_CTL_REG		0x18
-+#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_MASK	0xff
-+#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS	0
- #define SUN6I_FIFO_CTL_RF_RST			BIT(15)
-+#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_MASK	0xff
-+#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS	16
- #define SUN6I_FIFO_CTL_TF_RST			BIT(31)
- 
- #define SUN6I_FIFO_STA_REG		0x1c
-@@ -68,14 +74,16 @@
- #define SUN6I_CLK_CTL_CDR1(div)			(((div) & SUN6I_CLK_CTL_CDR1_MASK) << 8)
- #define SUN6I_CLK_CTL_DRS			BIT(12)
- 
-+#define SUN6I_MAX_XFER_SIZE		0xffffff
-+
- #define SUN6I_BURST_CNT_REG		0x30
--#define SUN6I_BURST_CNT(cnt)			((cnt) & 0xffffff)
-+#define SUN6I_BURST_CNT(cnt)			((cnt) & SUN6I_MAX_XFER_SIZE)
- 
- #define SUN6I_XMIT_CNT_REG		0x34
--#define SUN6I_XMIT_CNT(cnt)			((cnt) & 0xffffff)
-+#define SUN6I_XMIT_CNT(cnt)			((cnt) & SUN6I_MAX_XFER_SIZE)
- 
- #define SUN6I_BURST_CTL_CNT_REG		0x38
--#define SUN6I_BURST_CTL_CNT_STC(cnt)		((cnt) & 0xffffff)
-+#define SUN6I_BURST_CTL_CNT_STC(cnt)		((cnt) & SUN6I_MAX_XFER_SIZE)
- 
- #define SUN6I_TXDATA_REG		0x200
- #define SUN6I_RXDATA_REG		0x300
-@@ -105,6 +113,31 @@ static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value)
- 	writel(value, sspi->base_addr + reg);
- }
- 
-+static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi)
-+{
-+	u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG);
-+
-+	reg >>= SUN6I_FIFO_STA_TF_CNT_BITS;
-+
-+	return reg & SUN6I_FIFO_STA_TF_CNT_MASK;
-+}
-+
-+static inline void sun6i_spi_enable_interrupt(struct sun6i_spi *sspi, u32 mask)
-+{
-+	u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG);
-+
-+	reg |= mask;
-+	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg);
-+}
-+
-+static inline void sun6i_spi_disable_interrupt(struct sun6i_spi *sspi, u32 mask)
-+{
-+	u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG);
-+
-+	reg &= ~mask;
-+	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg);
-+}
-+
- static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len)
- {
- 	u32 reg, cnt;
-@@ -127,10 +160,13 @@ static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len)
- 
- static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi, int len)
- {
-+	u32 cnt;
- 	u8 byte;
- 
--	if (len > sspi->len)
--		len = sspi->len;
-+	/* See how much data we can fit */
-+	cnt = sspi->fifo_depth - sun6i_spi_get_tx_fifo_count(sspi);
-+
-+	len = min3(len, (int)cnt, sspi->len);
- 
- 	while (len--) {
- 		byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
-@@ -158,9 +194,7 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
- 
- static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
- {
--	struct sun6i_spi *sspi = spi_master_get_devdata(spi->master);
--
--	return sspi->fifo_depth - 1;
-+	return SUN6I_MAX_XFER_SIZE - 1;
- }
- 
- static int sun6i_spi_transfer_one(struct spi_master *master,
-@@ -170,12 +204,12 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
- 	struct sun6i_spi *sspi = spi_master_get_devdata(master);
- 	unsigned int mclk_rate, div, timeout;
- 	unsigned int start, end, tx_time;
-+	unsigned int trig_level;
- 	unsigned int tx_len = 0;
- 	int ret = 0;
- 	u32 reg;
- 
--	/* We don't support transfer larger than the FIFO */
--	if (tfr->len > sspi->fifo_depth)
-+	if (tfr->len > SUN6I_MAX_XFER_SIZE)
- 		return -EINVAL;
- 
- 	reinit_completion(&sspi->done);
-@@ -191,6 +225,17 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
- 			SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST);
- 
- 	/*
-+	 * Setup FIFO interrupt trigger level
-+	 * Here we choose 3/4 of the full fifo depth, as it's the hardcoded
-+	 * value used in old generation of Allwinner SPI controller.
-+	 * (See spi-sun4i.c)
-+	 */
-+	trig_level = sspi->fifo_depth / 4 * 3;
-+	sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG,
-+			(trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS) |
-+			(trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS));
-+
-+	/*
- 	 * Setup the transfer control register: Chip Select,
- 	 * polarities, etc.
- 	 */
-@@ -274,6 +319,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
- 
- 	/* Enable the interrupts */
- 	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
-+	sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TC |
-+					 SUN6I_INT_CTL_RF_RDY);
-+	if (tx_len > sspi->fifo_depth)
-+		sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ);
- 
- 	/* Start the transfer */
- 	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
-@@ -293,8 +342,6 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
- 		goto out;
- 	}
- 
--	sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
--
- out:
- 	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
- 
-@@ -309,10 +356,33 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id)
- 	/* Transfer complete */
- 	if (status & SUN6I_INT_CTL_TC) {
- 		sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC);
-+		sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
- 		complete(&sspi->done);
- 		return IRQ_HANDLED;
- 	}
- 
-+	/* Receive FIFO 3/4 full */
-+	if (status & SUN6I_INT_CTL_RF_RDY) {
-+		sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH);
-+		/* Only clear the interrupt _after_ draining the FIFO */
-+		sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_RF_RDY);
-+		return IRQ_HANDLED;
-+	}
-+
-+	/* Transmit FIFO 3/4 empty */
-+	if (status & SUN6I_INT_CTL_TF_ERQ) {
-+		sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH);
-+
-+		if (!sspi->len)
-+			/* nothing left to transmit */
-+			sun6i_spi_disable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ);
-+
-+		/* Only clear the interrupt _after_ re-seeding the FIFO */
-+		sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TF_ERQ);
-+
-+		return IRQ_HANDLED;
-+	}
-+
- 	return IRQ_NONE;
- }
- 
diff --git a/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch b/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch
deleted file mode 100644
index 25648e844..000000000
--- a/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
-index 9e2e099b..a065943d 100644
---- a/drivers/spi/spidev.c
-+++ b/drivers/spi/spidev.c
-@@ -749,13 +749,11 @@ static int spidev_probe(struct spi_device *spi)
- 
- 	/*
- 	 * spidev should never be referenced in DT without a specific
--	 * compatible string, it is a Linux implementation thing
--	 * rather than a description of the hardware.
-+	 * compatible string, but people don't care and use DT overlays
-+	 * to activate SPIdev on demand
- 	 */
- 	if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) {
--		dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n");
--		WARN_ON(spi->dev.of_node &&
--			!of_match_device(spidev_dt_ids, &spi->dev));
-+		dev_info(&spi->dev, "probing from DT");
- 	}
- 
- 	spidev_probe_acpi(spi);