ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/target/linux/ramips/Makefile b/target/linux/ramips/Makefile
new file mode 100644
index 0000000..2cfb3c5
--- /dev/null
+++ b/target/linux/ramips/Makefile
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2008-2011 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=mipsel
+BOARD:=ramips
+BOARDNAME:=MediaTek Ralink MIPS
+SUBTARGETS:=mt7620 mt7621 mt76x8 rt288x rt305x rt3883
+FEATURES:=squashfs gpio
+
+KERNEL_PATCHVER:=5.4
+KERNEL_TESTING_PATCHVER:=5.4
+
+define Target/Description
+	Build firmware images for Ralink RT288x/RT3xxx based boards.
+endef
+
+include $(INCLUDE_DIR)/target.mk
+DEFAULT_PACKAGES += kmod-leds-gpio kmod-gpio-button-hotplug
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/ramips/base-files/etc/hotplug.d/usb/10-motion b/target/linux/ramips/base-files/etc/hotplug.d/usb/10-motion
new file mode 100644
index 0000000..e96acc8
--- /dev/null
+++ b/target/linux/ramips/base-files/etc/hotplug.d/usb/10-motion
@@ -0,0 +1 @@
+[ "$ACTION" = "motion" ] && logger webcam motion event
diff --git a/target/linux/ramips/base-files/etc/inittab b/target/linux/ramips/base-files/etc/inittab
new file mode 100644
index 0000000..9820e71
--- /dev/null
+++ b/target/linux/ramips/base-files/etc/inittab
@@ -0,0 +1,3 @@
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K shutdown
+::askconsole:/usr/libexec/login.sh
diff --git a/target/linux/ramips/base-files/etc/uci-defaults/04_led_migration b/target/linux/ramips/base-files/etc/uci-defaults/04_led_migration
new file mode 100644
index 0000000..161b79d
--- /dev/null
+++ b/target/linux/ramips/base-files/etc/uci-defaults/04_led_migration
@@ -0,0 +1,8 @@
+. /lib/functions.sh
+. /lib/functions/migrations.sh
+
+remove_devicename_leds "rt2800soc-phy0" "rt2800pci-phy0"
+
+migrations_apply system
+
+exit 0
diff --git a/target/linux/ramips/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/ramips/base-files/etc/uci-defaults/09_fix-checksum
new file mode 100644
index 0000000..f2408f8
--- /dev/null
+++ b/target/linux/ramips/base-files/etc/uci-defaults/09_fix-checksum
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+fix_checksum() {
+	local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd)
+
+	[ "$kernel_size" ] && mtd -c 0x$kernel_size fix$1 firmware
+}
+
+board=$(board_name)
+
+case "$board" in
+dlink,dap-1522-a1)
+	fix_checksum wrg
+	;;
+dlink,dch-m225|\
+dlink,dir-645|\
+dlink,dir-860l-b1|\
+samsung,cy-swr1100)
+	fix_checksum seama
+	;;
+esac
diff --git a/target/linux/ramips/dts/mt7620a.dtsi b/target/linux/ramips/dts/mt7620a.dtsi
new file mode 100644
index 0000000..ebcb659
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a.dtsi
@@ -0,0 +1,605 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,mt7620a-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		spi1 = &spi1;
+		serial0 = &uartlite;
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,mt7620a-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,mt7620a-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		uart: uart@500 {
+			compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0x500 0x100>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uart";
+
+			interrupt-parent = <&intc>;
+			interrupts = <5>;
+
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <32>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio3: gpio@688 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x688 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <72>;
+			ralink,num-gpios = <1>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c: i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s: i2s@a00 {
+			compatible = "mediatek,mt7620-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x40>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+		};
+
+		spi1: spi@b40 {
+			compatible = "ralink,rt2880-spi";
+			reg = <0xb40 0x60>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_cs1>;
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			reg-shift = <2>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+		};
+
+		systick: systick@d00 {
+			compatible = "ralink,mt7620a-systick", "ralink,cevt-systick";
+			reg = <0xd00 0x10>;
+
+			resets = <&rstctrl 28>;
+			reset-names = "intc";
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <7>;
+		};
+
+		pcm: pcm@2000 {
+			compatible = "ralink,mt7620a-pcm";
+			reg = <0x2000 0x800>;
+
+			resets = <&rstctrl 11>;
+			reset-names = "pcm";
+
+			interrupt-parent = <&intc>;
+			interrupts = <4>;
+
+			status = "disabled";
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,mt7620a-gdma", "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		pcm_i2s_pins: pcm_i2s {
+			pcm_i2s {
+				groups = "uartf";
+				function = "pcm i2s";
+			};
+		};
+
+		uartf_gpio_pins: uartf_gpio {
+			uartf_gpio {
+				groups = "uartf";
+				function = "gpio uartf";
+			};
+		};
+
+		gpio_i2s_pins: gpio_i2s {
+			gpio_i2s {
+				groups = "uartf";
+				function = "gpio i2s";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		spi_cs1: spi1 {
+			spi1 {
+				groups = "spi refclk";
+				function = "spi refclk";
+			};
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+
+		mdio_pins: mdio {
+			mdio {
+				groups = "mdio";
+				function = "mdio";
+			};
+		};
+
+		mdio_refclk_pins: mdio_refclk {
+			mdio_refclk {
+				groups = "mdio";
+				function = "refclk";
+			};
+		};
+
+		ephy_pins: ephy {
+			ephy {
+				groups = "ephy";
+				function = "ephy";
+			};
+		};
+
+		wled_pins: wled {
+			wled {
+				groups = "wled";
+				function = "wled";
+			};
+		};
+
+		rgmii1_pins: rgmii1 {
+			rgmii1 {
+				groups = "rgmii1";
+				function = "rgmii1";
+			};
+		};
+
+		rgmii2_pins: rgmii2 {
+			rgmii2 {
+				groups = "rgmii2";
+				function = "rgmii2";
+			};
+		};
+
+		pcie_pins: pcie {
+			pcie {
+				groups = "pcie";
+				function = "pcie rst";
+			};
+		};
+
+		pa_pins: pa {
+			pa {
+				groups = "pa";
+				function = "pa";
+			};
+		};
+
+		sdhci_pins: sdhci {
+			sdhci {
+				groups = "nd_sd";
+				function = "sd";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,mt7620a-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	usbphy: usbphy {
+		compatible = "mediatek,mt7620-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+
+		clocks = <&clkctrl 22 &clkctrl 25>;
+		clock-names = "host", "device";
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "mediatek,mt7620-eth";
+		reg = <0x10100000 0x10000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		resets = <&rstctrl 21 &rstctrl 23>;
+		reset-names = "fe", "esw";
+
+		mediatek,switch = <&gsw>;
+
+		port@4 {
+			compatible = "mediatek,mt7620a-gsw-port", "mediatek,eth-port";
+			reg = <4>;
+
+			status = "disabled";
+		};
+
+		port@5 {
+			compatible = "mediatek,mt7620a-gsw-port", "mediatek,eth-port";
+			reg = <5>;
+
+			status = "disabled";
+		};
+
+		mdio-bus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+	};
+
+	gsw: gsw@10110000 {
+		compatible = "mediatek,mt7620-gsw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	sdhci: sdhci@10130000 {
+		compatible = "ralink,mt7620-sdhci";
+		reg = <0x10130000 0x4000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <14>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdhci_pins>;
+
+		status = "disabled";
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		status = "disabled";
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		status = "disabled";
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	pcie: pcie@10140000 {
+		compatible = "mediatek,mt7620-pci";
+		reg = <0x10140000 0x100
+			0x10142000 0x100>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		resets = <&rstctrl 26>;
+		reset-names = "pcie0";
+
+		clocks = <&clkctrl 26>;
+		clock-names = "pcie0";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <4>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie_pins>;
+
+		device_type = "pci";
+
+		bus-range = <0 255>;
+		ranges = <
+			0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
+			0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
+		>;
+
+		status = "disabled";
+
+		pcie0: pcie@0,0 {
+			reg = <0x0000 0 0 0 0>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			device_type = "pci";
+
+			ranges;
+		};
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt7620-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_aigale_ai-br100.dts b/target/linux/ramips/dts/mt7620a_aigale_ai-br100.dts
new file mode 100644
index 0000000..ba251c2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_aigale_ai-br100.dts
@@ -0,0 +1,113 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "aigale,ai-br100", "ralink,mt7620a-soc";
+	model = "Aigale Ai-BR100";
+
+	aliases {
+		led-boot = &led_wlan;
+		led-failsafe = &led_wlan;
+		led-running = &led_wlan;
+		led-upgrade = &led_wlan;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wlan: wlan {
+			label = "blue:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "u-boot-env";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0x7c0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "ephy", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_alfa-network_ac1200rm.dts b/target/linux/ramips/dts/mt7620a_alfa-network_ac1200rm.dts
new file mode 100644
index 0000000..752a940
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_alfa-network_ac1200rm.dts
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright (C) 2018 Piotr Dymacz <pepe2k@gmail.com>
+ *  All rights reserved.
+ */
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,ac1200rm", "ralink,mt7620a-soc";
+	model = "ALFA Network AC1200RM";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "nd_sd", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_alfa-network_r36m-e4g.dts b/target/linux/ramips/dts/mt7620a_alfa-network_r36m-e4g.dts
new file mode 100644
index 0000000..0991ae8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_alfa-network_r36m-e4g.dts
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,r36m-e4g", "ralink,mt7620a-soc";
+	model = "ALFA Network R36M-E4G";
+
+	aliases {
+		label-mac-device = &wmac;
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS1,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		modem-enable {
+			gpio-export,name = "modem-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		modem-rf-enable {
+			gpio-export,name = "modem-rf-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		rtc-enable {
+			gpio-export,name = "rtc-enable";
+			gpio-export,output = <1>;
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim-select {
+			gpio-export,name = "sim-select";
+			gpio-export,output = <0>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim1-detect {
+			gpio-export,name = "sim1-detect";
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim2-detect {
+			gpio-export,name = "sim2-detect";
+			gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		4g {
+			label = "orange:4g";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		sim1 {
+			label = "green:sim1";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		sim2 {
+			label = "green:sim2";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "orange:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "ephy", "pcie", "rgmii1", "wled";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&uart {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_alfa-network_tube-e4g.dts b/target/linux/ramips/dts/mt7620a_alfa-network_tube-e4g.dts
new file mode 100644
index 0000000..ca58d78
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_alfa-network_tube-e4g.dts
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,tube-e4g", "ralink,mt7620a-soc";
+	model = "ALFA Network Tube-E4G";
+
+	aliases {
+		label-mac-device = &ethernet;
+		led-boot = &power;
+		led-failsafe = &power;
+		led-running = &power;
+		led-upgrade = &power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		modem-enable {
+			gpio-export,name = "modem-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		modem-rf-enable {
+			gpio-export,name = "modem-rf-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim-select {
+			gpio-export,name = "sim-select";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim1-detect {
+			gpio-export,name = "sim1-detect";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim2-detect {
+			gpio-export,name = "sim2-detect";
+			gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		4g {
+			label = "green:4g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		power: power {
+			label = "green:power";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		sim1 {
+			label = "green:sim1";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		sim2 {
+			label = "green:sim2";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "ephy", "nd_sd", "pcie", "uartf";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7620a_asus_rp-n53.dts b/target/linux/ramips/dts/mt7620a_asus_rp-n53.dts
new file mode 100644
index 0000000..4c72c64
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_asus_rp-n53.dts
@@ -0,0 +1,172 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rp-n53", "ralink,mt7620a-soc";
+	model = "Asus RP-N53";
+
+	keys {
+		compatible = "gpio-keys";
+
+		touch {
+			label = "touch";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		audio {
+			label = "audio";
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_1>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		backlight {
+			label = "white:back";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi0 {
+			label = "blue:5g3";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi1 {
+			label = "blue:5g2";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "blue:5g1";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi3 {
+			label = "blue:wifi";
+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi4 {
+			label = "blue:2g1";
+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5 {
+			label = "blue:2g2";
+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi6 {
+			label = "blue:2g3";
+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&i2s {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_i2s_pins>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcm {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "mdio", "rgmii1";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci1814,5592";
+		reg = <0x0000 0 0 0 0>;
+		ralink,2ghz = <0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_asus_rt-ac51u.dts b/target/linux/ramips/dts/mt7620a_asus_rt-ac51u.dts
new file mode 100644
index 0000000..0710b25
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_asus_rt-ac51u.dts
@@ -0,0 +1,13 @@
+#include "mt7620a_asus_rt-ac5x.dtsi"
+
+/ {
+	compatible = "asus,rt-ac51u", "ralink,mt7620a-soc";
+	model = "Asus RT-AC51U";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_asus_rt-ac54u.dts b/target/linux/ramips/dts/mt7620a_asus_rt-ac54u.dts
new file mode 100644
index 0000000..acc6080
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_asus_rt-ac54u.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_asus_rt-ac5x.dtsi"
+
+/ {
+	compatible = "asus,rt-ac54u", "ralink,mt7620a-soc";
+	model = "Asus RT-AC54U";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_asus_rt-ac5x.dtsi b/target/linux/ramips/dts/mt7620a_asus_rt-ac5x.dtsi
new file mode 100644
index 0000000..423b4ed
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_asus_rt-ac5x.dtsi
@@ -0,0 +1,136 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi2g {
+			label = "blue:wifi2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&gpio0 {
+	enable-leds {
+		gpio-hog;
+		line-name = "enable-leds";
+		output-low;
+		gpios = <10 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wled", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_bdcom_wap2100-sk.dts b/target/linux/ramips/dts/mt7620a_bdcom_wap2100-sk.dts
new file mode 100644
index 0000000..fc2b74d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_bdcom_wap2100-sk.dts
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "bdcom,wap2100-sk", "ralink,mt7620a-soc";
+	model = "BDCOM WAP2100-SK";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf70000>;
+			};
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	default {
+		groups = "spi refclk", "uartf", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_buffalo_whr-1166d.dts b/target/linux/ramips/dts/mt7620a_buffalo_whr-1166d.dts
new file mode 100644
index 0000000..93a09f9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_buffalo_whr-1166d.dts
@@ -0,0 +1,175 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,whr-1166d", "ralink,mt7620a-soc";
+	model = "Buffalo WHR-1166D";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "red:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power2 {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "orange:wifi";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
+		};
+
+		router {
+			label = "orange:router";
+			gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+		};
+
+		router2 {
+			label = "green:router";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		bridge {
+			label = "bridge";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii-rxid";
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci0,0";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_buffalo_whr-300hp2.dts b/target/linux/ramips/dts/mt7620a_buffalo_whr-300hp2.dts
new file mode 100644
index 0000000..95152bc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_buffalo_whr-300hp2.dts
@@ -0,0 +1,151 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,whr-300hp2", "ralink,mt7620a-soc";
+	model = "Buffalo WHR-300HP2";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "red:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power2 {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "orange:wifi";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
+		};
+
+		router {
+			label = "green:router";
+			gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+		};
+
+		router2 {
+			label = "orange:router";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		bridge {
+			label = "bridge";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_buffalo_whr-600d.dts b/target/linux/ramips/dts/mt7620a_buffalo_whr-600d.dts
new file mode 100644
index 0000000..2269677
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_buffalo_whr-600d.dts
@@ -0,0 +1,161 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,whr-600d", "ralink,mt7620a-soc";
+	model = "Buffalo WHR-600D";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "red:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power2 {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "orange:wifi";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
+		};
+
+		router {
+			label = "green:router";
+			gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+		};
+
+		router2 {
+			label = "orange:router";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		bridge {
+			label = "bridge";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci1814,5592";
+		reg = <0x0000 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_cameo_810.dtsi b/target/linux/ramips/dts/mt7620a_cameo_810.dtsi
new file mode 100644
index 0000000..7040744
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_cameo_810.dtsi
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		power_orange {
+			label = "orange:power";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			factory5g: partition@50000 {
+				label = "factory5g";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "Wolf_Config";
+				reg = <0x60000 0x10000>;
+				read-only;
+			};
+
+			partition@70000 {
+				label = "MyDlink";
+				reg = <0x70000 0x80000>;
+				read-only;
+			};
+
+			partition@f0000 {
+				label = "Jffs2";
+				reg = <0xf0000 0x80000>;
+				read-only;
+			};
+
+			partition@170000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x170000 0x690000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "ephy";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+
+	ralink,mtd-eeprom = <&factory 0x0>;
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&factory 0x28>;
+		mtd-mac-address-increment = <2>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts b/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts
new file mode 100644
index 0000000..0c9f568
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dch-m225.dts
@@ -0,0 +1,178 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dch-m225", "ralink,mt7620a-soc";
+	model = "D-Link DCH-M225";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		status {
+			label = "red:status";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "Audio-I2S";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+		simple-audio-card,widgets =
+			"Headphone", "Headphones";
+		simple-audio-card,routing =
+			"Headphones", "HP_L",
+			"Headphones", "HP_R";
+		simple-audio-card,mclk-fs = <256>;
+		simple-audio-card,hp-det-gpio = <&gpio0 14 GPIO_ACTIVE_LOW>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		dailink0_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+
+		wlf,shared-lrclk;
+	};
+};
+
+&i2s {
+	#sound-dai-cells = <0>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio_refclk_pins>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x4000>;
+				read-only;
+			};
+
+			factory: partition@34000 {
+				label = "factory";
+				reg = <0x34000 0x4000>;
+				read-only;
+			};
+
+			nvram: partition@38000 {
+				label = "nvram";
+				reg = <0x38000 0x8000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "upgrade_rec";
+				reg = <0x50000 0x100000>;
+				read-only;
+			};
+
+			partition@150000 {
+				compatible = "seama";
+				label = "firmware";
+				reg = <0x150000 0x6b0000>;
+			};
+		};
+	};
+};
+
+&gdma {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii1";
+		function = "gpio";
+	};
+
+	gpio_i2s {
+		groups = "uartf";
+		function = "gpio i2s";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dir-510l.dts b/target/linux/ramips/dts/mt7620a_dlink_dir-510l.dts
new file mode 100644
index 0000000..774d90c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dir-510l.dts
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "dlink,dir-510l", "ralink,mt7620a-soc";
+	model = "D-Link DIR-510L";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs = "console=ttyS1,57600";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		status-red {
+			label = "red:status";
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&ethernet {
+	mediatek,portmap = "llllw";
+};
+
+&uart {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				label = "recovery";
+				reg = <0x10000 0x200000>;
+				read-only;
+			};
+
+			partition@210000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x210000 0xde0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76x0e@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mtd-mac-address = <&config 0xe490>;
+		mtd-mac-address-increment = <(2)>;
+		mediatek,mtd-eeprom = <&config 0xe05d>;
+	};
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dir-810l.dts b/target/linux/ramips/dts/mt7620a_dlink_dir-810l.dts
new file mode 100644
index 0000000..12173d1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dir-810l.dts
@@ -0,0 +1,6 @@
+#include "mt7620a_cameo_810.dtsi"
+
+/ {
+	compatible = "dlink,dir-810l", "ralink,mt7620a-soc";
+	model = "D-Link DIR-810L";
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts
new file mode 100644
index 0000000..b86ab14
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a1.dts
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-118-a1", "ralink,mt7620a-soc";
+	model = "D-Link DWR-118 A1";
+
+	aliases {
+		led-boot = &led_internet;
+		led-failsafe = &led_internet;
+		led-upgrade = &led_internet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_internet: internet {
+			label = "green:internet";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <0>;
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	default {
+		groups = "ephy", "uartf", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mtd-mac-address = <&config 0xe496>;
+		mtd-mac-address-increment = <(2)>;
+		mediatek,mtd-eeprom = <&config 0xe083>;
+
+		led {
+			led-sources = <0>;
+			led-active-low;
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii-rxid";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii-rxid";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a2.dts b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a2.dts
new file mode 100644
index 0000000..b0dd31c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dwr-118-a2.dts
@@ -0,0 +1,178 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-118-a2", "ralink,mt7620a-soc";
+	model = "D-Link DWR-118 A2";
+
+	aliases {
+		led-boot = &led_internet;
+		led-failsafe = &led_internet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_internet: internet {
+			label = "green:internet";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	default {
+		groups = "ephy", "uartf", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&config 0xe4a8>;
+		mtd-mac-address-increment = <(2)>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mediatek,portmap = "wllll";
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy0>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii-rxid";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <2>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_dlink_dwr-960.dts b/target/linux/ramips/dts/mt7620a_dlink_dwr-960.dts
new file mode 100644
index 0000000..4284c61
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dlink_dwr-960.dts
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "dlink,dwr-960", "ralink,mt7620a-soc";
+	model = "D-Link DWR-960";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		sms {
+			label = "green:sms";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		signal_green {
+			label = "green:signal";
+			gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		signal_red {
+			label = "red:signal";
+			gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		4g {
+			label = "green:4g";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mediatek,portmap = "wllll";
+
+	port@5 {
+		status = "okay";
+		phy-mode = "rgmii-txid";
+		phy-handle = <&phy7>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy7: ethernet-phy@7 {
+			reg = <7>;
+			phy-mode = "rgmii-id";
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mediatek,mtd-eeprom = <&config 0xe08e>;
+		mtd-mac-address = <&config 0xe50e>;
+		mtd-mac-address-increment = <2>;
+	};
+};
+
+&state_default {
+	default {
+		groups = "i2c", "wled", "spi refclk", "uartf", "ephy";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_dovado_tiny-ac.dts b/target/linux/ramips/dts/mt7620a_dovado_tiny-ac.dts
new file mode 100644
index 0000000..ba1a2be
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_dovado_tiny-ac.dts
@@ -0,0 +1,159 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dovado,tiny-ac", "ralink,mt7620a-soc";
+	model = "Dovado Tiny AC";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "orange:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usbpower {
+			gpio-export,name = "usbpower";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mediatek,portmap = "llllw";
+
+	port@4 {
+		status = "okay";
+		phy-mode = "rgmii";
+		phy-handle = <&phy4>;
+	};
+
+	port@5 {
+		status = "okay";
+		phy-mode = "rgmii";
+		phy-handle = <&phy5>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "nd_sd", "wled";
+		function = "gpio";
+	};
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts b/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts
new file mode 100644
index 0000000..03a4c96
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_edimax_br-6478ac-v2.dts
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Rohan Murch <rohan.murch@gmail.com>
+ * Copyright (C) 2016 Hans Ulli Kroll <ulli.kroll@googlemail.com>
+ * Copyright (C) 2017 James McKenzie <openwrt@madingley.org>
+ */
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,br-6478ac-v2", "ralink,mt7620a-soc";
+	model = "Edimax BR-6478AC v2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+		usb-power {
+			gpio-export,name="usb-power";
+			gpio-export,output=<1>;
+			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "cimage";
+				reg = <0x50000 0x20000>;
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x00070000 0x00790000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		phy1: ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		phy2: ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		phy3: ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy1f: ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mediatek,2ghz = <0>;
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-7476rpc.dts b/target/linux/ramips/dts/mt7620a_edimax_ew-7476rpc.dts
new file mode 100644
index 0000000..ebab7e4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_edimax_ew-7476rpc.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_edimax_ew-747x.dtsi"
+
+/ {
+	compatible = "edimax,ew-7476rpc", "ralink,mt7620a-soc";
+	model = "Edimax EW-7476RPC";
+};
diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-7478ac.dts b/target/linux/ramips/dts/mt7620a_edimax_ew-7478ac.dts
new file mode 100644
index 0000000..a0fa2e3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_edimax_ew-7478ac.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_edimax_ew-747x.dtsi"
+
+/ {
+	compatible = "edimax,ew-7478ac", "ralink,mt7620a-soc";
+	model = "Edimax EW-7478AC";
+};
diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts b/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts
new file mode 100644
index 0000000..986b047
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_edimax_ew-7478apc.dts
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,ew-7478apc", "ralink,mt7620a-soc";
+	model = "Edimax EW-7478APC";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+
+	enable_usb_power {
+		gpio-hog;
+		line-name = "enable USB power";
+		gpios = <5 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "cimage";
+				reg = <0x50000 0x20000>;
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x00070000 0x00790000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		phy1: ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		phy2: ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		phy3: ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy1f: ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mediatek,2ghz = <0>;
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi b/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi
new file mode 100644
index 0000000..6060fd9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_edimax_ew-747x.dtsi
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "ralink,mt7620a-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		switch_high {
+			label = "switch high";
+			gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		switch_off {
+			label = "switch off";
+			gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio2 27 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio2 30 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1radio";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio2 31 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+		};
+
+		crossband {
+			label = "green:crossband";
+			gpios = <&gpio2 29 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "cimage";
+				reg = <0x50000 0x20000>;
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x00070000 0x00790000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "nd_sd", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&pinctrl {
+	phy_reset_pins: phy-reset {
+		gpio {
+			groups = "spi refclk";
+			function = "gpio";
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins &phy_reset_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	phy-reset-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+	phy-reset-duration = <30>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			status = "disabled";
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		phy1: ethernet-phy@1 {
+			status = "disabled";
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		phy2: ethernet-phy@2 {
+			status = "disabled";
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		phy3: ethernet-phy@3 {
+			status = "disabled";
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		phy4: ethernet-phy@4 {
+			status = "disabled";
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mediatek,2ghz = <0>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_engenius_esr600.dts b/target/linux/ramips/dts/mt7620a_engenius_esr600.dts
new file mode 100644
index 0000000..ea895ac
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_engenius_esr600.dts
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "engenius,esr600", "ralink,mt7620a-soc";
+	model = "EnGenius ESR600";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "amber:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps2g {
+			label = "amber:wps2g";
+			gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+			debounce-interval = <60>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+			debounce-interval = <60>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			iNIC_rf: partition@50000 {
+				label = "iNIC_rf";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "firmware";
+				reg = <0x60000 0xf40000>;
+				compatible = "denx,uimage";
+			};
+
+			partition@fa0000 {
+				label = "backup";
+				reg = <0xfa0000 0x10000>;
+				read-only;
+			};
+
+			partition@fb0000 {
+				label = "storage";
+				reg = <0xfb0000 0x50000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&iNIC_rf 0x4>;
+
+	port@5 {
+		status = "okay";
+		phy-mode = "rgmii";
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+			qca,ar8327-initvals = <
+				0x10 0x40000000 /* POWER-ON STRAPPING */
+				0x04 0x07600000 /* PORT0 PAD MODE CTRL */
+				0x7c 0x0000007e /* PORT0 STATUS */
+				0x0c 0x05600000 /* PORT6 PAD MODE CTRL */
+				0x94 0x0000007e /* PORT6 STATUS */
+			>;
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "nd_sd", "wled";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci1814,5592";
+		reg = <0x0 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&iNIC_rf 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_fon_fon2601.dts b/target/linux/ramips/dts/mt7620a_fon_fon2601.dts
new file mode 100644
index 0000000..373205e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_fon_fon2601.dts
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "fon,fon2601", "ralink,mt7620a-soc";
+	model = "Fon FON2601";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power_r {
+			label = "red:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_g {
+			label = "green:internet";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		net_g {
+			label = "green:net";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_g {
+			label = "green:wifi";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,padding = <32>;
+				label = "firmware";
+				reg = <0x50000 0xf90000>;
+			};
+
+			partition@fe0000 {
+				label = "board_data";
+				reg = <0xfe0000 0x20000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+	nd_sd {
+		groups = "nd_sd";
+		function = "sd";
+	};
+	spi_cs {
+		groups = "spi refclk";
+		function = "spi refclk";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>, <&wled_pins>;
+};
+
+&pcie {
+	status = "okay";
+};
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_glinet_gl-mt300a.dts b/target/linux/ramips/dts/mt7620a_glinet_gl-mt300a.dts
new file mode 100644
index 0000000..545e11a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_glinet_gl-mt300a.dts
@@ -0,0 +1,144 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "glinet,gl-mt300a", "ralink,mt7620a-soc";
+	model = "GL-MT300A";
+
+	aliases {
+		label-mac-device = &wmac;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "gl-mt300a:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "gl-mt300a:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "gl-mt300a:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "gl-mt300a:usb";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		BTN_0 {
+			label = "BTN_0";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		BTN_1 {
+			label = "BTN_1";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@ff0000 {
+				label = "art";
+				reg = <0xff0000 0x10000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4000>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "wled","ephy","uartf","i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_glinet_gl-mt300n.dts b/target/linux/ramips/dts/mt7620a_glinet_gl-mt300n.dts
new file mode 100644
index 0000000..575566c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_glinet_gl-mt300n.dts
@@ -0,0 +1,135 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "glinet,gl-mt300n", "ralink,mt7620a-soc";
+	model = "GL-MT300N";
+
+	aliases {
+		label-mac-device = &wmac;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "gl-mt300n:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "gl-mt300n:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "gl-mt300n:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		BTN_0 {
+			label = "BTN_0";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		BTN_1 {
+			label = "BTN_1";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@ff0000 {
+				label = "art";
+				reg = <0xff0000 0x10000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4000>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "wled","ephy","i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_glinet_gl-mt750.dts b/target/linux/ramips/dts/mt7620a_glinet_gl-mt750.dts
new file mode 100644
index 0000000..7582378
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_glinet_gl-mt750.dts
@@ -0,0 +1,150 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "glinet,gl-mt750", "ralink,mt7620a-soc";
+	model = "GL-MT750";
+
+	aliases {
+		label-mac-device = &wmac;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "gl-mt750:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "gl-mt750:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "gl-mt750:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		BTN_0 {
+			label = "BTN_0";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		BTN_1 {
+			label = "BTN_1";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@ff0000 {
+				label = "art";
+				reg = <0xff0000 0x10000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4000>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wled","ephy","uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_head-weblink_hdrm200.dts b/target/linux/ramips/dts/mt7620a_head-weblink_hdrm200.dts
new file mode 100644
index 0000000..7d807bf
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_head-weblink_hdrm200.dts
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "head-weblink,hdrm200", "ralink,mt7620a-soc";
+	model = "Head Weblink HDRM200";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS1,57600";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		rssi {
+			label = "red:rssi";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		air {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "pa", "spi refclk",
+			       "wled";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&uart {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5661.dts b/target/linux/ramips/dts/mt7620a_hiwifi_hc5661.dts
new file mode 100644
index 0000000..90ce3c9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5661.dts
@@ -0,0 +1,33 @@
+#include "mt7620a_hiwifi_hc5x61.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5661", "hiwifi,hc5x61", "ralink,mt7620a-soc";
+	model = "HiWiFi HC5661";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5761.dts b/target/linux/ramips/dts/mt7620a_hiwifi_hc5761.dts
new file mode 100644
index 0000000..5b67779
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5761.dts
@@ -0,0 +1,59 @@
+#include "mt7620a_hiwifi_hc5x61.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5761", "hiwifi,hc5x61", "ralink,mt7620a-soc";
+	model = "HiWiFi HC5761";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts
new file mode 100644
index 0000000..08163e5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5861.dts
@@ -0,0 +1,106 @@
+#include "mt7620a_hiwifi_hc5x61.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5861", "hiwifi,hc5x61", "ralink,mt7620a-soc";
+	model = "HiWiFi HC5861";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		turbo {
+			label = "blue:turbo";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usbpower {
+			gpio-export,name = "usbpower";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		sdpower {
+			gpio-export,name = "sdpower";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi b/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi
new file mode 100644
index 0000000..6349ec5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_hiwifi_hc5x61.dtsi
@@ -0,0 +1,127 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hiwifi,hc5x61", "ralink,mt7620a-soc";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usbpower {
+			gpio-export,name = "usbpower";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&sysc {
+	ralink,gpiomux = "i2c", "jtag";
+	ralink,uartmux = "gpio";
+	ralink,wdtmux = <1>;
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@fd0000 {
+				label = "hwf_config";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			bdinfo: partition@fe0000 {
+				label = "bdinfo";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "backup";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_hnet_c108.dts b/target/linux/ramips/dts/mt7620a_hnet_c108.dts
new file mode 100644
index 0000000..4035139
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_hnet_c108.dts
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hnet,c108", "ralink,mt7620a-soc";
+	model = "HNET C108";
+
+	aliases {
+		led-boot = &led_lan_green;
+		led-failsafe = &led_lan_green;
+		led-running = &led_lan_green;
+		led-upgrade = &led_lan_green;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_modem {
+			gpio-export,name = "power_modem";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sdcard {
+			label = "green:sdcard";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		modem_green {
+			label = "green:modem";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_red {
+			label = "red:modem";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		lan_red {
+			label = "red:lan";
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_lan_green: lan_green {
+			label = "green:lan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "spi refclk", "ephy";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_iodata_wn-ac1167gr.dts b/target/linux/ramips/dts/mt7620a_iodata_wn-ac1167gr.dts
new file mode 100644
index 0000000..d59b481
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_iodata_wn-ac1167gr.dts
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wn-ac1167gr", "ralink,mt7620a-soc";
+	model = "I-O DATA WN-AC1167GR";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		notification {
+			label = "green:notification";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		auto {
+			label = "auto";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x8000>;
+				read-only;
+			};
+
+			iNIC_rf: partition@48000 {
+				label = "iNIC_rf";
+				reg = <0x48000 0x8000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "NoUsed";
+				reg = <0x50000 0x20000>;
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x70000 0x6b4000>;
+			};
+
+			partition@724000 {
+				label = "manufacture";
+				reg = <0x724000 0x8c000>;
+				read-only;
+			};
+
+			partition@7b0000 {
+				label = "backup";
+				reg = <0x7b0000 0x10000>;
+				read-only;
+			};
+
+			partition@7c0000 {
+				label = "storage";
+				reg = <0x7c0000 0x40000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&iNIC_rf 0x0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
new file mode 100644
index 0000000..e29431d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_iodata_wn-ac733gr3.dts
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wn-ac733gr3", "ralink,mt7620a-soc";
+	model = "I-O DATA WN-AC733GR3";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		notification {
+			label = "green:notification";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		router {
+			label = "router";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		auto {
+			label = "auto";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	rtl8367rb {
+		compatible = "realtek,rtl8367b";
+		gpio-sda = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 23 GPIO_ACTIVE_HIGH>;
+		realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x8000>;
+				read-only;
+			};
+
+			iNIC_rf: partition@48000 {
+				label = "iNIC_rf";
+				reg = <0x48000 0x8000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x6d4000>;
+			};
+
+			partition@724000 {
+				label = "manufacture";
+				reg = <0x724000 0x8c000>;
+				read-only;
+			};
+
+			partition@7b0000 {
+				label = "backup";
+				reg = <0x7b0000 0x10000>;
+				read-only;
+			};
+
+			partition@7c0000 {
+				label = "storage";
+				reg = <0x7c0000 0x40000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+};
+
+&gpio0 {
+	rtl8367rb_reset {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rtl8367rb-reset";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "mdio";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&iNIC_rf 0x0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_iptime.dtsi b/target/linux/ramips/dts/mt7620a_iptime.dtsi
new file mode 100644
index 0000000..5a6fdac
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_iptime.dtsi
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@30000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&uboot 0x1fc20>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&uboot 0x1f800>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <0>;
+			led-active-low;
+		};
+	};
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&wled_pins>;
+
+	ralink,mtd-eeprom = <&uboot 0x1f400>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_iptime_a1004ns.dts b/target/linux/ramips/dts/mt7620a_iptime_a1004ns.dts
new file mode 100644
index 0000000..6270af3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_iptime_a1004ns.dts
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_iptime.dtsi"
+
+/ {
+	compatible = "iptime,a1004ns", "ralink,mt7620a-soc";
+	model = "ipTIME A1004ns";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&firmware {
+	reg = <0x30000 0xfd0000>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_iptime_a104ns.dts b/target/linux/ramips/dts/mt7620a_iptime_a104ns.dts
new file mode 100644
index 0000000..c997d68
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_iptime_a104ns.dts
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_iptime.dtsi"
+
+/ {
+	compatible = "iptime,a104ns", "ralink,mt7620a-soc";
+	model = "ipTIME A104ns";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&firmware {
+	reg = <0x30000 0x7d0000>;
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "spi refclk";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_kimax_u25awf-h1.dts b/target/linux/ramips/dts/mt7620a_kimax_u25awf-h1.dts
new file mode 100644
index 0000000..218dd7a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_kimax_u25awf-h1.dts
@@ -0,0 +1,111 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/{
+	compatible = "kimax,u25awf-h1","ralink,mt7620a-soc";
+	model = "Kimax U25AWF-H1";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "red:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "uartf", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_lava_lr-25g001.dts b/target/linux/ramips/dts/mt7620a_lava_lr-25g001.dts
new file mode 100644
index 0000000..41d69d0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_lava_lr-25g001.dts
@@ -0,0 +1,154 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "lava,lr-25g001", "ralink,mt7620a-soc";
+	model = "LAVA LR-25G001";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2g {
+			label = "green:wifi2g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5g {
+			label = "green:wifi5g";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usbpower {
+			gpio-export,name = "usbpower";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	port@5 {
+		status = "okay";
+		phy-mode = "rgmii";
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+			qca,ar8327-initvals = <
+				0x04 0x87300000 /* PORT0 PAD MODE CTRL */
+				0x0c 0x00000000 /* PORT6 PAD MODE CTRL */
+				0x7c 0x0000007e /* PORT0_STATUS */
+				0x94 0x00000000 /* PORT6_STATUS */
+			>;
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76x0e@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mtd-mac-address = <&config 0xe07e>;
+		mtd-mac-address-increment = <(2)>;
+		mediatek,mtd-eeprom = <&config 0xe08a>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_lb-link_bl-w1200.dts b/target/linux/ramips/dts/mt7620a_lb-link_bl-w1200.dts
new file mode 100644
index 0000000..9e0b817
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_lb-link_bl-w1200.dts
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "lb-link,bl-w1200", "ralink,mt7620a-soc";
+	model = "LB-Link BL-W1200";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "wllll";
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dts b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dts
new file mode 100644
index 0000000..2bea987
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dts
@@ -0,0 +1,59 @@
+#include "mt7620a_lenovo_newifi-y1.dtsi"
+
+/ {
+	compatible = "lenovo,newifi-y1", "ralink,mt7620a-soc";
+	model = "Lenovo Y1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan1 {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2 {
+			label = "blue:wifi5g";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
diff --git a/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dtsi b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dtsi
new file mode 100644
index 0000000..c7b7ea7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1.dtsi
@@ -0,0 +1,103 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "lenovo,newifi-y1", "ralink,mt7620a-soc";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1s.dts b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1s.dts
new file mode 100644
index 0000000..0544550
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_lenovo_newifi-y1s.dts
@@ -0,0 +1,116 @@
+#include "mt7620a_lenovo_newifi-y1.dtsi"
+
+/ {
+	compatible = "lenovo,newifi-y1s", "lenovo,newifi-y1", "ralink,mt7620a-soc";
+	model = "Lenovo Y1S";
+
+	aliases {
+		led-boot = &led_power_blue;
+		led-failsafe = &led_power_blue;
+		led-running = &led_power_blue;
+		led-upgrade = &led_power_blue;
+		label-mac-device = &ethernet;
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb0 {
+			gpio-export,name = "usb0";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>;
+		};
+		usb1 {
+			gpio-export,name = "usb1";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+		};
+		usb2 {
+			gpio-export,name = "usb2";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power1 {
+			label = "yellow:power";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_blue: power2 {
+			label = "blue:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan1 {
+			label = "yellow:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2 {
+			label = "blue:wifi";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+		};
+
+		usb1 {
+			label = "yellow:usb";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+		};
+
+		usb2 {
+			label = "blue:usb";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "wllll";
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_linksys_e1700.dts b/target/linux/ramips/dts/mt7620a_linksys_e1700.dts
new file mode 100644
index 0000000..c38ea80
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_linksys_e1700.dts
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Imre Kaloz <kaloz@openwrt.org>
+ */
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "linksys,e1700", "ralink,mt7620a-soc";
+	model = "Linksys E1700";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		phy1: ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		phy2: ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		phy3: ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy1f: ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_microduino_microwrt.dts b/target/linux/ramips/dts/mt7620a_microduino_microwrt.dts
new file mode 100644
index 0000000..4307d51
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_microduino_microwrt.dts
@@ -0,0 +1,97 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "microduino,microwrt", "ralink,mt7620a-soc";
+	model = "Microduino MicroWRT";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "u-boot-env";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0xfc0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "wled", "i2c", "wdt", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex2700.dts b/target/linux/ramips/dts/mt7620a_netgear_ex2700.dts
new file mode 100644
index 0000000..9ed0883
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex2700.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Joseph C. Lehner <joseph.c.lehner@gmail.com>
+ */
+
+#include "mt7620a_netgear_ex2700_wn3000rp-v3.dtsi"
+
+/ {
+	compatible = "netgear,ex2700", "ralink,mt7620a-soc";
+	model = "Netgear EX2700";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power_g {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		power_r {
+			label = "red:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		device_g {
+			label = "green:device";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		device_r {
+			label = "red:device";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		router_g {
+			label = "green:router";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		router_r {
+			label = "red:router";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&partitions {
+	partition@0 {
+		label = "u-boot";
+		reg = <0x0 0x30000>;
+		read-only;
+	};
+
+	partition@30000 {
+		label = "u-boot-env";
+		reg = <0x30000 0x10000>;
+		read-only;
+	};
+
+	partition@40000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x40000 0x3b0000>;
+	};
+
+	art: partition@3f0000 {
+		label = "art";
+		reg = <0x3f0000 0x10000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex2700_wn3000rp-v3.dtsi b/target/linux/ramips/dts/mt7620a_netgear_ex2700_wn3000rp-v3.dtsi
new file mode 100644
index 0000000..e7b1f4b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex2700_wn3000rp-v3.dtsi
@@ -0,0 +1,58 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&art 0x0>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&art 0x1000>;
+	mtd-mac-address = <&art 0x6>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "spi refclk";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex3700.dts b/target/linux/ramips/dts/mt7620a_netgear_ex3700.dts
new file mode 100644
index 0000000..0ab84f7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex3700.dts
@@ -0,0 +1,8 @@
+/* This file is released into the public domain */
+
+#include "mt7620a_netgear_ex3x00_ex61xx.dtsi"
+
+/ {
+	compatible = "netgear,ex3700", "ralink,mt7620a-soc";
+	model = "Netgear EX3700/EX3800";
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex3x00_ex61xx.dtsi b/target/linux/ramips/dts/mt7620a_netgear_ex3x00_ex61xx.dtsi
new file mode 100644
index 0000000..11e8f7f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex3x00_ex61xx.dtsi
@@ -0,0 +1,152 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power_amber;
+		led-failsafe = &led_power_amber;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio2 23 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led_power_amber: power_amber {
+			label = "amber:power";
+			gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+		};
+
+		router_green {
+			label = "green:router";
+			gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
+		};
+
+		router_red {
+			label = "red:router";
+			gpios = <&gpio2 24 GPIO_ACTIVE_LOW>;
+		};
+
+		device_green {
+			label = "green:device";
+			gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+		};
+
+		device_red {
+			label = "red:device";
+			gpios = <&gpio2 21 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio2 27 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "board_data";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "nvram";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "rgmii2", "spi refclk";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex6120.dts b/target/linux/ramips/dts/mt7620a_netgear_ex6120.dts
new file mode 100644
index 0000000..2d37627
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex6120.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_netgear_ex3x00_ex61xx.dtsi"
+
+/ {
+	compatible = "netgear,ex6120", "ralink,mt7620a-soc";
+	model = "Netgear EX6120";
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_ex6130.dts b/target/linux/ramips/dts/mt7620a_netgear_ex6130.dts
new file mode 100644
index 0000000..0cb4dc6
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_ex6130.dts
@@ -0,0 +1,12 @@
+/* This file is released into the public domain */
+
+#include "mt7620a_netgear_ex3x00_ex61xx.dtsi"
+
+/ {
+	compatible = "netgear,ex6130", "ralink,mt7620a-soc";
+	model = "Netgear EX6130";
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netgear_wn3000rp-v3.dts b/target/linux/ramips/dts/mt7620a_netgear_wn3000rp-v3.dts
new file mode 100644
index 0000000..c9b1806
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netgear_wn3000rp-v3.dts
@@ -0,0 +1,91 @@
+/* This file is released into the public domain */
+
+#include "mt7620a_netgear_ex2700_wn3000rp-v3.dtsi"
+
+/ {
+	compatible = "netgear,wn3000rp-v3", "ralink,mt7620a-soc";
+	model = "Netgear WN3000RP v3";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power_g {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		power_r {
+			label = "red:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		client_g {
+			label = "green:client";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		client_r {
+			label = "red:client";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		router_g {
+			label = "green:router";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		router_r {
+			label = "red:router";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		l_arrow {
+			label = "blue:leftarrow";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		r_arrow {
+			label = "blue:rightarrow";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&partitions {
+	partition@0 {
+		label = "u-boot";
+		reg = <0x0 0x30000>;
+		read-only;
+	};
+
+	partition@30000 {
+		label = "u-boot-env";
+		reg = <0x30000 0x10000>;
+		read-only;
+	};
+
+	partition@40000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x40000 0x7b0000>;
+	};
+
+	art: partition@7f0000 {
+		label = "art";
+		reg = <0x7f0000 0x10000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_netis_wf2770.dts b/target/linux/ramips/dts/mt7620a_netis_wf2770.dts
new file mode 100644
index 0000000..f839048
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_netis_wf2770.dts
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netis,wf2770", "ralink,mt7620a-soc";
+	model = "NETIS WF2770";
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		led-toggle {
+			label = "led-toggle";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_ohyeah_oy-0001.dts b/target/linux/ramips/dts/mt7620a_ohyeah_oy-0001.dts
new file mode 100644
index 0000000..7dabbed
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_ohyeah_oy-0001.dts
@@ -0,0 +1,120 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ohyeah,oy-0001", "ralink,mt7620a-soc";
+	model = "OY-0001";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: powerled {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifiled {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		s1 {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_k2g.dts b/target/linux/ramips/dts/mt7620a_phicomm_k2g.dts
new file mode 100644
index 0000000..e01c60a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_phicomm_k2g.dts
@@ -0,0 +1,141 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "phicomm,k2g", "ralink,mt7620a-soc";
+	model = "Phicomm K2G";
+
+	aliases {
+		led-boot = &led_blue;
+		led-failsafe = &led_blue;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+		serial0 = &uartlite;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_blue: blue {
+			label = "blue:status";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		yellow {
+			label = "yellow:status";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		red {
+			label = "red:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <24000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x30000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x30000 0x10000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x40000 0x10000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				reg = <0x50000 0x50000>;
+				label = "permanent_config";
+				read-only;
+			};
+
+			partition@a0000 {
+				compatible = "denx,uimage";
+				reg = <0xa0000 0x760000>;
+				label = "firmware";
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts b/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts
new file mode 100644
index 0000000..ea87d64
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_phicomm_psg1208.dts
@@ -0,0 +1,120 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "phicomm,psg1208", "ralink,mt7620a-soc";
+	model = "Phicomm PSG1208";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "white:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "white:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_psg1218.dtsi b/target/linux/ramips/dts/mt7620a_phicomm_psg1218.dtsi
new file mode 100644
index 0000000..4163a9c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_phicomm_psg1218.dtsi
@@ -0,0 +1,101 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "phicomm,psg1218", "ralink,mt7620a-soc";
+
+	aliases {
+		led-boot = &led_blue;
+		led-failsafe = &led_blue;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_blue: blue {
+			label = "blue:status";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		yellow {
+			label = "yellow:status";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		red {
+			label = "red:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_psg1218a.dts b/target/linux/ramips/dts/mt7620a_phicomm_psg1218a.dts
new file mode 100644
index 0000000..baa0d8b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_phicomm_psg1218a.dts
@@ -0,0 +1,27 @@
+#include "mt7620a_phicomm_psg1218.dtsi"
+
+/ {
+	compatible = "phicomm,psg1218a", "phicomm,psg1218", "ralink,mt7620a-soc";
+	model = "Phicomm PSG1218 rev.A";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_phicomm_psg1218b.dts b/target/linux/ramips/dts/mt7620a_phicomm_psg1218b.dts
new file mode 100644
index 0000000..f7e70c9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_phicomm_psg1218b.dts
@@ -0,0 +1,20 @@
+#include "mt7620a_phicomm_psg1218.dtsi"
+
+/ {
+	compatible = "phicomm,psg1218b", "phicomm,psg1218", "ralink,mt7620a-soc";
+	model = "Phicomm PSG1218 rev.B";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd", "pa";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_planex_cs-qr10.dts b/target/linux/ramips/dts/mt7620a_planex_cs-qr10.dts
new file mode 100644
index 0000000..3edc41a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_planex_cs-qr10.dts
@@ -0,0 +1,139 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,cs-qr10", "ralink,mt7620a-soc";
+	model = "Planex CS-QR10";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		s1 {
+			label = "reset";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		s2 {
+			label = "wps";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&i2s {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_i2s_pins>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcm {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "spi refclk", "rgmii1";
+		function = "gpio";
+	};
+	wdt {
+		groups = "wdt";
+		function = "wdt refclk";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_planex_db-wrt01.dts b/target/linux/ramips/dts/mt7620a_planex_db-wrt01.dts
new file mode 100644
index 0000000..8f8f173
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_planex_db-wrt01.dts
@@ -0,0 +1,99 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,db-wrt01", "ralink,mt7620a-soc";
+	model = "Planex DB-WRT01";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "orange:power";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		s1 {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi refclk", "rgmii1";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_planex_mzk-750dhp.dts b/target/linux/ramips/dts/mt7620a_planex_mzk-750dhp.dts
new file mode 100644
index 0000000..e1c5568
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_planex_mzk-750dhp.dts
@@ -0,0 +1,130 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,mzk-750dhp", "ralink,mt7620a-soc";
+	model = "Planex MZK-750DHP";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		s1 {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		s2 {
+			label = "wps";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi refclk", "rgmii1", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_planex_mzk-ex300np.dts b/target/linux/ramips/dts/mt7620a_planex_mzk-ex300np.dts
new file mode 100644
index 0000000..5459886
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_planex_mzk-ex300np.dts
@@ -0,0 +1,139 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,mzk-ex300np", "ralink,mt7620a-soc";
+	model = "Planex MZK-EX300NP";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+
+		rep {
+			label = "blue:rep";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi1 {
+			label = "blue:wifi1";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "blue:wifi2";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi3 {
+			label = "blue:wifi3";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x730000>;
+			};
+
+			partition@780000 {
+				label = "Udata";
+				reg = <0x780000 0x80000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi refclk", "rgmii1", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_planex_mzk-ex750np.dts b/target/linux/ramips/dts/mt7620a_planex_mzk-ex750np.dts
new file mode 100644
index 0000000..457d4fd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_planex_mzk-ex750np.dts
@@ -0,0 +1,155 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,mzk-ex750np", "ralink,mt7620a-soc";
+	model = "Planex MZK-EX750NP";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "red:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		rep {
+			label = "blue:rep";
+			gpios = <&gpio2 16 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi1 {
+			label = "blue:wifi1";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "blue:wifi2";
+			gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi3 {
+			label = "blue:wifi3";
+			gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x730000>;
+			};
+
+			partition@780000 {
+				label = "Udata";
+				reg = <0x780000 0x80000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "nd_sd", "rgmii2", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_ralink_mt7620a-evb.dts b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-evb.dts
new file mode 100644
index 0000000..ae35941
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-evb.dts
@@ -0,0 +1,126 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,mt7620a-evb", "ralink,mt7620a-soc";
+	model = "Ralink MT7620a + MT7610e evaluation board";
+
+	keys {
+		compatible = "gpio-keys";
+
+		s2 {
+			label = "S2";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		s3 {
+			label = "S3";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mediatek,portmap = "llllw";
+
+	port@4 {
+		status = "okay";
+		phy-mode = "rgmii";
+		phy-handle = <&phy4>;
+	};
+
+	port@5 {
+		status = "okay";
+		phy-mode = "rgmii";
+		phy-handle = <&phy5>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7530-evb.dts b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7530-evb.dts
new file mode 100644
index 0000000..f7d8cae
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7530-evb.dts
@@ -0,0 +1,116 @@
+#include "mt7620a.dtsi"
+
+/ {
+	compatible = "ralink,mt7620a-mt7530-evb", "ralink,mt7620a-soc";
+	model = "Ralink MT7620a + MT7530 evaluation board";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mediatek,portmap = "llllw";
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+
+		phy1: ethernet-phy@1 {
+			reg = <1>;
+			phy-mode = "rgmii";
+		};
+
+		phy2: ethernet-phy@2 {
+			reg = <2>;
+			phy-mode = "rgmii";
+		};
+
+		phy3: ethernet-phy@3 {
+			reg = <3>;
+			phy-mode = "rgmii";
+		};
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy1f: ethernet-phy@1f {
+			reg = <0x1f>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <12>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7610e-evb.dts b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7610e-evb.dts
new file mode 100644
index 0000000..b7a71c3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-mt7610e-evb.dts
@@ -0,0 +1,88 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,mt7620a-mt7610e-evb", "ralink,mt7620a-soc";
+	model = "Ralink MT7620A evaluation board";
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mediatek,portmap = "llllw";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_ralink_mt7620a-v22sg-evb.dts b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-v22sg-evb.dts
new file mode 100644
index 0000000..0e963e1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_ralink_mt7620a-v22sg-evb.dts
@@ -0,0 +1,116 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,mt7620a-v22sg-evb", "ralink,mt7620a-soc";
+	model = "Ralink MT7620a V22SG High Power evaluation board";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	nand {
+		compatible = "mtk,mt7620-nand";
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "u-boot-env";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			factory: partition@60000 {
+				label = "factory";
+				reg = <0x60000 0x20000>;
+				read-only;
+			};
+
+			partition@80000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x80000 0x7f80000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "spi";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mediatek,portmap = "llllw";
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_sanlinking_d240.dts b/target/linux/ramips/dts/mt7620a_sanlinking_d240.dts
new file mode 100644
index 0000000..6cff557
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_sanlinking_d240.dts
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sanlinking,d240", "ralink,mt7620a-soc";
+	model = "Sanlinking Technologies D240";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_mpcie2 {
+			gpio-export,name = "power_mpcie2";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_mpcie1 {
+			gpio-export,name = "power_mpcie1";
+			gpio-export,output = <1>;
+			gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		air {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+	/* the pins function is already set during pinmux driver load */
+	/delete-property/ pinctrl-0;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "wled", "spi refclk", "pa";
+		function = "gpio";
+	};
+
+	/*
+	 * The sd function of the nd_sd group configures two of the
+	 * groups pins as gpios. The pins are used as PCIe reset/power.
+	 * Due to the driver load order, the pins are configured way to
+	 * late if triggered by the sd-card driver.
+	 * To not introduce another kind of driver load order
+	 * dependency and configure the pins as early as possible,
+	 * means during pinmux driver load.
+	 */
+	gpio_sd {
+		groups = "nd_sd";
+		function = "sd";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_sercomm_na930.dts b/target/linux/ramips/dts/mt7620a_sercomm_na930.dts
new file mode 100644
index 0000000..1ffc0a2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_sercomm_na930.dts
@@ -0,0 +1,179 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sercomm,na930", "ralink,mt7620a-soc";
+	model = "Sercomm NA930";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS1,57600";
+	};
+
+	nand {
+		compatible = "mtk,mt7620-nand";
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@200000 {
+				label = "factory";
+				reg = <0x200000 0x40000>;
+				read-only;
+			};
+
+			partition@240000 {
+				label = "Config";
+				reg = <0x240000 0x400000>;
+				read-only;
+			};
+
+			partition@640000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x640000 0x1400000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		zwave {
+			label = "zwave";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		zwave {
+			label = "blue:zwave";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		status {
+			label = "blue:status";
+			gpios = <&gpio2 26 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		service {
+			label = "blue:service";
+			gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio2 29 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		telit {
+			gpio-export,name = "telit";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "rgmii2", "spi", "ephy";
+		function = "gpio";
+	};
+
+	uartf_gpio {
+		groups = "uartf";
+		function = "gpio uartf";
+	};
+};
+
+&uart {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mediatek,portmap = "llllw";
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_sitecom_wlr-4100-v1-002.dts b/target/linux/ramips/dts/mt7620a_sitecom_wlr-4100-v1-002.dts
new file mode 100644
index 0000000..3b260c5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_sitecom_wlr-4100-v1-002.dts
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sitecom,wlr-4100-v1-002", "ralink,mt7620a-soc";
+	model = "Sitecom WLR-4100 v1 002";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "amber:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wps {
+			label = "white:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb-power {
+			gpio-export,name = "usb-power";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "backup";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "storage";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@5 {
+		status = "okay";
+
+		phy-mode = "rgmii";
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+
+			qca,ar8327-initvals = <
+				0x04 0x06200000  /* PORT0 PAD MODE CTRL */
+				0x08 0x01000000  /* PORT5 PAD MODE CTRL  RX delay EN all ports 0, 5, 6 */
+				0x7c 0x0000007e  /* PORT0_STATUS */
+				0x94 0x00000000  /* PORT6_STATUS */
+			>;
+		};
+	};
+};
+
+&gsw {
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&wmac {
+	status = "okay";
+
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "uartf", "i2c", "wled", "spi refclk";
+		function = "gpio";
+	};
+};
+
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
new file mode 100644
index 0000000..184af58
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c2-v1.dts
@@ -0,0 +1,189 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,archer-c2-v1", "ralink,mt7620a-soc";
+	model = "TP-Link Archer C2 v1";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	rtl8367rb {
+		compatible = "realtek,rtl8367b", "rtl8367b";
+		cpu_port = <6>;
+		realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+		mii-bus = <&mdio0>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7a0000>;
+			};
+
+			partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x10000>;
+				read-only;
+			};
+
+			rom: partition@7d0000 {
+				label = "rom";
+				reg = <0x7d0000 0x10000>;
+				read-only;
+			};
+
+			partition@7e0000 {
+				label = "romfile";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&rom 0xf100>;
+
+	port@5 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+
+	mdio0: mdio-bus {
+		status = "okay";
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "wled", "ephy", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&radio 0x0>;
+	mtd-mac-address = <&rom 0xf100>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		mtd-mac-address = <&rom 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c20-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c20-v1.dts
new file mode 100644
index 0000000..f7e7d50
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c20-v1.dts
@@ -0,0 +1,82 @@
+#include "mt7620a_tplink_archer.dtsi"
+
+/ {
+	compatible = "tplink,archer-c20-v1", "ralink,mt7620a-soc";
+	model = "TP-Link Archer C20 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "wled", "ephy", "spi refclk", "wdt";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+
+	mtd-mac-address = <&rom 0xf100>;
+	mtd-mac-address-increment = <(-2)>;
+};
+
+&wifi {
+	mtd-mac-address = <&rom 0xf100>;
+	mtd-mac-address-increment = <(-1)>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c20i.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c20i.dts
new file mode 100644
index 0000000..a6c3cea
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c20i.dts
@@ -0,0 +1,62 @@
+#include "mt7620a_tplink_archer.dtsi"
+
+/ {
+	compatible = "tplink,archer-c20i", "ralink,mt7620a-soc";
+	model = "TP-Link Archer C20i";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd", "ephy", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	mtd-mac-address = <&rom 0xf100>;
+};
+
+&wifi {
+	mtd-mac-address = <&rom 0xf100>;
+	mtd-mac-address-increment = <(-1)>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-c50-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-c50-v1.dts
new file mode 100644
index 0000000..d564552
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-c50-v1.dts
@@ -0,0 +1,82 @@
+#include "mt7620a_tplink_archer.dtsi"
+
+/ {
+	compatible = "tplink,archer-c50-v1", "ralink,mt7620a-soc";
+	model = "TP-Link Archer C50 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "ephy", "spi refclk", "mdio", "wdt", "nd_sd";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+
+	mtd-mac-address = <&rom 0xf100>;
+	mtd-mac-address-increment = <(-2)>;
+};
+
+&wifi {
+	mtd-mac-address = <&rom 0xf100>;
+	mtd-mac-address-increment = <(-1)>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer-mr200.dts b/target/linux/ramips/dts/mt7620a_tplink_archer-mr200.dts
new file mode 100644
index 0000000..4212a70
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer-mr200.dts
@@ -0,0 +1,194 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,archer-mr200", "ralink,mt7620a-soc";
+	model = "TP-Link Archer MR200";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "white:lan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "white:wan";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		4g {
+			label = "white:4g";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "white:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		signal1 {
+			label = "white:signal1";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		signal2 {
+			label = "white:signal2";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		signal3 {
+			label = "white:signal3";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		signal4 {
+			label = "white:signal4";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "white:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_usb {
+			gpio-export,name = "power_usb1";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7b0000>;
+			};
+
+			rom: partition@7d0000 {
+				label = "rom";
+				reg = <0x7d0000 0x10000>;
+				read-only;
+			};
+
+			partition@7e0000 {
+				label = "romfile";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "wled", "nd_sd", "ephy", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&rom 0xf100>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&radio 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_archer.dtsi b/target/linux/ramips/dts/mt7620a_tplink_archer.dtsi
new file mode 100644
index 0000000..d2fb891
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_archer.dtsi
@@ -0,0 +1,122 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7a0000>;
+			};
+
+			partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x10000>;
+				read-only;
+			};
+
+			rom: partition@7d0000 {
+				label = "rom";
+				reg = <0x7d0000 0x10000>;
+				read-only;
+			};
+
+			partition@7e0000 {
+				label = "romfile";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+
+	mtd-mac-address = <&rom 0xf100>;
+
+	mediatek,portmap = "wllll";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&radio 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi: mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_re200-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_re200-v1.dts
new file mode 100644
index 0000000..d2f5207
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_re200-v1.dts
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_tplink_re2x0-v1.dtsi"
+
+/ {
+	compatible = "tplink,re200-v1", "ralink,mt7620a-soc";
+	model = "TP-Link RE200 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		};
+
+		qss {
+			label = "green:qss";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g_red {
+			label = "red:wlan2g";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g_green {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+};
+
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "ephy", "wled", "rgmii1", "spi refclk";
+		function = "gpio";
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_re210-v1.dts b/target/linux/ramips/dts/mt7620a_tplink_re210-v1.dts
new file mode 100644
index 0000000..57cd0ed
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_re210-v1.dts
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_tplink_re2x0-v1.dtsi"
+
+/ {
+	compatible = "tplink,re210-v1", "ralink,mt7620a-soc";
+	model = "TP-Link RE210 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi_high {
+			label = "green:rssi-high";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi_low {
+			label = "red:rssi-low";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&keys {
+	led_power {
+		label = "LED power";
+		gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+		linux,code = <BTN_0>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "wled", "rgmii1";
+		function = "gpio";
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	port@4 {
+		status = "okay";
+
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_tplink_re2x0-v1.dtsi b/target/linux/ramips/dts/mt7620a_tplink_re2x0-v1.dtsi
new file mode 100644
index 0000000..80b47b7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_tplink_re2x0-v1.dtsi
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600n8";
+	};
+
+	keys: keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7c0000>;
+			};
+
+			partition@7e0000 {
+				label = "config";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&uboot 0x1fc00>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&radio 0x0>;
+	mtd-mac-address = <&uboot 0x1fc00>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		mtd-mac-address = <&uboot 0x1fc00>;
+		mtd-mac-address-increment = <2>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_trendnet_tew-810dr.dts b/target/linux/ramips/dts/mt7620a_trendnet_tew-810dr.dts
new file mode 100644
index 0000000..6c6ea18
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_trendnet_tew-810dr.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_cameo_810.dtsi"
+
+/ {
+	compatible = "trendnet,tew-810dr", "ralink,mt7620a-soc";
+	model = "TRENDnet TEW-810DR";
+};
diff --git a/target/linux/ramips/dts/mt7620a_wavlink_wl-wn530hg4.dts b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn530hg4.dts
new file mode 100644
index 0000000..d8ce40c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn530hg4.dts
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wavlink,wl-wn530hg4", "ralink,mt7620a-soc";
+	model = "Wavlink WL-WN530HG4";
+
+	aliases {
+		led-boot = &led_status_blue;
+		led-failsafe = &led_status_blue;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_blue;
+		serial0 = &uartlite;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		status_red {
+			label = "red:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <24000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_wavlink_wl-wn579x3.dts b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn579x3.dts
new file mode 100644
index 0000000..bfec806
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_wavlink_wl-wn579x3.dts
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wavlink,wl-wn579x3", "ralink,mt7620a-soc";
+	model = "Wavlink WL-WN579X3";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		switch_aps {
+			label = "mode_aps";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+
+		switch_repeater {
+			label = "mode_repeater";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		/* These three form the signal wifi strength segments */
+		wifi_high {
+			label = "blue:wifi_high";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_medium {
+			label = "blue:wifi_medium";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_low {
+			label = "blue:wifi_low";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "board_data";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "nvram";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+
+	port@4 {
+		status = "okay";
+		phy-handle = <&phy4>;
+		phy-mode = "rgmii";
+	};
+
+	port@5 {
+		status = "okay";
+		phy-handle = <&phy5>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+
+		phy5: ethernet-phy@5 {
+			reg = <5>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "ephy", "i2c", "wled", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts b/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts
new file mode 100644
index 0000000..11b1aa3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_xiaomi_miwifi-mini.dts
@@ -0,0 +1,152 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "xiaomi,miwifi-mini", "ralink,mt7620a-soc";
+	model = "Xiaomi MiWiFi Mini";
+
+	aliases {
+		led-boot = &led_blue;
+		led-failsafe = &led_blue;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+		label-mac-device = &ethernet;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_blue: blue {
+			label = "blue:status";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		yellow {
+			label = "yellow:status";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+
+		red {
+			label = "red:status";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@fd0000 {
+				label = "crash";
+				reg = <0xfd0000 0x10000>;
+			};
+
+			partition@fe0000 {
+				label = "reserved";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "Bdata";
+				reg = <0xff0000 0x10000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "rgmii1";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_youku_yk-l1.dts b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dts
new file mode 100644
index 0000000..5155318
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_youku_yk-l1.dtsi"
+
+/ {
+	compatible = "youku,yk-l1", "ralink,mt7620a-soc";
+	model = "Youku YK-L1";
+};
+
+&firmware {
+	reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi
new file mode 100644
index 0000000..61062a3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_youku_yk-l1.dtsi
@@ -0,0 +1,126 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				/* reg property is set based on flash size in DTS files */
+			};
+		};
+	};
+};
+
+&state_default {
+	default {
+		groups = "i2c", "rgmii1", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+
+	mtd-mac-address = <&factory 0x28>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_youku_yk-l1c.dts b/target/linux/ramips/dts/mt7620a_youku_yk-l1c.dts
new file mode 100644
index 0000000..c59f010
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_youku_yk-l1c.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_youku_yk-l1.dtsi"
+
+/ {
+	compatible = "youku,yk-l1c", "ralink,mt7620a-soc";
+	model = "Youku YK-L1c";
+};
+
+&firmware {
+	reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_yukai_bocco.dts b/target/linux/ramips/dts/mt7620a_yukai_bocco.dts
new file mode 100644
index 0000000..347c246
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_yukai_bocco.dts
@@ -0,0 +1,146 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "yukai,bocco", "ralink,mt7620a-soc";
+	model = "YUKAI Engineering BOCCO";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		s1 {
+			gpio-export,name = "rec";
+			gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
+		};
+		s2 {
+			gpio-export,name = "play";
+			gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "Audio-I2S";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+		simple-audio-card,widgets =
+			"Headphone", "Headphones";
+		simple-audio-card,routing =
+			"Headphones", "HP_L",
+			"Headphones", "HP_R";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		dailink0_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+
+		wlf,shared-lrclk;
+	};
+};
+
+&i2s {
+	#sound-dai-cells = <0>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_i2s_pins>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcm {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "spi refclk", "rgmii1";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-ape522ii.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-ape522ii.dts
new file mode 100644
index 0000000..28ae7c3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-ape522ii.dts
@@ -0,0 +1,129 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-ape522ii", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-APE522II";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sys1 {
+			label = "green:sys1";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		sys2 {
+			label = "green:sys2";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		sys3 {
+			label = "green:sys3";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		sys4 {
+			label = "green:sys4";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g4 {
+			label = "green:wlan2g4";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pa_pins>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wled", "i2c", "uartf", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g-16m.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g-16m.dts
new file mode 100644
index 0000000..bc2eec5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g-16m.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_zbtlink_zbt-we1026-5g.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we1026-5g-16m", "zbtlink,zbt-we1026-5g",
+		"zbtlink,zbt-we1026", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-WE1026-5G (16M)";
+};
+
+&firmware {
+	reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g.dtsi b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g.dtsi
new file mode 100644
index 0000000..f86ac1a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g.dtsi
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_zbtlink_zbt-we1026.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we1026-5g", "zbtlink,zbt-we1026",
+		"ralink,mt7620a-soc";
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	watchdog {
+		compatible = "linux,wdt-gpio";
+		gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		hw_algo = "toggle";
+		hw_margin_ms = <20000>;
+		always-running;
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h-32m.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h-32m.dts
new file mode 100644
index 0000000..577e7e0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h-32m.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_zbtlink_zbt-we1026-h.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we1026-h-32m", "zbtlink,zbt-we1026-h",
+		"zbtlink,zbt-we1026", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-WE1026-H (32M)";
+};
+
+&flash0 {
+	broken-flash-reset;
+};
+
+&firmware {
+	reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h.dtsi b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h.dtsi
new file mode 100644
index 0000000..09f0ba7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-h.dtsi
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_zbtlink_zbt-we1026.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we1026-h", "zbtlink,zbt-we1026",
+		"ralink,mt7620a-soc";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026.dtsi b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026.dtsi
new file mode 100644
index 0000000..3dae6d9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026.dtsi
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-we1026", "ralink,mt7620a-soc";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	aliases {
+		label-mac-device = &wmac;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+			};
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "spi refclk", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-16m.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-16m.dts
new file mode 100644
index 0000000..c3de533
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-16m.dts
@@ -0,0 +1,46 @@
+#include "mt7620a_zbtlink_zbt-we826.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we826-16m", "zbtlink,zbt-we826", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-WE826 (16M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-32m.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-32m.dts
new file mode 100644
index 0000000..ad07682
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-32m.dts
@@ -0,0 +1,47 @@
+#include "mt7620a_zbtlink_zbt-we826.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we826-32m", "zbtlink,zbt-we826", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-WE826 (32M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-e.dts b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-e.dts
new file mode 100644
index 0000000..6950211
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826-e.dts
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_zbtlink_zbt-we826.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-we826-e", "zbtlink,zbt-we826", "ralink,mt7620a-soc";
+	model = "Zbtlink ZBT-WE826-E";
+
+	/delete-node/ leds;
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: gsm {
+			label = "blue:gsm";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		signal {
+			label = "green:signal";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		sim {
+			label = "red:sim";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		air {
+			label = "red:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826.dtsi b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826.dtsi
new file mode 100644
index 0000000..cf2ca1c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we826.dtsi
@@ -0,0 +1,91 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-we826", "ralink,mt7620a-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		air {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "wled", "spi refclk", "pa";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_zte_q7.dts b/target/linux/ramips/dts/mt7620a_zte_q7.dts
new file mode 100644
index 0000000..550f750
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zte_q7.dts
@@ -0,0 +1,113 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zte,q7", "ralink,mt7620a-soc";
+	model = "ZTE Q7";
+
+	aliases {
+		led-boot = &led_status_blue;
+		led-failsafe = &led_status_blue;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_blue;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		statred {
+			label = "red:status";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: statblue {
+			label = "blue:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf", "rgmii1", "rgmii2", "ephy", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
new file mode 100644
index 0000000..1a5ff2d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620a_zyxel_keenetic-viva.dts
@@ -0,0 +1,174 @@
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-viva", "ralink,mt7620a-soc";
+	model = "ZyXEL Keenetic Viva";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		power_alert {
+			label = "red:power";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power {
+			label = "green:power";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		fn {
+			label = "fn";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb_power {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	rtl8367rb {
+		compatible = "realtek,rtl8367b";
+		cpu_port = <7>;
+		realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
+		mii-bus = <&mdio0>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii2_pins &mdio_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	port@4 {
+		status = "okay";
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+		phy-handle = <&phy4>;
+	};
+
+	mdio0: mdio-bus {
+		status = "okay";
+
+		phy4: ethernet-phy@4 {
+			reg = <4>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&gsw {
+	mediatek,port4-gmac;
+	mediatek,ephy-base = /bits/ 8 <8>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620n.dtsi b/target/linux/ramips/dts/mt7620n.dtsi
new file mode 100644
index 0000000..d5d704b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n.dtsi
@@ -0,0 +1,387 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,mt7620n-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		spi1 = &spi1;
+		serial0 = &uartlite;
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,mt7620a-sysc", "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,mt7620a-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,mt7620a-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,mt7620a-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <32>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio3: gpio@688 {
+			compatible = "ralink,mt7620a-gpio", "ralink,rt2880-gpio";
+			reg = <0x688 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <72>;
+			ralink,num-gpios = <1>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c: i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,mt7620a-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x40>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+		};
+
+		spi1: spi@b40 {
+			compatible = "ralink,rt2880-spi";
+			reg = <0xb40 0x60>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_cs1>;
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,mt7620a-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			reg-shift = <2>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+		};
+
+		systick: systick@d00 {
+			compatible = "ralink,mt7620a-systick", "ralink,cevt-systick";
+			reg = <0xd00 0x10>;
+
+			resets = <&rstctrl 28>;
+			reset-names = "intc";
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <7>;
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		ephy_pins: ephy {
+			ephy {
+				groups = "ephy";
+				function = "ephy";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		spi_cs1: spi1 {
+			spi1 {
+				groups = "spi refclk";
+				function = "spi refclk";
+			};
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,mt7620a-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	usbphy: usbphy {
+		compatible = "mediatek,mt7620-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+
+		clocks = <&clkctrl 22 &clkctrl 25>;
+		clock-names = "host", "device";
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "mediatek,mt7620-eth";
+		reg = <0x10100000 0x10000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		resets = <&rstctrl 21 &rstctrl 23>;
+		reset-names = "fe", "esw";
+
+		mediatek,switch = <&gsw>;
+	};
+
+	gsw: gsw@10110000 {
+		compatible = "mediatek,mt7620-gsw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		status = "disabled";
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		status = "disabled";
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt7620-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_asus_rt-n12p.dts b/target/linux/ramips/dts/mt7620n_asus_rt-n12p.dts
new file mode 100644
index 0000000..24a8779
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_asus_rt-n12p.dts
@@ -0,0 +1,123 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n12p", "ralink,mt7620n-soc";
+	model = "Asus RT-N12+";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		air {
+			label = "green:air";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled", "i2c", "wdt", "pa", "spi refclk";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_asus_rt-n14u.dts b/target/linux/ramips/dts/mt7620n_asus_rt-n14u.dts
new file mode 100644
index 0000000..ce51ff8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_asus_rt-n14u.dts
@@ -0,0 +1,136 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n14u", "ralink,mt7620n-soc";
+	model = "Asus RT-N14U";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		air {
+			label = "blue:air";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled", "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_buffalo_wmr-300.dts b/target/linux/ramips/dts/mt7620n_buffalo_wmr-300.dts
new file mode 100644
index 0000000..26803c0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_buffalo_wmr-300.dts
@@ -0,0 +1,112 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,wmr-300", "ralink,mt7620n-soc";
+	model = "Buffalo WMR-300";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		aoss1 {
+			label = "red:aoss";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		aoss2 {
+			label = "green:aoss";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "ephy";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_comfast_cf-wr800n.dts b/target/linux/ramips/dts/mt7620n_comfast_cf-wr800n.dts
new file mode 100644
index 0000000..c458f87
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_comfast_cf-wr800n.dts
@@ -0,0 +1,116 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "comfast,cf-wr800n", "ralink,mt7620n-soc";
+	model = "Comfast CF-WR800N";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		ethernet {
+			label = "white:ethernet";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "white:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "white:wps";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled", "spi refclk", "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_dlink_dwr-116-a1.dts b/target/linux/ramips/dts/mt7620n_dlink_dwr-116-a1.dts
new file mode 100644
index 0000000..d659262
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_dlink_dwr-116-a1.dts
@@ -0,0 +1,106 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-116-a1", "ralink,mt7620n-soc";
+	model = "D-Link DWR-116 A1/A2";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0x7e0000>;
+			};
+
+			config: partition@7f0000 {
+				label = "config";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	default {
+		groups = "i2c", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mediatek,portmap = "llllw";
+};
diff --git a/target/linux/ramips/dts/mt7620n_dlink_dwr-921-c1.dts b/target/linux/ramips/dts/mt7620n_dlink_dwr-921-c1.dts
new file mode 100644
index 0000000..d37bdb4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_dlink_dwr-921-c1.dts
@@ -0,0 +1,141 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-921-c1", "ralink,mt7620n-soc";
+	model = "D-Link DWR-921 C1";
+
+	aliases {
+		led-boot = &led_sstrenghg;
+		led-failsafe = &led_sstrenghg;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sms {
+			label = "green:sms";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_sstrenghg: sstrengthg {
+			label = "green:sigstrength";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		sstrengthr {
+			label = "red:sigstrength";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		4g {
+			label = "green:4g";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		lte_modem_enable {
+			gpio-export,name = "lte_modem_enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	default {
+		groups = "spi refclk", "i2c", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_dlink_dwr-922-e2.dts b/target/linux/ramips/dts/mt7620n_dlink_dwr-922-e2.dts
new file mode 100644
index 0000000..d3ca0dd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_dlink_dwr-922-e2.dts
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-922-e2", "ralink,mt7620n-soc";
+	model = "D-Link DWR-922 E2";
+
+	aliases {
+		led-boot = &sstrengthg;
+		led-failsafe = &sstrengthg;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led-boot = &sstrengthg;
+
+		sms {
+			label = "green:sms";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		sstrengthg: sstrengthg {
+			label = "green:sigstrength";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		sstrengthr {
+			label = "red:sigstrength";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		4g {
+			label = "green:4g";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		lte_modem_enable {
+			gpio-export,name = "lte_modem_enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0xfe0000>;
+			};
+
+			config: partition@ff0000 {
+				label = "config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&state_default {
+	default {
+		groups = "spi refclk", "i2c", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_elecom_wrh-300cr.dts b/target/linux/ramips/dts/mt7620n_elecom_wrh-300cr.dts
new file mode 100644
index 0000000..19d2f63
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_elecom_wrh-300cr.dts
@@ -0,0 +1,129 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "elecom,wrh-300cr", "ralink,mt7620n-soc";
+	model = "ELECOM WRH-300CR";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		ethernet {
+			label = "green:ethernet";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "recover";
+				reg = <0x50000 0x1c0000>;
+				read-only;
+			};
+
+			partition@210000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x210000 0xdf0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_hootoo_ht-tm05.dts b/target/linux/ramips/dts/mt7620n_hootoo_ht-tm05.dts
new file mode 100644
index 0000000..1c408bc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_hootoo_ht-tm05.dts
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620n_sunvalley_filehub.dtsi"
+
+/ {
+	compatible = "hootoo,ht-tm05", "ralink,mt7620n-soc";
+	model = "HooToo HT-TM05";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_kimax_u35wf.dts b/target/linux/ramips/dts/mt7620n_kimax_u35wf.dts
new file mode 100644
index 0000000..7d6d800
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_kimax_u35wf.dts
@@ -0,0 +1,111 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "kimax,u35wf","ralink,mt7620n-soc";
+	model = "Kimax U35WF";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:eth";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_kingston_mlw221.dts b/target/linux/ramips/dts/mt7620n_kingston_mlw221.dts
new file mode 100644
index 0000000..1186b83
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_kingston_mlw221.dts
@@ -0,0 +1,124 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "kingston,mlw221", "ralink,mt7620n-soc";
+	model = "Kingston MLW221";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		system {
+			label = "system";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf60000>;
+			};
+
+			partition@fb0000 {
+				label = "user-config";
+				reg = <0xfb0000 0x50000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_kingston_mlwg2.dts b/target/linux/ramips/dts/mt7620n_kingston_mlwg2.dts
new file mode 100644
index 0000000..eba7fab
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_kingston_mlwg2.dts
@@ -0,0 +1,124 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "kingston,mlwg2", "ralink,mt7620n-soc";
+	model = "Kingston MLWG2";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		system {
+			label = "system";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf60000>;
+			};
+
+			partition@fb0000 {
+				label = "user-config";
+				reg = <0xfb0000 0x50000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_netgear_jwnr2010-v5.dts b/target/linux/ramips/dts/mt7620n_netgear_jwnr2010-v5.dts
new file mode 100644
index 0000000..63cf38d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_netgear_jwnr2010-v5.dts
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620n_netgear_n300.dtsi"
+
+/ {
+	compatible = "netgear,jwnr2010-v5", "ralink,mt7620n-soc";
+	model = "Netgear JWNR2010 v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		lan1 {
+			label = "green:lan1";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "green:lan2";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3 {
+			label = "green:lan3";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4 {
+			label = "green:lan4";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_netgear_n300.dtsi b/target/linux/ramips/dts/mt7620n_netgear_n300.dtsi
new file mode 100644
index 0000000..6f5be57
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_netgear_n300.dtsi
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x20000 0x3c0000>;
+			};
+
+			partition@3e0000 {
+				label = "nvram";
+				reg = <0x3e0000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@3f0000 {
+				label = "factory";
+				reg = <0x3f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "pa", "ephy", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_nexx_wt3020-4m.dts b/target/linux/ramips/dts/mt7620n_nexx_wt3020-4m.dts
new file mode 100644
index 0000000..ed9170f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_nexx_wt3020-4m.dts
@@ -0,0 +1,46 @@
+#include "mt7620n_nexx_wt3020.dtsi"
+
+/ {
+	compatible = "nexx,wt3020-4m", "nexx,wt3020", "ralink,mt7620n-soc";
+	model = "Nexx WT3020 (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_nexx_wt3020-8m.dts b/target/linux/ramips/dts/mt7620n_nexx_wt3020-8m.dts
new file mode 100644
index 0000000..ac46ccb
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_nexx_wt3020-8m.dts
@@ -0,0 +1,54 @@
+#include "mt7620n_nexx_wt3020.dtsi"
+
+/ {
+	compatible = "nexx,wt3020-8m", "nexx,wt3020", "ralink,mt7620n-soc";
+	model = "Nexx WT3020 (8M)";
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_nexx_wt3020.dtsi b/target/linux/ramips/dts/mt7620n_nexx_wt3020.dtsi
new file mode 100644
index 0000000..1597c08
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_nexx_wt3020.dtsi
@@ -0,0 +1,56 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "nexx,wt3020", "ralink,mt7620n-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled", "pa", "i2c", "wdt", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_ravpower_rp-wd03.dts b/target/linux/ramips/dts/mt7620n_ravpower_rp-wd03.dts
new file mode 100644
index 0000000..320d61f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_ravpower_rp-wd03.dts
@@ -0,0 +1,27 @@
+#include "mt7620n_sunvalley_filehub.dtsi"
+
+/ {
+	compatible = "ravpower,rp-wd03", "ralink,mt7620n-soc";
+	model = "RAVPower RP-WD03";
+
+	aliases {
+		led-boot = &led_wifi_blue;
+		led-failsafe = &led_wifi_blue;
+		led-running = &led_wifi_blue;
+		led-upgrade = &led_wifi_blue;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi_green {
+			label = "green:wifi";
+			gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_wifi_blue: wifi_blue {
+			label = "blue:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi b/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi
new file mode 100644
index 0000000..20ff2db
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_sunvalley_filehub.dtsi
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	virtual_flash {
+		compatible = "mtd-concat";
+
+		devices = <&fwconcat0 &fwconcat1 &fwconcat2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,ih-magic = <IH_MAGIC_OKLI>;
+				label = "firmware";
+				reg = <0x0 0x0>;
+			};
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "loader";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			fwconcat1: partition@60000 {
+				label = "fwconcat1";
+				reg = <0x60000 0x170000>;
+			};
+
+			partition@1d0000 {
+				label = "u-boot-env";
+				reg = <0x1d0000 0x10000>;
+			};
+
+			fwconcat2: partition@1e0000 {
+				label = "fwconcat2";
+				reg = <0x1e0000 0x20000>;
+			};
+
+			fwconcat0: partition@200000 {
+				label = "fwconcat0";
+				reg = <0x200000 0x600000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "wled", "ephy";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_vonets_var11n-300.dts b/target/linux/ramips/dts/mt7620n_vonets_var11n-300.dts
new file mode 100644
index 0000000..97ed206
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_vonets_var11n-300.dts
@@ -0,0 +1,92 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "vonets,var11n-300", "ralink,mt7620n-soc";
+	model = "Vonets VAR11N-300";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_wrtnode_wrtnode.dts b/target/linux/ramips/dts/mt7620n_wrtnode_wrtnode.dts
new file mode 100644
index 0000000..144591d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_wrtnode_wrtnode.dts
@@ -0,0 +1,93 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "wrtnode,wrtnode", "ralink,mt7620n-soc";
+	model = "WRTNODE";
+
+	aliases {
+		led-boot = &led_indicator;
+		led-failsafe = &led_indicator;
+		led-running = &led_indicator;
+		led-upgrade = &led_indicator;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_indicator: indicator {
+			label = "blue:indicator";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "ephy", "wled", "pa", "i2c", "wdt", "uartf", "spi refclk";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_zbtlink_zbt-cpe102.dts b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-cpe102.dts
new file mode 100644
index 0000000..6d018b9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-cpe102.dts
@@ -0,0 +1,116 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-cpe102", "ralink,mt7620n-soc";
+	model = "Zbtlink ZBT-CPE102";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		led-boot = &led_4g_0;
+		led-failsafe = &led_4g_0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_4g_0: 4g-0 {
+			label = "green:4g-0";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		4g-1 {
+			label = "green:4g-1";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		4g-2 {
+			label = "green:4g-2";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x760000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wa05.dts b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wa05.dts
new file mode 100644
index 0000000..b29c034
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wa05.dts
@@ -0,0 +1,124 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-wa05", "ralink,mt7620n-soc";
+	model = "Zbtlink ZBT-WA05";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		air {
+			label = "blue:air";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x760000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_zbtlink_zbt-we2026.dts b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-we2026.dts
new file mode 100644
index 0000000..fe17998
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-we2026.dts
@@ -0,0 +1,109 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-we2026", "ralink,mt7620n-soc";
+	model = "Zbtlink ZBT-WE2026";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x760000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wr8305rt.dts b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wr8305rt.dts
new file mode 100644
index 0000000..af3ac4b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zbtlink_zbt-wr8305rt.dts
@@ -0,0 +1,123 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-wr8305rt", "ralink,mt7620n-soc";
+	model = "Zbtlink ZBT-WR8305RT";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "green:sys";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ephy_pins>;
+
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	default {
+		groups = "i2c", "uartf", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
new file mode 100644
index 0000000..4e5c68e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni-ii.dts
@@ -0,0 +1,148 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-omni-ii", "ralink,mt7620n-soc";
+	model = "ZyXEL Keenetic Omni II";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		fn {
+			label = "fn";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb_power {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wdt", "pa", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "wllll";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
new file mode 100644
index 0000000..e43f135
--- /dev/null
+++ b/target/linux/ramips/dts/mt7620n_zyxel_keenetic-omni.dts
@@ -0,0 +1,148 @@
+#include "mt7620n.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-omni", "ralink,mt7620n-soc";
+	model = "ZyXEL Keenetic Omni";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		fn {
+			label = "fn";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb_power {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gpio3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wdt", "pa", "spi refclk", "wled";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	mediatek,portmap = "llllw";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
new file mode 100644
index 0000000..7636f9d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621.dtsi
@@ -0,0 +1,628 @@
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/mips-gic.h>
+#include <dt-bindings/clock/mt7621-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "mediatek,mt7621-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "mips,mips1004Kc";
+			reg = <0>;
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "mips,mips1004Kc";
+			reg = <1>;
+		};
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	aliases {
+		serial0 = &uartlite;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	pll: pll {
+		compatible = "mediatek,mt7621-pll", "syscon";
+
+		#clock-cells = <1>;
+		clock-output-names = "cpu", "bus";
+	};
+
+	sysclock: sysclock {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+
+		/* FIXME: there should be way to detect this */
+		clock-frequency = <50000000>;
+	};
+
+	palmbus: palmbus@1E000000 {
+		compatible = "palmbus";
+		reg = <0x1E000000 0x100000>;
+		ranges = <0x0 0x1E000000 0x0FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "mtk,mt7621-sysc";
+			reg = <0x0 0x100>;
+		};
+
+		wdt: wdt@100 {
+			compatible = "mediatek,mt7621-wdt";
+			reg = <0x100 0x100>;
+		};
+
+		gpio: gpio@600 {
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+			compatible = "mediatek,mt7621-gpio";
+			gpio-controller;
+			interrupt-controller;
+			reg = <0x600 0x100>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 12 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		i2c: i2c@900 {
+			compatible = "mediatek,mt7621-i2c";
+			reg = <0x900 0x100>;
+
+			clocks = <&sysclock>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s: i2s@a00 {
+			compatible = "mediatek,mt7621-i2s";
+			reg = <0xa00 0x100>;
+
+			clocks = <&sysclock>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 16 IRQ_TYPE_LEVEL_HIGH>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		systick: systick@500 {
+			compatible = "ralink,mt7621-systick", "ralink,cevt-systick";
+			reg = <0x500 0x10>;
+
+			resets = <&rstctrl 28>;
+			reset-names = "intc";
+
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 5 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		memc: memc@5000 {
+			compatible = "mtk,mt7621-memc";
+			reg = <0x5000 0x1000>;
+		};
+
+		cpc: cpc@1fbf0000 {
+			compatible = "mtk,mt7621-cpc";
+			reg = <0x1fbf0000 0x8000>;
+		};
+
+		mc: mc@1fbf8000 {
+			compatible = "mtk,mt7621-mc";
+			reg = <0x1fbf8000 0x8000>;
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ns16550a";
+			reg = <0xc00 0x100>;
+
+			clock-frequency = <50000000>;
+
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 26 IRQ_TYPE_LEVEL_HIGH>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test;
+		};
+
+		uartlite2: uartlite2@d00 {
+			compatible = "ns16550a";
+			reg = <0xd00 0x100>;
+
+			clock-frequency = <50000000>;
+
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 27 IRQ_TYPE_LEVEL_HIGH>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart2_pins>;
+
+			status = "disabled";
+		};
+
+		uartlite3: uartlite3@e00 {
+			compatible = "ns16550a";
+			reg = <0xe00 0x100>;
+
+			clock-frequency = <50000000>;
+
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SHARED 28 IRQ_TYPE_LEVEL_HIGH>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart3_pins>;
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			status = "disabled";
+
+			compatible = "ralink,mt7621-spi";
+			reg = <0xb00 0x100>;
+
+			clocks = <&pll MT7621_CLK_BUS>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&gic>;
+			interrupts = <0 13 4>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+
+		hsdma: hsdma@7000 {
+			compatible = "mediatek,mt7621-hsdma";
+			reg = <0x7000 0x1000>;
+
+			resets = <&rstctrl 5>;
+			reset-names = "hsdma";
+
+			interrupt-parent = <&gic>;
+			interrupts = <0 11 4>;
+
+			#dma-cells = <1>;
+			#dma-channels = <1>;
+			#dma-requests = <1>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		uart1_pins: uart1 {
+			uart1 {
+				groups = "uart1";
+				function = "uart1";
+			};
+		};
+
+		uart2_pins: uart2 {
+			uart2 {
+				groups = "uart2";
+				function = "uart2";
+			};
+		};
+
+		uart3_pins: uart3 {
+			uart3 {
+				groups = "uart3";
+				function = "uart3";
+			};
+		};
+
+		rgmii1_pins: rgmii1 {
+			rgmii1 {
+				groups = "rgmii1";
+				function = "rgmii1";
+			};
+		};
+
+		rgmii2_pins: rgmii2 {
+			rgmii2 {
+				groups = "rgmii2";
+				function = "rgmii2";
+			};
+		};
+
+		mdio_pins: mdio {
+			mdio {
+				groups = "mdio";
+				function = "mdio";
+			};
+		};
+
+		pcie_pins: pcie {
+			pcie {
+				groups = "pcie";
+				function = "gpio";
+			};
+		};
+
+		nand_pins: nand {
+			spi-nand {
+				groups = "spi";
+				function = "nand1";
+			};
+
+			sdhci-nand {
+				groups = "sdhci";
+				function = "nand2";
+			};
+		};
+
+		sdhci_pins: sdhci {
+			sdhci {
+				groups = "sdhci";
+				function = "sdhci";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	sdhci: sdhci@1E130000 {
+		status = "disabled";
+
+		compatible = "ralink,mt7620-sdhci";
+		reg = <0x1E130000 0x4000>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdhci_pins>;
+	};
+
+	xhci: xhci@1E1C0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "mediatek,mt8173-xhci";
+		reg = <0x1e1c0000 0x1000
+		       0x1e1d0700 0x0100>;
+		reg-names = "mac", "ippc";
+
+		clocks = <&sysclock>;
+		clock-names = "sys_ck";
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 22 IRQ_TYPE_LEVEL_HIGH>;
+
+		/*
+		 * Port 1 of both hubs is one usb slot and referenced here.
+		 * The binding doesn't allow to address individual hubs.
+		 * hub 1 - port 1 is ehci and ohci, hub 2 - port 1 is xhci.
+		 */
+		xhci_ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+
+		/*
+		 * Only the second usb hub has a second port. That port serves
+		 * ehci and ohci.
+		 */
+		ehci_port2: port@2 {
+			reg = <2>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	gic: interrupt-controller@1fbc0000 {
+		compatible = "mti,gic";
+		reg = <0x1fbc0000 0x2000>;
+
+		interrupt-controller;
+		#interrupt-cells = <3>;
+
+		mti,reserved-cpu-vectors = <7>;
+
+		timer {
+			compatible = "mti,gic-timer";
+			interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>;
+			clocks = <&pll MT7621_CLK_CPU>;
+		};
+	};
+
+	nficlock: nficlock {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+
+		clock-frequency = <125000000>;
+	};
+
+	nand: nand@1e003000 {
+		status = "disabled";
+
+		compatible = "mediatek,mt7621-nfc";
+		reg = <0x1e003000 0x800
+			0x1e003800 0x800>;
+		reg-names = "nfi", "ecc";
+
+		clocks = <&nficlock>;
+		clock-names = "nfi_clk";
+	};
+
+	ethsys: syscon@1e000000 {
+		compatible = "mediatek,mt7621-ethsys",
+			     "syscon";
+		reg = <0x1e000000 0x1000>;
+		#clock-cells = <1>;
+	};
+
+	ethernet: ethernet@1e100000 {
+		compatible = "mediatek,mt7621-eth";
+		reg = <0x1e100000 0x10000>;
+
+		clocks = <&sysclock>;
+		clock-names = "ethif";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		resets = <&rstctrl 6 &rstctrl 23>;
+		reset-names = "fe", "eth";
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;
+
+		mediatek,ethsys = <&ethsys>;
+
+		gmac0: mac@0 {
+			compatible = "mediatek,eth-mac";
+			reg = <0>;
+			phy-mode = "rgmii";
+
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+				pause;
+			};
+		};
+
+		gmac1: mac@1 {
+			compatible = "mediatek,eth-mac";
+			reg = <1>;
+			status = "disabled";
+			phy-mode = "rgmii-rxid";
+		};
+
+		mdio: mdio-bus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			switch0: switch@1f {
+				compatible = "mediatek,mt7621";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0x1f>;
+				mediatek,mcm;
+				resets = <&rstctrl 2>;
+				reset-names = "mcm";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0>;
+
+					port@0 {
+						status = "disabled";
+						reg = <0>;
+						label = "lan0";
+					};
+
+					port@1 {
+						status = "disabled";
+						reg = <1>;
+						label = "lan1";
+					};
+
+					port@2 {
+						status = "disabled";
+						reg = <2>;
+						label = "lan2";
+					};
+
+					port@3 {
+						status = "disabled";
+						reg = <3>;
+						label = "lan3";
+					};
+
+					port@4 {
+						status = "disabled";
+						reg = <4>;
+						label = "lan4";
+					};
+
+					port@6 {
+						reg = <6>;
+						label = "cpu";
+						ethernet = <&gmac0>;
+						phy-mode = "rgmii";
+
+						fixed-link {
+							speed = <1000>;
+							full-duplex;
+						};
+					};
+				};
+			};
+		};
+	};
+
+	gsw: gsw@1e110000 {
+		compatible = "mediatek,mt7621-gsw";
+		reg = <0x1e110000 0x8000>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pcie: pcie@1e140000 {
+		compatible = "mediatek,mt7621-pci";
+		reg = <0x1e140000 0x100     /* host-pci bridge registers */
+			0x1e142000 0x100    /* pcie port 0 RC control registers */
+			0x1e143000 0x100    /* pcie port 1 RC control registers */
+			0x1e144000 0x100>;  /* pcie port 2 RC control registers */
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie_pins>;
+
+		device_type = "pci";
+
+		bus-range = <0 255>;
+		ranges = <
+			0x02000000 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */
+			0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */
+		>;
+
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH
+				GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH
+				GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>;
+
+		status = "disabled";
+
+		resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>;
+		reset-names = "pcie0", "pcie1", "pcie2";
+		clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>;
+		clock-names = "pcie0", "pcie1", "pcie2";
+		phys = <&pcie0_phy 1>, <&pcie2_phy 0>;
+		phy-names = "pcie-phy0", "pcie-phy2";
+
+		reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>;
+
+		pcie0: pcie@0,0 {
+			reg = <0x0000 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+			bus-range = <0x00 0xff>;
+		};
+
+		pcie1: pcie@1,0 {
+			reg = <0x0800 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+			bus-range = <0x00 0xff>;
+		};
+
+		pcie2: pcie@2,0 {
+			reg = <0x1000 0 0 0 0>;
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+			bus-range = <0x00 0xff>;
+		};
+	};
+
+	pcie0_phy: pcie-phy@1e149000 {
+		compatible = "mediatek,mt7621-pci-phy";
+		reg = <0x1e149000 0x0700>;
+		#phy-cells = <1>;
+	};
+
+	pcie2_phy: pcie-phy@1e14a000 {
+		compatible = "mediatek,mt7621-pci-phy";
+		reg = <0x1e14a000 0x0700>;
+		#phy-cells = <1>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_adslr_g7.dts b/target/linux/ramips/dts/mt7621_adslr_g7.dts
new file mode 100644
index 0000000..3290a5e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_adslr_g7.dts
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "adslr,g7", "mediatek,mt7621-soc";
+	model = "ADSLR G7";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe00c>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe00c>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_afoundry_ew1200.dts b/target/linux/ramips/dts/mt7621_afoundry_ew1200.dts
new file mode 100644
index 0000000..ed9e985
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_afoundry_ew1200.dts
@@ -0,0 +1,148 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "afoundry,ew1200", "mediatek,mt7621-soc";
+	model = "EW1200";
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = "green:run";
+			gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_alfa-network_quad-e4g.dts b/target/linux/ramips/dts/mt7621_alfa-network_quad-e4g.dts
new file mode 100644
index 0000000..e457dfc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_alfa-network_quad-e4g.dts
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,quad-e4g", "mediatek,mt7621-soc";
+	model = "ALFA Network Quad-E4G";
+
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		m2-enable {
+			gpio-export,name = "m2-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio 32 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie0-enable {
+			gpio-export,name = "minipcie0-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie0-reset {
+			gpio-export,name = "minipcie0-reset";
+			gpio-export,output = <0>;
+			gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie1-enable {
+			gpio-export,name = "minipcie1-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio 30 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie1-reset {
+			gpio-export,name = "minipcie1-reset";
+			gpio-export,output = <0>;
+			gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie2-enable {
+			gpio-export,name = "minipcie2-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio 31 GPIO_ACTIVE_HIGH>;
+		};
+
+		minipcie2-reset {
+			gpio-export,name = "minipcie2-reset";
+			gpio-export,output = <0>;
+			gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+		};
+
+		pcie-perst-disable {
+			gpio-export,name = "pcie-perst-enable";
+			gpio-export,output = <0>;
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+		};
+
+		sim-select {
+			gpio-export,name = "sim-select";
+			gpio-export,output = <1>;
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		watchdog-enable {
+			gpio-export,name = "watchdog-enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		user1 {
+			label = "user1";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		user2 {
+			label = "user2";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "red:system";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		m2 {
+			label = "orange:m2";
+			gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+		};
+
+		minipcie0 {
+			label = "orange:minipcie0";
+			gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+		};
+
+		minipcie1 {
+			label = "orange:minipcie1";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+		};
+
+		minipcie2 {
+			label = "orange:minipcie2";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	watchdog {
+		compatible = "linux,wdt-gpio";
+		gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+		hw_algo = "toggle";
+		hw_margin_ms = <25000>;
+		always-running;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	rtc@68 {
+		compatible = "ti,bq32000";
+		reg = <0x68>;
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "rgmii2", "wdt";
+		function = "gpio";
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&uartlite2 {
+	status = "okay";
+};
+
+&uartlite3 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_ampedwireless_ally-00x19k.dts b/target/linux/ramips/dts/mt7621_ampedwireless_ally-00x19k.dts
new file mode 100644
index 0000000..51d41c7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ampedwireless_ally-00x19k.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_ampedwireless_ally.dtsi"
+
+/ {
+	compatible = "ampedwireless,ally-00x19k", "mediatek,mt7621-soc";
+	model = "Amped Wireless ALLY-00X19K";
+};
+
+&switch0 {
+	ports {
+		port@2 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_ampedwireless_ally-r1900k.dts b/target/linux/ramips/dts/mt7621_ampedwireless_ally-r1900k.dts
new file mode 100644
index 0000000..cd2536e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ampedwireless_ally-r1900k.dts
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_ampedwireless_ally.dtsi"
+
+/ {
+	compatible = "ampedwireless,ally-r1900k", "mediatek,mt7621-soc";
+	model = "Amped Wireless ALLY-R1900K";
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan3";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_ampedwireless_ally.dtsi b/target/linux/ramips/dts/mt7621_ampedwireless_ally.dtsi
new file mode 100644
index 0000000..7736b06
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ampedwireless_ally.dtsi
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_status_amber;
+		led-failsafe = &led_status_amber;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_red;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		led_switch {
+			label = "led_switch";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+			linux,input-type = <EV_SW>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_green: status_green {
+			label = "green:status";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_amber: status_amber {
+			label = "amber:status";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7615";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7615";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "u-boot-env";
+			reg = <0x80000 0x80000>;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		/*
+		 * uboot expects to find kernels at 0x140000 & 0x2140000,
+		 * referred to as Uimage & Uimage1 in factory FW, respectively.
+		 * U-boot variable 'bootImage' controls which is booted;
+		 * 0 for the first, 1 for the 2nd.
+		 * There's a 3rd partition, Uimage2 (0x4140000), which
+		 * I expected to be a recovery image, but is actually blank.
+		 *
+		 * A kernel is considered suitable for handing control over
+		 * if its linux magic number exists & uImage CRC are correct.
+		 * If either of those conditions fail, 'bootImage' value
+		 * is toggled in uboot env & a restart performed in the hope that the
+		 * alternate kernel is okay.
+		 *
+		 * Note uboot's tftp flash install writes the transferred
+		 * image to the active kernel partition.
+		 */
+
+		partition@140000 {
+			label = "kernel";
+			reg = <0x140000 0x400000>;
+		};
+
+		partition@540000 {
+			label = "ubi";
+			reg = <0x540000 0x1c00000>;
+		};
+
+		partition@2140000 {
+			label = "oem";
+			reg = <0x2140000 0x2000000>;
+		};
+
+		partition@4140000 {
+			label = "backup";
+			reg = <0x4140000 0x2000000>;
+		};
+
+		partition@6140000 {
+			label = "chime";
+			reg = <0x6140000 0xa00000>;
+		};
+
+		partition@6b40000 {
+			label = "data";
+			reg = <0x6b40000 0xa00000>;
+		};
+
+		partition@7540000 {
+			label = "reserved";
+			reg = <0x7540000 0x840000>;
+			read-only;
+		};
+
+		partition@7d80000 {
+			label = "nvram";
+			reg = <0x7d80000 0x100000>;
+			read-only;
+		};
+
+		partition@7e80000 {
+			label = "hwconfig";
+			reg = <0x7e80000 0x100000>;
+			read-only;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asiarf_ap7621-001.dts b/target/linux/ramips/dts/mt7621_asiarf_ap7621-001.dts
new file mode 100644
index 0000000..cf91dc0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asiarf_ap7621-001.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_asiarf_ap7621.dtsi"
+
+/ {
+	compatible = "asiarf,ap7621-001", "mediatek,mt7621-soc";
+	model = "AsiaRF AP7621-001";
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asiarf_ap7621-nv1.dts b/target/linux/ramips/dts/mt7621_asiarf_ap7621-nv1.dts
new file mode 100644
index 0000000..5a4c03f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asiarf_ap7621-nv1.dts
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_asiarf_ap7621.dtsi"
+
+/ {
+	compatible = "asiarf,ap7621-nv1", "mediatek,mt7621-soc";
+	model = "AsiaRF AP7621-NV1";
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asiarf_ap7621.dtsi b/target/linux/ramips/dts/mt7621_asiarf_ap7621.dtsi
new file mode 100644
index 0000000..b011c7a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asiarf_ap7621.dtsi
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan1 {
+			label = "orange:wlan1";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan0 {
+			label = "orange:wlan0";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x2000>;
+			};
+
+			partition@32000 {
+				label = "2860";
+				reg = <0x32000 0x4000>;
+			};
+
+			partition@36000 {
+				label = "rtdev";
+				reg = <0x36000 0x2000>;
+			};
+
+			partition@38000 {
+				label = "Reserve";
+				reg = <0x38000 0x8000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "firmware";
+				reg = <0x50000 0xfa0000>;
+				compatible = "denx,uimage";
+			};
+
+			partition@ff0000 {
+				label = "nvram";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asus_rt-ac57u.dts b/target/linux/ramips/dts/mt7621_asus_rt-ac57u.dts
new file mode 100644
index 0000000..dcf5cea
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asus_rt-ac57u.dts
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-ac57u", "mediatek,mt7621-soc";
+	model = "ASUS RT-AC57U";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 48 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+			debounce-interval = <60>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+			debounce-interval = <60>;
+		};
+	};
+
+	led-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "LED-Power";
+		gpio = <&gpio 46 GPIO_ACTIVE_LOW>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "sdhci";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asus_rt-ac65p.dts b/target/linux/ramips/dts/mt7621_asus_rt-ac65p.dts
new file mode 100644
index 0000000..9be178e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asus_rt-ac65p.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_asus_rt-acx5p.dtsi"
+
+/ {
+	compatible = "asus,rt-ac65p", "mediatek,mt7621-soc";
+	model = "ASUS RT-AC65P";
+};
diff --git a/target/linux/ramips/dts/mt7621_asus_rt-ac85p.dts b/target/linux/ramips/dts/mt7621_asus_rt-ac85p.dts
new file mode 100644
index 0000000..cc8e0c2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asus_rt-ac85p.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_asus_rt-acx5p.dtsi"
+
+/ {
+	compatible = "asus,rt-ac85p", "mediatek,mt7621-soc";
+	model = "ASUS RT-AC85P";
+};
diff --git a/target/linux/ramips/dts/mt7621_asus_rt-acx5p.dtsi b/target/linux/ramips/dts/mt7621_asus_rt-acx5p.dtsi
new file mode 100644
index 0000000..b5e8655
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asus_rt-acx5p.dtsi
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1radio";
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0xe0000>;
+			read-only;
+		};
+
+		partition@e0000 {
+			label = "u-boot-env";
+			reg = <0xe0000 0x100000>;
+			read-only;
+		};
+
+		factory: partition@1e0000 {
+			label = "factory";
+			reg = <0x1e0000 0x100000>;
+			read-only;
+		};
+
+		factory2: partition@2e0000 {
+			label = "factory2";
+			reg = <0x2e0000 0x100000>;
+			read-only;
+		};
+
+		partition@3e0000 {
+			label = "kernel";
+			reg = <0x3e0000 0x400000>;
+		};
+
+		partition@7e0000 {
+			label = "ubi";
+			reg = <0x7e0000 0x2e00000>;
+		};
+
+		partition@35e0000 {
+			label = "firmware2";
+			reg = <0x35e0000 0x3200000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi0: wifi@0,0 {
+		compatible = "pci14c3,7615";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi1: wifi@0,0 {
+		compatible = "pci14c3,7615";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_asus_rt-n56u-b1.dts b/target/linux/ramips/dts/mt7621_asus_rt-n56u-b1.dts
new file mode 100644
index 0000000..b78e594
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_asus_rt-n56u-b1.dts
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n56u-b1", "mediatek,mt7621-soc";
+	model = "ASUS RT-N56U B1";
+
+	aliases {
+		label-mac-device = &wan;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+			debounce-interval = <60>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+			debounce-interval = <60>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x8004>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_buffalo_wsr-1166dhp.dts b/target/linux/ramips/dts/mt7621_buffalo_wsr-1166dhp.dts
new file mode 100644
index 0000000..f921146
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_buffalo_wsr-1166dhp.dts
@@ -0,0 +1,212 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,wsr-1166dhp", "mediatek,mt7621-soc";
+	model = "Buffalo WSR-1166DHP";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet_g {
+			label = "green:internet";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		router_g {
+			label = "green:router";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		router_o {
+			label = "orange:router";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_o {
+			label = "orange:internet";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_o {
+			label = "orange:wifi";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		diag {
+			label = "orange:diag";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_g {
+			label = "green:wifi";
+			gpios = <&gpio 48 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		power {
+			label = "power";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		auto {
+			label = "mode";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		router {
+			label = "router";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,trx";
+				label = "firmware";
+				reg = <0x50000 0xf90000>;
+			};
+
+			partition@fe0000 {
+				label = "board_data";
+				reg = <0xfe0000 0x20000>;
+			};
+		};
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "rgmii2", "sdhci";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_buffalo_wsr-2533dhpl.dts b/target/linux/ramips/dts/mt7621_buffalo_wsr-2533dhpl.dts
new file mode 100644
index 0000000..048eac5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_buffalo_wsr-2533dhpl.dts
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,wsr-2533dhpl", "mediatek,mt7621-soc";
+	model = "Buffalo WSR-2533DHPL";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_diag;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet_green {
+			label = "green:internet";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		router_green {
+			label = "green:router";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		router_amber {
+			label = "amber:router";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_amber {
+			label = "amber:internet";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless_amber {
+			label = "amber:wireless";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		led_diag: diag {
+			label = "amber:diag";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless_green {
+			label = "green:wireless";
+			gpios = <&gpio 48 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		auto {
+			label = "auto";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		bridge {
+			label = "wb";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+
+		router {
+			label = "router";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+
+		power {
+			label = "power";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_POWER>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,trx";
+				label = "firmware";
+				reg = <0x50000 0x7c0000>;
+			};
+
+			partition@810000 {
+				label = "Kernel2";
+				reg = <0x810000 0x7c0000>;
+				read-only;
+			};
+
+			partition@fd0000 {
+				label = "glbcfg";
+				reg = <0xfd0000 0x010000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "board_data";
+				reg = <0xfe0000 0x20000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <(-1)>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "wdt", "sdhci";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_buffalo_wsr-600dhp.dts b/target/linux/ramips/dts/mt7621_buffalo_wsr-600dhp.dts
new file mode 100644
index 0000000..7392b1d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_buffalo_wsr-600dhp.dts
@@ -0,0 +1,210 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,wsr-600dhp", "mediatek,mt7621-soc";
+	model = "Buffalo WSR-600DHP";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_o {
+			label = "orange:wifi";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		diag {
+			label = "orange:diag";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi_g {
+			label = "green:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		router_o {
+			label = "orange:router";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+
+		router_g {
+			label = "green:router";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_o {
+			label = "orange:internet";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_g {
+			label = "green:internet";
+			gpios = <&gpio 48 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		power {
+			label = "power";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		auto {
+			label = "mode";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		router {
+			label = "router";
+			gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "rgmii2", "sdhci";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	rt5592@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_cudy_wr1300.dts b/target/linux/ramips/dts/mt7621_cudy_wr1300.dts
new file mode 100644
index 0000000..a66ce94
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_cudy_wr1300.dts
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "cudy,wr1300", "mediatek,mt7621-soc";
+	model = "Cudy WR1300";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "green:sys";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@fd0000 {
+				label = "debug";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "backup";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			bdinfo: partition@ff0000 {
+				label = "bdinfo";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		mtd-mac-address = <&bdinfo 0xde00>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mtd-mac-address = <&bdinfo 0xde00>;
+		mtd-mac-address-increment = <2>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&bdinfo 0xde00>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&bdinfo 0xde00>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "i2c", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_cudy_wr2100.dts b/target/linux/ramips/dts/mt7621_cudy_wr2100.dts
new file mode 100644
index 0000000..692c94d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_cudy_wr2100.dts
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "cudy,wr2100", "mediatek,mt7621-soc";
+	model = "Cudy WR2100";
+
+	aliases {
+		led-boot = &led_internet_blue;
+		led-failsafe = &led_internet_blue;
+		led-running = &led_internet_blue;
+		led-upgrade = &led_internet_blue;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_internet_blue: internet_blue {
+			label = "blue:internet";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_red {
+			label = "red:internet";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1 {
+			label = "green:lan1";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "green:lan2";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3 {
+			label = "green:lan3";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4 {
+			label = "green:lan4";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&bdinfo 0xde00>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@1,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@fd0000 {
+				label = "debug";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "backup";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			bdinfo: partition@ff0000 {
+				label = "bdinfo";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+
+			mtd-mac-address = <&bdinfo 0xde00>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_d-team_newifi-d2.dts b/target/linux/ramips/dts/mt7621_d-team_newifi-d2.dts
new file mode 100644
index 0000000..5622855
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_d-team_newifi-d2.dts
@@ -0,0 +1,190 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "d-team,newifi-d2", "mediatek,mt7621-soc";
+	model = "Newifi-D2";
+
+	aliases {
+		led-boot = &led_power_blue;
+		led-failsafe = &led_power_blue;
+		led-running = &led_power_blue;
+		led-upgrade = &led_power_blue;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power-amber {
+			label = "amber:power";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_blue: power-blue {
+			label = "blue:power";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		internet-amber {
+			label = "amber:internet";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		internet-blue {
+			label = "blue:internet";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_usb3 {
+			gpio-export,name = "power_usb3";
+			gpio-export,output = <1>;
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <45000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uart2", "uart3";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_d-team_pbr-m1.dts b/target/linux/ramips/dts/mt7621_d-team_pbr-m1.dts
new file mode 100644
index 0000000..2fcdce5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_d-team_pbr-m1.dts
@@ -0,0 +1,216 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "d-team,pbr-m1", "mediatek,mt7621-soc";
+	model = "PBR-M1";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "blue:power";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_usb2 {
+			gpio-export,name = "power_usb2";
+			gpio-export,output = <1>;
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_usb3 {
+			gpio-export,name = "power_usb3";
+			gpio-export,output = <1>;
+			gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_sata {
+			gpio-export,name = "power_sata";
+			gpio-export,output = <1>;
+			gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	beeper: beeper {
+		compatible = "gpio-beeper";
+		gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	rtc@51 {
+		status = "okay";
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pinctrl {
+	uart3_gpio: uart3-gpio {
+		uart3 {
+			groups = "uart3";
+			function = "gpio";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+	pinctrl-0 = <&pcie_pins>, <&uart3_gpio>;
+	reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>,
+		      <&gpio 7 GPIO_ACTIVE_LOW>;
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-1960-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-1960-a1.dts
new file mode 100644
index 0000000..0f4fbc1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-1960-a1.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-xx60-a1.dtsi"
+
+/ {
+	compatible = "dlink,dir-1960-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-1960 A1";
+};
+
+&leds {
+	usb_white {
+		label = "white:usb";
+		gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&xhci_ehci_port1>;
+		linux,default-trigger = "usbport";
+	};
+};
+
+&wifi0 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <1>;
+};
+
+&wifi1 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <2>;
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-2640-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-2640-a1.dts
new file mode 100644
index 0000000..323a790
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-2640-a1.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-xx60-a1.dtsi"
+
+/ {
+	compatible = "dlink,dir-2640-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-2640 A1";
+};
+
+&leds {
+	usb2_white {
+		label = "white:usb2";
+		gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&ehci_port2>;
+		linux,default-trigger = "usbport";
+	};
+
+	usb3_white {
+		label = "white:usb3";
+		gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&xhci_ehci_port1>;
+		linux,default-trigger = "usbport";
+	};
+};
+
+&wifi0 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <1>;
+};
+
+&wifi1 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <2>;
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-2660-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-2660-a1.dts
new file mode 100644
index 0000000..fbf233d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-2660-a1.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-xx60-a1.dtsi"
+
+/ {
+	compatible = "dlink,dir-2660-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-2660 A1";
+};
+
+&leds {
+	usb2_white {
+		label = "white:usb2";
+		gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&ehci_port2>;
+		linux,default-trigger = "usbport";
+	};
+
+	usb3_white {
+		label = "white:usb3";
+		gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&xhci_ehci_port1>;
+		linux,default-trigger = "usbport";
+	};
+};
+
+&wifi0 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <1>;
+};
+
+&wifi1 {
+	mtd-mac-address = <&factory 0xe000>;
+	mtd-mac-address-increment = <2>;
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-860l-b1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-860l-b1.dts
new file mode 100644
index 0000000..f843f62
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-860l-b1.dts
@@ -0,0 +1,172 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-860l-b1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-860L B1";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "orange:power";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power2 {
+			label = "green:power";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		net {
+			label = "orange:net";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		net2 {
+			label = "green:net";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x4000>;
+				read-only;
+			};
+
+			radio: partition@34000 {
+				label = "radio";
+				reg = <0x34000 0x4000>;
+				read-only;
+			};
+
+			factory: partition@38000 {
+				label = "factory";
+				reg = <0x38000 0x8000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "defaults";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "seama";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&radio 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+
+	reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>,
+		      <&gpio 8 GPIO_ACTIVE_LOW>;
+};
+
+&pcie0 {
+	wifi0: mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x2000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi1: mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-867-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-867-a1.dts
new file mode 100644
index 0000000..b2ba5ec
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-867-a1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-a1.dtsi"
+
+/ {
+	compatible = "dlink,dir-867-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-867 A1";
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-878-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-878-a1.dts
new file mode 100644
index 0000000..4bfe5ca
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-878-a1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-a1.dtsi"
+
+/ {
+	compatible = "dlink,dir-878-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-878 A1";
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-882-a1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-882-a1.dts
new file mode 100644
index 0000000..cef0705
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-882-a1.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-a1.dtsi"
+#include "mt7621_dlink_dir-882-x1.dtsi"
+
+/ {
+	compatible = "dlink,dir-882-a1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-882 A1";
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-882-r1.dts b/target/linux/ramips/dts/mt7621_dlink_dir-882-r1.dts
new file mode 100644
index 0000000..26b6f34
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-882-r1.dts
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-r1.dtsi"
+#include "mt7621_dlink_dir-882-x1.dtsi"
+
+/ {
+	compatible = "dlink,dir-882-r1", "mediatek,mt7621-soc";
+	model = "D-Link DIR-882 R1";
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-882-x1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-882-x1.dtsi
new file mode 100644
index 0000000..cafb1df
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-882-x1.dtsi
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+&leds {
+	usb2 {
+		label = "green:usb2";
+		gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&ehci_port2>;
+		linux,default-trigger = "usbport";
+	};
+
+	usb3 {
+		label = "green:usb3";
+		gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		trigger-sources = <&xhci_ehci_port1>;
+		linux,default-trigger = "usbport";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi
new file mode 100644
index 0000000..95ef0af
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-a1.dtsi
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-x1.dtsi"
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			partition@60000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,padding = <96>;
+				label = "firmware";
+				reg = <0x60000 0xfa0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-8xx-r1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-r1.dtsi
new file mode 100644
index 0000000..e93a06d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-r1.dtsi
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_dlink_dir-8xx-x1.dtsi"
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-8xx-x1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-x1.dtsi
new file mode 100644
index 0000000..7ab0e8b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-8xx-x1.dtsi
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power_orange;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_net_orange;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		wifi {
+			label = "wifi";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		led_power_orange: power_orange {
+			label = "orange:power";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		led_net_orange: net_orange {
+			label = "orange:net";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		net_green {
+			label = "green:net";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi b/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi
new file mode 100644
index 0000000..a54b2be
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power_orange;
+		led-failsafe = &led_power_white;
+		led-running = &led_power_white;
+		led-upgrade = &led_net_orange;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		led_power_orange: power_orange {
+			label = "orange:power";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_white: power_white {
+			label = "white:power";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		led_net_orange: net_orange {
+			label = "orange:net";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		net_white {
+			label = "white:net";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "config";
+			reg = <0x80000 0x80000>;
+			read-only;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		partition@140000 {
+			label = "config2";
+			reg = <0x140000 0x40000>;
+			read-only;
+		};
+
+		partition@180000 {
+			label = "firmware";
+			compatible = "openwrt,uimage", "denx,uimage";
+			openwrt,padding = <96>;
+			reg = <0x180000 0x2800000>;
+		};
+
+		partition@2980000 {
+			label = "private";
+			reg = <0x2980000 0x2000000>;
+			read-only;
+		};
+
+		partition@4980000 {
+			label = "firmware2";
+			compatible = "openwrt,uimage", "denx,uimage";
+			openwrt,padding = <96>;
+			reg = <0x4980000 0x2800000>;
+		};
+
+		partition@7180000 {
+			label = "mydlink";
+			reg = <0x7180000 0x600000>;
+			read-only;
+		};
+
+		partition@7780000 {
+			label = "reserved";
+			reg = <0x7780000 0x880000>;
+			read-only;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi0: wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi1: wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_edimax_ra21s.dts b/target/linux/ramips/dts/mt7621_edimax_ra21s.dts
new file mode 100644
index 0000000..1aea949
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_edimax_ra21s.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_edimax_rx21s.dtsi"
+
+/ {
+	compatible = "edimax,ra21s", "mediatek,mt7621-soc";
+	model = "Edimax RA21S";
+};
diff --git a/target/linux/ramips/dts/mt7621_edimax_re23s.dts b/target/linux/ramips/dts/mt7621_edimax_re23s.dts
new file mode 100644
index 0000000..9b96573
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_edimax_re23s.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,re23s", "mediatek,mt7621-soc";
+	model = "Edimax RE23S";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_wifi_red;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		wifi_green {
+			label = "green:wifi";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		wifi_amber {
+			label = "amber:wifi";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_wifi_red: wifi_red {
+			label = "red:wifi";
+			gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "cimage";
+				reg = <0x50000 0x20000>;
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x70000 0xf50000>;
+			};
+
+			partition@fc0000 {
+				label = "freespace";
+				reg = <0xfc0000 0x40000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x8004>;
+};
+
+&switch0 {
+	ports {
+		port@4 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_edimax_rg21s.dts b/target/linux/ramips/dts/mt7621_edimax_rg21s.dts
new file mode 100644
index 0000000..6ac01dd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_edimax_rg21s.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_edimax_rx21s.dtsi"
+
+/ {
+	compatible = "edimax,rg21s", "mediatek,mt7621-soc";
+	model = "Edimax RG21S";
+};
diff --git a/target/linux/ramips/dts/mt7621_edimax_rx21s.dtsi b/target/linux/ramips/dts/mt7621_edimax_rx21s.dtsi
new file mode 100644
index 0000000..3f3bae4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_edimax_rx21s.dtsi
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: led_1 {
+			label = "red:led1";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_2 {
+			label = "red:led2";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_3 {
+			label = "red:led3";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_4 {
+			label = "red:led4";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi0: wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi1: wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1167ghbk2-s.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1167ghbk2-s.dts
new file mode 100644
index 0000000..b6a7383
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1167ghbk2-s.dts
@@ -0,0 +1,178 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "elecom,wrc-1167ghbk2-s", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1167GHBK2-S";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan2g {
+			label = "white:wlan2g";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan5g {
+			label = "white:wlan5g";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_blue {
+			label = "blue:power";
+			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps {
+			label = "red:wps";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_red {
+			label = "red:power";
+			gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf20000>;
+			};
+
+			partition@f70000 {
+				label = "user_data";
+				reg = <0xf70000 0x80000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "NVRAM";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		mtd-mac-address = <&factory 0xe000>;
+		mtd-mac-address-increment = <1>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1167gs2-b.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1167gs2-b.dts
new file mode 100644
index 0000000..6349fd4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1167gs2-b.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-1pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1167gs2-b", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1167GS2-B";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xfff4>;
+};
+
+&wan {
+	mtd-mac-address = <&factory 0xfffa>;
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0xb00000>;
+	};
+
+	partition@b50000 {
+		label = "tm_pattern";
+		reg = <0xb50000 0x380000>;
+		read-only;
+	};
+
+	partition@ed0000 {
+		label = "tm_key";
+		reg = <0xed0000 0x80000>;
+		read-only;
+	};
+
+	partition@f50000 {
+		label = "nvram";
+		reg = <0xf50000 0x30000>;
+		read-only;
+	};
+
+	partition@f80000 {
+		label = "user_data";
+		reg = <0xf80000 0x80000>;
+		read-only;
+	};
+};
+
+&wifi {
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <(-1)>;
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1167gst2.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1167gst2.dts
new file mode 100644
index 0000000..11b7824
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1167gst2.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-1pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1167gst2", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1167GST2";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&wan {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0x1800000>;
+	};
+
+	partition@1850000 {
+		label = "tm_pattern";
+		reg = <0x1850000 0x400000>;
+		read-only;
+	};
+
+	partition@1c50000 {
+		label = "tm_key";
+		reg = <0x1c50000 0x100000>;
+		read-only;
+	};
+
+	partition@1d50000 {
+		label = "nvram";
+		reg = <0x1d50000 0xb0000>;
+		read-only;
+	};
+
+	partition@1e00000 {
+		label = "user_data";
+		reg = <0x1e00000 0x200000>;
+		read-only;
+	};
+};
+
+&wifi {
+	mtd-mac-address = <&factory 0xe006>;
+	mtd-mac-address-increment = <1>;
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1750gs.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gs.dts
new file mode 100644
index 0000000..71e4c16
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gs.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1750gs", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1750GS";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0xb00000>;
+	};
+
+	partition@b50000 {
+		label = "tm_pattern";
+		reg = <0xb50000 0x380000>;
+		read-only;
+	};
+
+	partition@ed0000 {
+		label = "tm_key";
+		reg = <0xed0000 0x80000>;
+		read-only;
+	};
+
+	partition@f50000 {
+		label = "art_block";
+		reg = <0xf50000 0x30000>;
+		read-only;
+	};
+
+	partition@f80000 {
+		label = "user_data";
+		reg = <0xf80000 0x80000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1750gst2.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gst2.dts
new file mode 100644
index 0000000..4b8888c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gst2.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1750gst2", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1750GST2";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0x1800000>;
+	};
+
+	partition@1850000 {
+		label = "tm_pattern";
+		reg = <0x1850000 0x400000>;
+		read-only;
+	};
+
+	partition@1c50000 {
+		label = "tm_key";
+		reg = <0x1c50000 0x100000>;
+		read-only;
+	};
+
+	partition@1d50000 {
+		label = "nvram";
+		reg = <0x1d50000 0xb0000>;
+		read-only;
+	};
+
+	partition@1e00000 {
+		label = "user_data";
+		reg = <0x1e00000 0x200000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1750gsv.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gsv.dts
new file mode 100644
index 0000000..6719c34
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1750gsv.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1750gsv", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1750GSV";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0xb00000>;
+	};
+
+	partition@b50000 {
+		label = "tm_pattern";
+		reg = <0xb50000 0x380000>;
+		read-only;
+	};
+
+	partition@ed0000 {
+		label = "tm_key";
+		reg = <0xed0000 0x80000>;
+		read-only;
+	};
+
+	partition@f50000 {
+		label = "nvram";
+		reg = <0xf50000 0x30000>;
+		read-only;
+	};
+
+	partition@f80000 {
+		label = "user_data";
+		reg = <0xf80000 0x80000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-1900gst.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-1900gst.dts
new file mode 100644
index 0000000..675e086
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-1900gst.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-1900gst", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-1900GST";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0xb00000>;
+	};
+
+	partition@b50000 {
+		label = "tm_pattern";
+		reg = <0xb50000 0x380000>;
+		read-only;
+	};
+
+	partition@ed0000 {
+		label = "tm_key";
+		reg = <0xed0000 0x80000>;
+		read-only;
+	};
+
+	partition@f50000 {
+		label = "art_block";
+		reg = <0xf50000 0x30000>;
+		read-only;
+	};
+
+	partition@f80000 {
+		label = "user_data";
+		reg = <0xf80000 0x80000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-2533ghbk-i.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-2533ghbk-i.dts
new file mode 100644
index 0000000..a5436d5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-2533ghbk-i.dts
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "elecom,wrc-2533ghbk-i", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-2533GHBK-I";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "red:wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan2g {
+			label = "white:wlan2g";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan5g {
+			label = "white:wlan5g";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy1radio";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		auto {
+			label = "auto";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x9a0000>;
+			};
+
+			partition@9f0000 {
+				label = "TM_1";
+				reg = <0x9f0000 0x200000>;
+				read-only;
+			};
+
+			partition@bf0000 {
+				label = "TM_2";
+				reg = <0xbf0000 0x200000>;
+				read-only;
+			};
+
+			partition@df0000 {
+				label = "manufacture";
+				reg = <0xdf0000 0x180000>;
+				read-only;
+			};
+
+			partition@f70000 {
+				label = "backup";
+				reg = <0xf70000 0x10000>;
+				read-only;
+			};
+
+			partition@f80000 {
+				label = "storage";
+				reg = <0xf80000 0x80000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst.dts
new file mode 100644
index 0000000..dacd540
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst.dts
@@ -0,0 +1,38 @@
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-2533gst", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-2533GST";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0xb00000>;
+	};
+
+	partition@b50000 {
+		label = "tm_pattern";
+		reg = <0xb50000 0x380000>;
+		read-only;
+	};
+
+	partition@ed0000 {
+		label = "tm_key";
+		reg = <0xed0000 0x80000>;
+		read-only;
+	};
+
+	partition@f50000 {
+		label = "art_block";
+		reg = <0xf50000 0x30000>;
+		read-only;
+	};
+
+	partition@f80000 {
+		label = "user_data";
+		reg = <0xf80000 0x80000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst2.dts b/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst2.dts
new file mode 100644
index 0000000..a998b61
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-2533gst2.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_elecom_wrc-gs-2pci.dtsi"
+
+/ {
+	compatible = "elecom,wrc-2533gst2", "mediatek,mt7621-soc";
+	model = "ELECOM WRC-2533GST2";
+};
+
+&partitions {
+	partition@50000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x50000 0x1800000>;
+	};
+
+	partition@1850000 {
+		label = "tm_pattern";
+		reg = <0x1850000 0x400000>;
+		read-only;
+	};
+
+	partition@1c50000 {
+		label = "tm_key";
+		reg = <0x1c50000 0x100000>;
+		read-only;
+	};
+
+	partition@1d50000 {
+		label = "nvram";
+		reg = <0x1d50000 0xb0000>;
+		read-only;
+	};
+
+	partition@1e00000 {
+		label = "user_data";
+		reg = <0x1e00000 0x200000>;
+		read-only;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-gs-1pci.dtsi b/target/linux/ramips/dts/mt7621_elecom_wrc-gs-1pci.dtsi
new file mode 100644
index 0000000..7495453
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-gs-1pci.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_elecom_wrc-gs.dtsi"
+
+&leds {
+	wlan2g {
+		label = "white:wlan2g";
+		gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+	};
+
+	wlan5g {
+		label = "white:wlan5g";
+		gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt", "sdhci";
+		function = "gpio";
+	};
+};
+
+&pcie0 {
+	wifi: wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-gs-2pci.dtsi b/target/linux/ramips/dts/mt7621_elecom_wrc-gs-2pci.dtsi
new file mode 100644
index 0000000..642724d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-gs-2pci.dtsi
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_elecom_wrc-gs.dtsi"
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&wan {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "jtag", "wdt", "sdhci";
+		function = "gpio";
+	};
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-sources = <0>;
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <0>;
+			led-active-low;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_elecom_wrc-gs.dtsi b/target/linux/ramips/dts/mt7621_elecom_wrc-gs.dtsi
new file mode 100644
index 0000000..9cf2b66
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_elecom_wrc-gs.dtsi
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+		label-mac-device = &wan;
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_blue {
+			label = "blue:power";
+			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps {
+			label = "red:wps";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_red {
+			label = "red:power";
+			gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		client {
+			label = "client";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		extender {
+			label = "extender";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		router {
+			label = "router";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&switch0 {
+	ports {
+		wan: port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_firefly_firewrt.dts b/target/linux/ramips/dts/mt7621_firefly_firewrt.dts
new file mode 100644
index 0000000..62423f0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_firefly_firewrt.dts
@@ -0,0 +1,147 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "firefly,firewrt", "mediatek,mt7621-soc";
+	model = "Firefly FireWRT";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		power {
+			label = "power";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_gehua_ghl-r-001.dts b/target/linux/ramips/dts/mt7621_gehua_ghl-r-001.dts
new file mode 100644
index 0000000..e7b19fa
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_gehua_ghl-r-001.dts
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "gehua,ghl-r-001", "mediatek,mt7621-soc";
+	model = "GeHua GHL-R-001";
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&uartlite3 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+		broken-flash-reset;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts b/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts
new file mode 100644
index 0000000..e805454
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_glinet_gl-mt1300.dts
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "glinet,gl-mt1300", "mediatek,mt7621-soc";
+	model = "GL.iNet GL-MT1300";
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+		label-mac-device = &wan;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		switch {
+			label = "switch";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = "blue:run";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		system {
+			label = "white:system";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4000>;
+	mtd-mac-address-increment = <1>;
+};
+
+&switch0 {
+	ports {
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4000>;
+		};
+	};
+};
+
+&uartlite3 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		group = "wdt", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_gnubee_gb-pc1.dts b/target/linux/ramips/dts/mt7621_gnubee_gb-pc1.dts
new file mode 100644
index 0000000..5910f11
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_gnubee_gb-pc1.dts
@@ -0,0 +1,116 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "gnubee,gb-pc1", "mediatek,mt7621-soc";
+	model = "GB-PC1";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "green:power";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-on";
+		};
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "ethblack";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "ethblue";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_gnubee_gb-pc2.dts b/target/linux/ramips/dts/mt7621_gnubee_gb-pc2.dts
new file mode 100644
index 0000000..e27c4e4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_gnubee_gb-pc2.dts
@@ -0,0 +1,151 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "gnubee,gb-pc2", "mediatek,mt7621-soc";
+	model = "GB-PC2";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		ethblack-green {
+			label = "green:ethblack";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+
+		ethblue-green {
+			label = "green:ethblue";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		ethyellow-green {
+			label = "green:ethyellow";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		ethyellow-orange {
+			label = "orange:ethyellow";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "green:power";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-on";
+		};
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "disk-activity";
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&gmac1 {
+	status = "okay";
+	label = "ethyellow";
+	phy-handle = <&ethphy5>;
+
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&mdio {
+	ethphy5: ethernet-phy@5 {
+		reg = <5>;
+		phy-mode = "rgmii-rxid";
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "ethblack";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "ethblue";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_hiwifi_hc5962.dts b/target/linux/ramips/dts/mt7621_hiwifi_hc5962.dts
new file mode 100644
index 0000000..774fb93
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_hiwifi_hc5962.dts
@@ -0,0 +1,161 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hiwifi,hc5962", "mediatek,mt7621-soc";
+	model = "HiWiFi HC5962";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "white:status";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_system: system {
+			label = "red:system";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			panic-indicator;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	ubi-concat {
+		compatible = "mtd-concat";
+		devices = <&ubiconcat0 &ubiconcat1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ubi";
+				reg = <0x0 0x79c0000>;
+			};
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "debug";
+			reg = <0x80000 0x80000>;
+			read-only;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		partition@140000 {
+			label = "kernel";
+			reg = <0x140000 0x400000>;
+		};
+
+		ubiconcat0: partition@540000 {
+			label = "ubiconcat0";
+			reg = <0x540000 0x1c80000>;
+		};
+
+		partition@21c0000 {
+			label = "bdinfo";
+			reg = <0x21c0000 0x80000>;
+			read-only;
+		};
+
+		ubiconcat1: partition@2240000 {
+			label = "ubiconcat1";
+			reg = <0x2240000 0x5d40000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr.dts b/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr.dts
new file mode 100644
index 0000000..879fb68
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr.dts
@@ -0,0 +1,193 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wn-ax1167gr", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-AX1167GR";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		auto {
+			label = "auto";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		custom {
+			label = "custom";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "Bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "Config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			iNIC_rf: partition@50000 {
+				label = "iNIC_rf";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x60000 0xf30000>;
+			};
+
+			partition@f90000 {
+				label = "Key";
+				reg = <0xf90000 0x10000>;
+				read-only;
+			};
+
+			partition@fa0000 {
+				label = "backup";
+				reg = <0xfa0000 0x10000>;
+				read-only;
+			};
+
+			partition@fb0000 {
+				label = "storage";
+				reg = <0xfb0000 0x50000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&iNIC_rf 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&iNIC_rf 0x0>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr2.dts b/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr2.dts
new file mode 100644
index 0000000..8e778ce
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-ax1167gr2.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_iodata_wn-xx-xr.dtsi"
+
+/ {
+	compatible = "iodata,wn-ax1167gr2", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-AX1167GR2";
+};
+
+&partitions {
+	partition@6b00000 {
+		label = "Backup";
+		reg = <0x6b00000 0x1480000>;
+		read-only;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-ax2033gr.dts b/target/linux/ramips/dts/mt7621_iodata_wn-ax2033gr.dts
new file mode 100644
index 0000000..eb69086
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-ax2033gr.dts
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_iodata_wn-xx-xr.dtsi"
+
+/ {
+	compatible = "iodata,wn-ax2033gr", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-AX2033GR";
+};
+
+&partitions {
+	partition@6b00000 {
+		label = "Backup";
+		reg = <0x6b00000 0x1480000>;
+		read-only;
+	};
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2483000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 5710000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-dx1167r.dts b/target/linux/ramips/dts/mt7621_iodata_wn-dx1167r.dts
new file mode 100644
index 0000000..4492f43
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-dx1167r.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_iodata_wn-xx-xr.dtsi"
+
+/ {
+	compatible = "iodata,wn-dx1167r", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-DX1167R";
+};
+
+&partitions {
+	partition@6b00000 {
+		label = "idmkey";
+		reg = <0x6b00000 0x0100000>;
+		read-only;
+	};
+
+	partition@6c00000 {
+		label = "Backup";
+		reg = <0x6c00000 0x1380000>;
+		read-only;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-dx1200gr.dts b/target/linux/ramips/dts/mt7621_iodata_wn-dx1200gr.dts
new file mode 100644
index 0000000..055c1ab
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-dx1200gr.dts
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wn-dx1200gr", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-DX1200GR";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &wan;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		repeater {
+			label = "repeater";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "u-boot-env";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		factory: partition@200000 {
+			label = "factory";
+			reg = <0x200000 0x200000>;
+		};
+
+		partition@400000 {
+			label = "kernel";
+			reg = <0x400000 0x400000>;
+		};
+
+		partition@800000 {
+			label = "ubi";
+			reg = <0x800000 0x2e00000>;
+		};
+
+		partition@3600000 {
+			label = "Config";
+			reg = <0x3600000 0x100000>;
+			read-only;
+		};
+
+		partition@3700000 {
+			label = "firmware_2";
+			reg = <0x3700000 0x3200000>;
+		};
+
+		partition@6900000 {
+			label = "Config_2";
+			reg = <0x6900000 0x100000>;
+			read-only;
+		};
+
+		partition@6a00000 {
+			label = "persist";
+			reg = <0x6a00000 0x100000>;
+		};
+
+		partition@6b00000 {
+			label = "idmkey";
+			reg = <0x6b00000 0x100000>;
+			read-only;
+		};
+
+		partition@6c00000 {
+			label = "Backup";
+			reg = <0x6c00000 0x1380000>;
+			read-only;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x1e000>;
+};
+
+&switch0 {
+	ports {
+		wan: port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x1e006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-gx300gr.dts b/target/linux/ramips/dts/mt7621_iodata_wn-gx300gr.dts
new file mode 100644
index 0000000..06d024e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-gx300gr.dts
@@ -0,0 +1,185 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wn-gx300gr", "mediatek,mt7621-soc";
+	model = "I-O DATA WN-GX300GR";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		auto {
+			label = "auto";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		custom {
+			label = "custom";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "Bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "Config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "iNIC_rf";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x60000 0x770000>;
+			};
+
+			partition@7d0000 {
+				label = "Key";
+				reg = <0x7d0000 0x10000>;
+				read-only;
+			};
+
+			partition@7e0000 {
+				label = "backup";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "storage";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wn-xx-xr.dtsi b/target/linux/ramips/dts/mt7621_iodata_wn-xx-xr.dtsi
new file mode 100644
index 0000000..ff9e525
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wn-xx-xr.dtsi
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &wan;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		repeater {
+			label = "repeater";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions: partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x0100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "u-boot-env";
+			reg = <0x0100000 0x0100000>;
+			read-only;
+		};
+
+		factory: partition@200000 {
+			label = "factory";
+			reg = <0x0200000 0x0100000>;
+		};
+
+		partition@300000 {
+			label = "SecondBoot";
+			reg = <0x0300000 0x0100000>;
+			read-only;
+		};
+
+		partition@400000 {
+			label = "kernel";
+			reg = <0x0400000 0x0400000>;
+		};
+
+		partition@800000 {
+			label = "ubi";
+			reg = <0x0800000 0x2e00000>;
+		};
+
+		partition@3600000 {
+			label = "Config";
+			reg = <0x3600000 0x0100000>;
+			read-only;
+		};
+
+		partition@3700000 {
+			label = "firmware_2";
+			reg = <0x3700000 0x3200000>;
+		};
+
+		partition@6900000 {
+			label = "Config_2";
+			reg = <0x6900000 0x0100000>;
+			read-only;
+		};
+
+		partition@6a00000 {
+			label = "persist";
+			reg = <0x6a00000 0x0100000>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		wan: port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iodata_wnpr2600g.dts b/target/linux/ramips/dts/mt7621_iodata_wnpr2600g.dts
new file mode 100644
index 0000000..0e808f6
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iodata_wnpr2600g.dts
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iodata,wnpr2600g", "mediatek,mt7621-soc";
+	model = "I-O DATA WNPR2600G";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		notification {
+			label = "green:notification";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy1radio";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		auto {
+			label = "auto";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x000000 0x030000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x030000 0x010000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x040000 0x010000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x050000 0xda0000>;
+			};
+
+			partition@df0000 {
+				label = "manufacture";
+				reg = <0xdf0000 0x190000>;
+				read-only;
+			};
+
+			partition@f80000 {
+				label = "storage";
+				reg = <0xf80000 0x080000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_iptime_a6ns-m.dts b/target/linux/ramips/dts/mt7621_iptime_a6ns-m.dts
new file mode 100644
index 0000000..4ebd980
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iptime_a6ns-m.dts
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iptime,a6ns-m", "mediatek,mt7621-soc";
+	model = "ipTIME A6ns-M";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1radio";
+		};
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0xfc0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&uboot 0x1fc20>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&uboot 0x1fc40>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_iptime_a8004t.dts b/target/linux/ramips/dts/mt7621_iptime_a8004t.dts
new file mode 100644
index 0000000..df6aed6
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_iptime_a8004t.dts
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "iptime,a8004t", "mediatek,mt7621-soc";
+	model = "ipTIME A8004T";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_cpu: cpu {
+			label = "orange:cpu";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "orange:wlan2g";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan5g {
+			label = "orange:wlan5g";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1radio";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0xfc0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&uboot 0x1fc20>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&uboot 0x1fc40>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "jtag", "i2c";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts b/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts
new file mode 100644
index 0000000..ae312fc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_jcg_jhr-ac876m.dts
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,jhr-ac876m", "mediatek,mt7621-soc";
+	model = "JCG JHR-AC876M";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+		label-mac-device = &wan;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb3 {
+			label = "blue:usb3";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		usb2 {
+			label = "blue:usb2";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_jcg_q20.dts b/target/linux/ramips/dts/mt7621_jcg_q20.dts
new file mode 100644
index 0000000..f0e8293
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_jcg_q20.dts
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,q20", "mediatek,mt7621-soc";
+	model = "JCG Q20";
+
+	aliases {
+		led-boot = &led_status_red;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_blue;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	ubi-concat {
+		compatible = "mtd-concat";
+		devices = <&ubiconcat0 &ubiconcat1>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "ubi";
+				reg = <0x0 0x5900000>;
+			};
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "Config";
+			reg = <0x80000 0x80000>;
+		};
+
+		factory: partition@100000 {
+			label = "Factory";
+			reg = <0x100000 0x80000>;
+			read-only;
+		};
+
+		partition@180000 {
+			label = "kernel";
+			reg = <0x180000 0x400000>;
+		};
+
+		ubiconcat0: partition@580000 {
+			label = "ubiconcat0";
+			reg = <0x580000 0x1c00000>;
+		};
+
+		partition@2180000 {
+			label = "firmware_backup";
+			reg = <0x2180000 0x2000000>;
+		};
+
+		partition@4180000 {
+			label = "rootfs_data_back";
+			reg = <0x4180000 0x80000>;
+			read-only;
+		};
+
+		partition@4200000 {
+			label = "nvram_config";
+			reg = <0x4200000 0x80000>;
+			read-only;
+		};
+
+		ubiconcat1: partition@4280000 {
+			label = "ubiconcat1";
+			reg = <0x4280000 0x3d00000>;
+		};
+
+		/*
+		 * last 512 KiB are for the bad block table
+		 */
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x3fff4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x3fffa>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan2";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_jcg_y2.dts b/target/linux/ramips/dts/mt7621_jcg_y2.dts
new file mode 100644
index 0000000..06d6579
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_jcg_y2.dts
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,y2", "mediatek,mt7621-soc";
+	model = "JCG Y2";
+
+	aliases {
+		led-boot = &led_internet;
+		led-failsafe = &led_internet;
+		led-upgrade = &led_internet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_internet: internet {
+			label = "blue:internet";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_lenovo_newifi-d1.dts b/target/linux/ramips/dts/mt7621_lenovo_newifi-d1.dts
new file mode 100644
index 0000000..fa26900
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_lenovo_newifi-d1.dts
@@ -0,0 +1,163 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "lenovo,newifi-d1", "mediatek,mt7621-soc";
+	model = "Newifi-D1";
+
+	aliases {
+		led-boot = &led_blue;
+		led-failsafe = &led_blue;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status-red {
+			label = "red:status";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		status-green {
+			label = "green:status";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_blue: status-blue {
+			label = "blue:status";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb2power {
+			gpio-export,name = "usb2power";
+			gpio-export,output = <1>;
+			gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb3power {
+			gpio-export,name = "usb3power";
+			gpio-export,output = <1>;
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <45000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_e5600.dts b/target/linux/ramips/dts/mt7621_linksys_e5600.dts
new file mode 100644
index 0000000..91db315
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_e5600.dts
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "linksys,e5600", "mediatek,mt7621-soc";
+	model = "Linksys E5600";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "amber:wps";
+			gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan_blue {
+			label = "blue:wan";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "u_env";
+			reg = <0x80000 0x40000>;
+			read-only;
+		};
+
+		factory: partition@c0000 {
+			label = "factory";
+			reg = <0xc0000 0x40000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "s_env";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "devinfo";
+			reg = <0x140000 0x40000>;
+			read-only;
+		};
+
+		partition@180000 {
+			label = "kernel";
+			reg = <0x180000 0x400000>;
+		};
+
+		partition@580000 {
+			label = "ubi";
+			reg = <0x580000 0x1a00000>;
+		};
+
+		partition@1f80000 {
+			label = "alt_firmware";
+			reg = <0x1f80000 0x1e00000>;
+		};
+
+		partition@3d80000 {
+			label = "gdata";
+			reg = <0x3d80000 0x4200000>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "jtag";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_ea7300-v1.dts b/target/linux/ramips/dts/mt7621_linksys_ea7300-v1.dts
new file mode 100644
index 0000000..3e50d85
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_ea7300-v1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_linksys_ea7xxx.dtsi"
+
+/ {
+	compatible = "linksys,ea7300-v1", "mediatek,mt7621-soc";
+	model = "Linksys EA7300 v1";
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_ea7300-v2.dts b/target/linux/ramips/dts/mt7621_linksys_ea7300-v2.dts
new file mode 100644
index 0000000..4ee1488
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_ea7300-v2.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_linksys_ea7xxx.dtsi"
+
+/ {
+	compatible = "linksys,ea7300-v2", "mediatek,mt7621-soc";
+	model = "Linksys EA7300 v2";
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_ea7500-v2.dts b/target/linux/ramips/dts/mt7621_linksys_ea7500-v2.dts
new file mode 100644
index 0000000..8e13cc2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_ea7500-v2.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_linksys_ea7xxx.dtsi"
+
+/ {
+	compatible = "linksys,ea7500-v2", "mediatek,mt7621-soc";
+	model = "Linksys EA7500 v2";
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_ea7xxx.dtsi b/target/linux/ramips/dts/mt7621_linksys_ea7xxx.dtsi
new file mode 100644
index 0000000..ecff640
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_ea7xxx.dtsi
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1_green {
+			label = "green:lan1";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2_green {
+			label = "green:lan2";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3_green {
+			label = "green:lan3";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4_green {
+			label = "green:lan4";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "u_env";
+			reg = <0x80000 0x40000>;
+			read-only;
+		};
+
+		factory: partition@c0000 {
+			label = "factory";
+			reg = <0xc0000 0x40000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "s_env";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "devinfo";
+			reg = <0x140000 0x40000>;
+			read-only;
+		};
+
+		partition@180000 {
+			label = "kernel";
+			reg = <0x180000 0x400000>;
+		};
+
+		partition@580000 {
+			label = "ubi";
+			reg = <0x580000 0x2400000>;
+		};
+
+		partition@2980000 {
+			label = "alt_kernel";
+			reg = <0x2980000 0x400000>;
+			read-only;
+		};
+
+		partition@2d80000 {
+			label = "alt_rootfs";
+			reg = <0x2d80000 0x2400000>;
+			read-only;
+		};
+
+		partition@5180000 {
+			label = "sysdiag";
+			reg = <0x5180000 0x100000>;
+			read-only;
+		};
+
+		partition@5280000 {
+			label = "syscfg";
+			reg = <0x5280000 0x2d00000>;
+			read-only;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_ea8100-v1.dts b/target/linux/ramips/dts/mt7621_linksys_ea8100-v1.dts
new file mode 100644
index 0000000..6cc2219
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_ea8100-v1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_linksys_ea7xxx.dtsi"
+
+/ {
+	compatible = "linksys,ea8100-v1", "mediatek,mt7621-soc";
+	model = "Linksys EA8100";
+};
diff --git a/target/linux/ramips/dts/mt7621_linksys_re6500.dts b/target/linux/ramips/dts/mt7621_linksys_re6500.dts
new file mode 100644
index 0000000..319d0d7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_linksys_re6500.dts
@@ -0,0 +1,145 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "linksys,re6500", "mediatek,mt7621-soc";
+	model = "Linksys RE6500";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "orange:wifi";
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts b/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts
new file mode 100644
index 0000000..0499655
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mediatek_ap-mt7621a-v60.dts
@@ -0,0 +1,152 @@
+#include "mt7621.dtsi"
+
+/ {
+	compatible = "mediatek,ap-mt7621a-v60", "mediatek,mt7621-soc";
+	model = "Mediatek AP-MT7621A-V60 EVB";
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "Audio-I2S";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+		simple-audio-card,widgets =
+			"Microphone", "Microphone Jack",
+			"Headphone", "Headphone Jack";
+		simple-audio-card,routing =
+			"LINPUT1", "Microphone Jack",
+			"RINPUT1", "Microphone Jack",
+			"Headphone Jack", "HP_L",
+			"Headphone Jack", "HP_R";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		dailink0_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&pinctrl {
+	i2s_pins: i2s {
+		i2s {
+			groups = "uart3";
+			function = "i2s";
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+		wlf,shared-lrclk;
+	};
+};
+
+&gdma {
+	status = "okay";
+};
+
+&i2s {
+	#sound-dai-cells = <0>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s_pins>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "mx25l6405d","jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x5>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x5>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_mediatek_mt7621-eval-board.dts b/target/linux/ramips/dts/mt7621_mediatek_mt7621-eval-board.dts
new file mode 100644
index 0000000..c86eea0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mediatek_mt7621-eval-board.dts
@@ -0,0 +1,76 @@
+#include "mt7621.dtsi"
+
+/ {
+	compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
+	model = "Mediatek MT7621 evaluation board";
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "uboot";
+			reg = <0x00000 0x80000>; /* 64 KB */
+		};
+
+		partition@80000 {
+			label = "uboot_env";
+			reg = <0x80000 0x80000>; /* 64 KB */
+		};
+
+		partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "rootfs";
+			reg = <0x140000 0xec0000>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "rgmii2", "sdhci";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik.dtsi b/target/linux/ramips/dts/mt7621_mikrotik.dtsi
new file mode 100644
index 0000000..1fc523e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys: keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <33000000>;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "RouterBoot";
+				reg = <0x0 0x40000>;
+				read-only;
+				compatible = "mikrotik,routerboot-partitions";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				partition@0 {
+					label = "bootloader1";
+					reg = <0x0 0x0>;
+					read-only;
+				};
+
+				hard_config {
+					read-only;
+				};
+
+				partition@10000 {
+					label = "bootloader2";
+					reg = <0x10000 0xf000>;
+					read-only;
+				};
+
+				soft_config {
+				};
+
+				partition@30000 {
+					label = "bios";
+					reg = <0x30000 0x1000>;
+					read-only;
+				};
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik_routerboard-750gr3.dts b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-750gr3.dts
new file mode 100644
index 0000000..7f329b2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-750gr3.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_mikrotik_routerboard-7xx.dtsi"
+
+/ {
+	compatible = "mikrotik,routerboard-750gr3", "mediatek,mt7621-soc";
+	model = "MikroTik RouterBOARD 750Gr3";
+
+	aliases {
+		led-boot = &led_usr;
+		led-failsafe = &led_usr;
+		led-running = &led_usr;
+		led-upgrade = &led_usr;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		pwr {
+			label = "blue:pwr";
+			gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led_usr: usr {
+			label = "green:usr";
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik_routerboard-760igs.dts b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-760igs.dts
new file mode 100644
index 0000000..ed0b4e5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-760igs.dts
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_mikrotik_routerboard-7xx.dtsi"
+
+/ {
+	compatible = "mikrotik,routerboard-760igs", "mediatek,mt7621-soc";
+	model = "MikroTik RouterBOARD 760iGS";
+
+	aliases {
+		led-boot = &led_pwr;
+		led-failsafe = &led_pwr;
+		led-running = &led_pwr;
+		led-upgrade = &led_pwr;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_pwr: pwr {
+			label = "blue:pwr";
+			gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		sfp {
+			label = "blue:sfp";
+			gpios = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sfp1: sfp1 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c>;
+		los-gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+		mod-def0-gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		tx-disable-gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
+		maximum-power-milliwatt = <1000>;
+	};
+};
+
+&mdio {
+	ephy7: ethernet-phy@7 {
+		reg = <7>;
+		sfp = <&sfp1>;
+	};
+};
+
+&gmac1 {
+	status = "okay";
+
+	label = "sfp";
+	phy-handle = <&ephy7>;
+};
+
+&i2c {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		/* gpio7 (uart3 group) goes high when
+		 * port5 (PoE out) is cabled to a
+		 * Mikrotik PoE-in capable port,
+		 * such as port1 on another rb760iGS */
+		groups = "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik_routerboard-7xx.dtsi b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-7xx.dtsi
new file mode 100644
index 0000000..b8fae51
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-7xx.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_mikrotik.dtsi"
+
+/ {
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		buzzer {
+			/* Beeper requires PWM for frequency selection */
+			gpio-export,name = "buzzer";
+			gpio-export,output = <0>;
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb_power {
+			gpio-export,name = "usb_power";
+			gpio-export,output = <1>;
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&keys {
+	mode {
+		label = "mode";
+		gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		linux,code = <BTN_0>;
+	};
+};
+
+&partitions {
+	partition@40000 {
+		compatible = "mikrotik,minor";
+		label = "firmware";
+		reg = <0x040000 0xfc0000>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan5";
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m11g.dts b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m11g.dts
new file mode 100644
index 0000000..20a834a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m11g.dts
@@ -0,0 +1,91 @@
+#include "mt7621_mikrotik.dtsi"
+
+/ {
+	compatible = "mikrotik,routerboard-m11g", "mediatek,mt7621-soc";
+	model = "MikroTik RouterBOARD M11G";
+
+	aliases {
+		led-boot = &led_usr;
+		led-failsafe = &led_usr;
+		led-running = &led_usr;
+		led-upgrade = &led_usr;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_usr: usr {
+			label = "green:usr";
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		rssi0 {
+			label = "green:rssi0";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi1 {
+			label = "green:rssi1";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi2 {
+			label = "green:rssi2";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi3 {
+			label = "green:rssi3";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi4 {
+			label = "green:rssi4";
+			gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	pcie0_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie0_vcc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+};
+
+&partitions {
+	partition@40000 {
+		compatible = "mikrotik,minor";
+		label = "firmware";
+		reg = <0x040000 0xfc0000>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m33g.dts b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m33g.dts
new file mode 100644
index 0000000..affbaf3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mikrotik_routerboard-m33g.dts
@@ -0,0 +1,129 @@
+#include "mt7621_mikrotik.dtsi"
+
+/ {
+	compatible = "mikrotik,routerboard-m33g", "mediatek,mt7621-soc";
+	model = "MikroTik RouterBOARD M33G";
+
+	aliases {
+		led-boot = &led_usr;
+		led-failsafe = &led_usr;
+		led-running = &led_usr;
+		led-upgrade = &led_usr;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_usr: usr {
+			label = "green:usr";
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	pcie0_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie0_vcc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio 9 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	pcie1_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie1_vcc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio 10 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	pcie2_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie2_vcc";
+
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	usb_vcc_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vcc";
+
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+};
+
+&spi0 {
+	flash@1 {
+		compatible = "jedec,spi-nor";
+		reg = <1>;
+		spi-max-frequency = <33000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			// Region <0x0 0x40000> seems reserved by OEM
+
+			partition@40000 {
+				compatible = "mikrotik,minor";
+				label = "firmware";
+				reg = <0x040000 0xfc0000>;
+			};
+		};
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "wdt";
+		function = "gpio";
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_mqmaker_witi.dts b/target/linux/ramips/dts/mt7621_mqmaker_witi.dts
new file mode 100644
index 0000000..4590147
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mqmaker_witi.dts
@@ -0,0 +1,136 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mqmaker,witi", "mediatek,mt7621-soc";
+	model = "MQmaker WiTi";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	rtc@51 {
+		status = "okay";
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&factory 0xe000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+		mtd-mac-address = <&factory 0xe000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_mtc_wr1201.dts b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
new file mode 100644
index 0000000..8a79d9c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_mtc_wr1201.dts
@@ -0,0 +1,175 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mtc,wr1201", "mediatek,mt7621-soc";
+	model = "MTC Wireless Router WR1201";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		eth_link {
+			label = "green:eth_link";
+			gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "Bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "Config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfa0000>;
+			};
+
+			partition@ff0000 {
+				label = "Second_Config";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_ex6150.dts b/target/linux/ramips/dts/mt7621_netgear_ex6150.dts
new file mode 100644
index 0000000..0da8f6b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_ex6150.dts
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netgear,ex6150", "mediatek,mt7621-soc";
+	model = "Netgear EX6150";
+
+	aliases {
+		led-boot = &power_green;
+		led-failsafe = &power_amber;
+		led-running = &power_green;
+		led-upgrade = &power_amber;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power_amber: power_amber {
+			label = "amber:power";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		power_green: power_green {
+			label = "green:power";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+
+		rightarrow {
+			label = "blue:rightarrow";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+
+		leftarrow {
+			label = "blue:leftarrow";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+		};
+
+		router_green {
+			label = "green:router";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		router_red {
+			label = "red:router";
+			gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
+		};
+
+		client_green {
+			label = "green:client";
+			gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		client_red {
+			label = "red:client";
+			gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		toggle {
+			label = "AP/Extender toggle";
+			gpios = <&gpio 48 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+			/* Active when switch is set to "Access Point" */
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xe80000>;
+			};
+
+			partition@ed0000 {
+				label = "ML1";
+				reg = <0xed0000 0x10000>;
+				read-only;
+			};
+
+			partition@ef0000 {
+				label = "ML2";
+				reg = <0xef0000 0x20000>;
+				read-only;
+			};
+
+			partition@f10000 {
+				label = "ML3";
+				reg = <0xf10000 0x20000>;
+				read-only;
+			};
+
+			partition@f30000 {
+				label = "ML4";
+				reg = <0xf30000 0x20000>;
+				read-only;
+			};
+
+			partition@f50000 {
+				label = "ML5";
+				reg = <0xf50000 0x20000>;
+				read-only;
+			};
+
+			partition@f70000 {
+				label = "ML6";
+				reg = <0xf70000 0x20000>;
+				read-only;
+			};
+
+			partition@f90000 {
+				label = "ML7";
+				reg = <0xf90000 0x20000>;
+				read-only;
+			};
+
+			partition@fb0000 {
+				label = "T_Meter1";
+				reg = <0xfb0000 0x10000>;
+				read-only;
+			};
+
+			partition@fc0000 {
+				label = "T_Meter2";
+				reg = <0xfc0000 0x10000>;
+				read-only;
+			};
+
+			partition@fd0000 {
+				label = "POT";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "board_data";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "nvram";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+
+	reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>,
+		      <&gpio 8 GPIO_ACTIVE_LOW>;
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "sdhci", "rgmii2", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6220.dts b/target/linux/ramips/dts/mt7621_netgear_r6220.dts
new file mode 100644
index 0000000..cc29d4e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6220.dts
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_ayx.dtsi"
+
+/ {
+	compatible = "netgear,r6220", "mediatek,mt7621-soc";
+	model = "Netgear R6220";
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "SC PID";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		partition@200000 {
+			label = "kernel";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "ubi";
+			reg = <0x600000 0x1c00000>;
+		};
+
+		factory: partition@2e00000 {
+			label = "factory";
+			reg = <0x2e00000 0x100000>;
+			read-only;
+		};
+
+		partition@4200000 {
+			label = "reserved";
+			reg = <0x4200000 0x3c00000>;
+			read-only;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6260.dts b/target/linux/ramips/dts/mt7621_netgear_r6260.dts
new file mode 100644
index 0000000..b32f26d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6260.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_chj.dtsi"
+
+/ {
+	compatible = "netgear,r6260", "mediatek,mt7621-soc";
+	model = "Netgear R6260";
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6350.dts b/target/linux/ramips/dts/mt7621_netgear_r6350.dts
new file mode 100644
index 0000000..22535c9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6350.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_chj.dtsi"
+
+/ {
+	compatible = "netgear,r6350", "mediatek,mt7621-soc";
+	model = "Netgear R6350";
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6700-v2.dts b/target/linux/ramips/dts/mt7621_netgear_r6700-v2.dts
new file mode 100644
index 0000000..b93d6aa
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6700-v2.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_bzv.dtsi"
+
+/ {
+	compatible = "netgear,r6700-v2", "mediatek,mt7621-soc";
+	model = "Netgear R6700 v2";
+};
+
+&leds {
+	guest_wifi {
+		gpios = <&gpio_expander 6 GPIO_ACTIVE_LOW>;
+		label = "white:guest_wifi";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6800.dts b/target/linux/ramips/dts/mt7621_netgear_r6800.dts
new file mode 100644
index 0000000..c7afc53
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6800.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_bzv.dtsi"
+
+/ {
+	compatible = "netgear,r6800", "mediatek,mt7621-soc";
+	model = "Netgear R6800";
+};
+
+&leds {
+	usb2 {
+		gpios = <&gpio_expander 6 GPIO_ACTIVE_LOW>;
+		label = "white:usb2";
+		linux,default-trigger = "usbport";
+		trigger-sources = <&ehci_port2>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_r6850.dts b/target/linux/ramips/dts/mt7621_netgear_r6850.dts
new file mode 100644
index 0000000..78e9093
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_r6850.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_chj.dtsi"
+
+/ {
+	compatible = "netgear,r6850", "mediatek,mt7621-soc";
+	model = "Netgear R6850";
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_sercomm_ayx.dtsi b/target/linux/ramips/dts/mt7621_netgear_sercomm_ayx.dtsi
new file mode 100644
index 0000000..1a19cd0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_sercomm_ayx.dtsi
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mediatek,mt7621-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		wifi {
+			label = "wifi";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		internet {
+			label = "green:wan";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	reg_usb_vbus: regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 10 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&xhci {
+	vbus-supply = <&reg_usb_vbus>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi b/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
new file mode 100644
index 0000000..71c95e7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_sercomm_bzv.dtsi
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mediatek,mt7621-soc";
+
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power_white;
+		led-failsafe = &led_power_orange;
+		led-running = &led_power_white;
+		led-upgrade = &led_power_orange;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		led_power_orange: power_orange {
+			gpios = <&gpio_expander 0 GPIO_ACTIVE_LOW>;
+			label = "orange:power";
+		};
+
+		led_power_white: power_white {
+			gpios = <&gpio_expander 1 GPIO_ACTIVE_LOW>;
+			label = "white:power";
+		};
+
+		wan_orange {
+			gpios = <&gpio_expander 2 GPIO_ACTIVE_LOW>;
+			label = "orange:wan";
+		};
+
+		wan_white {
+			gpios = <&gpio_expander 3 GPIO_ACTIVE_LOW>;
+			label = "white:wan";
+		};
+
+		wlan2g {
+			gpios = <&gpio_expander 4 GPIO_ACTIVE_LOW>;
+			label = "white:wlan2g";
+			linux,default-trigger = "phy0radio";
+		};
+
+		wlan5g {
+			gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>;
+			label = "white:wlan5g";
+			linux,default-trigger = "phy1radio";
+		};
+
+		usb3 {
+			gpios = <&gpio_expander 7 GPIO_ACTIVE_LOW>;
+			label = "white:usb3";
+			linux,default-trigger = "usbport";
+			trigger-sources = <&xhci_ehci_port1>;
+		};
+
+		lan1_orange {
+			gpios = <&gpio_expander 8 GPIO_ACTIVE_LOW>;
+			label = "orange:lan1";
+		};
+
+		lan1_white {
+			gpios = <&gpio_expander 9 GPIO_ACTIVE_LOW>;
+			label = "white:lan1";
+		};
+
+		lan2_orange {
+			gpios = <&gpio_expander 10 GPIO_ACTIVE_LOW>;
+			label = "orange:lan2";
+		};
+
+		lan2_white {
+			gpios = <&gpio_expander 11 GPIO_ACTIVE_LOW>;
+			label = "white:lan2";
+		};
+
+		lan3_orange {
+			gpios = <&gpio_expander 12 GPIO_ACTIVE_LOW>;
+			label = "orange:lan3";
+		};
+
+		lan3_white {
+			gpios = <&gpio_expander 13 GPIO_ACTIVE_LOW>;
+			label = "white:lan3";
+		};
+
+		lan4_orange {
+			gpios = <&gpio_expander 14 GPIO_ACTIVE_LOW>;
+			label = "orange:lan4";
+		};
+
+		lan4_white {
+			gpios = <&gpio_expander 15 GPIO_ACTIVE_LOW>;
+			label = "white:lan4";
+		};
+
+		wps {
+			gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
+			label = "white:wps";
+		};
+
+		wlan {
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			label = "white:wlan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <2>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	gpio_expander: i2c0gpio-expander@20{
+		#gpio-cells = <2>;
+		#interrupt-cells = <2>;
+		compatible = "semtech,sx1503q";
+		reg = <0x20>;
+
+		gpio-controller;
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "SC PART_MAP";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		partition@200000 {
+			label = "kernel";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "ubi";
+			reg = <0x600000 0x2800000>;
+		};
+
+		partition@2e00000 {
+			label = "reserved0";
+			reg = <0x2e00000 0x1800000>;
+			read-only;
+		};
+
+		factory: partition@4600000 {
+			label = "factory";
+			reg = <0x4600000 0x200000>;
+			read-only;
+		};
+
+		partition@4800000 {
+			label = "reserved1";
+			reg = <0x4800000 0x3800000>;
+			read-only;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi b/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
new file mode 100644
index 0000000..7a15cd1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_sercomm_chj.dtsi
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mediatek,mt7621-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		internet {
+			label = "green:wan";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	reg_usb_vbus: regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 10 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&xhci {
+	vbus-supply = <&reg_usb_vbus>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <2>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "SC PART_MAP";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		partition@200000 {
+			label = "kernel";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "ubi";
+			reg = <0x600000 0x2800000>;
+		};
+
+		partition@2e00000 {
+			label = "reserved0";
+			reg = <0x2e00000 0x1800000>;
+			read-only;
+		};
+
+		factory: partition@4600000 {
+			label = "factory";
+			reg = <0x4600000 0x200000>;
+			read-only;
+		};
+
+		partition@4800000 {
+			label = "reserved1";
+			reg = <0x4800000 0x3800000>;
+			read-only;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_wac104.dts b/target/linux/ramips/dts/mt7621_netgear_wac104.dts
new file mode 100644
index 0000000..fbedeb2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_wac104.dts
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0-only or MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netgear,wac104", "mediatek,mt7621-soc";
+	model = "Netgear WAC104";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		wifi {
+			label = "wifi";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "SC PID";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		partition@200000 {
+			label = "kernel";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "ubi";
+			reg = <0x600000 0x1c00000>;
+		};
+
+		factory: partition@2e00000 {
+			label = "factory";
+			reg = <0x2e00000 0x100000>;
+			read-only;
+		};
+
+		partition@4200000 {
+			label = "reserved";
+			reg = <0x4200000 0x3c00000>;
+			read-only;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_wac124.dts b/target/linux/ramips/dts/mt7621_netgear_wac124.dts
new file mode 100644
index 0000000..92860c0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_wac124.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_chj.dtsi"
+
+/ {
+	compatible = "netgear,wac124", "mediatek,mt7621-soc";
+	model = "Netgear WAC124";
+};
diff --git a/target/linux/ramips/dts/mt7621_netgear_wndr3700-v5.dts b/target/linux/ramips/dts/mt7621_netgear_wndr3700-v5.dts
new file mode 100644
index 0000000..90c0ca1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netgear_wndr3700-v5.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "mt7621_netgear_sercomm_ayx.dtsi"
+
+/ {
+	compatible = "netgear,wndr3700-v5", "mediatek,mt7621-soc";
+	model = "Netgear WNDR3700 v5";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@f30000 {
+				label = "factory";
+				reg = <0xf30000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xee0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_netis_wf2881.dts b/target/linux/ramips/dts/mt7621_netis_wf2881.dts
new file mode 100644
index 0000000..7dfd133
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_netis_wf2881.dts
@@ -0,0 +1,163 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netis,wf2881", "mediatek,mt7621-soc";
+	model = "NETIS WF2881";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "config";
+			reg = <0x80000 0x80000>;
+			read-only;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		partition@140000 {
+			label = "firmware";
+			reg = <0x140000 0x7e40000>;
+
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "kernel";
+				reg = <0x0 0x400000>;
+			};
+
+			partition@400000 {
+				label = "ubi";
+				reg = <0x400000 0x7a40000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "uart2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_phicomm_k2p.dts b/target/linux/ramips/dts/mt7621_phicomm_k2p.dts
new file mode 100644
index 0000000..83169cd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_phicomm_k2p.dts
@@ -0,0 +1,143 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "phicomm,k2p", "mediatek,mt7621-soc";
+	model = "Phicomm K2P";
+
+	aliases {
+		led-boot = &led_blue;
+		led-failsafe = &led_blue;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		stat_r {
+			label = "red:status";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		stat_y {
+			label = "yellow:status";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		led_blue: stat_b {
+			label = "blue:status";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "permanent_config";
+				reg = <0x50000 0x50000>;
+				read-only;
+			};
+
+			partition@a0000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0xa0000 0xf60000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_planex_vr500.dts b/target/linux/ramips/dts/mt7621_planex_vr500.dts
new file mode 100644
index 0000000..5f8f190
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_planex_vr500.dts
@@ -0,0 +1,116 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,vr500", "mediatek,mt7621-soc";
+	model = "Planex VR500";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3fb0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "sdhci";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_samknows_whitebox-v8.dts b/target/linux/ramips/dts/mt7621_samknows_whitebox-v8.dts
new file mode 100644
index 0000000..9561c97
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_samknows_whitebox-v8.dts
@@ -0,0 +1,147 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "samknows,whitebox-v8", "mediatek,mt7621-soc";
+	model = "SamKnows Whitebox 8";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 47 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "sdhci";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_sercomm_na502.dts b/target/linux/ramips/dts/mt7621_sercomm_na502.dts
new file mode 100644
index 0000000..af55d10
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_sercomm_na502.dts
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sercomm,na502", "mediatek,mt7621-soc";
+	model = "SERCOMM NA502";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		zwave {
+			label = "green:zwave";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+
+		service {
+			label = "green:service";
+			gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+		};
+
+		zigbee {
+			label = "green:zigbee";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+		};
+
+		bluetooth {
+			label = "green:bluetooth";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		select {
+			label = "select";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		sync {
+			label = "sync";
+			gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+
+		zwave_reset {
+			gpio-export,name = "zwave_reset";
+			gpio-export,output = <1>;
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+		};
+
+		zigbee_reset {
+			gpio-export,name = "zigbee_reset";
+			gpio-export,output = <1>;
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "config";
+			reg = <0x80000 0x80000>;
+			read-only;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "kernel1";
+			reg = <0x140000 0x1400000>;
+		};
+
+		partition@1540000 {
+			label = "kernel";
+			reg = <0x1540000 0x400000>;
+		};
+
+		partition@1940000 {
+			label = "ubi";
+			reg = <0x1940000 0x1000000>;
+		};
+
+		partition@2940000 {
+			label = "user_storage";
+			reg = <0x2940000 0x100000>;
+		};
+
+		partition@2a40000 {
+			label = "data";
+			reg = <0x2a40000 0x1000000>;
+		};
+
+		partition@3a40000 {
+			label = "storage";
+			reg = <0x3a40000 0x3200000>;
+		};
+
+		partition@6c40000 {
+			label = "backup";
+			reg = <0x6c40000 0x1340000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mtd-mac-address = <&factory 0xe000>;
+		mtd-mac-address-increment = <1>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		mtd-mac-address = <&factory 0xe000>;
+		mtd-mac-address-increment = <2>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&switch0 {
+	ports {
+		port@4 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&uartlite2 {
+	status = "okay";
+};
+
+&uartlite3 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_storylink_sap-g3200u3.dts b/target/linux/ramips/dts/mt7621_storylink_sap-g3200u3.dts
new file mode 100644
index 0000000..d44960a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_storylink_sap-g3200u3.dts
@@ -0,0 +1,144 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "storylink,sap-g3200u3", "mediatek,mt7621-soc";
+	model = "STORYLiNK SAP-G3200U3";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+				read-only;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_telco-electronics_x1.dts b/target/linux/ramips/dts/mt7621_telco-electronics_x1.dts
new file mode 100644
index 0000000..f597d0f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_telco-electronics_x1.dts
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "telco-electronics,x1", "mediatek,mt7621-soc";
+	model = "Telco Electronics X1";
+
+	aliases {
+		led-boot = &system_led;
+		led-failsafe = &system_led;
+		led-running = &system_led;
+		led-upgrade = &system_led;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		system_led: system {
+			label = "green:system";
+			gpios = <&gpio 26 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_offline {
+			label = "red:modem-offline";
+			gpios = <&gpio 23 GPIO_ACTIVE_HIGH>;
+		};
+
+		modem_4g {
+			label = "blue:modem-4g";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_3g {
+			label = "green:modem-3g";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_rssi_lowest {
+			label = "green:modem-rssi-lowest";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_rssi_low {
+			label = "green:modem-rssi-low";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_rssi_medium {
+			label = "green:modem-rssi-medium";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_rssi_high {
+			label = "green:modem-rssi-high";
+			gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
+		};
+
+		modem_rssi_highest {
+			label = "green:modem-rssi-highest";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <14000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+
+	pcie0 {
+		wifi@0,0 {
+			compatible = "pci14c3,7603";
+			reg = <0x0000 0 0 0 0>;
+			mediatek,mtd-eeprom = <&factory 0x0000>;
+			ieee80211-freq-limit = <2400000 2500000>;
+		};
+	};
+
+	pcie1 {
+		wifi@0,0 {
+			compatible = "pci14c3,7662";
+			reg = <0x0000 0 0 0 0>;
+			mediatek,mtd-eeprom = <&factory 0x8000>;
+			ieee80211-freq-limit = <5000000 6000000>;
+			led {
+				led-sources = <2>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_thunder_timecloud.dts b/target/linux/ramips/dts/mt7621_thunder_timecloud.dts
new file mode 100644
index 0000000..fe11f4f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_thunder_timecloud.dts
@@ -0,0 +1,114 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "thunder,timecloud", "mediatek,mt7621-soc";
+	model = "Thunder Timecloud";
+
+	aliases {
+		led-boot = &led_statuso;
+		led-failsafe = &led_statuso;
+		led-running = &led_statuso;
+		led-upgrade = &led_statuso;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		statw {
+			label = "white:status";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_statuso: stato {
+			label = "orange:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		BTN_0 {
+			label = "BTN_0";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@4 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "jtag";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_totolink_a7000r.dts b/target/linux/ramips/dts/mt7621_totolink_a7000r.dts
new file mode 100644
index 0000000..d0e38f1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_totolink_a7000r.dts
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "totolink,a7000r", "mediatek,mt7621-soc";
+	model = "TOTOLINK A7000R";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_totolink_x5000r.dts b/target/linux/ramips/dts/mt7621_totolink_x5000r.dts
new file mode 100644
index 0000000..b05d839
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_totolink_x5000r.dts
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "totolink,x5000r", "mediatek,mt7621-soc";
+	model = "TOTOLINK X5000R";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+		label-mac-device = &gmac0;
+		serial0 = &uartlite;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_archer-a6-v3.dts b/target/linux/ramips/dts/mt7621_tplink_archer-a6-v3.dts
new file mode 100644
index 0000000..46cb365
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_archer-a6-v3.dts
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,archer-a6-v3", "mediatek,mt7621-soc";
+	model = "TP-Link Archer A6 v3";
+
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5g {
+			label = "green:wifi5g";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wifi2g {
+			label = "green:wifi2g";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "firmware";
+				compatible = "denx,uimage";
+				reg = <0x40000 0xf60000>;
+			};
+
+			config: partition@fa0000 {
+				label = "config";
+				reg = <0xfa0000 0x50000>;
+				read-only;
+			};
+
+			radio: partition@ff0000 {
+				label = "radio";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups =  "i2c", "uart2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		mtd-mac-address = <&config 0x8>;
+		mtd-mac-address-increment = <1>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		mtd-mac-address = <&config 0x8>;
+		mtd-mac-address-increment = <2>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&config 0x8>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts b/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts
new file mode 100644
index 0000000..7d38b7b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_archer-c6u-v1.dts
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,archer-c6u-v1", "mediatek,mt7621-soc";
+	model = "TP-Link Archer C6U v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan-orange {
+			label = "orange:wan";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5g {
+			label = "green:wifi5g";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wifi2g {
+			label = "green:wifi2g";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wan-green {
+			label = "green:wan";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	reg_usb_vbus: regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 3 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x000000 0x040000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x040000 0xf60000>;
+			};
+
+			config: partition@fa0000 {
+				label = "config";
+				reg = <0xfa0000 0x010000>;
+				read-only;
+			};
+
+			partition@fb0000 {
+				label = "tplink";
+				reg = <0xfb0000 0x040000>;
+				read-only;
+			};
+
+			radio: partition@ff0000 {
+				label = "radio";
+				reg = <0xff0000 0x010000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		mtd-mac-address = <&config 0x8>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		mtd-mac-address = <&config 0x8>;
+		mtd-mac-address-increment = <(-1)>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
+};
+
+&gmac0 {
+	mtd-mac-address = <&config 0x8>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&config 0x8>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "jtag", "wdt", "sdhci";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	vbus-supply = <&reg_usb_vbus>;
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_eap235-wall-v1.dts b/target/linux/ramips/dts/mt7621_tplink_eap235-wall-v1.dts
new file mode 100644
index 0000000..17308eb
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_eap235-wall-v1.dts
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	compatible = "tplink,eap235-wall-v1", "mediatek,mt7621-soc";
+	model = "TP-Link EAP235-Wall v1";
+
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "white:status";
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		led {
+			label = "led";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+
+		poe_passthrough {
+			gpio-export,name = "poe-passthrough";
+			gpio-export,output = <0>;
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x00000 0x80000>;
+				read-only;
+			};
+
+			partition@80000 {
+				label = "partition-table";
+				reg = <0x80000 0x10000>;
+				read-only;
+			};
+
+			info: partition@90000 {
+				label = "product-info";
+				reg = <0x90000 0x10000>;
+				read-only;
+			};
+
+			partition@a0000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x0a0000 0xd20000>;
+			};
+
+			partition@dc0000 {
+				label = "user-config";
+				reg = <0xdc0000 0x030000>;
+				read-only;
+			};
+
+			/* 0xdf0000 - 0xf30000 unused  */
+
+			partition@f30000 {
+				label = "mutil-log";
+				reg = <0xf30000 0x080000>;
+				read-only;
+			};
+
+			partition@fb0000 {
+				label = "oops";
+				reg = <0xfb0000 0x040000>;
+				read-only;
+			};
+
+			radio: partition@ff0000 {
+				label = "radio";
+				reg = <0xff0000 0x010000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		mtd-mac-address = <&info 0x8>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&info 0x8>;
+		mtd-mac-address-increment = <1>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&info 0x8>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan0";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_re350-v1.dts b/target/linux/ramips/dts/mt7621_tplink_re350-v1.dts
new file mode 100644
index 0000000..9f29ecd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_re350-v1.dts
@@ -0,0 +1,166 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,re350-v1", "mediatek,mt7621-soc";
+	model = "TP-LINK RE350 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2g {
+			label = "blue:wifi2G";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5g {
+			label = "blue:wifi5G";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		wps_r {
+			label = "red:wps";
+			gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps_b {
+			label = "blue:wps";
+			gpios = <&gpio 26 GPIO_ACTIVE_HIGH>;
+		};
+
+		eth {
+			label = "green:eth_act";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+
+		eth2 {
+			label = "green:eth_link";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		led {
+			label = "led";
+			gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		power {
+			label = "power";
+			gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x5e0000>;
+			};
+
+			config: partition@600000 {
+				label = "config";
+				reg = <0x600000 0x50000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		mtd-mac-address = <&config 0x10008>;
+		mtd-mac-address-increment = <1>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&config 0x10008>;
+		mtd-mac-address-increment = <2>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&config 0x10008>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "rgmii2", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_re500-v1.dts b/target/linux/ramips/dts/mt7621_tplink_re500-v1.dts
new file mode 100644
index 0000000..f199423
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_re500-v1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_tplink_rexx0-v1.dtsi"
+
+/ {
+	compatible = "tplink,re500-v1", "mediatek,mt7621-soc";
+	model = "TP-Link RE500 v1";
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_re650-v1.dts b/target/linux/ramips/dts/mt7621_tplink_re650-v1.dts
new file mode 100644
index 0000000..dcc5a3b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_re650-v1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_tplink_rexx0-v1.dtsi"
+
+/ {
+	compatible = "tplink,re650-v1", "mediatek,mt7621-soc";
+	model = "TP-Link RE650 v1";
+};
diff --git a/target/linux/ramips/dts/mt7621_tplink_rexx0-v1.dtsi b/target/linux/ramips/dts/mt7621_tplink_rexx0-v1.dtsi
new file mode 100644
index 0000000..45a9830
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_tplink_rexx0-v1.dtsi
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &gmac0;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		power {
+			label = "power";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_POWER>;
+		};
+
+		led {
+			label = "led";
+			gpios = <&gpio 30 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_LIGHTS_TOGGLE>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+			debounce-interval = <60>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2g {
+			label = "blue:wifi2g";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wifi5g {
+			label = "blue:wifi5g";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wps_red {
+			label = "red:wps";
+			gpios = <&gpio 26 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps_blue {
+			label = "blue:wps";
+			gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
+		};
+
+		eth_act {
+			label = "green:eth_act";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+		};
+
+		eth_link {
+			label = "green:eth_link";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0xde0000>;
+			};
+
+			config: partition@e00000 {
+				label = "config";
+				reg = <0xe00000 0x50000>;
+				read-only;
+			};
+
+			/* range 0xe50000 to 0xff0000 is empty in vendor
+			 * firmware, so we do not use it either
+			 */
+
+			radio: partition@ff0000 {
+				label = "radio";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "rgmii2", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x0>;
+		mtd-mac-address = <&config 0x10008>;
+		mtd-mac-address-increment = <1>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		mtd-mac-address = <&config 0x10008>;
+		mtd-mac-address-increment = <2>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&config 0x10008>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x-sfp.dts b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x-sfp.dts
new file mode 100644
index 0000000..9f92178
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x-sfp.dts
@@ -0,0 +1,73 @@
+#include "mt7621_ubnt_edgerouter-x.dtsi"
+
+/ {
+	model = "Ubiquiti EdgeRouter X SFP";
+	compatible = "ubnt,edgerouter-x-sfp", "mediatek,mt7621-soc";
+
+	sfp_eth5: sfp_eth5 {
+		compatible = "sff,sfp";
+		i2c-bus = <&i2c>;
+		mod-def0-gpio = <&expander0 5 GPIO_ACTIVE_LOW>;
+		maximum-power-milliwatt = <1000>;
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	/*
+	 * PCA9655 GPIO expander
+	 *  0-POE power port eth0
+	 *  1-POE power port eth1
+	 *  2-POE power port eth2
+	 *  3-POE power port eth3
+	 *  4-POE power port eth4
+	 *  5-SFP_MOD_DEF0#
+	 *  6-
+	 *  7-
+	 *  8-Pull up to VCC
+	 *  9-Pull down to GND
+	 * 10-Pull down to GND
+	 * 11-Pull down to GND
+	 * 12-Pull down to GND
+	 * 13-Pull down to GND
+	 * 14-Pull down to GND
+	 * 15-Pull down to GND
+	 */
+	expander0: pca9555@25 {
+		compatible = "nxp,pca9555";
+		interrupt-parent = <&gpio>;
+		interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x25>;
+	};
+};
+
+&gpio {
+	sfp_i2c_clk_gate {
+		gpio-hog;
+		gpios = <7 GPIO_ACTIVE_LOW>;
+		output-high;
+	};
+};
+
+&mdio {
+	ephy7: ethernet-phy@7 {
+		reg = <7>;
+		sfp = <&sfp_eth5>;
+	};
+};
+
+&switch0 {
+	ports {
+		port@5 {
+			reg = <5>;
+			label = "eth5";
+			phy-handle = <&ephy7>;
+			phy-mode = "rgmii-rxid";
+			mtd-mac-address = <&factory 0x22>;
+			mtd-mac-address-increment = <5>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dts b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dts
new file mode 100644
index 0000000..bca7c61
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dts
@@ -0,0 +1,6 @@
+#include "mt7621_ubnt_edgerouter-x.dtsi"
+
+/ {
+	model = "Ubiquiti EdgeRouter X";
+	compatible = "ubnt,edgerouter-x", "mediatek,mt7621-soc";
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dtsi b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dtsi
new file mode 100644
index 0000000..04eb49b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_edgerouter-x.dtsi
@@ -0,0 +1,143 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &gmac0;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x22>;
+	label = "dsa";
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "eth0";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "eth1";
+			mtd-mac-address = <&factory 0x22>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@2 {
+			status = "okay";
+			label = "eth2";
+			mtd-mac-address = <&factory 0x22>;
+			mtd-mac-address-increment = <2>;
+		};
+
+		port@3 {
+			status = "okay";
+			label = "eth3";
+			mtd-mac-address = <&factory 0x22>;
+			mtd-mac-address-increment = <3>;
+		};
+
+		port@4 {
+			status = "okay";
+			label = "eth4";
+			mtd-mac-address = <&factory 0x22>;
+			mtd-mac-address-increment = <4>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "u-boot-env";
+			reg = <0x80000 0x60000>;
+			read-only;
+		};
+
+		factory: partition@e0000 {
+			label = "factory";
+			reg = <0xe0000 0x60000>;
+		};
+
+		partition@140000 {
+			label = "kernel1";
+			reg = <0x140000 0x300000>;
+		};
+
+		partition@440000 {
+			label = "kernel2";
+			reg = <0x440000 0x300000>;
+		};
+
+		partition@740000 {
+			label = "ubi";
+			reg = <0x740000 0xf7c0000>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "pcie", "rgmii2", "jtag";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	/*
+	 * This board has 2Mb spi flash soldered in and visible
+	 * from manufacturer's firmware.
+	 * But this SoC shares spi and nand pins,
+	 * and current driver doesn't handle this sharing well
+	 */
+	status = "disabled";
+
+	flash@1 {
+		compatible = "jedec,spi-nor";
+		reg = <1>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "spi";
+				reg = <0x0 0x200000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_unifi-6-lite.dts b/target/linux/ramips/dts/mt7621_ubnt_unifi-6-lite.dts
new file mode 100644
index 0000000..d374fd3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_unifi-6-lite.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_ubnt_unifi.dtsi"
+
+/ {
+	compatible = "ubnt,unifi-6-lite", "mediatek,mt7621-soc";
+	model = "Ubiquiti UniFi 6 Lite";
+
+	chosen {
+		bootargs-override = "console=ttyS0,115200";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x60000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "u-boot-env";
+				reg = <0x60000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@70000 {
+				label = "factory";
+				reg = <0x70000 0x40000>;
+				read-only;
+			};
+
+			eeprom: partition@b0000 {
+				label = "eeprom";
+				reg = <0xb0000 0x10000>;
+				read-only;
+			};
+
+			partition@c0000 {
+				label = "bs";
+				reg = <0xc0000 0x10000>;
+			};
+
+			partition@d0000 {
+				label = "cfg";
+				reg = <0xd0000 0x100000>;
+				read-only;
+			};
+
+			partition@1d0000 {
+				compatible = "denx,fit";
+				label = "firmware";
+				reg = <0x1d0000 0xf10000>;
+			};
+
+			partition@10e0000 {
+				label = "kernel1";
+				reg = <0x10e0000 0xf10000>;
+			};
+		};
+	};
+};
+
+&wlan_2g {
+	mtd-mac-address = <&eeprom 0x0>;
+};
+
+&wlan_5g {
+	mediatek,mtd-eeprom = <&factory 0x20000>;
+	mtd-mac-address = <&eeprom 0x6>;
+	ieee80211-freq-limit = <5000000 6000000>;
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_unifi-nanohd.dts b/target/linux/ramips/dts/mt7621_ubnt_unifi-nanohd.dts
new file mode 100644
index 0000000..7a36ecf
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_unifi-nanohd.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_ubnt_unifi.dtsi"
+
+/ {
+	compatible = "ubnt,unifi-nanohd", "mediatek,mt7621-soc";
+	model = "Ubiquiti UniFi nanoHD";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x60000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "u-boot-env";
+				reg = <0x60000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@70000 {
+				label = "factory";
+				reg = <0x70000 0x10000>;
+				read-only;
+			};
+
+			eeprom: partition@80000 {
+				label = "eeprom";
+				reg = <0x80000 0x10000>;
+				read-only;
+			};
+
+			partition@90000 {
+				label = "bs";
+				reg = <0x90000 0x10000>;
+			};
+
+			partition@a0000 {
+				label = "cfg";
+				reg = <0xa0000 0x100000>;
+				read-only;
+			};
+
+			partition@1a0000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x1a0000 0xf30000>;
+			};
+
+			partition@10d0000 {
+				label = "kernel1";
+				reg = <0x10d0000 0xf30000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wlan_5g {
+	mediatek,mtd-eeprom = <&factory 0x8000>;
+};
diff --git a/target/linux/ramips/dts/mt7621_ubnt_unifi.dtsi b/target/linux/ramips/dts/mt7621_ubnt_unifi.dtsi
new file mode 100644
index 0000000..e0625ba
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_ubnt_unifi.dtsi
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_white;
+		led-failsafe = &led_white;
+		led-running = &led_blue;
+		led-upgrade = &led_blue;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_blue: dome_blue {
+			label = "blue:dome";
+			gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_white: dome_white {
+			label = "white:dome";
+			gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wlan_2g: wifi@0,0 {
+		reg = <0x0 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&pcie1 {
+	wlan_5g: wifi@0,0 {
+		reg = <0x0 0 0 0 0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&eeprom 0x0>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_unielec_u7621-01-16m.dts b/target/linux/ramips/dts/mt7621_unielec_u7621-01-16m.dts
new file mode 100644
index 0000000..d063f08
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_unielec_u7621-01-16m.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_unielec_u7621-01.dtsi"
+
+/ {
+	compatible = "unielec,u7621-01-16m", "unielec,u7621-01", "mediatek,mt7621-soc";
+	model = "UniElec U7621-01 (16M flash)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <14000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_unielec_u7621-01.dtsi b/target/linux/ramips/dts/mt7621_unielec_u7621-01.dtsi
new file mode 100644
index 0000000..336f68e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_unielec_u7621-01.dtsi
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unielec,u7621-01", "mediatek,mt7621-soc";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		modem_reset {
+			gpio-export,name = "modem_reset";
+			gpio-export,output = <1>;
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_unielec_u7621-06-16m.dts b/target/linux/ramips/dts/mt7621_unielec_u7621-06-16m.dts
new file mode 100644
index 0000000..e9789cf
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_unielec_u7621-06-16m.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  Copyright(c) 2017 Piotr Dymacz <pepe2k@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7621_unielec_u7621-06.dtsi"
+
+/ {
+	compatible = "unielec,u7621-06-16m", "unielec,u7621-06", "mediatek,mt7621-soc";
+	model = "UniElec U7621-06 (16M flash)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <14000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_unielec_u7621-06-64m.dts b/target/linux/ramips/dts/mt7621_unielec_u7621-06-64m.dts
new file mode 100644
index 0000000..74e4d66
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_unielec_u7621-06-64m.dts
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  Copyright(c) 2017 Piotr Dymacz <pepe2k@gmail.com>.
+ *  Copyright(c) 2018 Nishant Sharma <codemarauder@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7621_unielec_u7621-06.dtsi"
+
+/ {
+	compatible = "unielec,u7621-06-64m", "unielec,u7621-06", "mediatek,mt7621-soc";
+	model = "UniElec U7621-06 (64M flash)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3fb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_unielec_u7621-06.dtsi b/target/linux/ramips/dts/mt7621_unielec_u7621-06.dtsi
new file mode 100644
index 0000000..3b149df
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_unielec_u7621-06.dtsi
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  Copyright(c) 2017 Piotr Dymacz <pepe2k@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unielec,u7621-06", "mediatek,mt7621-soc";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		modem_reset {
+			gpio-export,name = "modem_reset";
+			gpio-export,output = <1>;
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		led4 {
+			label = "green:led4";
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		led5 {
+			label = "green:led5";
+			gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_wavlink_wl-wn531a6.dts b/target/linux/ramips/dts/mt7621_wavlink_wl-wn531a6.dts
new file mode 100644
index 0000000..04f656d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wavlink_wl-wn531a6.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wavlink,wl-wn531a6", "mediatek,mt7621-soc";
+	model = "Wavlink WL-WN531A6";
+
+	aliases {
+		led-boot = &led_status_red;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_red;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "Reset Button";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		touch { /* RH6015C touch sensor -> GPIO 14 */
+			label = "Touch Button";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		turbo {
+			label = "Turbo Button";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+
+		wps {
+			label = "WPS Button";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_blue: status_blue {
+			label = "blue:power";
+			gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_red: status_red {
+			label = "red:power";
+			gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
+		};
+
+		wifi2g {
+			label = "blue:wifi2g";
+			gpios = <&gpio 23 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xeb0000>;
+			};
+
+			partition@f00000 {
+				label = "vendor";
+				reg = <0xf00000 0x100000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "rgmii2", "jtag", "wdt";
+		function = "gpio";
+	};
+};
+
+&uartlite2 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_wevo_11acnas.dts b/target/linux/ramips/dts/mt7621_wevo_11acnas.dts
new file mode 100644
index 0000000..60d3185
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wevo_11acnas.dts
@@ -0,0 +1,17 @@
+#include "mt7621_wevo_w2914ns-v2.dtsi"
+
+/ {
+	compatible = "wevo,11acnas", "mediatek,mt7621-soc";
+	model = "WeVO 11AC NAS Router";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dts b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dts
new file mode 100644
index 0000000..bd44983
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dts
@@ -0,0 +1,17 @@
+#include "mt7621_wevo_w2914ns-v2.dtsi"
+
+/ {
+	compatible = "wevo,w2914ns-v2", "mediatek,mt7621-soc";
+	model = "WeVO W2914NS v2";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi
new file mode 100644
index 0000000..ffa86a4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_wevo_w2914ns-v2.dtsi
@@ -0,0 +1,138 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &wan;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+
+		led {
+			led-sources = <0>;
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x2e>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts b/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts
new file mode 100644
index 0000000..803bf5c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_winstars_ws-wn583a6.dts
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "winstars,ws-wn583a6", "mediatek,mt7621-soc";
+	model = "Winstars WS-WN583A6";
+
+	aliases {
+		led-boot = &led_status_red;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_red;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		night_light_white {
+			label = "white:night_light";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
+		};
+
+		status_amber {
+			label = "amber:status";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <104000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3-pro.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3-pro.dts
new file mode 100644
index 0000000..e8f3a50
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3-pro.dts
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "xiaomi,mi-router-3-pro", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router 3 Pro";
+
+	aliases {
+		led-boot = &led_status_yellow;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_yellow;
+		label-mac-device = &gmac0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_yellow: status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:04:1Gbps";
+		};
+
+		lan3_amber {
+			label = "amber:lan3";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:03:1Gbps";
+		};
+
+		lan2_amber {
+			label = "amber:lan2";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:02:1Gbps";
+		};
+
+		lan1_amber {
+			label = "amber:lan1";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:01:1Gbps";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	reg_usb_vbus: regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&xhci {
+	vbus-supply = <&reg_usb_vbus>;
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x40000>;
+			read-only;
+		};
+
+		partition@40000 {
+			label = "Config";
+			reg = <0x40000 0x40000>;
+		};
+
+		partition@80000 {
+			label = "Bdata";
+			reg = <0x80000 0x40000>;
+			read-only;
+		};
+
+		factory: partition@c0000 {
+			label = "factory";
+			reg = <0x0c0000 0x40000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "crash";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "crash_syslog";
+			reg = <0x140000 0x80000>;
+		};
+
+		partition@1c0000 {
+			label = "reserved0";
+			reg = <0x1c0000 0x40000>;
+			read-only;
+		};
+
+		/* We keep stock xiaomi firmware (kernel0) here */
+		partition@200000 {
+			label = "kernel_stock";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "kernel";
+			reg = <0x600000 0x400000>;
+		};
+
+		partition@a00000 {
+			label = "ubi";
+			reg = <0xa00000 0xf580000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g-v2.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g-v2.dts
new file mode 100644
index 0000000..fe03ff1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g-v2.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_mi-router-4a-3g-v2.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-3g-v2", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router 3G v2";
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts
new file mode 100644
index 0000000..40ea662
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-3g.dts
@@ -0,0 +1,117 @@
+#include "mt7621_xiaomi_nand_128m.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-3g", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router 3G";
+
+	aliases {
+		led-boot = &led_status_yellow;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_yellow;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_yellow: status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:01:1Gbps";
+		};
+
+		lan1_amber {
+			label = "amber:lan1";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:03:1Gbps";
+		};
+
+		lan2_amber {
+			label = "amber:lan2";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "dsa-0.0:02:1Gbps";
+		};
+	};
+
+	reg_usb_vbus: regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio 12 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+};
+
+&xhci {
+	vbus-supply = <&reg_usb_vbus>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe006>;
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts
new file mode 100644
index 0000000..18cbe0c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4.dts
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_nand_128m.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-4", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router 4";
+
+	aliases {
+		led-boot = &led_status_yellow;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_yellow;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_yellow: status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&keys {
+	minet {
+		label = "minet";
+		gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		linux,code = <KEY_WPS_BUTTON>;
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-3g-v2.dtsi b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-3g-v2.dtsi
new file mode 100644
index 0000000..cc5abf0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-3g-v2.dtsi
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_status_yellow;
+		led-failsafe = &led_status_yellow;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_yellow;
+		label-mac-device = &wan;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_yellow: status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "Bdata";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@50000 {
+				label = "factory";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "crash";
+				reg = <0x60000 0x10000>;
+				read-only;
+			};
+
+			partition@70000 {
+				label = "cfg_bak";
+				reg = <0x70000 0x10000>;
+				read-only;
+			};
+
+			partition@80000 {
+				label = "overlay";
+				reg = <0x80000 0x100000>;
+				read-only;
+			};
+
+			firmware: partition@180000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x180000 0xe80000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		wan: port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-gigabit.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-gigabit.dts
new file mode 100644
index 0000000..4387d3b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-4a-gigabit.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_mi-router-4a-3g-v2.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-4a-gigabit", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router 4A Gigabit Edition";
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_mi-router-ac2100.dts b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-ac2100.dts
new file mode 100644
index 0000000..6cca16a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_mi-router-ac2100.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_router-ac2100.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-ac2100", "mediatek,mt7621-soc";
+	model = "Xiaomi Mi Router AC2100";
+
+	aliases {
+		led-boot = &led_status_yellow;
+		led-failsafe = &led_status_yellow;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_blue;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan_yellow {
+			label = "yellow:wan";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_blue {
+			label = "blue:wan";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_yellow: status_yellow {
+			label = "yellow:status";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi b/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi
new file mode 100644
index 0000000..12e6bcc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_nand_128m.dtsi
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200n8";
+	};
+
+	keys: keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "Config";
+			reg = <0x80000 0x40000>;
+		};
+
+		partition@c0000 {
+			label = "Bdata";
+			reg = <0xc0000 0x40000>;
+			read-only;
+		};
+
+		factory: partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		partition@140000 {
+			label = "crash";
+			reg = <0x140000 0x40000>;
+		};
+
+		partition@180000 {
+			label = "crash_syslog";
+			reg = <0x180000 0x40000>;
+		};
+
+		partition@1c0000 {
+			label = "reserved0";
+			reg = <0x1c0000 0x40000>;
+			read-only;
+		};
+
+		/* uboot expects to find kernels at 0x200000 & 0x600000
+		 * referred to as system 1 & system 2 respectively.
+		 * a kernel is considered suitable for handing control over
+		 * if its linux magic number exists & uImage CRC are correct.
+		 * If either of those conditions fail, a matching sys'n'_fail flag
+		 * is set in uboot env & a restart performed in the hope that the
+		 * alternate kernel is okay.
+		 * if neither kernel checksums ok and both are marked failed, system 2
+		 * is booted anyway.
+		 *
+		 * Note uboot's tftp flash install writes the transferred
+		 * image to both kernel partitions.
+		 */
+
+		/* We keep stock xiaomi firmware (kernel0) here */
+		partition@200000 {
+			label = "kernel_stock";
+			reg = <0x200000 0x400000>;
+		};
+
+		partition@600000 {
+			label = "kernel";
+			reg = <0x600000 0x400000>;
+		};
+
+		/* ubi partition is the result of squashing
+		 * next consecutive stock partitions:
+		 * - rootfs0 (rootfs partition for stock kernel0),
+		 * - rootfs1 (rootfs partition for stock failsafe kernel1),
+		 * - overlay (used as ubi overlay in stock fw)
+		 * resulting 117,5MiB space for packages.
+		 */
+
+		partition@a00000 {
+			label = "ubi";
+			reg = <0xa00000 0x7580000>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_redmi-router-ac2100.dts b/target/linux/ramips/dts/mt7621_xiaomi_redmi-router-ac2100.dts
new file mode 100644
index 0000000..4299de3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_redmi-router-ac2100.dts
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_router-ac2100.dtsi"
+
+/ {
+	compatible = "xiaomi,redmi-router-ac2100", "mediatek,mt7621-soc";
+	model = "Xiaomi Redmi Router AC2100";
+
+	aliases {
+		led-boot = &led_status_amber;
+		led-failsafe = &led_status_amber;
+		led-running = &led_status_white;
+		led-upgrade = &led_status_white;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_amber: status_amber {
+			label = "amber:status";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_white: status_white {
+			label = "white:status";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_white {
+			label = "white:wan";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi b/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi
new file mode 100644
index 0000000..7e6b3af
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaomi_router-ac2100.dtsi
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_xiaomi_nand_128m.dtsi"
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan3";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xiaoyu_xy-c5.dts b/target/linux/ramips/dts/mt7621_xiaoyu_xy-c5.dts
new file mode 100644
index 0000000..a87bcd0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xiaoyu_xy-c5.dts
@@ -0,0 +1,128 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "xiaoyu,xy-c5", "mediatek,mt7621-soc";
+	model = "XiaoYu XY-C5";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		work {
+			label = "green:work";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_sys: sys {
+			label = "green:sys";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0x4>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_xzwifi_creativebox-v1.dts b/target/linux/ramips/dts/mt7621_xzwifi_creativebox-v1.dts
new file mode 100644
index 0000000..182b6db
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_xzwifi_creativebox-v1.dts
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "xzwifi,creativebox-v1", "mediatek,mt7621-soc";
+	model = "CreativeBox v1";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "blue:power";
+			gpios = <&gpio 31 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 32 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 33 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		power_usb2 {
+			gpio-export,name = "power_usb2";
+			gpio-export,output = <1>;
+			gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_usb3 {
+			gpio-export,name = "power_usb3";
+			gpio-export,output = <1>;
+			gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
+		};
+
+		power_sata {
+			gpio-export,name = "power_sata";
+			gpio-export,output = <1>;
+			gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci1400,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_youhua_wr1200js.dts b/target/linux/ramips/dts/mt7621_youhua_wr1200js.dts
new file mode 100644
index 0000000..a77d13c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_youhua_wr1200js.dts
@@ -0,0 +1,166 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "youhua,wr1200js", "mediatek,mt7621-soc";
+	model = "YouHua WR1200JS";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		wifi {
+			label = "wifi";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "lan4";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart2", "uart3", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_youku_yk-l2.dts b/target/linux/ramips/dts/mt7621_youku_yk-l2.dts
new file mode 100644
index 0000000..6271888
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_youku_yk-l2.dts
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "youku,yk-l2", "mediatek,mt7621-soc";
+	model = "Youku YK-L2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+		led {
+			led-active-low;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_yuncore_ax820.dts b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
new file mode 100644
index 0000000..9775ec3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_yuncore_ax820.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "yuncore,ax820", "mediatek,mt7621-soc";
+	model = "YunCore AX820";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_green: status_green {
+			label = "green:status";
+			gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	watchdog {
+		compatible = "linux,wdt-gpio";
+		gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		hw_algo = "toggle";
+		hw_margin_ms = <200>;
+		always-running;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "Bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "Config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			/* range 0x40000 to 0x50000 is empty in vendor
+			 * firmware, so we do not use it either
+			 */
+
+			factory: partition@50000 {
+				label = "Factory";
+				reg = <0x50000 0x40000>;
+				read-only;
+			};
+
+			partition@90000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x90000 0xf70000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
new file mode 100644
index 0000000..cd71166
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we1326.dts
@@ -0,0 +1,132 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-we1326", "mediatek,mt7621-soc";
+	model = "Zbtlink ZBT-WE1326";
+
+	aliases {
+		label-mac-device = &wifi1;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi0: mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	wifi1: mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
new file mode 100644
index 0000000..10e08cd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-we3526.dts
@@ -0,0 +1,137 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-we3526", "mediatek,mt7621-soc";
+	model = "Zbtlink ZBT-WE3526";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+		};
+	};
+};
+
+&pcie1 {
+	wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe006>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg2626.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg2626.dts
new file mode 100644
index 0000000..06c4f1d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg2626.dts
@@ -0,0 +1,152 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-wg2626", "mediatek,mt7621-soc";
+	model = "Zbtlink ZBT-WG2626";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+
+	reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>,
+			<&gpio 8 GPIO_ACTIVE_LOW>;
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&pcie1 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+		ieee80211-freq-limit = <2400000 2500000>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-16m.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-16m.dts
new file mode 100644
index 0000000..4094ef1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-16m.dts
@@ -0,0 +1,10 @@
+#include "mt7621_zbtlink_zbt-wg3526.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-wg3526-16m", "zbtlink,zbt-wg3526", "mediatek,mt7621-soc";
+	model = "Zbtlink ZBT-WG3526 (16M)";
+};
+
+&firmware {
+	reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-32m.dts b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-32m.dts
new file mode 100644
index 0000000..66a7622
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526-32m.dts
@@ -0,0 +1,14 @@
+#include "mt7621_zbtlink_zbt-wg3526.dtsi"
+
+/ {
+	compatible = "zbtlink,zbt-wg3526-32m", "zbtlink,zbt-wg3526", "mediatek,mt7621-soc";
+	model = "Zbtlink ZBT-WG3526 (32M)";
+};
+
+&flash0 {
+	broken-flash-reset;
+};
+
+&firmware {
+	reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526.dtsi b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526.dtsi
new file mode 100644
index 0000000..1e44945
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zbtlink_zbt-wg3526.dtsi
@@ -0,0 +1,153 @@
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zbtlink,zbt-wg3526", "mediatek,mt7621-soc";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+		label-mac-device = &wifi0;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+			};
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi0: wifi@0,0 {
+		compatible = "pci14c3,7603";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
+
+&pcie1 {
+	wifi1: wifi@0,0 {
+		compatible = "pci14c3,7662";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+		};
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan1";
+		};
+
+		port@1 {
+			status = "okay";
+			label = "lan2";
+		};
+
+		port@2 {
+			status = "okay";
+			label = "lan3";
+		};
+
+		port@3 {
+			status = "okay";
+			label = "lan4";
+		};
+
+		port@4 {
+			status = "okay";
+			label = "wan";
+			mtd-mac-address = <&factory 0xe000>;
+			mtd-mac-address-increment = <1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "rgmii2";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zio_freezio.dts b/target/linux/ramips/dts/mt7621_zio_freezio.dts
new file mode 100644
index 0000000..be7e5dc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zio_freezio.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621_wevo_w2914ns-v2.dtsi"
+
+/ {
+	compatible = "zio,freezio", "mediatek,mt7621-soc";
+	model = "ZIO FREEZIO";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&xhci_ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
new file mode 100644
index 0000000..f6a4228
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zyxel_nr7101.dts
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,nr7101", "mediatek,mt7621-soc";
+	model = "ZyXEL NR7101";
+
+	aliases {
+		led-boot = &power;
+		led-failsafe = &power;
+		led-running = &power;
+		led-upgrade = &power;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led@13 {
+			label = "yellow:system";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		power: led@14 {
+			label = "green:system";
+			gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		led@15 {
+			label = "red:system";
+			gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wlan";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WLAN>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio {
+	lte_pwrkey {
+		gpio-hog;
+		gpios = <4 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "lte-pwrkey";
+	};
+
+	lte_power {
+		gpio-hog;
+		gpios = <18 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "lte-power";
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "Config";
+			reg = <0x80000 0x80000>;
+		};
+
+		factory: partition@100000 {
+			label = "Factory";
+			reg = <0x100000 0x40000>;
+			read-only;
+		};
+
+		partition@140000 {
+			label = "Kernel";
+			reg = <0x140000 0x1ec0000>;
+		};
+
+		partition@540000 {
+			label = "ubi";
+			reg = <0x540000 0x1ac0000>;
+		};
+
+		partition@2140000 {
+			label = "Kernel2";
+			reg = <0x2140000 0x1ec0000>;
+		};
+
+		partition@4000000 {
+			label = "wwan";
+			reg = <0x4000000 0x100000>;
+		};
+
+		partition@4100000 {
+			label = "data";
+			reg = <0x4100000 0x1000000>;
+		};
+
+		partition@5100000 {
+			label = "rom-d";
+			reg = <0x5100000 0x100000>;
+			read-only;
+		};
+
+		partition@5200000 {
+			label = "reserve";
+			reg = <0x5200000 0x80000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&switch0 {
+	ports {
+		port@2 {
+			status = "okay";
+			label = "lan";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "rgmii2", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
new file mode 100644
index 0000000..0596dc7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7621_zyxel_wap6805.dts
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7621.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,wap6805", "mediatek,mt7621-soc";
+	model = "ZyXEL WAP6805";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+		label-mac-device = &gmac0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		status_blink {
+			label = "blink:status";
+			gpios = <&gpio 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_green: status_green {
+			label = "green:status";
+			gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&nand {
+	status = "okay";
+
+	partitions {
+		compatible = "fixed-partitions";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "Bootloader";
+			reg = <0x0 0x100000>;
+			read-only;
+		};
+
+		partition@100000 {
+			label = "MRD";
+			reg = <0x100000 0x100000>;
+			read-only;
+		};
+
+		factory: partition@200000 {
+			label = "Factory";
+			reg = <0x200000 0x100000>;
+			read-only;
+		};
+
+		partition@300000 {
+			label = "Config";
+			reg = <0x300000 0x100000>;
+		};
+
+		partition@400000 {
+			label = "Kernel";
+			reg = <0x400000 0x2000000>;
+		};
+
+		partition@800000 {
+			label = "ubi";
+			reg = <0x800000 0x1c00000>;
+		};
+
+		partition@2400000 {
+			label = "Kernel2";
+			reg = <0x2400000 0x2000000>;
+		};
+
+		partition@4400000 {
+			label = "Private";
+			reg = <0x4400000 0x100000>;
+		};
+
+		partition@4500000 {
+			label = "Log";
+			reg = <0x4500000 0x1000000>;
+		};
+
+		partition@5500000 {
+			label = "App";
+			reg = <0x5500000 0x2b00000>;
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x0>;
+	};
+};
+
+&gmac0 {
+	mtd-mac-address = <&factory 0xe000>;
+};
+
+&gmac1 {
+	status = "okay";
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&switch0 {
+	ports {
+		port@0 {
+			status = "okay";
+			label = "lan4";
+		};
+		port@1 {
+			status = "okay";
+			label = "lan3";
+		};
+		port@2 {
+			status = "okay";
+			label = "lan2";
+		};
+		port@3 {
+			status = "okay";
+			label = "lan1";
+		};
+	};
+};
+
+&xhci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart3", "jtag", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi
new file mode 100644
index 0000000..aa46de7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an.dtsi
@@ -0,0 +1,498 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "mediatek,mt7628an-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	aliases {
+		serial0 = &uartlite;
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,mt7620a-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		watchdog: watchdog@100 {
+			compatible = "ralink,mt7628an-wdt", "mediatek,mt7621-wdt";
+			reg = <0x100 0x30>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <24>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,mt7628an-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 9>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+
+			ralink,intc-registers = <0x9c 0xa0
+						 0x6c 0xa4
+						 0x80 0x78>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,mt7620a-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		gpio: gpio@600 {
+			compatible = "mediatek,mt7621-gpio";
+			reg = <0x600 0x100>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			#interrupt-cells = <2>;
+			interrupt-controller;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		i2c: i2c@900 {
+			compatible = "mediatek,mt7621-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s: i2s@a00 {
+			compatible = "mediatek,mt7628-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,mt7621-spi";
+			reg = <0xb00 0x100>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ns16550a";
+			reg = <0xc00 0x100>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test;
+
+			clock-frequency = <40000000>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <20>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_pins>;
+		};
+
+		uart1: uart1@d00 {
+			compatible = "ns16550a";
+			reg = <0xd00 0x100>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test;
+
+			clock-frequency = <40000000>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uart1";
+
+			interrupt-parent = <&intc>;
+			interrupts = <21>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart1_pins>;
+
+			status = "disabled";
+		};
+
+		uart2: uart2@e00 {
+			compatible = "ns16550a";
+			reg = <0xe00 0x100>;
+
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			no-loopback-test;
+
+			clock-frequency = <40000000>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "uart2";
+
+			interrupt-parent = <&intc>;
+			interrupts = <22>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart2_pins>;
+
+			status = "disabled";
+		};
+
+		pwm: pwm@5000 {
+			compatible = "mediatek,mt7628-pwm";
+			reg = <0x5000 0x1000>;
+			#pwm-cells = <2>;
+
+			resets = <&rstctrl 31>;
+			reset-names = "pwm";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&pwm0_pins>, <&pwm1_pins>;
+
+			status = "disabled";
+		};
+
+		pcm: pcm@2000 {
+			compatible = "ralink,mt7620a-pcm";
+			reg = <0x2000 0x800>;
+
+			resets = <&rstctrl 11>;
+			reset-names = "pcm";
+
+			interrupt-parent = <&intc>;
+			interrupts = <4>;
+
+			status = "disabled";
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		spi_cs1_pins: spi_cs1 {
+			spi_cs1 {
+				groups = "spi cs1";
+				function = "spi cs1";
+			};
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		i2s_pins: i2s {
+			i2s {
+				groups = "i2s";
+				function = "i2s";
+			};
+		};
+
+		uart0_pins: uartlite {
+			uartlite {
+				groups = "uart0";
+				function = "uart0";
+			};
+		};
+
+		uart1_pins: uart1 {
+			uart1 {
+				groups = "uart1";
+				function = "uart1";
+			};
+		};
+
+		uart2_pins: uart2 {
+			uart2 {
+				groups = "uart2";
+				function = "uart2";
+			};
+		};
+
+		sdxc_pins: sdxc {
+			sdxc {
+				groups = "sdmode";
+				function = "sdxc";
+			};
+		};
+
+		pwm0_pins: pwm0 {
+			pwm0 {
+				groups = "pwm0";
+				function = "pwm0";
+			};
+		};
+
+		pwm1_pins: pwm1 {
+			pwm1 {
+				groups = "pwm1";
+				function = "pwm1";
+			};
+		};
+
+		pcm_i2s_pins: pcm_i2s {
+			pcm_i2s {
+				groups = "i2s";
+				function = "pcm";
+			};
+		};
+
+		refclk_pins: refclk {
+			refclk {
+				groups = "refclk";
+				function = "refclk";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,mt7620a-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	usbphy: usbphy@10120000 {
+		compatible = "mediatek,mt7628-usbphy", "mediatek,mt7620-usbphy";
+		reg = <0x10120000 0x1000>;
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+		clocks = <&clkctrl 22 &clkctrl 25>;
+		clock-names = "host", "device";
+	};
+
+	sdhci: sdhci@10130000 {
+		compatible = "ralink,mt7620-sdhci";
+		reg = <0x10130000 0x4000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <14>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdxc_pins>;
+
+		status = "disabled";
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "ralink,rt5350-eth";
+		reg = <0x10100000 0x10000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		resets = <&rstctrl 21 &rstctrl 23>;
+		reset-names = "fe", "esw";
+
+		mediatek,switch = <&esw>;
+	};
+
+	esw: esw@10110000 {
+		compatible = "mediatek,mt7628-esw", "ralink,rt3050-esw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	pcie: pcie@10140000 {
+		compatible = "mediatek,mt7620-pci";
+		reg = <0x10140000 0x100
+			0x10142000 0x100>;
+
+		#address-cells = <3>;
+		#size-cells = <2>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <4>;
+
+		resets = <&rstctrl 26 &rstctrl 27>;
+		reset-names = "pcie0", "pcie1";
+		clocks = <&clkctrl 26 &clkctrl 27>;
+		clock-names = "pcie0", "pcie1";
+
+		status = "disabled";
+
+		device_type = "pci";
+
+		bus-range = <0 255>;
+		ranges = <
+			0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
+			0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
+		>;
+
+		pcie0: pcie@0,0 {
+			reg = <0x0000 0 0 0 0>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			device_type = "pci";
+
+			ranges;
+		};
+	};
+
+	wmac: wmac@10300000 {
+		compatible = "mediatek,mt7628-wmac";
+		reg = <0x10300000 0x100000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		status = "disabled";
+
+		mediatek,mtd-eeprom = <&factory 0x0000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_alfa-network_awusfree1.dts b/target/linux/ramips/dts/mt7628an_alfa-network_awusfree1.dts
new file mode 100644
index 0000000..d4f6a09
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_alfa-network_awusfree1.dts
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright (C) 2018 Piotr Dymacz <pepe2k@gmail.com>
+ *  All rights reserved.
+ */
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,awusfree1", "mediatek,mt7628an-soc";
+	model = "ALFA Network AWUSFREE1";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "orange:system";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&esw {
+	mediatek,portdisable = <0x1e>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+
+	ext_lna {
+		groups = "uart1";
+		function = "sw_r";
+	};
+
+	ext_pa {
+		groups = "i2s";
+		function = "antenna";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@31000 {
+				label = "config";
+				reg = <0x31000 0xf000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_asus_rt-n10p-v3.dts b/target/linux/ramips/dts/mt7628an_asus_rt-n10p-v3.dts
new file mode 100644
index 0000000..b638c21
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_asus_rt-n10p-v3.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7628an_asus_rt-n1x.dtsi"
+
+/ {
+	compatible = "asus,rt-n10p-v3", "mediatek,mt7628an-soc";
+	model = "Asus RT-N10P V3";
+};
diff --git a/target/linux/ramips/dts/mt7628an_asus_rt-n11p-b1.dts b/target/linux/ramips/dts/mt7628an_asus_rt-n11p-b1.dts
new file mode 100644
index 0000000..d62d4ad
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_asus_rt-n11p-b1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7628an_asus_rt-n1x.dtsi"
+
+/ {
+	compatible = "asus,rt-n11p-b1", "mediatek,mt7628an-soc";
+	model = "Asus RT-N11P B1";
+};
diff --git a/target/linux/ramips/dts/mt7628an_asus_rt-n12-vp-b1.dts b/target/linux/ramips/dts/mt7628an_asus_rt-n12-vp-b1.dts
new file mode 100644
index 0000000..8c44c36
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_asus_rt-n12-vp-b1.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7628an_asus_rt-n1x.dtsi"
+
+/ {
+	compatible = "asus,rt-n12-vp-b1", "mediatek,mt7628an-soc";
+	model = "Asus RT-N12 VP B1";
+};
diff --git a/target/linux/ramips/dts/mt7628an_asus_rt-n1x.dtsi b/target/linux/ramips/dts/mt7628an_asus_rt-n1x.dtsi
new file mode 100644
index 0000000..239bb08
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_asus_rt-n1x.dtsi
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "p0led_an", "p1led_an", "refclk", "wled_an";
+		function = "gpio";
+	};
+};
+
+&usbphy {
+	status = "disabled";
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7628an_buffalo_wcr-1166ds.dts b/target/linux/ramips/dts/mt7628an_buffalo_wcr-1166ds.dts
new file mode 100644
index 0000000..cb4c61e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_buffalo_wcr-1166ds.dts
@@ -0,0 +1,176 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,wcr-1166ds", "mediatek,mt7628an-soc";
+	model = "Buffalo WCR-1166DS";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		router_o {
+			label = "orange:router";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		router_g {
+			label = "green:router";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_o {
+			label = "orange:internet";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		internet_g {
+			label = "green:internet";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless_o {
+			label = "orange:wireless";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless_g {
+			label = "green:wireless";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		diag {
+			label = "orange:diag";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,portdisable = <0x27>;
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart1", "wled_an", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "wdt", "refclk", "gpio", "i2s";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,trx";
+				label = "firmware";
+				reg = <0x50000 0x7c0000>;
+			};
+
+			partition@810000 {
+				label = "firmware2";
+				reg = <0x810000 0x7c0000>;
+			};
+
+			partition@fd0000 {
+				label = "glbcfg";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "board_data";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_cudy_wr1000.dts b/target/linux/ramips/dts/mt7628an_cudy_wr1000.dts
new file mode 100644
index 0000000..adc9988
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_cudy_wr1000.dts
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "cudy,wr1000", "mediatek,mt7628an-soc";
+	model = "Cudy WR1000";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-upgrade = &led_wps;
+		label-mac-device = &wmac;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "rfkill";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan1 {
+			label = "blue:lan1";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "blue:lan2";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2s", "refclk", "wdt", "p4led_an",
+				"p3led_an", "p2led_an", "wled_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts b/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts
new file mode 100644
index 0000000..e5c5232
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_d-team_pbr-d1.dts
@@ -0,0 +1,161 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "d-team,pbr-d1", "mediatek,mt7628an-soc";
+	model = "PBR-D1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		serial0 = &uart2;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "orange:usb";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: power {
+			label = "orange:power";
+			gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 70 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	wgpio: gpio-wifi {
+		compatible = "mediatek,gpio-wifi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+
+	i2c {
+		groups = "i2c";
+		function = "gpio";
+	};
+
+	i2s {
+		groups = "i2s";
+		function = "gpio";
+	};
+
+	spis {
+		groups = "spis";
+		function = "gpio";
+	};
+
+	wdt {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x0fb0000>;
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-high;
+};
diff --git a/target/linux/ramips/dts/mt7628an_duzun_dm06.dts b/target/linux/ramips/dts/mt7628an_duzun_dm06.dts
new file mode 100644
index 0000000..f0d3dcb
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_duzun_dm06.dts
@@ -0,0 +1,131 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "duzun,dm06", "mediatek,mt7628an-soc";
+	model = "DuZun DM06";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "Audio-I2S";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&dailink0_master>;
+		simple-audio-card,frame-master = <&dailink0_master>;
+		simple-audio-card,widgets =
+			"Headphone", "Headphones";
+		simple-audio-card,routing =
+			"Headphones", "HP_L",
+			"Headphones", "HP_R";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s>;
+		};
+
+		dailink0_master: simple-audio-card,codec {
+			sound-dai = <&codec>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "uart1";
+		function = "gpio";
+	};
+};
+
+&i2c {
+	status = "okay";
+
+	codec: wm8960@1a {
+		#sound-dai-cells = <0>;
+		compatible = "wlf,wm8960";
+		reg = <0x1a>;
+
+		wlf,shared-lrclk;
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+	mediatek,portdisable = <0x3c>;
+};
+
+&i2s {
+	#sound-dai-cells = <0>;
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s_pins>, <&refclk_pins>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <60000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_elecom_wrc-1167fs.dts b/target/linux/ramips/dts/mt7628an_elecom_wrc-1167fs.dts
new file mode 100644
index 0000000..aa60b8a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_elecom_wrc-1167fs.dts
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "elecom,wrc-1167fs", "mediatek,mt7628an-soc";
+	model = "ELECOM WRC-1167FS";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wps {
+			label = "red:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		ap {
+			label = "ap";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x730000>;
+			};
+
+			partition@780000 {
+				label = "storage";
+				reg = <0x780000 0x80000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,portdisable = <0x27>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wled_an", "p3led_an", "p4led_an", "wdt", "refclk", "i2c", "i2s";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts b/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts
new file mode 100644
index 0000000..c5e0c2e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_glinet_gl-mt300n-v2.dts
@@ -0,0 +1,133 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/{
+	compatible = "glinet,gl-mt300n-v2", "mediatek,mt7628an-soc";
+	model = "GL-MT300N-V2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			default-state = "on";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "red:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		BTN_0 {
+			label = "BTN_0";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		BTN_1 {
+			label = "BTN_1";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_glinet_microuter-n300.dts b/target/linux/ramips/dts/mt7628an_glinet_microuter-n300.dts
new file mode 100644
index 0000000..09afe72
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_glinet_microuter-n300.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_glinet_vixmini_microuter.dtsi"
+
+/ {
+	compatible = "glinet,microuter-n300", "mediatek,mt7628an-soc";
+	model = "GL.iNet microuter-N300";
+};
+
+&firmware_part {
+		reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_glinet_vixmini.dts b/target/linux/ramips/dts/mt7628an_glinet_vixmini.dts
new file mode 100644
index 0000000..02c29d1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_glinet_vixmini.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_glinet_vixmini_microuter.dtsi"
+
+/ {
+	compatible = "glinet,vixmini", "mediatek,mt7628an-soc";
+	model = "GL.iNet VIXMINI";
+};
+
+&firmware_part {
+		reg = <0x50000 0x7b0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_glinet_vixmini_microuter.dtsi b/target/linux/ramips/dts/mt7628an_glinet_vixmini_microuter.dtsi
new file mode 100644
index 0000000..738968d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_glinet_vixmini_microuter.dtsi
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power_blue;
+		led-failsafe = &led_power_blue;
+		led-running = &led_power_blue;
+		led-upgrade = &led_power_blue;
+
+		label-mac-device = &ethernet;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_blue: power {
+			label = "blue:power";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "white:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "wled_an", "p1led_an";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			/*
+			 * Firmware-partition size is model-specific
+			 * due to different flash sizes.
+			 */
+			firmware_part: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts b/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts
new file mode 100644
index 0000000..eaae0b9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hak5_wifi-pineapple-mk7.dts
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hak5,wifi-pineapple-mk7", "mediatek,mt7628an-soc";
+	model = "Hak5 WiFi Pineapple Mark 7";
+
+	aliases {
+		led-boot = &led_system_blue;
+		led-failsafe = &led_system_blue;
+		led-upgrade = &led_system_blue;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		system_red {
+			label = "red:system";
+			gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		system_green {
+			label = "green:system";
+			gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_system_blue: system_blue {
+			label = "blue:system";
+			gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb-power {
+			gpio-export,name = "usb-power";
+			gpio-export,output = <1>;
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	sdhci@10130000 {
+		compatible = "ralink,mt7620-sdhci";
+		reg = <0x10130000 4000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <14>;
+
+		status = "okay";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "i2c", "i2s";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	status = "okay";
+
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_hilink_hlk-7628n.dts b/target/linux/ramips/dts/mt7628an_hilink_hlk-7628n.dts
new file mode 100644
index 0000000..f5106a5
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hilink_hlk-7628n.dts
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hilink,hlk-7628n", "mediatek,mt7628an-soc";
+	model = "HILINK HLK-7628N";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c";
+		function = "gpio";
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_hilink_hlk-7688a.dts b/target/linux/ramips/dts/mt7628an_hilink_hlk-7688a.dts
new file mode 100644
index 0000000..1f878b0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hilink_hlk-7688a.dts
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hilink,hlk-7688a", "mediatek,mt7628an-soc";
+	model = "Hi-Link HLK-7688A";
+
+	aliases {
+		led-boot = &led_wlan;
+		led-failsafe = &led_wlan;
+		led-upgrade = &led_wlan;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wlan: wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_hiwifi_hc5661a.dts b/target/linux/ramips/dts/mt7628an_hiwifi_hc5661a.dts
new file mode 100644
index 0000000..9e4068c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hiwifi_hc5661a.dts
@@ -0,0 +1,41 @@
+#include "mt7628an_hiwifi_hc5x61a.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5661a", "mediatek,mt7628an-soc";
+	model = "HiWiFi HC5661A";
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7628an_hiwifi_hc5761a.dts b/target/linux/ramips/dts/mt7628an_hiwifi_hc5761a.dts
new file mode 100644
index 0000000..828e5b8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hiwifi_hc5761a.dts
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_hiwifi_hc5x61a.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5761a", "mediatek,mt7628an-soc";
+	model = "HiWiFi HC5761A";
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio 37 GPIO_ACTIVE_HIGH>;
+		};
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 40 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy1tpt";
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb_power {
+			gpio-export,name = "usb_power";
+			gpio-export,output = <0>;
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "refclk", "wdt", "p2led_an", "p3led_an", "wled_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_hiwifi_hc5861b.dts b/target/linux/ramips/dts/mt7628an_hiwifi_hc5861b.dts
new file mode 100644
index 0000000..326c412
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hiwifi_hc5861b.dts
@@ -0,0 +1,54 @@
+#include "mt7628an_hiwifi_hc5x61a.dtsi"
+
+/ {
+	compatible = "hiwifi,hc5861b", "mediatek,mt7628an-soc";
+	model = "HiWiFi HC5861B";
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		mtd-mac-address = <&factory 0x2e>;
+		ieee80211-freq-limit = <5000000 6000000>;
+
+		led {
+			led-sources = <2>;
+			led-active-low;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi b/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi
new file mode 100644
index 0000000..7bd394c
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_hiwifi_hc5x61a.dtsi
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hiwifi,hc5x61a", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "hw_panic";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf70000>;
+			};
+
+			partition@fc0000 {
+				label = "oem";
+				reg = <0xfc0000 0x20000>;
+				read-only;
+			};
+
+			bdinfo: partition@fe0000 {
+				label = "bdinfo";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "backup";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_iptime.dtsi b/target/linux/ramips/dts/mt7628an_iptime.dtsi
new file mode 100644
index 0000000..8a33c37
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_iptime.dtsi
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+			debounce-interval = <60>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+			debounce-interval = <60>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0x7c0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart1", "wdt";
+		function = "gpio";
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&ethernet {
+	mtd-mac-address = <&uboot 0x1fc20>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_iptime_a3.dts b/target/linux/ramips/dts/mt7628an_iptime_a3.dts
new file mode 100644
index 0000000..d90a075
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_iptime_a3.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_iptime.dtsi"
+
+/ {
+	compatible = "iptime,a3", "mediatek,mt7628an-soc";
+	model = "ipTIME A3";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+	mediatek,portdisable = <0x32>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_iptime_a604m.dts b/target/linux/ramips/dts/mt7628an_iptime_a604m.dts
new file mode 100644
index 0000000..2f626f1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_iptime_a604m.dts
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_iptime.dtsi"
+
+/ {
+	compatible = "iptime,a604m", "mediatek,mt7628an-soc";
+	model = "ipTIME A604M";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uart1", "wdt";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_jotale_js76x8-16m.dts b/target/linux/ramips/dts/mt7628an_jotale_js76x8-16m.dts
new file mode 100644
index 0000000..8bf91fe
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_jotale_js76x8-16m.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_jotale_js76x8.dtsi"
+
+/ {
+	compatible = "jotale,js76x8-16m", "jotale,js76x8", "mediatek,mt7628an-soc";
+	model = "Jotale JS76x8 (16M)";
+};
+
+&firmware {
+	reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_jotale_js76x8-32m.dts b/target/linux/ramips/dts/mt7628an_jotale_js76x8-32m.dts
new file mode 100644
index 0000000..75ee988
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_jotale_js76x8-32m.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_jotale_js76x8.dtsi"
+
+/ {
+	compatible = "jotale,js76x8-32m", "jotale,js76x8", "mediatek,mt7628an-soc";
+	model = "Jotale JS76x8 (32M)";
+};
+
+&flash0 {
+	broken-flash-reset;
+};
+
+&firmware {
+	reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_jotale_js76x8-8m.dts b/target/linux/ramips/dts/mt7628an_jotale_js76x8-8m.dts
new file mode 100644
index 0000000..4147376
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_jotale_js76x8-8m.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_jotale_js76x8.dtsi"
+
+/ {
+	compatible = "jotale,js76x8-8m", "mediatek,mt7628an-soc";
+	model = "Jotale JS76x8 (8M)";
+};
+
+&firmware {
+	reg = <0x50000 0x7b0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi b/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi
new file mode 100644
index 0000000..e4952d4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_jotale_js76x8.dtsi
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jotale,js76x8", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "green:system";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				/* reg property is set based on flash size in DTS files */
+			};
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&i2s {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-low;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts
new file mode 100644
index 0000000..cbec8c9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_mediatek_linkit-smart-7688.dts
@@ -0,0 +1,160 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mediatek,linkit-smart-7688", "mediatek,mt7628an-soc";
+	model = "MediaTek LinkIt Smart 7688";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS2,57600";
+	};
+
+	aliases {
+		serial0 = &uart2;
+	};
+
+	bootstrap {
+		compatible = "mediatek,linkit";
+
+		status = "okay";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "orange:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+
+	refclk {
+		groups = "refclk";
+		function = "gpio";
+	};
+
+	i2s {
+		groups = "i2s";
+		function = "gpio";
+	};
+
+	spis {
+		groups = "spis";
+		function = "gpio";
+	};
+
+	wled_an {
+		groups = "wled_an";
+		function = "gpio";
+	};
+
+	wdt {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-high;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_mediatek_mt7628an-eval-board.dts b/target/linux/ramips/dts/mt7628an_mediatek_mt7628an-eval-board.dts
new file mode 100644
index 0000000..5418dac
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_mediatek_mt7628an-eval-board.dts
@@ -0,0 +1,61 @@
+#include "mt7628an.dtsi"
+
+/ {
+	compatible = "mediatek,mt7628an-eval-board", "mediatek,mt7628an-soc";
+	model = "Mediatek MT7628AN evaluation board";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_mercury_mac1200r-v2.dts b/target/linux/ramips/dts/mt7628an_mercury_mac1200r-v2.dts
new file mode 100644
index 0000000..7aa678a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_mercury_mac1200r-v2.dts
@@ -0,0 +1,100 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mercury,mac1200r-v2", "mediatek,mt7628an-soc";
+	model = "Mercury MAC1200R v2";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x1d800>;
+			};
+
+			factory: partition@1d800 {
+				label = "factory_info";
+				reg = <0x1d800 0x800>;
+				read-only;
+			};
+
+			art: partition@1e000 {
+				label = "art";
+				reg = <0x1e000 0x2000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+			};
+
+			partition@30000 {
+				label = "u-boot2";
+				reg = <0x30000 0x10000>;
+			};
+
+			partition@40000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x40000 0x7c0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	pinctrl-names = "default";
+	mtd-mac-address = <&factory 0xd>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&art 0x0>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&art 0x1000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_minew_g1-c.dts b/target/linux/ramips/dts/mt7628an_minew_g1-c.dts
new file mode 100644
index 0000000..3f1c205
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_minew_g1-c.dts
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Minew G1-C";
+	compatible = "minew,g1-c", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "red:system";
+			gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		ws2812 {
+			gpio-export,name = "ws2812";
+			gpio-export,output = <1>;
+			gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		};
+
+		nrf_power {
+			gpio-export,name = "nrf_power";
+			gpio-export,output = <1>;
+			gpios = <&gpio 45 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+
+	p0led_an {
+		groups = "p0led_an";
+		function = "gpio";
+	};
+
+	uart1 {
+		groups = "uart1";
+		function = "gpio";
+	};
+
+	wdt {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	m25p80@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-high;
+};
diff --git a/target/linux/ramips/dts/mt7628an_netgear_r6020.dts b/target/linux/ramips/dts/mt7628an_netgear_r6020.dts
new file mode 100644
index 0000000..6ae7474
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_netgear_r6020.dts
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_netgear_r6xxx.dtsi"
+
+/ {
+	compatible = "netgear,r6020", "mediatek,mt7628an-soc";
+	model = "Netgear R6020";
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "p2led_an", "p3led_an",
+		         "p4led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&partitions {
+	partition@90000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x90000 0x6f0000>;
+	};
+
+	partition@780000 {
+		label = "ML";
+		reg = <0x780000 0x20000>;
+		read-only;
+	};
+
+	partition@7a0000 {
+		label = "ML1";
+		reg = <0x7a0000 0x20000>;
+		read-only;
+	};
+
+	partition@7c0000 {
+		label = "ML2";
+		reg = <0x7c0000 0x20000>;
+		read-only;
+	};
+
+	partition@7e0000 {
+		label = "POT";
+		reg = <0x7e0000 0x10000>;
+		read-only;
+	};
+
+	partition@7f0000 {
+		label = "reserved";
+		reg = <0x7f0000 0x10000>;
+		read-only;
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7628an_netgear_r6080.dts b/target/linux/ramips/dts/mt7628an_netgear_r6080.dts
new file mode 100644
index 0000000..73cfc47
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_netgear_r6080.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_netgear_r6xxx.dtsi"
+
+/ {
+	compatible = "netgear,r6080", "mediatek,mt7628an-soc";
+	model = "Netgear R6080";
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "p2led_an", "p3led_an",
+		         "p4led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&partitions {
+	partition@90000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x90000 0x760000>;
+	};
+
+	partition@7f0000 {
+		label = "reserved";
+		reg = <0x7f0000 0x10000>;
+		read-only;
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7628an_netgear_r6120.dts b/target/linux/ramips/dts/mt7628an_netgear_r6120.dts
new file mode 100644
index 0000000..f4d9823
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_netgear_r6120.dts
@@ -0,0 +1,49 @@
+#include "mt7628an_netgear_r6xxx.dtsi"
+
+/ {
+	compatible = "netgear,r6120", "mediatek,mt7628an-soc";
+	model = "Netgear R6120";
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+
+	usb-regulator {
+		compatible = "regulator-fixed";
+
+		regulator-name = "USB-power";
+		gpio = <&gpio 45 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+
+		regulator-always-on;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "p2led_an", "p3led_an",
+		         "p4led_an", "wdt", "wled_an", "uart1";
+		function = "gpio";
+	};
+};
+
+&partitions {
+	partition@90000 {
+		compatible = "denx,uimage";
+		label = "firmware";
+		reg = <0x90000 0xf60000>;
+	};
+
+	partition@ff0000 {
+		label = "reserved";
+		reg = <0xff0000 0x10000>;
+		read-only;
+	};
+};
+
+&wifi5 {
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <(2)>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi b/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi
new file mode 100644
index 0000000..c3d7da2
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_netgear_r6xxx.dtsi
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g_green {
+			label = "green:wlan2g";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan2g_orange {
+			label = "orange:wlan2g";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <86000000>;
+		m25p,fast-read;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "nvram";
+				reg = <0x60000 0x30000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi5: wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_onion_omega2.dts b/target/linux/ramips/dts/mt7628an_onion_omega2.dts
new file mode 100644
index 0000000..a34638b
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_onion_omega2.dts
@@ -0,0 +1,10 @@
+#include "mt7628an_onion_omega2.dtsi"
+
+/ {
+	compatible = "onion,omega2", "mediatek,mt7628an-soc";
+	model = "Onion Omega2";
+};
+
+&firmware {
+	reg = <0x50000 0xfb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi b/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi
new file mode 100644
index 0000000..460a563
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_onion_omega2.dtsi
@@ -0,0 +1,165 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "onion,omega2", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "amber:system";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+
+	perst {
+		groups = "perst";
+		function = "gpio";
+	};
+
+	refclk {
+		groups = "refclk";
+		function = "gpio";
+	};
+
+	i2s {
+		groups = "i2s";
+		function = "gpio";
+	};
+
+	spis {
+		groups = "spis";
+		function = "gpio";
+	};
+
+	wled_kn {
+		groups = "wled_kn";
+		function = "gpio";
+	};
+
+	wled_an {
+		groups = "wled_an";
+		function = "gpio";
+	};
+
+	wdt {
+		groups = "wdt";
+		function = "gpio";
+	};
+
+	pwm0 {
+		groups = "pwm0";
+		function = "gpio";
+	};
+
+	pwm1 {
+		groups = "pwm1";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			firmware: partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-low;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_onion_omega2p.dts b/target/linux/ramips/dts/mt7628an_onion_omega2p.dts
new file mode 100644
index 0000000..5694576
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_onion_omega2p.dts
@@ -0,0 +1,14 @@
+#include "mt7628an_onion_omega2.dtsi"
+
+/ {
+	compatible = "onion,omega2p", "onion,omega2", "mediatek,mt7628an-soc";
+	model = "Onion Omega2+";
+};
+
+&flash0 {
+	broken-flash-reset;
+};
+
+&firmware {
+	reg = <0x50000 0x1fb0000>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_rakwireless_rak633.dts b/target/linux/ramips/dts/mt7628an_rakwireless_rak633.dts
new file mode 100644
index 0000000..63c4901
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_rakwireless_rak633.dts
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "rakwireless,rak633", "mediatek,mt7628an-soc";
+	model = "Rakwireless RAK633";
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	wled_an {
+		groups = "wled_an";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&i2s {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_ravpower_rp-wd009.dts b/target/linux/ramips/dts/mt7628an_ravpower_rp-wd009.dts
new file mode 100644
index 0000000..6962651
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_ravpower_rp-wd009.dts
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ravpower,rp-wd009", "mediatek,mt7628an-soc";
+	model = "RAVPower RP-WD009";
+
+	aliases {
+		led-boot = &led_globe;
+		led-failsafe = &led_globe;
+		led-running = &led_globe;
+		led-upgrade = &led_globe;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_globe: globe {
+			label = "white:globe";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2 {
+			label = "white:wlan2";
+			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5 {
+			label = "white:wlan5";
+			gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		sd_white {
+			label = "white:sd";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		sd_red {
+			label = "red:sd";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		/* Power interrupt on Pin 39 */
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 21 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		backup {
+			label = "backup";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_COPY>;
+		};
+	};
+};
+
+&gpio {
+	mt7610-power {
+		gpio-hog;
+		gpios = <20 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "mt7610-power";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uart1", "wled_an", "p0led_an", "p2led_an", "p3led_an",
+				"p4led_an", "uart2", "pwm0", "i2s";
+		function = "gpio";
+	};
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+
+	/* Custom PMIC at 0x0a */
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5470000 6000000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "loader";
+				reg = <0x50000 0x180000>;
+			};
+
+			partition@1d0000 {
+				label = "params";
+				reg = <0x1d0000 0x10000>;
+				read-only;
+			};
+
+			partition@1e0000 {
+				label = "user_backup";
+				reg = <0x1e0000 0x10000>;
+				read-only;
+			};
+
+			partition@1f0000 {
+				label = "user";
+				reg = <0x1f0000 0x10000>;
+				read-only;
+			};
+
+			partition@200000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x200000 0xdf0000>;
+			};
+
+			partition@ff0000 {
+				label = "mode";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_skylab_skw92a.dts b/target/linux/ramips/dts/mt7628an_skylab_skw92a.dts
new file mode 100644
index 0000000..6e1cb39
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_skylab_skw92a.dts
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "skylab,skw92a", "mediatek,mt7628an-soc";
+	model = "SKYLAB SKW92A";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: wps {
+			label = "green:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wdt", "refclk", "wled_an";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+				compatible = "denx,uimage";
+			};
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_tama_w06.dts b/target/linux/ramips/dts/mt7628an_tama_w06.dts
new file mode 100644
index 0000000..2be5f3f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tama_w06.dts
@@ -0,0 +1,99 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tama,w06", "mediatek,mt7628an-soc";
+	model = "Tama W06";
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless {
+			label = "green:wlan";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&state_default {
+	gpio {
+		groups = "uart1", "p0led_an", "wdt";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xeb0000>;
+			};
+
+			partition@f00000 {
+				label = "user-data";
+				reg = <0xf00000 0x100000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_totolink_a3.dts b/target/linux/ramips/dts/mt7628an_totolink_a3.dts
new file mode 100644
index 0000000..246dfad
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_totolink_a3.dts
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_iptime.dtsi"
+
+/ {
+	compatible = "totolink,a3", "mediatek,mt7628an-soc";
+	model = "TOTOLINK A3";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_cpu: cpu {
+			label = "blue:cpu";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "blue:wlan";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+	mediatek,portdisable = <0x32>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_totolink_lr1200.dts b/target/linux/ramips/dts/mt7628an_totolink_lr1200.dts
new file mode 100644
index 0000000..ab5fdd3
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_totolink_lr1200.dts
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "totolink,lr1200", "mediatek,mt7628dan";
+	model = "TOTOLINK LR1200";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "blue:sys";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		sms {
+			label = "blue:sms";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		4g {
+			label = "blue:4g";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi1 {
+			label = "blue:rssi1";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi2 {
+			label = "blue:rssi2";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi3 {
+			label = "blue:rssi3";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi4 {
+			label = "blue:rssi4";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&gpio {
+	gpio_modem_reset {
+		gpio-hog;
+		gpios = <45 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "modem-reset";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "i2c", "i2s", "refclk", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi b/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi
new file mode 100644
index 0000000..b6ce7b1
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_8m-split-uboot.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "factory-uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "boot";
+				reg = <0x30000 0x20000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x50000 0x770000>;
+			};
+
+			partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x10000>;
+				read-only;
+			};
+
+			rom: partition@7d0000 {
+				label = "rom";
+				reg = <0x7d0000 0x10000>;
+				read-only;
+			};
+
+			partition@7e0000 {
+				label = "romfile";
+				reg = <0x7e0000 0x10000>;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	mtd-mac-address = <&rom 0xf100>;
+	mediatek,mtd-eeprom = <&radio 0x0>;
+};
+
+&ethernet {
+	mtd-mac-address = <&rom 0xf100>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_8m.dtsi b/target/linux/ramips/dts/mt7628an_tplink_8m.dtsi
new file mode 100644
index 0000000..2faf8a8
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_8m.dtsi
@@ -0,0 +1,64 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7a0000>;
+			};
+
+			partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@7d0000 {
+				label = "factory";
+				reg = <0x7d0000 0x30000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	mtd-mac-address = <&factory 0xf100>;
+	mediatek,mtd-eeprom = <&factory 0x20000>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0xf100>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v4.dts
new file mode 100644
index 0000000..58743db
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v4.dts
@@ -0,0 +1,107 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,archer-c20-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link Archer C20 v4";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&wmac {
+	mtd-mac-address-increment = <(-2)>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2s", "gpio", "refclk", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x28000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&factory 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v5.dts
new file mode 100644
index 0000000..d76ce34
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_archer-c20-v5.dts
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m-split-uboot.dtsi"
+
+/ {
+	compatible = "tplink,archer-c20-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link Archer C20 v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "green:wlan2g";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5g {
+			label = "green:wlan5g";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "i2s", "gpio", "refclk", "p0led_an", "p1led_an",
+					"p2led_an", "p3led_an", "p4led_an", "wdt";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&rom 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v3.dts b/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v3.dts
new file mode 100644
index 0000000..4966d56
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v3.dts
@@ -0,0 +1,102 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,archer-c50-v3", "mediatek,mt7628an-soc";
+	model = "TP-Link Archer C50 v3";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5 {
+			label = "green:wlan5g";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "gpio", "p0led_an", "p1led_an", "p2led_an",
+				   "p3led_an", "p4led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x28000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&factory 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v4.dts
new file mode 100644
index 0000000..11bf903
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_archer-c50-v4.dts
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m-split-uboot.dtsi"
+
+/ {
+	compatible = "tplink,archer-c50-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link Archer C50 v4";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2 {
+			label = "green:wlan2g";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan5 {
+			label = "green:wlan5g";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "p0led_an", "p1led_an", "p2led_an",
+				   "p3led_an", "p4led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&rom 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re200-v2.dts b/target/linux/ramips/dts/mt7628an_tplink_re200-v2.dts
new file mode 100644
index 0000000..a7e5e51
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re200-v2.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_re200.dtsi"
+
+/ {
+	compatible = "tplink,re200-v2", "mediatek,mt7628an-soc";
+	model = "TP-Link RE200 v2";
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re200-v3.dts b/target/linux/ramips/dts/mt7628an_tplink_re200-v3.dts
new file mode 100644
index 0000000..2c4e09e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re200-v3.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_re200.dtsi"
+
+/ {
+	compatible = "tplink,re200-v3", "mediatek,mt7628an-soc";
+	model = "TP-Link RE200 v3";
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re200-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_re200-v4.dts
new file mode 100644
index 0000000..83f1f3a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re200-v4.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_re200.dtsi"
+
+/ {
+	compatible = "tplink,re200-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link RE200 v4";
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re200.dtsi b/target/linux/ramips/dts/mt7628an_tplink_re200.dtsi
new file mode 100644
index 0000000..95addff
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re200.dtsi
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		label-mac-device = &ethernet;
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600n8";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2g_green {
+			label = "green:wifi2g";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wifi5g_green {
+			label = "green:wifi5g";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		wifi2g_red {
+			label = "red:wifi2g";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi5g_red {
+			label = "red:wifi5g";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7a0000>;
+			};
+
+			config: partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x30000>;
+				read-only;
+			};
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "p4led_an", "p3led_an", "p2led_an", "p1led_an",
+				"p0led_an", "wled_an", "i2c", "wdt", "refclk";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&config 0x2008>;
+};
+
+&wmac {
+	status = "okay";
+
+	mediatek,mtd-eeprom = <&radio 0x0>;
+	mtd-mac-address = <&config 0x2008>;
+	mtd-mac-address-increment = <1>;
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&config 0x2008>;
+		mtd-mac-address-increment = <2>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re220-v2.dts b/target/linux/ramips/dts/mt7628an_tplink_re220-v2.dts
new file mode 100644
index 0000000..82d385a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re220-v2.dts
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_re200.dtsi"
+
+/ {
+	compatible = "tplink,re220-v2", "mediatek,mt7628an-soc";
+	model = "TP-Link RE220 v2";
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_re305-v1.dts b/target/linux/ramips/dts/mt7628an_tplink_re305-v1.dts
new file mode 100644
index 0000000..22e15eb
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_re305-v1.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,re305-v1", "mediatek,mt7628an-soc";
+	model = "TP-Link RE305 v1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2g {
+			label = "blue:wlan2g";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wlan5g {
+			label = "blue:wlan5g";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy1tpt";
+		};
+
+		rssi1 {
+			label = "red:rssi";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		rssi2 {
+			label = "blue:rssi";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x5e0000>;
+			};
+
+			config: partition@600000 {
+				label = "config";
+				reg = <0x600000 0x50000>;
+				read-only;
+			};
+
+			/*
+				The flash space between 0x650000 and 0x7f0000 is blank in the
+				stock firmware so it is left out as well.
+			*/
+
+			radio: partition@7f0000 {
+				label = "radio";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "refclk", "wdt", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&radio 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&config 0x10008>;
+		mtd-mac-address-increment = <2>;
+	};
+};
+
+&wmac {
+	status = "okay";
+
+	mediatek,mtd-eeprom = <&radio 0x0>;
+	mtd-mac-address = <&config 0x10008>;
+	mtd-mac-address-increment = <1>;
+};
+
+&ethernet {
+	mtd-mac-address = <&config 0x10008>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-mr3020-v3.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-mr3020-v3.dts
new file mode 100644
index 0000000..5bc1275
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-mr3020-v3.dts
@@ -0,0 +1,132 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,tl-mr3020-v3", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-MR3020 v3";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		modec1 {
+			label = "sw1";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		modec2 {
+			label = "sw2";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wan {
+			label = "green:3g";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ehci_port1>, <&ohci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x7a0000>;
+			};
+
+			partition@7c0000 {
+				label = "config";
+				reg = <0x7c0000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@7d0000 {
+				label = "factory";
+				reg = <0x7d0000 0x30000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2s", "refclk", "wdt", "p2led_an", "p1led_an", "p0led_an", "wled_an";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+	mtd-mac-address = <&factory 0xf100>;
+	mediatek,mtd-eeprom = <&factory 0x20000>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0xf100>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-mr3420-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-mr3420-v5.dts
new file mode 100644
index 0000000..173b4cd
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-mr3420-v5.dts
@@ -0,0 +1,81 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-mr3420-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-MR3420 v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "i2s", "p2led_an", "refclk", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v4.dts
new file mode 100644
index 0000000..a142be7
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v4.dts
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-mr6400-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-MR6400 v4";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "white:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "white:wlan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		lan {
+			label = "white:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		signal1 {
+			label = "white:signal1";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		signal2 {
+			label = "white:signal2";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		signal3 {
+			label = "white:signal3";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "refclk", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,portdisable = <0x21>;
+};
+
+&wmac {
+	mtd-mac-address = <&factory 0x1f100>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x1f100>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v5.dts
new file mode 100644
index 0000000..7ab1963
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-mr6400-v5.dts
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-mr6400-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-MR6400 v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "white:wlan";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		lan {
+			label = "white:lan";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "white:power";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "white:wan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		signal1 {
+			label = "white:signal1";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		signal2 {
+			label = "white:signal2";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		signal3 {
+			label = "white:signal3";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "uart1", "wdt";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x37>;
+	mediatek,portdisable = <0x30>;
+};
+
+&wmac {
+	mtd-mac-address = <&factory 0x1f100>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x1f100>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wa801nd-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wa801nd-v5.dts
new file mode 100644
index 0000000..de9a484
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wa801nd-v5.dts
@@ -0,0 +1,75 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wa801nd-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WA801ND v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 36 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wps_red {
+			label = "red:wps";
+			gpios = <&gpio 43 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps_green {
+			label = "green:wps";
+			gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "perst", "refclk",
+				"uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr802n-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr802n-v4.dts
new file mode 100644
index 0000000..bce3404
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr802n-v4.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr802n-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR802N v4";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "refclk", "wdt";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0xf100>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v4.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v4.dts
new file mode 100644
index 0000000..8a8ba81
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v4.dts
@@ -0,0 +1,71 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr840n-v4", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR840N v4";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 36 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p2led_an", "perst", "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v5.dts
new file mode 100644
index 0000000..1f8f7f4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr840n-v5.dts
@@ -0,0 +1,107 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,tl-wr840n-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR840N v5";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	/* LED used is dual-color,dual lead LED */
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power {
+			label = "green:power";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		orange {
+			label = "orange:power";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x20000 0x3d0000>;
+			};
+
+			factory: partition@3f0000 {
+				label = "factory";
+				reg = <0x3f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&wmac {
+	status = "okay";
+	mtd-mac-address = <&factory 0xf100>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0xf100>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p2led_an", "perst";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v13.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v13.dts
new file mode 100644
index 0000000..5c7f983
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v13.dts
@@ -0,0 +1,97 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr841n-v13", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR841N v13";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 36 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1 {
+			label = "green:lan1";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "green:lan2";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3 {
+			label = "green:lan3";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4 {
+			label = "green:lan4";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "perst", "refclk", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v14.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v14.dts
new file mode 100644
index 0000000..a1a83bf
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr841n-v14.dts
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tplink,tl-wr841n-v14", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR841N v14";
+
+	aliases {
+		led-boot = &led_wlan;
+		led-failsafe = &led_wlan;
+		led-upgrade = &led_wlan;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wlan: wlan {
+			label = "green:wlan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+
+		wan_orange {
+			label = "orange:wan";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "boot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "tplink,firmware";
+				label = "firmware";
+				reg = <0x10000 0x3e0000>;
+			};
+
+			factory: partition@3f0000 {
+				label = "factory";
+				reg = <0x3f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&wmac {
+	status = "okay";
+
+	mtd-mac-address = <&factory 0xf100>;
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0xf100>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&state_default {
+	gpio {
+		groups = "p4led_an", "p3led_an", "p2led_an", "p1led_an", "p0led_an", "wdt";
+		function = "gpio";
+	};
+};
+
+&gpio {
+	led_wlan_enable {
+		gpio-hog;
+		gpios = <43 GPIO_ACTIVE_HIGH>;
+		output-high;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr842n-v5.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr842n-v5.dts
new file mode 100644
index 0000000..9077ec0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr842n-v5.dts
@@ -0,0 +1,81 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr842n-v5", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR842N v5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "i2s", "p2led_an", "refclk", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr850n-v2.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr850n-v2.dts
new file mode 100644
index 0000000..7abeae9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr850n-v2.dts
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr850n-v2", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR850N v2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 36 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "phy0tpt";
+		};
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p2led_an", "perst", "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_tplink_tl-wr902ac-v3.dts b/target/linux/ramips/dts/mt7628an_tplink_tl-wr902ac-v3.dts
new file mode 100644
index 0000000..77a68ac
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_tplink_tl-wr902ac-v3.dts
@@ -0,0 +1,98 @@
+#include "mt7628an_tplink_8m.dtsi"
+
+/ {
+	compatible = "tplink,tl-wr902ac-v3", "mediatek,mt7628an-soc";
+	model = "TP-Link TL-WR902AC v3";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		sw1 {
+			label = "sw1";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		sw2 {
+			label = "sw2";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "i2s", "p0led_an", "p2led_an", "p4led_an", "uart1", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x28000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+		mtd-mac-address = <&factory 0xf100>;
+		mtd-mac-address-increment = <(-1)>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_unielec_u7628-01-16m.dts b/target/linux/ramips/dts/mt7628an_unielec_u7628-01-16m.dts
new file mode 100644
index 0000000..c25a31f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_unielec_u7628-01-16m.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  Copyright(c) 2017 Piotr Dymacz <pepe2k@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7628an_unielec_u7628-01.dtsi"
+
+/ {
+	compatible = "unielec,u7628-01-16m", "unielec,u7628-01", "mediatek,mt7628an-soc";
+	model = "UniElec U7628-01 (16M flash)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <12000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_unielec_u7628-01.dtsi b/target/linux/ramips/dts/mt7628an_unielec_u7628-01.dtsi
new file mode 100644
index 0000000..f0a6b1d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_unielec_u7628-01.dtsi
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ *  Copyright(c) 2017 Kristian Evensen <kristian.evensen@gmail.com>.
+ *  Copyright(c) 2017 Piotr Dymacz <pepe2k@gmail.com>.
+ *  All rights reserved.
+ */
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unielec,u7628-01", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1 {
+			label = "green:lan1";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "green:lan2";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+
+		lan3 {
+			label = "green:lan3";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		lan4 {
+			label = "green:lan4";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "p0led_an", "p1led_an", "p2led_an", "p3led_an", "p4led_an", "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_vocore_vocore2-lite.dts b/target/linux/ramips/dts/mt7628an_vocore_vocore2-lite.dts
new file mode 100644
index 0000000..f8bdc27
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_vocore_vocore2-lite.dts
@@ -0,0 +1,62 @@
+#include "mt7628an_vocore_vocore2.dtsi"
+
+/ {
+	compatible = "vocore,vocore2-lite", "vocore,vocore2", "mediatek,mt7628an-soc";
+	model = "VoCore2-Lite";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_vocore_vocore2.dts b/target/linux/ramips/dts/mt7628an_vocore_vocore2.dts
new file mode 100644
index 0000000..f4bb872
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_vocore_vocore2.dts
@@ -0,0 +1,62 @@
+#include "mt7628an_vocore_vocore2.dtsi"
+
+/ {
+	compatible = "vocore,vocore2", "mediatek,mt7628an-soc";
+	model = "VoCore2";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "fuchsia:status";
+			gpios = <&gpio 44 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_vocore_vocore2.dtsi b/target/linux/ramips/dts/mt7628an_vocore_vocore2.dtsi
new file mode 100644
index 0000000..bffcdf6
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_vocore_vocore2.dtsi
@@ -0,0 +1,55 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "vocore,vocore2", "mediatek,mt7628an-soc";
+
+	aliases {
+		label-mac-device = &wmac;
+	};
+
+	chosen {
+		bootargs = "console=ttyS2,115200";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "wled_an", "refclk", "wdt";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x7>;
+	mediatek,portdisable = <0x3a>;
+};
+
+&i2s {
+	status = "okay";
+};
+
+&gdma {
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_wavlink_wl-wn570ha1.dts b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn570ha1.dts
new file mode 100644
index 0000000..9cea8b4
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn570ha1.dts
@@ -0,0 +1,125 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "wavlink,wl-wn570ha1", "mediatek,mt7628an-soc";
+	model = "Wavlink WL-WN570HA1";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "green:power";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi-high {
+			label = "green:wifi-high";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi-med {
+			label = "green:wifi-med";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi-low {
+			label = "green:wifi-low";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wled_an", "p0led_an", "wdt", "refclk";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_wavlink_wl-wn575a3.dts b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn575a3.dts
new file mode 100644
index 0000000..d6d418f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn575a3.dts
@@ -0,0 +1,120 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "wavlink,wl-wn575a3", "mediatek,mt7628an-soc";
+	model = "Wavlink WL-WN575A3";
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi-high {
+			label = "green:wifi-high";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi-med {
+			label = "green:wifi-med";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi-low {
+			label = "green:wifi-low";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wled_an", "gpio", "refclk", "wdt", "p0led_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_wavlink_wl-wn577a2.dts b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn577a2.dts
new file mode 100644
index 0000000..b5f8ff0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wavlink_wl-wn577a2.dts
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "wavlink,wl-wn577a2", "maginon,wlr-755", "mediatek,mt7628an-soc";
+	model = "WAVLINK WL-WN577A2";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio 40 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "wdt", "p0led_an", "p3led_an", "p4led_an";
+		function = "gpio";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&usbphy {
+	status = "disabled";
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
diff --git a/target/linux/ramips/dts/mt7628an_widora_neo-16m.dts b/target/linux/ramips/dts/mt7628an_widora_neo-16m.dts
new file mode 100644
index 0000000..c6bd640
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_widora_neo-16m.dts
@@ -0,0 +1,56 @@
+#include "mt7628an_widora_neo.dtsi"
+
+/ {
+	compatible = "widora,neo-16m", "widora,neo", "mediatek,mt7628an-soc";
+	model = "Widora-NEO (16M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x0fb0000>;
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_widora_neo-32m.dts b/target/linux/ramips/dts/mt7628an_widora_neo-32m.dts
new file mode 100644
index 0000000..312e6a9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_widora_neo-32m.dts
@@ -0,0 +1,57 @@
+#include "mt7628an_widora_neo.dtsi"
+
+/ {
+	compatible = "widora,neo-32m", "widora,neo", "mediatek,mt7628an-soc";
+	model = "Widora-NEO (32M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <40000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_widora_neo.dtsi b/target/linux/ramips/dts/mt7628an_widora_neo.dtsi
new file mode 100644
index 0000000..4c60ad9
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_widora_neo.dtsi
@@ -0,0 +1,118 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "widora,neo", "mediatek,mt7628an-soc";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "orange:wifi";
+			gpios = <&wgpio 0 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	wgpio: gpio-wifi {
+		compatible = "mediatek,gpio-wifi";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+
+	perst {
+		groups = "perst";
+		function = "gpio";
+	};
+
+	refclk {
+		groups = "refclk";
+		function = "gpio";
+	};
+
+	i2s {
+		groups = "i2s";
+		function = "gpio";
+	};
+
+	spis {
+		groups = "spis";
+		function = "gpio";
+	};
+
+	wled_kn {
+		groups = "wled_kn";
+		function = "gpio";
+	};
+
+	wled_an {
+		groups = "wled_an";
+		function = "wled_an";
+	};
+
+	wdt {
+		groups = "wdt";
+		function = "gpio";
+	};
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-low;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts b/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts
new file mode 100644
index 0000000..08cf9ab
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wiznet_wizfi630s.dts
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wiznet,wizfi630s", "mediatek,mt7628an-soc";
+	model = "WIZnet WizFi630S";
+
+	chosen {
+		bootargs = "console=ttyS1,115200";
+	};
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+		serial0 = &uart1;
+		serial1 = &uartlite;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = "green:run";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+		};
+
+		ledwps {
+			label = "green:wps";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		leduart1 {
+			label = "green:uart1";
+			gpios = <&gpio 0 GPIO_ACTIVE_LOW>;
+		};
+
+		leduart2 {
+			label = "green:uart2";
+			gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		scm1 {
+			label = "SCM1";
+			gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+
+		scm2 {
+			label = "SCM2";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_2>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "i2s", "i2c", "wdt", "refclk", "p1led_an", "p2led_an";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins>, <&spi_cs1_pins>;
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&pwm {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+	mediatek,portdisable = <0x26>;
+};
+
+&sdhci {
+	status = "okay";
+	mediatek,cd-high;
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2.dtsi b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2.dtsi
new file mode 100644
index 0000000..2f2b942
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2.dtsi
@@ -0,0 +1,91 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wrtnode,wrtnode2", "mediatek,mt7628an-soc";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&sdhci {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2p.dts b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2p.dts
new file mode 100644
index 0000000..88ec3f0
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2p.dts
@@ -0,0 +1,29 @@
+#include "mt7628an_wrtnode_wrtnode2.dtsi"
+
+/ {
+	compatible = "wrtnode,wrtnode2p", "wrtnode,wrtnode2", "mediatek,mt7628an-soc";
+	model = "WRTnode2P";
+
+	aliases {
+		led-boot = &led_indicator;
+		led-failsafe = &led_indicator;
+		led-running = &led_indicator;
+		led-upgrade = &led_indicator;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_indicator: indicator {
+			label = "blue:indicator";
+			gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "gpio";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2r.dts b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2r.dts
new file mode 100644
index 0000000..511354a
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_wrtnode_wrtnode2r.dts
@@ -0,0 +1,51 @@
+#include "mt7628an_wrtnode_wrtnode2.dtsi"
+
+/ {
+	compatible = "wrtnode,wrtnode2r", "wrtnode,wrtnode2", "mediatek,mt7628an-soc";
+	model = "WRTnode2R";
+
+	aliases {
+		led-boot = &led_indicator;
+		led-failsafe = &led_indicator;
+		led-running = &led_indicator;
+		led-upgrade = &led_indicator;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		led_indicator: indicator {
+			label = "blue:indicator";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio";
+		function = "gpio";
+	};
+};
+
+&pinctrl {
+	led_pins: led {
+		gpio {
+			groups = "wled_an";
+			function = "gpio";
+		};
+	};
+};
+
+&spi0 {
+	spidev@1 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "linux,spidev";
+		reg = <1>;
+		spi-max-frequency = <10000000>;
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4.dtsi b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4.dtsi
new file mode 100644
index 0000000..0f5897f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4.dtsi
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		led-boot = &led_power_yellow;
+		led-failsafe = &led_power_yellow;
+		led-running = &led_power_blue;
+		led-upgrade = &led_power_yellow;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_blue: power_blue {
+			label = "blue:power";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power_yellow: power_yellow {
+			label = "yellow:power";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash0: flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions: partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "config";
+				reg = <0x20000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "crash";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				label = "cfg_bak";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			/* additional partitions in DTS */
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m.dts b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m.dts
new file mode 100644
index 0000000..37797fc
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4a-100m.dts
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_xiaomi_mi-router-4.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-4a-100m", "mediatek,mt7628an-soc";
+	model = "Xiaomi Mi Router 4A (100M Edition)";
+};
+
+&partitions {
+	partition@60000 {
+		label = "overlay";
+		reg = <0x60000 0x100000>;
+		read-only;
+	};
+
+	partition@160000 {
+		label = "firmware";
+		reg = <0x160000 0xea0000>;
+		compatible = "denx,uimage";
+	};
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	wifi@0,0 {
+		compatible = "mediatek,mt76";
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <(-1)>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+	mediatek,portdisable = <0x2a>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4c.dts b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4c.dts
new file mode 100644
index 0000000..4389a9d
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_mi-router-4c.dts
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7628an_xiaomi_mi-router-4.dtsi"
+
+/ {
+	compatible = "xiaomi,mi-router-4c", "mediatek,mt7628an-soc";
+	model = "Xiaomi Mi Router 4C";
+
+	aliases {
+		label-mac-device = &ethernet;
+	};
+};
+
+&flash0 {
+	spi-max-frequency = <40000000>;
+};
+
+&partitions {
+	partition@60000 {
+		label = "overlay";
+		reg = <0x60000 0x100000>;
+		read-only;
+	};
+
+	partition@160000 {
+		label = "firmware";
+		reg = <0x160000 0xea0000>;
+		compatible = "denx,uimage";
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3d>;
+	mediatek,portdisable = <0x29>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_xiaomi_miwifi-nano.dts b/target/linux/ramips/dts/mt7628an_xiaomi_miwifi-nano.dts
new file mode 100644
index 0000000..ae6a72e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_xiaomi_miwifi-nano.dts
@@ -0,0 +1,117 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "xiaomi,miwifi-nano", "mediatek,mt7628an-soc";
+	model = "Xiaomi MiWiFi Nano";
+
+	aliases {
+		led-boot = &led_status_amber;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_amber;
+		label-mac-device = &ethernet;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_blue: status_blue {
+			label = "blue:status";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_red: status_red {
+			label = "red:status";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_amber: status_amber {
+			label = "amber:status";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "refclk", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&ehci {
+	status = "disabled";
+};
+
+&ohci {
+	status = "disabled";
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,portdisable = <0x2a>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <40000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7628an_zbtlink_zbt-we1226.dts b/target/linux/ramips/dts/mt7628an_zbtlink_zbt-we1226.dts
new file mode 100644
index 0000000..ac2a01e
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_zbtlink_zbt-we1226.dts
@@ -0,0 +1,113 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "zbtlink,zbt-we1226", "mediatek,mt7628an-soc";
+	model = "Zbtlink ZBT-WE1226";
+
+	aliases {
+		led-boot = &led_wlan;
+		led-failsafe = &led_wlan;
+		led-running = &led_wlan;
+		led-upgrade = &led_wlan;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 38 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio 39 GPIO_ACTIVE_LOW>;
+		};
+
+		lan1 {
+			label = "green:lan1";
+			gpios = <&gpio 43 GPIO_ACTIVE_LOW>;
+		};
+
+		lan2 {
+			label = "green:lan2";
+			gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wlan: wlan {
+			label = "green:wlan";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "p0led_an", "p1led_an", "p4led_an", "wdt", "wled_an";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
diff --git a/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
new file mode 100644
index 0000000..7f21f1f
--- /dev/null
+++ b/target/linux/ramips/dts/mt7628an_zyxel_keenetic-extra-ii.dts
@@ -0,0 +1,200 @@
+#include "mt7628an.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-extra-ii", "mediatek,mt7628an-soc";
+	model = "ZyXEL Keenetic Extra II";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600n8";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		fn {
+			label = "fn";
+			gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+			default-state = "keep";
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio 44 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usbpower {
+			gpio-export,name = "usbpower";
+			gpio-export,output = <1>;
+			gpios = <&gpio 6 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		broken-flash-reset;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xe90000>;
+			};
+
+			partition@ee0000 {
+				label = "config_1";
+				reg = <0xee0000 0x10000>;
+				read-only;
+			};
+
+			partition@ef0000 {
+				label = "storage";
+				reg = <0xef0000 0x100000>;
+				read-only;
+			};
+
+			partition@ff0000 {
+				label = "dump";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+
+			partition@1000000 {
+				label = "u-state";
+				reg = <0x1000000 0x30000>;
+				read-only;
+			};
+
+			partition@1030000 {
+				label = "u-config_res";
+				reg = <0x1030000 0x10000>;
+				read-only;
+			};
+
+			partition@1040000 {
+				label = "rf-eeprom_res";
+				reg = <0x1040000 0x10000>;
+				read-only;
+			};
+
+			partition@1050000 {
+				label = "firmware_2";
+				reg = <0x1050000 0xe90000>;
+				read-only;
+			};
+
+			partition@1ee0000 {
+				label = "config_2";
+				reg = <0x1ee0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	status = "okay";
+};
+
+&pcie {
+	status = "okay";
+};
+
+&pcie0 {
+	mt76@0,0 {
+		reg = <0x0000 0 0 0 0>;
+		mediatek,mtd-eeprom = <&factory 0x8000>;
+		ieee80211-freq-limit = <5000000 6000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "gpio", "i2s", "refclk", "spi cs1", "uart1", "wled_an";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/rt2880.dtsi b/target/linux/ramips/dts/rt2880.dtsi
new file mode 100644
index 0000000..092b37a
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880.dtsi
@@ -0,0 +1,240 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,rt2880-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	aliases {
+		serial0 = &uartlite;
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	palmbus: palmbus@300000 {
+		compatible = "palmbus";
+		reg = <0x300000 0x200000>;
+		ranges = <0x0 0x300000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,rt2880-sysc";
+			reg = <0x000 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+
+			status = "disabled";
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,rt2880-memc";
+			reg = <0x300 0x100>;
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <32>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c: i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 9>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <8>;
+
+			reg-shift = <2>;
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+			sdram {
+				groups = "sdram";
+				function = "sdram";
+			};
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	pci: pci@440000 {
+		compatible = "ralink,rt288x-pci";
+		reg = <0x00440000 0x20000>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		status = "disabled";
+	};
+
+	ethernet: ethernet@400000 {
+		compatible = "ralink,rt2880-eth";
+		reg = <0x00400000 0x10000>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		resets = <&rstctrl 18>;
+		reset-names = "fe";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		status = "disabled";
+
+		port@0 {
+			compatible = "ralink,rt2880-port", "mediatek,eth-port";
+			reg = <0>;
+		};
+
+		mdio-bus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+	};
+
+	wmac: wmac@480000 {
+		compatible = "ralink,rt2880-wmac";
+		reg = <0x480000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+};
diff --git a/target/linux/ramips/dts/rt2880_airlink101_ar670w.dts b/target/linux/ramips/dts/rt2880_airlink101_ar670w.dts
new file mode 100644
index 0000000..9d78ca1
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_airlink101_ar670w.dts
@@ -0,0 +1,108 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "airlink101,ar670w", "ralink,rt2880-soc";
+	model = "Airlink101 AR670W";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@bdc00000 {
+		compatible = "cfi-flash";
+		reg = <0xbc400000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x30000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			factory: partition@30000 {
+				reg = <0x30000 0x10000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "lzma";
+				reg = <0x40000 0x3c0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wpsblue {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "uartlite";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x2004>;
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "mii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x2000>;
+};
diff --git a/target/linux/ramips/dts/rt2880_airlink101_ar725w.dts b/target/linux/ramips/dts/rt2880_airlink101_ar725w.dts
new file mode 100644
index 0000000..7038fc6
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_airlink101_ar725w.dts
@@ -0,0 +1,118 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "airlink101,ar725w", "ralink,rt2880-soc";
+	model = "Airlink101 AR725W";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@bdc00000 {
+		compatible = "cfi-flash";
+		reg = <0xbc400000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x30000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x30000 0x10000>;
+				label = "u-boot-env";
+			};
+
+			factory: partition@40000 {
+				reg = <0x40000 0x10000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x50000 0x3B0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		wpsred {
+			label = "red:wps";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		wpsblue {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "uartlite";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "mii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt2880_asus_rt-n15.dts b/target/linux/ramips/dts/rt2880_asus_rt-n15.dts
new file mode 100644
index 0000000..4b832fa
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_asus_rt-n15.dts
@@ -0,0 +1,116 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "asus,rt-n15", "ralink,rt2880-soc";
+	model = "Asus RT-N15";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	rtl8366s {
+		compatible = "realtek,rtl8366s";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartlite", "mdio";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt2880_belkin_f5d8235-v1.dts b/target/linux/ramips/dts/rt2880_belkin_f5d8235-v1.dts
new file mode 100644
index 0000000..cbaa3e8
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_belkin_f5d8235-v1.dts
@@ -0,0 +1,237 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "belkin,f5d8235-v1", "ralink,rt2880-soc";
+	model = "Belkin F5D8235 v1";
+
+	aliases {
+		led-boot = &led_wired_blue;
+		led-failsafe = &led_wired_blue;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0xbc400000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	rtl8366s {
+		compatible = "realtek,rtl8366s";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+
+		realtek,initvals = <
+			0x0242 0x02BF
+			0x0245 0x02BF
+			0x0248 0x02BF
+			0x024B 0x02BF
+			0x024E 0x02BF
+			0x0251 0x02BF
+			0x0254 0x0A3F
+			0x0256 0x0A3F
+			0x0258 0x0A3F
+			0x025A 0x0A3F
+			0x025C 0x0A3F
+			0x025E 0x0A3F
+			0x0263 0x007C
+			0x0100 0x0004
+			0xBE5B 0x3500
+			0x800E 0x200F
+			0xBE1D 0x0F00
+			0x8001 0x5011
+			0x800A 0xA2F4
+			0x800B 0x17A3
+			0xBE4B 0x17A3
+			0xBE41 0x5011
+			0xBE17 0x2100
+			0x8000 0x8304
+			0xBE40 0x8304
+			0xBE4A 0xA2F4
+			0x800C 0xA8D5
+			0x8014 0x5500
+			0x8015 0x0004
+			0xBE4C 0xA8D5
+			0xBE59 0x0008
+			0xBE09 0x0E00
+			0xBE36 0x1036
+			0xBE37 0x1036
+			0x800D 0x00FF
+			0xBE4D 0x00FF
+		>;
+
+		realtek,green-ethernet-features;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+
+		internet2 {
+			label = "amber:internet";
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+
+		modem {
+			label = "blue:modem";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		modem2 {
+			label = "amber:modem";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+
+		router {
+			label = "blue:router";
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		storage {
+			label = "blue:storage";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		storage2 {
+			label = "amber:storage";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		security {
+			label = "blue:security";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		security2 {
+			label = "amber:security";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wired_blue: wired {
+			label = "blue:wired";
+			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+		};
+
+		wired2 {
+			label = "amber:wired";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless {
+			label = "blue:wireless";
+			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+		};
+
+		wireless2 {
+			label = "amber:wireless";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "mdio", "uartlite";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+};
+
+&pci {
+	status = "okay";
+
+	usb@11,0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "pci1033,0035";
+		reg = <0x8800 0 0 0 0>;
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	usb@11,1 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "pci1033,00e0";
+		reg = <0x8900 0 0 0 0>;
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt2880_buffalo_wli-tx4-ag300n.dts b/target/linux/ramips/dts/rt2880_buffalo_wli-tx4-ag300n.dts
new file mode 100644
index 0000000..a1f10ae
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_buffalo_wli-tx4-ag300n.dts
@@ -0,0 +1,119 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "buffalo,wli-tx4-ag300n", "ralink,rt2880-soc";
+	model = "Buffalo WLI-TX4-AG300N";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		bandwidth {
+			label = "bandwidth";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		diag {
+			label = "red:diag";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		security {
+			label = "blue:security";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <100 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt2880_buffalo_wzr-agl300nh.dts b/target/linux/ramips/dts/rt2880_buffalo_wzr-agl300nh.dts
new file mode 100644
index 0000000..cd9e918
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_buffalo_wzr-agl300nh.dts
@@ -0,0 +1,141 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "buffalo,wzr-agl300nh", "ralink,rt2880-soc";
+	model = "Buffalo WZR-AGL300NH";
+
+	aliases {
+		led-boot = &led_router;
+		led-failsafe = &led_router;
+		led-running = &led_router;
+		led-upgrade = &led_router;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	rtl8366s {
+		compatible = "realtek,rtl8366s";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		router {
+			label = "router_switch";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+			linux,code = <BTN_0>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_router: router {
+			label = "green:router";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		diag {
+			label = "red:diag";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		security_g {
+			label = "orange:security_g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		security_n {
+			label = "orange:security_n";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartlite", "mdio";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt2880_dlink_dap-1522-a1.dts b/target/linux/ramips/dts/rt2880_dlink_dap-1522-a1.dts
new file mode 100644
index 0000000..3de9dc7
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_dlink_dap-1522-a1.dts
@@ -0,0 +1,141 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dap-1522-a1", "ralink,rt2880-soc";
+	model = "D-Link DAP-1522 A1";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@bc400000 {
+		compatible = "cfi-flash";
+		reg = <0xbc400000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				compatible = "wrg";
+				label = "firmware";
+				reg = <0x40000 0x3a0000>;
+			};
+		};
+	};
+
+	rtl8366s {
+		compatible = "realtek,rtl8366s";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio2 16 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+
+		bridge {
+			label = "bridge";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio2 17 GPIO_ACTIVE_LOW>;
+		};
+
+		ap {
+			label = "blue:ap";
+			gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
+		};
+
+		sta {
+			label = "red:sta";
+			gpios = <&gpio2 19 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status: status {
+			label = "blue:status";
+			gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio2 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartlite", "pci";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x2004>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			phy-mode = "mii";
+			reg = <0>;
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x2000>;
+};
diff --git a/target/linux/ramips/dts/rt2880_ralink_v11st-fe.dts b/target/linux/ramips/dts/rt2880_ralink_v11st-fe.dts
new file mode 100644
index 0000000..39045bf
--- /dev/null
+++ b/target/linux/ramips/dts/rt2880_ralink_v11st-fe.dts
@@ -0,0 +1,84 @@
+#include "rt2880.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,v11st-fe", "ralink,rt2880-soc";
+	model = "Ralink V11ST-FE";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x0030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x00050000 0x003b0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&ethernet {
+	status = "okay";
+};
+
+&pci {
+	status = "okay";
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050.dtsi b/target/linux/ramips/dts/rt3050.dtsi
new file mode 100644
index 0000000..847c216
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050.dtsi
@@ -0,0 +1,358 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,rt3050-soc", "ralink,rt3052-soc", "ralink,rt3350-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		serial0 = &uartlite;
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,rt3050-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,rt3050-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,rt3050-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		uart: uart@500 {
+			compatible = "ralink,rt3050-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0x500 0x100>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uart";
+
+			interrupt-parent = <&intc>;
+			interrupts = <5>;
+
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,rt3050-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <12>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gdma: gdma@700 {
+			compatible = "ralink,rt305x-gdma";
+			reg = <0x700 0x100>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <8>;
+
+			status = "disabled";
+		};
+
+		i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s@a00 {
+			compatible = "ralink,rt3050-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+
+			dmas = <&gdma 4>;
+			dma-names = "tx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,rt3050-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x100>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,rt3050-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			reg-shift = <2>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+			sdram {
+				groups = "sdram";
+				function = "sdram";
+			};
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		rgmii_pins: rgmii {
+			rgmii {
+				groups = "rgmii";
+				function = "rgmii";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt3050-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	usbphy: usbphy {
+		compatible = "ralink,rt3050-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22>;
+		reset-names = "host";
+		clocks = <&clkctrl 18>;
+		clock-names = "host";
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "ralink,rt3050-eth";
+		reg = <0x10100000 0x10000>;
+
+		resets = <&rstctrl 21>;
+		reset-names = "fe";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		mediatek,switch = <&esw>;
+	};
+
+	esw: esw@10110000 {
+		compatible = "ralink,rt3050-esw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt3050-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+
+	otg: otg@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "ralink,rt3050-otg", "snps,dwc2";
+		reg = <0x101c0000 0x40000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		resets = <&rstctrl 22>;
+		reset-names = "otg";
+
+		status = "disabled";
+
+		otg_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_8devices_carambola.dts b/target/linux/ramips/dts/rt3050_8devices_carambola.dts
new file mode 100644
index 0000000..4ad23ff
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_8devices_carambola.dts
@@ -0,0 +1,79 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "8devices,carambola", "ralink,rt3050-soc";
+	model = "8devices Carambola";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	i2c-gpio {
+		compatible = "i2c-gpio";
+		gpios = <&gpio0 1 GPIO_ACTIVE_HIGH &gpio0 2 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <10>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_allnet_all0256n-4m.dts b/target/linux/ramips/dts/rt3050_allnet_all0256n-4m.dts
new file mode 100644
index 0000000..efb96da
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_allnet_all0256n-4m.dts
@@ -0,0 +1,46 @@
+#include "rt3050_allnet_all0256n.dtsi"
+
+/ {
+	compatible = "allnet,all0256n-4m", "allnet,all0256n", "ralink,rt3050-soc";
+	model = "Allnet ALL0256N (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_allnet_all0256n-8m.dts b/target/linux/ramips/dts/rt3050_allnet_all0256n-8m.dts
new file mode 100644
index 0000000..866d9a9
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_allnet_all0256n-8m.dts
@@ -0,0 +1,46 @@
+#include "rt3050_allnet_all0256n.dtsi"
+
+/ {
+	compatible = "allnet,all0256n-8m", "allnet,all0256n", "ralink,rt3050-soc";
+	model = "Allnet ALL0256N (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_allnet_all0256n.dtsi b/target/linux/ramips/dts/rt3050_allnet_all0256n.dtsi
new file mode 100644
index 0000000..7458165
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_allnet_all0256n.dtsi
@@ -0,0 +1,57 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "allnet,all0256n", "ralink,rt3050-soc";
+
+	leds {
+		compatible = "gpio-leds";
+
+		rssilow {
+			label = "green:rssilow";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		rssimed {
+			label = "green:rssimed";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		rssihigh {
+			label = "green:rssihigh";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-16m.dts b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-16m.dts
new file mode 100644
index 0000000..9cc29d0
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-16m.dts
@@ -0,0 +1,64 @@
+#include "rt3050_alphanetworks_asl26555.dtsi"
+
+/ {
+	compatible = "alphanetworks,asl26555-16m", "alphanetworks,asl26555", "ralink,rt3050-soc";
+	model = "Alpha ASL26555 (16M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xf80000>;
+			};
+
+			partition@fd0000 {
+				label = "cert";
+				reg = <0xfd0000 0x10000>;
+				read-only;
+			};
+
+			partition@fe0000 {
+				label = "langpack";
+				reg = <0xfe0000 0x10000>;
+				read-only;
+			};
+
+			devdata: partition@ff0000 {
+				label = "devdata";
+				reg = <0xff0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-8m.dts b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-8m.dts
new file mode 100644
index 0000000..c5465b4
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555-8m.dts
@@ -0,0 +1,58 @@
+#include "rt3050_alphanetworks_asl26555.dtsi"
+
+/ {
+	compatible = "alphanetworks,asl26555-8m", "alphanetworks,asl26555", "ralink,rt3050-soc";
+	model = "Alpha ASL26555 (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "rgdb";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "cert";
+				reg = <0x7e0000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "langpack";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_alphanetworks_asl26555.dtsi b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555.dtsi
new file mode 100644
index 0000000..028238a
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_alphanetworks_asl26555.dtsi
@@ -0,0 +1,101 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alphanetworks,asl26555", "ralink,rt3050-soc";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		eth {
+			label = "green:eth";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wan-red {
+			label = "red:wan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		wan-green {
+			label = "green:wan";
+			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power_green: power-green {
+			label = "green:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		power-red {
+			label = "red:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		3g-green {
+			label = "green:3g";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		3g-red {
+			label = "red:3g";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devdata 0x4004>;
+};
+
+&esw {
+	mediatek,portmap = <0x1e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devdata 0x4000>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_arcwireless_freestation5.dts b/target/linux/ramips/dts/rt3050_arcwireless_freestation5.dts
new file mode 100644
index 0000000..44b2ad4
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_arcwireless_freestation5.dts
@@ -0,0 +1,110 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "arcwireless,freestation5", "ralink,rt3050-soc";
+	model = "ARC FreeStation5";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+
+		/*
+		 * Used to enable power-over-ethernet passthrough from port0 to port1.
+		 * Disable passthrough by default to prevent accidental equipment damage.
+		 */
+		poe {
+			gpio-export,name = "poe-passthrough";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/*
+		 * The following leds are defined in the ArcOS firmware, but reportedly
+		 * not present in the Freestation5 device.
+		 */
+		wifi {
+			label = "unknown:wifi";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		powerg {
+			label = "unknown:powerg";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "unknown:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x01>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_asus_rt-g32-b1.dts b/target/linux/ramips/dts/rt3050_asus_rt-g32-b1.dts
new file mode 100644
index 0000000..0baa2fe
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_asus_rt-g32-b1.dts
@@ -0,0 +1,85 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-g32-b1", "ralink,rt3050-soc";
+	model = "Asus RT-G32 B1";
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			devconf: partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devconf 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devconf 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_asus_rt-n10-plus.dts b/target/linux/ramips/dts/rt3050_asus_rt-n10-plus.dts
new file mode 100644
index 0000000..5c19755
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_asus_rt-n10-plus.dts
@@ -0,0 +1,91 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n10-plus", "ralink,rt3050-soc";
+	model = "Asus RT-N10+";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			devconf: partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devconf 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devconf 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_asus_wl-330n.dts b/target/linux/ramips/dts/rt3050_asus_wl-330n.dts
new file mode 100644
index 0000000..cc6cd38
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_asus_wl-330n.dts
@@ -0,0 +1,106 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,wl-330n", "ralink,rt3050-soc";
+	model = "Asus WL-330N";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		link {
+			label = "blue:link";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_asus_wl-330n3g.dts b/target/linux/ramips/dts/rt3050_asus_wl-330n3g.dts
new file mode 100644
index 0000000..c2513c5
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_asus_wl-330n3g.dts
@@ -0,0 +1,115 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,wl-330n3g", "ralink,rt3050-soc";
+	model = "Asus WL-330N3G";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		3g2 {
+			label = "red:3g";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_dlink_dcs-930.dts b/target/linux/ramips/dts/rt3050_dlink_dcs-930.dts
new file mode 100644
index 0000000..ff01fe2
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_dlink_dcs-930.dts
@@ -0,0 +1,112 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dcs-930", "ralink,rt3050-soc";
+	model = "D-Link DCS-930";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x400000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "red:alert";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "jtag", "mdio", "rgmii", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_dlink_dir-300-b1.dts b/target/linux/ramips/dts/rt3050_dlink_dir-300-b1.dts
new file mode 100644
index 0000000..7699dca
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_dlink_dir-300-b1.dts
@@ -0,0 +1,118 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-300-b1", "ralink,rt3050-soc";
+	model = "D-Link DIR-300 B1";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status {
+			label = "amber:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_green: status2 {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "amber:wan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wan2 {
+			label = "green:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "jtag", "mdio", "rgmii", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devdata 0x4004>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devdata 0x4000>;
+};
diff --git a/target/linux/ramips/dts/rt3050_dlink_dir-600-b1.dts b/target/linux/ramips/dts/rt3050_dlink_dir-600-b1.dts
new file mode 100644
index 0000000..21f0a73
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_dlink_dir-600-b1.dts
@@ -0,0 +1,118 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-600-b1", "ralink,rt3050-soc";
+	model = "D-Link DIR-600 B1";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status {
+			label = "amber:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_green: status2 {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "amber:wan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wan2 {
+			label = "green:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "jtag", "mdio", "rgmii", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devdata 0x4004>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devdata 0x4000>;
+};
diff --git a/target/linux/ramips/dts/rt3050_dlink_dir-615-d.dts b/target/linux/ramips/dts/rt3050_dlink_dir-615-d.dts
new file mode 100644
index 0000000..e84c9d9
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_dlink_dir-615-d.dts
@@ -0,0 +1,116 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-615-d", "ralink,rt3050-soc";
+	model = "D-Link DIR-615 D";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+		label-mac-device = &wmac;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status_amber {
+			label = "amber:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_green: status_green {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wan_amber {
+			label = "amber:wan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wan_green {
+			label = "green:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devdata 0x4000>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "jtag", "mdio", "rgmii", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/rt3050_dlink_dir-620-a1.dts b/target/linux/ramips/dts/rt3050_dlink_dir-620-a1.dts
new file mode 100644
index 0000000..c134803
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_dlink_dir-620-a1.dts
@@ -0,0 +1,127 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-620-a1", "ralink,rt3050-soc";
+	model = "D-Link DIR-620 A1";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status {
+			label = "amber:status";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_green: status2 {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "amber:wan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wan2 {
+			label = "green:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		wps2 {
+			label = "amber:wps";
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts b/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts
new file mode 100644
index 0000000..07ff8bc
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_edimax_3g-6200n.dts
@@ -0,0 +1,123 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,3g-6200n", "ralink,rt3050-soc";
+	model = "Edimax 3g-6200n";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@3e0000 {
+				label = "cimage";
+				reg = <0x3e0000 0x20000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x50000 0x390000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "amber:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "wlanswitch";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts b/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts
new file mode 100644
index 0000000..f339b7e
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_edimax_3g-6200nl.dts
@@ -0,0 +1,110 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,3g-6200nl", "ralink,rt3050-soc";
+	model = "Edimax 3g-6200nl";
+
+	aliases {
+		led-boot = &led_internet;
+		led-failsafe = &led_internet;
+		led-running = &led_internet;
+		led-upgrade = &led_internet;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@3e0000 {
+				label = "cimage";
+				reg = <0x3e0000 0x20000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				label = "firmware";
+				reg = <0x50000 0x390000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_internet: internet {
+			label = "green:internet";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portdisable = <0x37>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_huawei_d105.dts b/target/linux/ramips/dts/rt3050_huawei_d105.dts
new file mode 100644
index 0000000..2784b0c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_huawei_d105.dts
@@ -0,0 +1,103 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "huawei,d105", "ralink,rt3050-soc";
+	model = "Huawei D105";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_jcg_jhr-n805r.dts b/target/linux/ramips/dts/rt3050_jcg_jhr-n805r.dts
new file mode 100644
index 0000000..581edc6
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_jcg_jhr-n805r.dts
@@ -0,0 +1,95 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,jhr-n805r", "ralink,rt3050-soc";
+	model = "JCG JHR-N805R";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_netcore_nw718.dts b/target/linux/ramips/dts/rt3050_netcore_nw718.dts
new file mode 100644
index 0000000..124a2ba
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_netcore_nw718.dts
@@ -0,0 +1,117 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netcore,nw718", "ralink,rt3050-soc";
+	model = "Netcore NW718";
+
+	aliases {
+		led-boot = &led_cpu;
+		led-failsafe = &led_cpu;
+		led-running = &led_cpu;
+		led-upgrade = &led_cpu;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_cpu: cpu {
+			label = "amber:cpu";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "amber:usb";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps {
+			label = "amber:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x20000>;
+				read-only;
+			};
+
+			factory: partition@50000 {
+				label = "factory";
+				reg = <0x50000 0x10000>;
+				read-only;
+			};
+
+			partition@60000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x60000 0x3a0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_sparklan_wcr-150gn.dts b/target/linux/ramips/dts/rt3050_sparklan_wcr-150gn.dts
new file mode 100644
index 0000000..e457491
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_sparklan_wcr-150gn.dts
@@ -0,0 +1,109 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sparklan,wcr-150gn", "ralink,rt3050-soc";
+	model = "Sparklan WCR-150GN";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		user {
+			label = "amber:user";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: power {
+			label = "amber:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_teltonika_rut5xx.dts b/target/linux/ramips/dts/rt3050_teltonika_rut5xx.dts
new file mode 100644
index 0000000..742edbb
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_teltonika_rut5xx.dts
@@ -0,0 +1,99 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "teltonika,rut5xx", "ralink,rt3050-soc";
+	model = "Teltonika RUT5XX";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3050_tenda_w150m.dts b/target/linux/ramips/dts/rt3050_tenda_w150m.dts
new file mode 100644
index 0000000..2826993
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_tenda_w150m.dts
@@ -0,0 +1,123 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tenda,w150m", "ralink,rt3050-soc";
+	model = "Tenda W150M";
+
+	aliases {
+		led-boot = &led_ap;
+		led-failsafe = &led_ap;
+		led-running = &led_ap;
+		led-upgrade = &led_ap;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3grouter {
+			label = "blue:3grouter";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_ap: ap {
+			label = "blue:ap";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wisprouter {
+			label = "blue:wisprouter";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wirelessrouter {
+			label = "blue:wirelessrouter";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wpsreset {
+			label = "blue:wpsreset";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3050_trendnet_tew-638apb-v2.dts b/target/linux/ramips/dts/rt3050_trendnet_tew-638apb-v2.dts
new file mode 100644
index 0000000..7df592b
--- /dev/null
+++ b/target/linux/ramips/dts/rt3050_trendnet_tew-638apb-v2.dts
@@ -0,0 +1,103 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "trendnet,tew-638apb-v2", "ralink,rt3050-soc";
+	model = "TRENDnet TEW-638APB v2";
+
+	aliases {
+		led-boot = &led_wps_green;
+		led-failsafe = &led_wps_green;
+		led-running = &led_wps_green;
+		led-upgrade = &led_wps_green;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x400000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "orange:wps";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps_green: wps2 {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_accton_wr6202.dts b/target/linux/ramips/dts/rt3052_accton_wr6202.dts
new file mode 100644
index 0000000..fac721c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_accton_wr6202.dts
@@ -0,0 +1,115 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "accton,wr6202", "ralink,rt3052-soc";
+	model = "Accton WR6202";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_alfa-network_w502u.dts b/target/linux/ramips/dts/rt3052_alfa-network_w502u.dts
new file mode 100644
index 0000000..d88df8c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_alfa-network_w502u.dts
@@ -0,0 +1,113 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "alfa-network,w502u", "ralink,rt3052-soc";
+	model = "ALFA Network W502U";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_wps: wps {
+			label = "blue:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_argus_atp-52b.dts b/target/linux/ramips/dts/rt3052_argus_atp-52b.dts
new file mode 100644
index 0000000..39afaa5
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_argus_atp-52b.dts
@@ -0,0 +1,105 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "argus,atp-52b", "ralink,rt3052-soc";
+	model = "Argus ATP-52B";
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7a0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = "green:run";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		net {
+			label = "amber:net";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_asiarf_awapn2403.dts b/target/linux/ramips/dts/rt3052_asiarf_awapn2403.dts
new file mode 100644
index 0000000..5d73043
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_asiarf_awapn2403.dts
@@ -0,0 +1,91 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asiarf,awapn2403", "ralink,rt3052-soc";
+	model = "AsiaRF AWAPN2403";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_asus_rt-n13u.dts b/target/linux/ramips/dts/rt3052_asus_rt-n13u.dts
new file mode 100644
index 0000000..a67a839
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_asus_rt-n13u.dts
@@ -0,0 +1,107 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n13u", "ralink,rt3052-soc";
+	model = "Asus RT-N13U";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "blue:wifi";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <10>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_aximcom_mr-102n.dts b/target/linux/ramips/dts/rt3052_aximcom_mr-102n.dts
new file mode 100644
index 0000000..2d5f077
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_aximcom_mr-102n.dts
@@ -0,0 +1,125 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "aximcom,mr-102n", "ralink,rt3052-soc";
+	model = "AXIMCom MR-102N";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "nvram";
+				reg = <0x7e0000 0x10000>;
+			};
+
+			partition@7f0000 {
+				label = "nvram_backup";
+				reg = <0x7f0000 0x10000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_status: status {
+			label = "amber:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	status = "okay";
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_aztech_hw550-3g.dts b/target/linux/ramips/dts/rt3052_aztech_hw550-3g.dts
new file mode 100644
index 0000000..f58a519
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_aztech_hw550-3g.dts
@@ -0,0 +1,125 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "aztech,hw550-3g", "ralink,rt3052-soc";
+	model = "Aztech HW550-3G";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		connect {
+			label = "connect";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_CONNECT>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_belkin_f5d8235-v2.dts b/target/linux/ramips/dts/rt3052_belkin_f5d8235-v2.dts
new file mode 100644
index 0000000..a9db288
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_belkin_f5d8235-v2.dts
@@ -0,0 +1,142 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "belkin,f5d8235-v2", "ralink,rt3052-soc";
+	model = "Belkin F5D8235 v2";
+
+	aliases {
+		led-boot = &led_router;
+		led-failsafe = &led_router;
+		led-running = &led_router;
+		led-upgrade = &led_router;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			uboot: partition@0 {
+				label = "uboot";
+				reg = <0x0 0x50000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+
+			partition@7e0000 {
+				label = "nvram";
+				reg = <0x7e0000 0x10000>;
+			};
+
+			factory: partition@7f0000 {
+				label = "factory";
+				reg = <0x7f0000 0x10000>;
+			};
+		};
+	};
+
+	rtl8366rb {
+		compatible = "realtek,rtl8366rb";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		internet {
+			label = "blue:internet";
+			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+		};
+
+		internet2 {
+			label = "amber:internet";
+			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+		};
+
+		modem {
+			label = "blue:modem";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		modem2 {
+			label = "amber:modem";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		led_router: router {
+			label = "blue:router";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		storage {
+			label = "blue:storage";
+			gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		storage2 {
+			label = "amber:storage";
+			gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
+		};
+
+		security {
+			label = "blue:security";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		security2 {
+			label = "amber:security";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&uboot 0x40004>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+};
+
+&esw {
+	ralink,rgmii = <1>;
+	mediatek,portmap = <0x3f>;
+	ralink,fct2 = <0x0002500c>;
+	/*
+	 * ext phy base addr 31, rx/tx clock skew 0,
+	 * turbo mii off, rgmi 3.3v off, port 5 polling off
+	 * port5: enabled, gige, full-duplex, rx/tx-flow-control
+	 * port6: enabled, gige, full-duplex, rx/tx-flow-control
+	*/
+	ralink,fpa2 = <0x1f003fff>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&uboot 0x40000>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_buffalo_whr-g300n.dts b/target/linux/ramips/dts/rt3052_buffalo_whr-g300n.dts
new file mode 100644
index 0000000..ca6259d
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_buffalo_whr-g300n.dts
@@ -0,0 +1,125 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "buffalo,whr-g300n", "ralink,rt3052-soc";
+	model = "Buffalo WHR-G300N";
+
+	aliases {
+		led-boot = &led_diag;
+		led-failsafe = &led_diag;
+		led-upgrade = &led_diag;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3a0000>;
+			};
+
+			partition@3f0000 {
+				label = "user";
+				reg = <0x3f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_diag: diag {
+			label = "red:diag";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		router {
+			label = "green:router";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		security {
+			label = "amber:security";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		aoss {
+			label = "aoss";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		router-off {
+			label = "router-off";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_2>;
+		};
+
+		router-on {
+			label = "router-on";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_3>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_dlink_dap-1350.dts b/target/linux/ramips/dts/rt3052_dlink_dap-1350.dts
new file mode 100644
index 0000000..a2584e0
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_dlink_dap-1350.dts
@@ -0,0 +1,134 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dap-1350", "ralink,rt3052-soc";
+	model = "D-Link DAP-1350";
+
+	aliases {
+		led-boot = &led_power_blue;
+		led-failsafe = &led_power_blue;
+		led-running = &led_power_blue;
+		led-upgrade = &led_power_blue;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x30000>;
+				read-only;
+			};
+
+			partition@70000 {
+				label = "devlang";
+				reg = <0x70000 0x40000>;
+				read-only;
+			};
+
+			partition@b0000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0xb0000 0x750000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_blue: power {
+			label = "blue:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		power2 {
+			label = "red:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rt {
+			label = "rt";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devdata 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devdata 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_engenius_esr-9753.dts b/target/linux/ramips/dts/rt3052_engenius_esr-9753.dts
new file mode 100644
index 0000000..4566e7a
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_engenius_esr-9753.dts
@@ -0,0 +1,103 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "engenius,esr-9753", "ralink,rt3052-soc";
+	model = "Senao / EnGenius ESR-9753";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "orange:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "orange:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_fon_fonera-20n.dts b/target/linux/ramips/dts/rt3052_fon_fonera-20n.dts
new file mode 100644
index 0000000..9d89c6e
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_fon_fonera-20n.dts
@@ -0,0 +1,153 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "fon,fonera-20n", "ralink,rt3052-soc";
+	model = "La Fonera 2.0N";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "orange:wifi";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "orange:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		switch {
+			label = "switch";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi", "jtag", "mdio", "rgmii", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	mediatek,portmap = <0x2f>;
+
+	port@0 {
+		compatible = "swconfig,port";
+		reg = <0>;
+		swconfig,segment = "lan";
+		swconfig,portmap = <0 4>;
+	};
+
+	port@1 {
+		compatible = "swconfig,port";
+		reg = <1>;
+		swconfig,segment = "lan";
+		swconfig,portmap = <1 3>;
+	};
+
+	port@2 {
+		compatible = "swconfig,port";
+		reg = <2>;
+		swconfig,segment = "lan";
+		swconfig,portmap = <2 2>;
+	};
+
+	port@3 {
+		compatible = "swconfig,port";
+		reg = <3>;
+		swconfig,segment = "lan";
+		swconfig,portmap = <3 1>;
+	};
+
+	port@4 {
+		compatible = "swconfig,port";
+		reg = <4>;
+		swconfig,segment = "wan";
+		swconfig,portmap = <4 0>;
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_hauppauge_broadway.dts b/target/linux/ramips/dts/rt3052_hauppauge_broadway.dts
new file mode 100644
index 0000000..6734f5b
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_hauppauge_broadway.dts
@@ -0,0 +1,96 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hauppauge,broadway", "ralink,rt3052-soc";
+	model = "Hauppauge Broadway";
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x790000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		diskmounted {
+			label = "red:diskmounted";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps_active {
+			label = "red:wps_active";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		factory {
+			label = "Factory Reset button";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_huawei_hg255d.dts b/target/linux/ramips/dts/rt3052_huawei_hg255d.dts
new file mode 100644
index 0000000..92ea59b
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_huawei_hg255d.dts
@@ -0,0 +1,141 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "huawei,hg255d", "ralink,rt3052-soc";
+	model = "HuaWei HG255D";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x1000000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x40000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			factory: partition@60000 {
+				label = "factory";
+				reg = <0x60000 0x20000>;
+				read-only;
+			};
+
+			partition@80000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x80000 0xf60000>;
+			};
+
+			partition@fa0000 {
+				label = "factory-orig";
+				reg = <0xfa0000 0x20000>;
+				read-only;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		voice {
+			label = "green:voice";
+			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <10>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_jcg_jhr-n825r.dts b/target/linux/ramips/dts/rt3052_jcg_jhr-n825r.dts
new file mode 100644
index 0000000..7b71af4
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_jcg_jhr-n825r.dts
@@ -0,0 +1,90 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,jhr-n825r", "ralink,rt3052-soc";
+	model = "JCG JHR-N825R";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led_system: system {
+			label = "red:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_jcg_jhr-n926r.dts b/target/linux/ramips/dts/rt3052_jcg_jhr-n926r.dts
new file mode 100644
index 0000000..5431443
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_jcg_jhr-n926r.dts
@@ -0,0 +1,136 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "jcg,jhr-n926r", "ralink,rt3052-soc";
+	model = "JCG JHR-N926R";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan1 {
+			label = "red:wlan";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan2 {
+			label = "yellow:wlan";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan3 {
+			label = "green:wlan";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		display_data {
+			gpio-export,name = "display_data";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		display_clock {
+			gpio-export,name = "display_clock";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		display_blank {
+			gpio-export,name = "display_blank";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wlan {
+			label = "wlan";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x2e>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_mofinetwork_mofi3500-3gn.dts b/target/linux/ramips/dts/rt3052_mofinetwork_mofi3500-3gn.dts
new file mode 100644
index 0000000..245f01c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_mofinetwork_mofi3500-3gn.dts
@@ -0,0 +1,122 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "mofinetwork,mofi3500-3gn", "ralink,rt3052-soc";
+	model = "MoFi Network MOFI3500-3GN";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		connect {
+			label = "connect";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_CONNECT>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_netgear_wnce2001.dts b/target/linux/ramips/dts/rt3052_netgear_wnce2001.dts
new file mode 100644
index 0000000..e5d70bd
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_netgear_wnce2001.dts
@@ -0,0 +1,145 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "netgear,wnce2001", "ralink,rt3052-soc";
+	model = "Netgear WNCE2001";
+
+	aliases {
+		led-boot = &led_power_green;
+		led-failsafe = &led_power_green;
+		led-running = &led_power_green;
+		led-upgrade = &led_power_green;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power_green: power-green {
+			label = "green:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		power-red {
+			label = "red:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan-green {
+			label = "green:wlan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		wlan-red {
+			label = "red:wlan";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rt {
+			label = "rt";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		ap {
+			label = "ap";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			factory: partition@30000 {
+				label = "factory";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "config";
+				reg = <0x40000 0x20000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "language";
+				reg = <0x60000 0x30000>;
+				read-only;
+			};
+
+			partition@90000 {
+				label = "pot";
+				reg = <0x90000 0x10000>;
+				read-only;
+			};
+
+			partition@a0000 {
+				label = "checksum";
+				reg = <0xa0000 0x10000>;
+			};
+
+			partition@b0000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0xb0000 0x350000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_nexaira_bc2.dts b/target/linux/ramips/dts/rt3052_nexaira_bc2.dts
new file mode 100644
index 0000000..d3d5afe
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_nexaira_bc2.dts
@@ -0,0 +1,91 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "nexaira,bc2", "ralink,rt3052-soc";
+	model = "NexAira BC2";
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_omnima_miniembwifi.dts b/target/linux/ramips/dts/rt3052_omnima_miniembwifi.dts
new file mode 100644
index 0000000..bc3dd5e
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_omnima_miniembwifi.dts
@@ -0,0 +1,101 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "omnima,miniembwifi", "ralink,rt3052-soc";
+	model = "Omnima MiniEMBWiFi";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_petatel_psr-680w.dts b/target/linux/ramips/dts/rt3052_petatel_psr-680w.dts
new file mode 100644
index 0000000..b17097c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_petatel_psr-680w.dts
@@ -0,0 +1,100 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "petatel,psr-680w", "ralink,rt3052-soc";
+	model = "Petatel PSR-680W Wireless 3G Router";
+
+	aliases {
+		led-boot = &led_wan;
+		led-failsafe = &led_wan;
+		led-running = &led_wan;
+		led-upgrade = &led_wan;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wan: wan {
+			label = "red:wan";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_planex_mzk-w300nh2.dts b/target/linux/ramips/dts/rt3052_planex_mzk-w300nh2.dts
new file mode 100644
index 0000000..ff199f8
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_planex_mzk-w300nh2.dts
@@ -0,0 +1,120 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,mzk-w300nh2", "ralink,rt3052-soc";
+	model = "Planex MZK-W300NH2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@3e0000 {
+				label = "cimage";
+				reg = <0x3e0000 0x20000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x390000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "amber:wlan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "amber:wps";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rt {
+			label = "rt";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_planex_mzk-wdpr.dts b/target/linux/ramips/dts/rt3052_planex_mzk-wdpr.dts
new file mode 100644
index 0000000..7f660d6
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_planex_mzk-wdpr.dts
@@ -0,0 +1,89 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "planex,mzk-wdpr", "ralink,rt3052-soc";
+	model = "Planex MZK-WDPR";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@7f0000 {
+				label = "Data3G";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x680000>;
+			};
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+
+		lcd_ctrl1 {
+			gpio-export,name = "lcd_ctrl1";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_poray_ip2202.dts b/target/linux/ramips/dts/rt3052_poray_ip2202.dts
new file mode 100644
index 0000000..f3dab80
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_poray_ip2202.dts
@@ -0,0 +1,97 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "poray,ip2202", "ralink,rt3052-soc";
+	model = "Poray IP2202";
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = "green:run";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		net {
+			label = "amber:net";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_prolink_pwh2004.dts b/target/linux/ramips/dts/rt3052_prolink_pwh2004.dts
new file mode 100644
index 0000000..312007c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_prolink_pwh2004.dts
@@ -0,0 +1,93 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "prolink,pwh2004", "ralink,rt3052-soc";
+	model = "Prolink PWH2004";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "red:wifi";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_ralink_v22rw-2x2.dts b/target/linux/ramips/dts/rt3052_ralink_v22rw-2x2.dts
new file mode 100644
index 0000000..2689feb
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_ralink_v22rw-2x2.dts
@@ -0,0 +1,103 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,v22rw-2x2", "ralink,rt3052-soc";
+	model = "Ralink AP-RT3052-V22RW-2X2";
+
+	aliases {
+		led-boot = &led_security;
+		led-failsafe = &led_security;
+		led-running = &led_security;
+		led-upgrade = &led_security;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_security: security {
+			label = "green:security";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "red:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_sitecom_wl-351.dts b/target/linux/ramips/dts/rt3052_sitecom_wl-351.dts
new file mode 100644
index 0000000..f4aa24e
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_sitecom_wl-351.dts
@@ -0,0 +1,129 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sitecom,wl-351", "ralink,rt3052-soc";
+	model = "Sitecom WL-351 v1 002";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "amber:power";
+			gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+		};
+
+		unpopulated {
+			label = "amber:unpopulated";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		unpopulated2 {
+			label = "blue:unpopulated";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	rtl8366rb {
+		compatible = "realtek,rtl8366rb";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>;
+};
+
+&esw {
+	ralink,rgmii = <1>;
+	mediatek,portmap = <0x3f>;
+	ralink,fct2 = <0x0002500c>;
+	/*
+	 * ext phy base addr 31, rx/tx clock skew 0,
+	 * turbo mii off, rgmi 3.3v off, port 5 polling off
+	 * port5: enabled, gige, full-duplex, rx/tx-flow-control
+	 * port6: enabled, gige, full-duplex, rx/tx-flow-control
+	*/
+	ralink,fpa2 = <0x1f003fff>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_skyline_sl-r7205.dts b/target/linux/ramips/dts/rt3052_skyline_sl-r7205.dts
new file mode 100644
index 0000000..89e6c9e
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_skyline_sl-r7205.dts
@@ -0,0 +1,102 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "skyline,sl-r7205", "ralink,rt3052-soc";
+	model = "Skyline SL-R7205 Wireless 3G Router";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_tenda_3g300m.dts b/target/linux/ramips/dts/rt3052_tenda_3g300m.dts
new file mode 100644
index 0000000..dcebe64
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_tenda_3g300m.dts
@@ -0,0 +1,132 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tenda,3g300m", "ralink,rt3052-soc";
+	model = "Tenda 3G300M";
+
+	aliases {
+		led-boot = &led_ap;
+		led-failsafe = &led_ap;
+		led-running = &led_ap;
+		led-upgrade = &led_ap;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3grouter {
+			label = "blue:3grouter";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		led_ap: ap {
+			label = "blue:ap";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wisprouter {
+			label = "blue:wisprouter";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wirelessrouter {
+			label = "blue:wirelessrouter";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wpsreset {
+			label = "blue:wpsreset";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_tenda_w306r-v2.dts b/target/linux/ramips/dts/rt3052_tenda_w306r-v2.dts
new file mode 100644
index 0000000..f6c1b2d
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_tenda_w306r-v2.dts
@@ -0,0 +1,97 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tenda,w306r-v2", "ralink,rt3052-soc";
+	model = "Tenda W306R V2.0";
+
+	aliases {
+		led-boot = &led_sys;
+		led-failsafe = &led_sys;
+		led-running = &led_sys;
+		led-upgrade = &led_sys;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_sys: sys {
+			label = "green:sys";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "RESET/WPS";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-4m.dts b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-4m.dts
new file mode 100644
index 0000000..d3393c0
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-4m.dts
@@ -0,0 +1,43 @@
+#include "rt3052_unbranded_wr512-3gn.dtsi"
+
+/ {
+	compatible = "unbranded,wr512-3gn-4m", "unbranded,wr512-3gn", "ralink,rt3052-soc";
+	model = "WR512-3GN (4M)";
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-8m.dts b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-8m.dts
new file mode 100644
index 0000000..ce25dc9
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn-8m.dts
@@ -0,0 +1,43 @@
+#include "rt3052_unbranded_wr512-3gn.dtsi"
+
+/ {
+	compatible = "unbranded,wr512-3gn-8m", "unbranded,wr512-3gn", "ralink,rt3052-soc";
+	model = "WR512-3GN (8M)";
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn.dtsi b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn.dtsi
new file mode 100644
index 0000000..dad0da1
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_unbranded_wr512-3gn.dtsi
@@ -0,0 +1,80 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unbranded,wr512-3gn", "ralink,rt3052-soc";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		gateway {
+			label = "green:gateway";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		ap {
+			label = "green:ap";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		station {
+			label = "green:station";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_unbranded_xdx-rn502j.dts b/target/linux/ramips/dts/rt3052_unbranded_xdx-rn502j.dts
new file mode 100644
index 0000000..d94da95
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_unbranded_xdx-rn502j.dts
@@ -0,0 +1,101 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unbranded,xdx-rn502j", "ralink,rt3052-soc";
+	model = "XDX RN502J";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_upvel_ur-326n4g.dts b/target/linux/ramips/dts/rt3052_upvel_ur-326n4g.dts
new file mode 100644
index 0000000..fc71437
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_upvel_ur-326n4g.dts
@@ -0,0 +1,122 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "upvel,ur-326n4g", "ralink,rt3052-soc";
+	model = "UPVEL UR-326N4G";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		gateway {
+			label = "green:gateway";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		ap {
+			label = "green:ap";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		station {
+			label = "green:station";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4004>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_upvel_ur-336un.dts b/target/linux/ramips/dts/rt3052_upvel_ur-336un.dts
new file mode 100644
index 0000000..2c00ca8
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_upvel_ur-336un.dts
@@ -0,0 +1,122 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "upvel,ur-336un", "ralink,rt3052-soc";
+	model = "UPVEL UR-336UN";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		gateway {
+			label = "green:gateway";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		ap {
+			label = "green:ap";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		station {
+			label = "green:station";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4004>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
new file mode 100644
index 0000000..6c65d34
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_zyxel_keenetic.dts
@@ -0,0 +1,121 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic", "ralink,rt3052-soc";
+	model = "ZyXEL Keenetic";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&otg_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RFKILL>;
+			linux,input-type = <EV_SW>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&otg {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
new file mode 100644
index 0000000..db4f8d4
--- /dev/null
+++ b/target/linux/ramips/dts/rt3052_zyxel_nbg-419n.dts
@@ -0,0 +1,103 @@
+#include "rt3050.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,nbg-419n", "ralink,rt3052-soc";
+	model = "ZyXEL NBG-419N";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1f000000 {
+		compatible = "cfi-flash";
+		reg = <0x1f000000 0x800000>;
+		bank-width = <2>;
+		device-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3352.dtsi b/target/linux/ramips/dts/rt3352.dtsi
new file mode 100644
index 0000000..2a51b14
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352.dtsi
@@ -0,0 +1,401 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,rt3352-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		spi1 = &spi1;
+		serial0 = &uartlite;
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,rt3352-sysc", "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,rt3352-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,rt3352-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,rt3352-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,rt3352-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		uart: uart@500 {
+			compatible = "ralink,rt3352-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0x500 0x100>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uart";
+
+			interrupt-parent = <&intc>;
+			interrupts = <5>;
+
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,rt3352-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <6>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s@a00 {
+			compatible = "ralink,rt3352-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,rt3352-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+
+			status = "disabled";
+		};
+
+		spi1: spi@b40 {
+			compatible = "ralink,rt3352-spi", "ralink,rt2880-spi";
+			reg = <0xb40 0x60>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_cs1>;
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,rt3352-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			reg-shift = <2>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		mdio_pins: mdio {
+			mdio {
+				groups = "mdio";
+				function = "mdio";
+			};
+		};
+
+		rgmii_pins: rgmii {
+			rgmii {
+				groups = "rgmii";
+				function = "rgmii";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		spi_cs1: spi1 {
+			spi1 {
+				groups = "spi_cs1";
+				function = "spi_cs1";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt3352-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "ralink,rt3352-eth", "ralink,rt3050-eth";
+		reg = <0x10100000 0x10000>;
+
+		resets = <&rstctrl 21>;
+		reset-names = "fe";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		mediatek,switch = <&esw>;
+	};
+
+	esw: esw@10110000 {
+		compatible = "ralink,rt3352-esw", "ralink,rt3050-esw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	usbphy: usbphy {
+		compatible = "ralink,rt3352-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+		clocks = <&clkctrl 18 &clkctrl 20>;
+		clock-names = "host", "device";
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt3352-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		status = "disabled";
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		status = "disabled";
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3352_allnet_all5002.dts b/target/linux/ramips/dts/rt3352_allnet_all5002.dts
new file mode 100644
index 0000000..3aa132a
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352_allnet_all5002.dts
@@ -0,0 +1,111 @@
+#include "rt3352.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "allnet,all5002", "ralink,rt3352-soc";
+	model = "Allnet ALL5002";
+
+	i2c-gpio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "i2c-gpio";
+		gpios = <&gpio0 1 GPIO_ACTIVE_HIGH &gpio0 2 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <10>;
+
+		pcf0: iexp@38 {
+			#gpio-cells = <2>;
+			compatible = "inxp,pcf8574a";
+			reg = <0x38>;
+			gpio-controller;
+		};
+
+		hwmon@4b {
+			compatible = "national,lm92";
+			reg = <0x4b>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		ld1 {
+			label = "green:ld1";
+			gpios = <&pcf0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		ld2 {
+			label = "green:ld2";
+			gpios = <&pcf0 1 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3352_dlink_dir-615-h1.dts b/target/linux/ramips/dts/rt3352_dlink_dir-615-h1.dts
new file mode 100644
index 0000000..2233c90
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352_dlink_dir-615-h1.dts
@@ -0,0 +1,125 @@
+#include "rt3352.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-615-h1", "ralink,rt3352-soc";
+	model = "D-Link DIR-615 H1";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_green;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+		label-mac-device = &wmac;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status {
+			label = "amber:status";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_status_green: status2 {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		wan {
+			label = "amber:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		wan2 {
+			label = "green:wan";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins &mdio_pins>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3352_dlink_dir-620-d1.dts b/target/linux/ramips/dts/rt3352_dlink_dir-620-d1.dts
new file mode 100644
index 0000000..50b762c
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352_dlink_dir-620-d1.dts
@@ -0,0 +1,110 @@
+#include "rt3352.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-620-d1", "ralink,rt3352-soc";
+	model = "D-Link DIR-620 D1";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins &mdio_pins>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3352_zte_mf283plus.dts b/target/linux/ramips/dts/rt3352_zte_mf283plus.dts
new file mode 100644
index 0000000..a91d0e6
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352_zte_mf283plus.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rt3352.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zte,mf283plus", "ralink,rt3352-soc";
+	model = "ZTE MF283+";
+
+	aliases {
+		led-boot = &led_wwan_green;
+		led-failsafe = &led_wwan_red;
+		led-upgrade = &led_wwan_red;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wwan_blue: wwan_blue {
+			label = "blue:wwan";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wwan_green: wwan_green {
+			label = "green:wwan";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wwan_red: wwan_red {
+			label = "red:wwan";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+		};
+
+		signal {
+			label = "blue:signal";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x60000>;
+				read-only;
+			};
+
+			partition@60000 {
+				label = "u-boot-env";
+				reg = <0x60000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@70000 {
+				label = "factory";
+				reg = <0x70000 0x10000>;
+				read-only;
+			};
+
+			partition@80000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x80000 0xf80000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
new file mode 100644
index 0000000..84bb645
--- /dev/null
+++ b/target/linux/ramips/dts/rt3352_zyxel_nbg-419n-v2.dts
@@ -0,0 +1,125 @@
+#include "rt3352.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,nbg-419n-v2", "ralink,rt3352-soc";
+	model = "ZyXEL NBG-419N v2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+		rfkill {
+			label = "rfkill";
+			linux,input-type = <EV_SW>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "rgmii", "mdio", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
new file mode 100644
index 0000000..98426b8
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_asus_rt-n56u.dts
@@ -0,0 +1,147 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asus,rt-n56u", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "Asus RT-N56U";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x0030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x00050000 0x007b0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	rtl8367 {
+		compatible = "realtek,rtl8367";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "blue:lan";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "blue:wan";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,0 {
+		compatible = "pci1814,3091";
+		reg = <0x10000 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,2ghz = <0>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_dlink_dir-645.dts b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
new file mode 100644
index 0000000..2331375
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_dlink_dir-645.dts
@@ -0,0 +1,148 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-645", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "D-Link DIR-645";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	rtl8367b {
+		compatible = "realtek,rtl8367b";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		inet {
+			label = "green:inet";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x4000>;
+				read-only;
+			};
+
+			factory: partition@34000 {
+				label = "factory";
+				reg = <0x34000 0x4000>;
+				read-only;
+			};
+
+			partition@38000 {
+				label = "nvram";
+				reg = <0x38000 0x8000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devdata";
+				reg = <0x40000 0x10000>;
+			};
+
+			partition@50000 {
+				compatible = "seama";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 0>;
+	};
+};
+
+&wmac {
+	ralink,5ghz = <0>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
new file mode 100644
index 0000000..56d9dc0
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_edimax_br-6475nd.dts
@@ -0,0 +1,175 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/mtd/partitions/uimage.h>
+
+/ {
+	compatible = "edimax,br-6475nd", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "Edimax BR-6475nD";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,input-type = <EV_SW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan {
+			label = "amber:wlan";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		wlan_5ghz {
+			label = "amber:wlan_5ghz";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x00000000 0x00030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "nvram";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			devdata: partition@50000 {
+				reg = <0x00050000 0x00020000>;
+				label = "devdata";
+				read-only;
+			};
+
+			partition@70000 {
+				compatible = "openwrt,uimage", "denx,uimage";
+				openwrt,offset = <FW_EDIMAX_OFFSET>;
+				openwrt,partition-magic = <FW_MAGIC_EDIMAX>;
+				reg = <0x00070000 0x00790000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	rtl8367 {
+		compatible = "realtek,rtl8367";
+		gpio-sda = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+	};
+
+	/*
+	 * Unclear if this is the correct gpio setup; the USB ports are
+	 * unpopulated on a stock BR-6475nD, even though the hardware exists
+	 * and the headers are there.
+	 */
+	/*
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name="usb";
+			gpio-export,output=<0>;
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+	*/
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&timer {
+	status = "okay";
+};
+
+&uartlite {
+	status = "okay";
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&devdata 0xd>;
+
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,0 {
+		compatible = "pci0,0";
+		reg = <0x10000 0 0 0 0>;
+		ralink,5ghz = <0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_engenius_esr600h.dts b/target/linux/ramips/dts/rt3662_engenius_esr600h.dts
new file mode 100644
index 0000000..cce44ed
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_engenius_esr600h.dts
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "engenius,esr600h", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "EnGenius ESR600H";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset-wps {
+			label = "reset-wps";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x1000>;
+			};
+
+			partition@32000 {
+				label = "config";
+				reg = <0x32000 0xe000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+
+			qca,ar8327-initvals = <
+				0x04 0x07600000 /* PORT0 PAD MODE CTRL */
+				0x0c 0x07600000 /* PORT6 PAD MODE CTRL */
+				0x10 0x40000000 /* Power-on Strapping: 176-pin interface configuration */
+				0x50 0xc437c437 /* LED Control Register 0 */
+				0x54 0xc337c337 /* LED Control Register 1 */
+				0x58 0x00000000 /* LED Control Register 2 */
+				0x5c 0x03ffff00 /* LED Control Register 3 */
+				0x7c 0x0000007e /* PORT0_STATUS */
+				0x94 0x0000007e /* PORT6 STATUS */
+			>;
+		};
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,1,0 {
+		compatible = "pci1814,3091";
+		reg = <0x0 1 0 0 0>;
+		ralink,5ghz = <0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+
+	ralink,2ghz = <0>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_loewe_wmdr-143n.dts b/target/linux/ramips/dts/rt3662_loewe_wmdr-143n.dts
new file mode 100644
index 0000000..2501c17
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_loewe_wmdr-143n.dts
@@ -0,0 +1,66 @@
+#include "rt3883.dtsi"
+
+/ {
+	compatible = "loewe,wmdr-143n", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "Loewe WMDR-143N";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x00010000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "mii";
+	};
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "mii";
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt3662_omnima_hpm.dts b/target/linux/ramips/dts/rt3662_omnima_hpm.dts
new file mode 100644
index 0000000..c0f30ec
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_omnima_hpm.dts
@@ -0,0 +1,158 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "omnima,hpm", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "Omnima HPM";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power {
+			label = "orange:power";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+
+		eth {
+			label = "green:eth";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		eth2 {
+			label = "red:eth";
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+
+		wifi2 {
+			label = "red:wifi";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+		/* gpio 12 and 13 handle the OC input */
+
+		usb0 {
+			gpio-export,name = "usb0";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb1 {
+			gpio-export,name = "usb1";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x0030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "config";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x00050000 0x00fb0000>;
+				label = "firmware";
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	phy-handle = <&phy0>;
+	phy-mode = "rgmii";
+	mtd-mac-address = <&factory 0x28>;
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@4 {
+			reg = <4>;
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
new file mode 100644
index 0000000..ad41785
--- /dev/null
+++ b/target/linux/ramips/dts/rt3662_samsung_cy-swr1100.dts
@@ -0,0 +1,154 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "samsung,cy-swr1100", "ralink,rt3662-soc", "ralink,rt3883-soc";
+	model = "Samsung CY-SWR1100";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x4000>;
+				read-only;
+			};
+
+			factory: partition@34000 {
+				label = "factory";
+				reg = <0x34000 0x4000>;
+				read-only;
+			};
+
+			partition@38000 {
+				label = "nvram";
+				reg = <0x38000 0x8000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "seama";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+
+	rtl8367 {
+		compatible = "realtek,rtl8367";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		realtek,extif0 = <1 0 1 1 1 1 1 1 2>;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "blue:usb";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "spi";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,0 {
+		compatible = "pci1814,3091";
+		reg = <0x10000 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x2000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,2ghz = <0>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3883.dtsi b/target/linux/ramips/dts/rt3883.dtsi
new file mode 100644
index 0000000..a605d60
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883.dtsi
@@ -0,0 +1,499 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,rt3883-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips74Kc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		spi1 = &spi1;
+		serial0 = &uartlite;
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,rt3883-sysc", "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,rt3883-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,rt3883-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,rt3883-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,rt3883-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		uart: uart@500 {
+			compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0x500 0x100>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uart";
+
+			interrupt-parent = <&intc>;
+			interrupts = <5>;
+
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+		};
+
+		gpio1: gpio@638 {
+			compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+			reg = <0x638 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <24>;
+			ralink,num-gpios = <16>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio2: gpio@660 {
+			compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <40>;
+			ralink,num-gpios = <32>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		gpio3: gpio@688 {
+			compatible = "ralink,rt3883-gpio", "ralink,rt2880-gpio";
+			reg = <0x688 0x24>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <72>;
+			ralink,num-gpios = <24>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+		};
+
+		i2s@a00 {
+			compatible = "ralink,rt3883-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+
+			status = "disabled";
+		};
+
+		spi1: spi@b40 {
+			compatible = "ralink,rt3883-spi", "ralink,rt2880-spi";
+			reg = <0xb40 0x60>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_cs1>;
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,rt3883-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			reg-shift = <2>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		spi_cs1: spi1 {
+			spi1 {
+				groups = "pci";
+				function = "pci-func";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+
+		pci_pins: pci {
+			pci {
+				groups = "pci";
+				function = "pci-fnc";
+			};
+		};
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "ralink,rt3883-eth";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x10100000 0x10000>;
+
+		resets = <&rstctrl 21>;
+		reset-names = "fe";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		port@0 {
+			compatible = "ralink,rt3883-port", "mediatek,eth-port";
+			reg = <0>;
+		};
+
+		mdio-bus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt3883-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	pci: pci@10140000 {
+		compatible = "ralink,rt3883-pci";
+		reg = <0x10140000 0x20000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges; /* direct mapping */
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pci_pins>;
+
+		status = "disabled";
+
+		pciintc: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <4>;
+		};
+
+		pci@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			#interrupt-cells = <1>;
+
+			device_type = "pci";
+
+			bus-range = <0 255>;
+			ranges = <
+				0x02000000 0 0x00000000 0x20000000 0 0x10000000 /* pci memory */
+				0x01000000 0 0x00000000 0x10160000 0 0x00010000 /* io space */
+			>;
+
+			interrupt-map-mask = <0xf800 0 0 7>;
+			interrupt-map = <
+				/* IDSEL 17 */
+				0x8800 0 0 1 &pciintc 18
+				0x8800 0 0 2 &pciintc 18
+				0x8800 0 0 3 &pciintc 18
+				0x8800 0 0 4 &pciintc 18
+				/* IDSEL 18 */
+				0x9000 0 0 1 &pciintc 19
+				0x9000 0 0 2 &pciintc 19
+				0x9000 0 0 3 &pciintc 19
+				0x9000 0 0 4 &pciintc 19
+			>;
+
+			pci1: pci@1 {
+				reg = <0x0800 0 0 0 0>;
+				device_type = "pci";
+				#interrupt-cells = <1>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				status = "disabled";
+
+				interrupt-map-mask = <0x0 0 0 0>;
+				interrupt-map = <0x0 0 0 0 &pciintc 20>;
+
+				bus-range = <1 255>;
+				ranges;
+			};
+
+			pci17: pci@11,0 {
+				reg = <0x8800 0 0 0 0>;
+				#interrupt-cells = <1>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				status = "disabled";
+			};
+
+			pci18: pci@12,0 {
+				reg = <0x9000 0 0 0 0>;
+				#interrupt-cells = <1>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+
+				status = "disabled";
+			};
+		};
+	};
+
+	usbphy: usbphy {
+		compatible = "ralink,rt3352-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+		clocks = <&clkctrl 22 &clkctrl 25>;
+		clock-names = "host", "device";
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt3883-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		status = "disabled";
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		status = "disabled";
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts b/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts
new file mode 100644
index 0000000..78c9bb4
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883_belkin_f9k1109v1.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rt3883_belkin_f9k110x.dtsi"
+
+/ {
+	compatible = "belkin,f9k1109v1", "ralink,rt3883-soc";
+	model = "Belkin F9K1109 Version 1.0";
+
+	aliases {
+		led-boot = &led_status_amber;
+		led-failsafe = &led_status_amber;
+		led-running = &led_status_blue;
+		led-upgrade = &led_status_amber;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status_amber: internet_amber {
+			label = "amber:internet";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_blue: internet_blue {
+			label = "blue:internet";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		usb1 {
+			label = "green:usb1";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		usb2 {
+			label = "green:usb2";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port2>, <&ehci_port2>;
+			linux,default-trigger = "usbport";
+		};
+
+		wps_amber {
+			label = "amber:wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		wps_blue {
+			label = "blue:wps";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&ehci {
+	ehci_port2: port@2 {
+		reg = <2>;
+		#trigger-source-cells = <0>;
+	};
+};
+
+&ohci {
+	ohci_port2: port@2 {
+		reg = <2>;
+		#trigger-source-cells = <0>;
+	};
+};
diff --git a/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi b/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
new file mode 100644
index 0000000..0b2c760
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883_belkin_f9k110x.dtsi
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "ralink,rt3883-soc";
+
+	rtl8367b {
+		compatible = "realtek,rtl8367b";
+		gpio-sda = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		gpio-sck = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		realtek,extif1 = <1 0 1 1 1 1 1 1 2>;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <25000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7a0000>;
+			};
+
+			partition@7f0000 {
+				label = "user-cfg";
+				reg = <0x7f0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&ethernet {
+	port@0 {
+		mediatek,fixed-link = <1000 1 1 1>;
+		phy-mode = "rgmii";
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@1,0 {
+		compatible = "pci1814,3091";
+		reg = <0x10000 0 0 0 0>;
+		ralink,5ghz = <0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3883_sitecom_wlr-6000.dts b/target/linux/ramips/dts/rt3883_sitecom_wlr-6000.dts
new file mode 100644
index 0000000..ccf9917
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883_sitecom_wlr-6000.dts
@@ -0,0 +1,182 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "sitecom,wlr-6000", "ralink,rt3883-soc";
+	model = "Sitecom WLR-6000";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		ops {
+			label = "white:ops";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x8004>;
+	mtd-mac-address-increment = <1>;
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+
+			qca,ar8327-initvals = <
+				0x04 0x07600000 /* PORT0 PAD MODE CTRL */
+				0x0c 0x07600000 /* PORT6 PAD MODE CTRL */
+				0x10 0x40000000 /* Power-on Strapping: 176-pin interface configuration */
+				0x50 0xc437c437 /* LED Control Register 0 */
+				0x54 0xc337c337 /* LED Control Register 1 */
+				0x58 0x00000000 /* LED Control Register 2 */
+				0x5c 0x03ffff00 /* LED Control Register 3 */
+				0x7c 0x0000007e /* PORT0_STATUS */
+				0x94 0x0000007e /* PORT6 STATUS */
+			>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <8600000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x713000>;
+			};
+
+			partition@763000 {
+				label = "manufacture";
+				reg = <0x763000 0x7D000>;
+				read-only;
+			};
+
+			partition@7E0000 {
+				label = "backup";
+				reg = <0x7E0000 0x10000>;
+				read-only;
+			};
+
+			partition@7F0000 {
+				label = "storage";
+				reg = <0x7F0000 0x10000>;
+				read-only;
+			};
+		};
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,0 {
+		compatible = "pci1814,3091";
+		reg = <0x10000 0 0 0 0>;
+		ralink,mtd-eeprom = <&factory 0x8000>;
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,2ghz = <0>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&ehci {
+	status = "okay";
+};
+
+&ohci {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt3883_trendnet_tew-691gr.dts b/target/linux/ramips/dts/rt3883_trendnet_tew-691gr.dts
new file mode 100644
index 0000000..03e504a
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883_trendnet_tew-691gr.dts
@@ -0,0 +1,121 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "trendnet,tew-691gr", "ralink,rt3883-soc";
+	model = "TRENDnet TEW-691GR";
+
+	aliases {
+		led-boot = &led_wps;
+		led-failsafe = &led_wps;
+		led-running = &led_wps;
+		led-upgrade = &led_wps;
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x0030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x00050000 0x007b0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		rfkill {
+			label = "rfkill";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wps: wps {
+			label = "green:wps";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+		};
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,5ghz = <0>;
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <1>;
+};
diff --git a/target/linux/ramips/dts/rt3883_trendnet_tew-692gr.dts b/target/linux/ramips/dts/rt3883_trendnet_tew-692gr.dts
new file mode 100644
index 0000000..95a2bb7
--- /dev/null
+++ b/target/linux/ramips/dts/rt3883_trendnet_tew-692gr.dts
@@ -0,0 +1,147 @@
+#include "rt3883.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "trendnet,tew-692gr", "ralink,rt3883-soc";
+	model = "TRENDnet TEW-692GR";
+
+	aliases {
+		led-boot = &led_wps_green;
+		led-failsafe = &led_wps_green;
+		led-running = &led_wps_green;
+		led-upgrade = &led_wps_green;
+	};
+
+	flash@1c000000 {
+		compatible = "cfi-flash";
+		reg = <0x1c000000 0x800000>;
+		bank-width = <2>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x0030000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@30000 {
+				reg = <0x00030000 0x00010000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			factory: partition@40000 {
+				reg = <0x00040000 0x00010000>;
+				label = "factory";
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				reg = <0x00050000 0x007b0000>;
+				label = "firmware";
+			};
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <100>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		wps {
+			label = "orange:wps";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		led_wps_green: wps2 {
+			label = "green:wps";
+			gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "spi", "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	status = "okay";
+	mtd-mac-address = <&factory 0x4>;
+
+	port@0 {
+		phy-handle = <&phy0>;
+		phy-mode = "rgmii";
+	};
+
+	mdio-bus {
+		status = "okay";
+
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+			phy-mode = "rgmii";
+
+			qca,ar8327-initvals = <
+				0x04 0x07600000 /* PORT0 PAD MODE CTRL */
+				0x0c 0x07600000 /* PORT6 PAD MODE CTRL */
+				0x10 0x40000000 /* Power-on Strapping: 176-pin interface configuration */
+				0x50 0xc437c437 /* LED Control Register 0 */
+				0x54 0xc337c337 /* LED Control Register 1 */
+				0x58 0x00000000 /* LED Control Register 2 */
+				0x5c 0x03ffff00 /* LED Control Register 3 */
+				0x7c 0x0000007e /* PORT0_STATUS */
+				0x94 0x0000007e /* PORT6 STATUS */
+			>;
+		};
+	};
+};
+
+&pci {
+	status = "okay";
+};
+
+&pci1 {
+	status = "okay";
+
+	wifi@0,0 {
+		compatible = "pci0,0";
+		reg = < 0x10000 0 0 0 0 >;
+		ralink,2ghz = <0>;
+	};
+};
+
+&wmac {
+	status = "okay";
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,5ghz = <0>;
+	mtd-mac-address = <&factory 0x4>;
+	mtd-mac-address-increment = <3>;
+};
diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi
new file mode 100644
index 0000000..da282b5
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350.dtsi
@@ -0,0 +1,411 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ralink,rt5350-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			compatible = "mips,mips24KEc";
+			reg = <0>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	cpuintc: cpuintc {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	aliases {
+		spi0 = &spi0;
+		spi1 = &spi1;
+		serial0 = &uartlite;
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1FFFFF>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "ralink,rt5350-sysc", "ralink,rt3050-sysc", "syscon";
+			reg = <0x0 0x100>;
+		};
+
+		timer: timer@100 {
+			compatible = "ralink,rt5350-timer", "ralink,rt2880-timer";
+			reg = <0x100 0x20>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		watchdog: watchdog@120 {
+			compatible = "ralink,rt5350-wdt", "ralink,rt2880-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl 8>;
+			reset-names = "wdt";
+
+			interrupt-parent = <&intc>;
+			interrupts = <1>;
+		};
+
+		intc: intc@200 {
+			compatible = "ralink,rt5350-intc", "ralink,rt2880-intc";
+			reg = <0x200 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "intc";
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <2>;
+		};
+
+		memc: memc@300 {
+			compatible = "ralink,rt5350-memc", "ralink,rt3050-memc";
+			reg = <0x300 0x100>;
+
+			resets = <&rstctrl 20>;
+			reset-names = "mc";
+
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+		};
+
+		uart: uart@500 {
+			compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0x500 0x100>;
+
+			resets = <&rstctrl 12>;
+			reset-names = "uart";
+
+			interrupt-parent = <&intc>;
+			interrupts = <5>;
+
+			reg-shift = <2>;
+
+			status = "disabled";
+		};
+
+		gpio0: gpio@600 {
+			compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+			reg = <0x600 0x34>;
+
+			resets = <&rstctrl 13>;
+			reset-names = "pio";
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <0>;
+			ralink,num-gpios = <22>;
+			ralink,register-map = [ 00 04 08 0c
+						20 24 28 2c
+						30 34 ];
+		};
+
+		gpio1: gpio@660 {
+			compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
+			reg = <0x660 0x24>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <6>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			ralink,gpio-base = <22>;
+			ralink,num-gpios = <6>;
+			ralink,register-map = [ 00 04 08 0c
+						10 14 18 1c
+						20 24 ];
+
+			status = "disabled";
+		};
+
+		i2c: i2c@900 {
+			compatible = "ralink,rt2880-i2c";
+			reg = <0x900 0x100>;
+
+			resets = <&rstctrl 16>;
+			reset-names = "i2c";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c_pins>;
+
+			status = "disabled";
+		};
+
+		i2s: i2s@a00 {
+			compatible = "ralink,rt3352-i2s";
+			reg = <0xa00 0x100>;
+
+			resets = <&rstctrl 17>;
+			reset-names = "i2s";
+
+			interrupt-parent = <&intc>;
+			interrupts = <10>;
+
+			txdma-req = <2>;
+			rxdma-req = <3>;
+
+			dmas = <&gdma 4>,
+				<&gdma 6>;
+			dma-names = "tx", "rx";
+
+			status = "disabled";
+		};
+
+		spi0: spi@b00 {
+			compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
+			reg = <0xb00 0x40>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins>;
+
+			status = "disabled";
+		};
+
+		spi1: spi@b40 {
+			compatible = "ralink,rt5350-spi", "ralink,rt2880-spi";
+			reg = <0xb40 0x60>;
+
+			resets = <&rstctrl 18>;
+			reset-names = "spi";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_cs1>;
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "ralink,rt5350-uart", "ralink,rt2880-uart", "ns16550a";
+			reg = <0xc00 0x100>;
+
+			resets = <&rstctrl 19>;
+			reset-names = "uartl";
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartlite_pins>;
+
+			reg-shift = <2>;
+		};
+
+		systick: systick@d00 {
+			compatible = "ralink,rt5350-systick", "ralink,cevt-systick";
+			reg = <0xd00 0x10>;
+
+			interrupt-parent = <&cpuintc>;
+			interrupts = <7>;
+		};
+
+		pcm: pcm@2000 {
+			compatible = "ralink,rt5350-pcm";
+			reg = <0x2000 0x800>;
+
+			resets = <&rstctrl 11>;
+			reset-names = "pcm";
+
+			interrupt-parent = <&intc>;
+			interrupts = <4>;
+
+			status = "disabled";
+		};
+
+		gdma: gdma@2800 {
+			compatible = "ralink,rt3883-gdma";
+			reg = <0x2800 0x800>;
+
+			resets = <&rstctrl 14>;
+			reset-names = "dma";
+
+			interrupt-parent = <&intc>;
+			interrupts = <7>;
+
+			#dma-cells = <1>;
+			#dma-channels = <16>;
+			#dma-requests = <16>;
+
+			status = "disabled";
+		};
+	};
+
+	pinctrl: pinctrl {
+		compatible = "ralink,rt2880-pinmux";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinctrl0 {
+		};
+
+		i2c_pins: i2c_pins {
+			i2c_pins {
+				groups = "i2c";
+				function = "i2c";
+			};
+		};
+
+		spi_pins: spi_pins {
+			spi_pins {
+				groups = "spi";
+				function = "spi";
+			};
+		};
+
+		phy_led_pins: phy_led {
+			phy_led {
+				groups = "led";
+				function = "led";
+			};
+		};
+
+		uartlite_pins: uartlite {
+			uart {
+				groups = "uartlite";
+				function = "uartlite";
+			};
+		};
+
+		uartf_pins: uartf {
+			uartf {
+				groups = "uartf";
+				function = "uartf";
+			};
+		};
+
+		spi_cs1: spi1 {
+			spi1 {
+				groups = "spi_cs1";
+				function = "spi_cs1";
+			};
+		};
+	};
+
+	rstctrl: rstctrl {
+		compatible = "ralink,rt5350-reset", "ralink,rt2880-reset";
+		#reset-cells = <1>;
+	};
+
+	clkctrl: clkctrl {
+		compatible = "ralink,rt2880-clock";
+		#clock-cells = <1>;
+	};
+
+	usbphy: usbphy {
+		compatible = "ralink,rt3352-usbphy";
+		#phy-cells = <0>;
+
+		ralink,sysctl = <&sysc>;
+		resets = <&rstctrl 22 &rstctrl 25>;
+		reset-names = "host", "device";
+		clocks = <&clkctrl 18>;
+		clock-names = "host";
+	};
+
+	ethernet: ethernet@10100000 {
+		compatible = "ralink,rt5350-eth";
+		reg = <0x10100000 0x10000>;
+
+		resets = <&rstctrl 21 &rstctrl 23>;
+		reset-names = "fe", "esw";
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <5>;
+
+		mediatek,switch = <&esw>;
+	};
+
+	esw: esw@10110000 {
+		compatible = "ralink,rt5350-esw", "ralink,rt3050-esw";
+		reg = <0x10110000 0x8000>;
+
+		resets = <&rstctrl 23>;
+		reset-names = "esw";
+
+		interrupt-parent = <&intc>;
+		interrupts = <17>;
+	};
+
+	wmac: wmac@10180000 {
+		compatible = "ralink,rt5350-wmac", "ralink,rt2880-wmac";
+		reg = <0x10180000 0x40000>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <6>;
+
+		ralink,eeprom = "soc_wmac.eeprom";
+	};
+
+	ehci: ehci@101c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		ehci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+
+	ohci: ohci@101c1000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "generic-ohci";
+		reg = <0x101c1000 0x1000>;
+
+		phys = <&usbphy>;
+		phy-names = "usb";
+
+		interrupt-parent = <&intc>;
+		interrupts = <18>;
+
+		ohci_port1: port@1 {
+			reg = <1>;
+			#trigger-source-cells = <0>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_7links_px-4885-4m.dts b/target/linux/ramips/dts/rt5350_7links_px-4885-4m.dts
new file mode 100644
index 0000000..383bde7
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_7links_px-4885-4m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_7links_px-4885.dtsi"
+
+/ {
+	compatible = "7links,px-4885-4m", "7links,px-4885", "ralink,rt5350-soc";
+	model = "7Links PX-4885 (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "devdata";
+				reg = <0x20000 0x20000>;
+				read-only;
+			};
+
+			devconf: partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_7links_px-4885-8m.dts b/target/linux/ramips/dts/rt5350_7links_px-4885-8m.dts
new file mode 100644
index 0000000..25c635a
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_7links_px-4885-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_7links_px-4885.dtsi"
+
+/ {
+	compatible = "7links,px-4885-8m", "7links,px-4885", "ralink,rt5350-soc";
+	model = "7Links PX-4885 (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x20000>;
+				read-only;
+			};
+
+			partition@20000 {
+				label = "devdata";
+				reg = <0x20000 0x20000>;
+				read-only;
+			};
+
+			devconf: partition@40000 {
+				label = "devconf";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_7links_px-4885.dtsi b/target/linux/ramips/dts/rt5350_7links_px-4885.dtsi
new file mode 100644
index 0000000..a15d140
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_7links_px-4885.dtsi
@@ -0,0 +1,61 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "7links,px-4885", "ralink,rt5350-soc";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "orange:wifi";
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+
+		storage {
+			label = "blue:storage";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devconf 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&devconf 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_airlive_air3gii.dts b/target/linux/ramips/dts/rt5350_airlive_air3gii.dts
new file mode 100644
index 0000000..0a62c75
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_airlive_air3gii.dts
@@ -0,0 +1,95 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "airlive,air3gii", "ralink,rt5350-soc";
+	model = "AirLive Air3GII";
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "green:wlan";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		mobile {
+			label = "green:mobile";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_allnet_all5003.dts b/target/linux/ramips/dts/rt5350_allnet_all5003.dts
new file mode 100644
index 0000000..96dde0f
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_allnet_all5003.dts
@@ -0,0 +1,103 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "allnet,all5003", "ralink,rt5350-soc";
+	model = "Allnet ALL5003";
+
+	i2c-gpio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "i2c-gpio";
+		gpios = <&gpio0 1 GPIO_ACTIVE_HIGH &gpio0 2 GPIO_ACTIVE_HIGH>;
+		i2c-gpio,delay-us = <10>;
+
+		pcf0: iexp@38 {
+			#gpio-cells = <2>;
+			compatible = "inxp,pcf8574a";
+			reg = <0x38>;
+			gpio-controller;
+		};
+
+		hwmon@4b {
+			compatible = "national,lm92";
+			reg = <0x4b>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		ld1 {
+			label = "green:ld1";
+			gpios = <&pcf0 0 GPIO_ACTIVE_LOW>;
+		};
+
+		ld2 {
+			label = "green:ld2";
+			gpios = <&pcf0 1 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x1fb0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-4m.dts b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-4m.dts
new file mode 100644
index 0000000..56f1ced
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-4m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_asiarf_awm002-evb.dtsi"
+
+/ {
+	compatible = "asiarf,awm002-evb-4m", "ralink,rt5350-soc";
+	model = "AsiaRF AWM002 EVB (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		reg = <0>;
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-8m.dts b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-8m.dts
new file mode 100644
index 0000000..43b599a
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_asiarf_awm002-evb.dtsi"
+
+/ {
+	compatible = "asiarf,awm002-evb-8m", "ralink,rt5350-soc";
+	model = "AsiaRF AWM002 EVB (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		reg = <0>;
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_asiarf_awm002-evb.dtsi b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb.dtsi
new file mode 100644
index 0000000..80965a4
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_asiarf_awm002-evb.dtsi
@@ -0,0 +1,63 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "asiarf,awm002-evb", "ralink,rt5350-soc";
+
+	leds {
+		compatible = "gpio-leds";
+
+		tx {
+			label = "green:tx";
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		rx {
+			label = "green:rx";
+			gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset_wps {
+			label = "reset_wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x3f>;
+};
diff --git a/target/linux/ramips/dts/rt5350_belkin_f7c027.dts b/target/linux/ramips/dts/rt5350_belkin_f7c027.dts
new file mode 100644
index 0000000..e3691b7
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_belkin_f7c027.dts
@@ -0,0 +1,139 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "belkin,f7c027", "ralink,rt5350-soc";
+	model = "Belkin F7C027";
+
+	aliases {
+		led-boot = &led_status_orange;
+		led-failsafe = &led_status_orange;
+		led-running = &led_status_orange;
+		led-upgrade = &led_status_orange;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		status {
+			label = "blue:status";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "blue:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		led_status_orange: orange {
+			label = "orange:status";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		relay {
+			label = "device:relay";
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		top {
+			label = "restore";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		power {
+			label = "power";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RFKILL>;
+		};
+
+		sensor {
+			label = "sensor";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x770000>;
+			};
+
+			partition@7c0000 {
+				label = "firmware2";
+				reg = <0x7c0000 0x770000>;
+			};
+
+			partition@f30000 {
+				label = "belkin_settings";
+				reg = <0xf30000 0xa0000>;
+			};
+
+			partition@fd0000 {
+				label = "unknown";
+				reg = <0xfd0000 0x10000>;
+			};
+
+			partition@fe0000 {
+				label = "nvram";
+				reg = <0xfe0000 0x10000>;
+			};
+
+			partition@ff0000 {
+				label = "user_factory";
+				reg = <0xff0000 0x10000>;
+			};
+		};
+	};
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_dlink_dcs-930l-b1.dts b/target/linux/ramips/dts/rt5350_dlink_dcs-930l-b1.dts
new file mode 100644
index 0000000..58a8407
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_dlink_dcs-930l-b1.dts
@@ -0,0 +1,106 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dcs-930l-b1", "ralink,rt5350-soc";
+	model = "D-Link DCS-930L B1";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_dlink_dir-300-b7.dts b/target/linux/ramips/dts/rt5350_dlink_dir-300-b7.dts
new file mode 100644
index 0000000..bcc02f3
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_dlink_dir-300-b7.dts
@@ -0,0 +1,109 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-300-b7", "ralink,rt5350-soc";
+	model = "D-Link DIR-300 B7";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "blue:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	status = "okay";
+	ralink,led-polarity = <1>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_dlink_dir-320-b1.dts b/target/linux/ramips/dts/rt5350_dlink_dir-320-b1.dts
new file mode 100644
index 0000000..7d9bb0e
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_dlink_dir-320-b1.dts
@@ -0,0 +1,129 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-320-b1", "ralink,rt5350-soc";
+	model = "D-Link DIR-320 B1";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		usb {
+			label = "green:usb";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		root_hub {
+			gpio-export,name = "root_hub";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_dlink_dir-610-a1.dts b/target/linux/ramips/dts/rt5350_dlink_dir-610-a1.dts
new file mode 100644
index 0000000..5bd8719
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_dlink_dir-610-a1.dts
@@ -0,0 +1,110 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dir-610-a1", "ralink,rt5350-soc";
+	model = "D-Link DIR-610 A1";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			devdata: partition@30000 {
+				label = "devdata";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "seama";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&devdata 0x4004>;
+};
+
+&esw {
+	status = "okay";
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	status = "okay";
+	ralink,led-polarity = <1>;
+	ralink,mtd-eeprom = <&devdata 0x4000>;
+};
diff --git a/target/linux/ramips/dts/rt5350_dlink_dwr-512-b.dts b/target/linux/ramips/dts/rt5350_dlink_dwr-512-b.dts
new file mode 100644
index 0000000..48fb1d4
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_dlink_dwr-512-b.dts
@@ -0,0 +1,145 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "dlink,dwr-512-b", "ralink,rt5350-soc";
+	model = "D-Link DWR-512 B";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		sms {
+			label = "green:sms";
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+		led_status: status {
+			label = "green:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+		2g {
+			label = "green:2g";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+		3g {
+			label = "green:3g";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+		};
+		sstrengthr {
+			label = "red:sigstrength";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+		sstrengthg {
+			label = "green:sigstrength";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		slic_int {
+			gpio-export,name = "slic_int";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+		modem3g_enable {
+			gpio-export,name = "modem3g_enable";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+		m25p,fast-read;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "jboot";
+				reg = <0x0 0x10000>;
+				read-only;
+			};
+
+			partition@10000 {
+				compatible = "amit,jimage";
+				label = "firmware";
+				reg = <0x10000 0x7e0000>;
+			};
+
+			config: partition@7f0000 {
+				label = "config";
+				reg = <0x7f0000 0x10000>;
+			};
+		};
+	};
+};
+
+&spi1 {
+	status = "okay";
+
+	spidev@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "siliconlabs,si3210";
+
+		reg = <0>;
+		spi-max-frequency = <1000000>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&ethernet {
+	mtd-mac-address = <&config 0xe07e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&config 0xe08a>;
+	ralink,led-polarity = <1>;
+	mtd-mac-address = <&config 0xe07e>;
+};
diff --git a/target/linux/ramips/dts/rt5350_easyacc_wizard-8800.dts b/target/linux/ramips/dts/rt5350_easyacc_wizard-8800.dts
new file mode 100644
index 0000000..3b1fdd4
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_easyacc_wizard-8800.dts
@@ -0,0 +1,65 @@
+#include "rt5350.dtsi"
+
+/ {
+	compatible = "easyacc,wizard-8800", "ralink,rt5350-soc";
+	model = "EASYACC WI-STOR WIZARD 8800";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_hame_mpr-a1.dts b/target/linux/ramips/dts/rt5350_hame_mpr-a1.dts
new file mode 100644
index 0000000..1386ec9
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_hame_mpr-a1.dts
@@ -0,0 +1,117 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hame,mpr-a1", "ralink,rt5350-soc";
+	model = "HAME MPR-A1";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "red:power";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		root_hub {
+			gpio-export,name = "root_hub";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_hame_mpr-a2.dts b/target/linux/ramips/dts/rt5350_hame_mpr-a2.dts
new file mode 100644
index 0000000..f9365d5
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_hame_mpr-a2.dts
@@ -0,0 +1,118 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hame,mpr-a2", "ralink,rt5350-soc";
+	model = "HAME MPR-A2";
+
+	aliases {
+		led-boot = &led_system;
+		led-failsafe = &led_system;
+		led-running = &led_system;
+		led-upgrade = &led_system;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_system: system {
+			label = "blue:system";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "red:power";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		root_hub {
+			gpio-export,name = "root_hub";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x1>;
+	mediatek,portdisable = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_hilink_hlk-rm04.dts b/target/linux/ramips/dts/rt5350_hilink_hlk-rm04.dts
new file mode 100644
index 0000000..83b1fb2
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_hilink_hlk-rm04.dts
@@ -0,0 +1,111 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hilink,hlk-rm04", "ralink,rt5350-soc";
+	model = "HILINK HLK-RM04";
+
+	chosen {
+		bootargs = "console=ttyS1,57600";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		/* I2C */
+		gpio1 {
+			/* I2C_I2C_SD */
+			gpio-export,name = "hlk-rm04:gpio0";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+		gpio2 {
+			/* I2C_I2C_SCLK */
+			gpio-export,name = "hlk-rm04:gpio1";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+		wps {
+			label = "wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&uart {
+	status = "okay";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag";
+		function = "gpio";
+	};
+
+	uartf_gpio {
+		groups = "uartf";
+		function = "gpio uartf";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_hootoo_ht-tm02.dts b/target/linux/ramips/dts/rt5350_hootoo_ht-tm02.dts
new file mode 100644
index 0000000..543fda7
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_hootoo_ht-tm02.dts
@@ -0,0 +1,108 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "hootoo,ht-tm02", "ralink,rt5350-soc";
+	model = "HooToo HT-TM02";
+
+	aliases {
+		led-boot = &led_wlan;
+		led-failsafe = &led_wlan;
+		led-running = &led_wlan;
+		led-upgrade = &led_wlan;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wlan: wlan {
+			label = "blue:wlan";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		modeswitch {
+			label = "modeswitch";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x10>;
+	mediatek,portdisable = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_intenso_memory2move.dts b/target/linux/ramips/dts/rt5350_intenso_memory2move.dts
new file mode 100644
index 0000000..8ab2a87
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_intenso_memory2move.dts
@@ -0,0 +1,110 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "intenso,memory2move", "ralink,rt5350-soc";
+	model = "Intenso Memory 2 Move";
+
+	aliases {
+		led-boot = &led_wifi;
+		led-failsafe = &led_wifi;
+		led-running = &led_wifi;
+		led-upgrade = &led_wifi;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600n8 root=/dev/mtdblock5";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_wifi: wifi {
+			label = "blue:wifi";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		wan {
+			label = "green:wan";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		power {
+			label = "power";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "Bootloader";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "Config";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_nexx_wt1520-4m.dts b/target/linux/ramips/dts/rt5350_nexx_wt1520-4m.dts
new file mode 100644
index 0000000..0b1b57c
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nexx_wt1520-4m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_nexx_wt1520.dtsi"
+
+/ {
+	compatible = "nexx,wt1520-4m", "nexx,wt1520", "ralink,rt5350-soc";
+	model = "Nexx WT1520 (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_nexx_wt1520-8m.dts b/target/linux/ramips/dts/rt5350_nexx_wt1520-8m.dts
new file mode 100644
index 0000000..c28dae3
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nexx_wt1520-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_nexx_wt1520.dtsi"
+
+/ {
+	compatible = "nexx,wt1520-8m", "nexx,wt1520", "ralink,rt5350-soc";
+	model = "Nexx WT1520 (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_nexx_wt1520.dtsi b/target/linux/ramips/dts/rt5350_nexx_wt1520.dtsi
new file mode 100644
index 0000000..540fd25
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nexx_wt1520.dtsi
@@ -0,0 +1,34 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "nexx,wt1520", "ralink,rt5350-soc";
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_nixcore_x1-16m.dts b/target/linux/ramips/dts/rt5350_nixcore_x1-16m.dts
new file mode 100644
index 0000000..19b7f39
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nixcore_x1-16m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_nixcore_x1.dtsi"
+
+/ {
+	compatible = "nixcore,x1-16m", "nixcore,x1", "ralink,rt5350-soc";
+	model = "NixcoreX1 (16M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_nixcore_x1-8m.dts b/target/linux/ramips/dts/rt5350_nixcore_x1-8m.dts
new file mode 100644
index 0000000..888c67d
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nixcore_x1-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_nixcore_x1.dtsi"
+
+/ {
+	compatible = "nixcore,x1-8m", "nixcore,x1", "ralink,rt5350-soc";
+	model = "NixcoreX1 (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_nixcore_x1.dtsi b/target/linux/ramips/dts/rt5350_nixcore_x1.dtsi
new file mode 100644
index 0000000..2459c6b
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_nixcore_x1.dtsi
@@ -0,0 +1,141 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "nixcore,x1", "ralink,rt5350-soc";
+
+	chosen {
+		bootargs = "console=ttyS1,57600";
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		gpio0 {
+			gpio-export,name = "gpio0";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio1 {
+			gpio-export,name = "gpio1";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* GPIOs 1-6 are I2C,SPI */
+		/* GPIO 7-14 are uart1 */
+		/* GPIOs 15 & 16 are uart2 */
+		/* JTAG */
+
+		gpio17 {
+			/* JTAG_TDO */
+			gpio-export,name = "gpio17";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio18 {
+			/* JTAG_TDI */
+			gpio-export,name = "gpio18";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio19 {
+			/* JTAG_TMS */
+			gpio-export,name = "gpio19";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio20 {
+			/* JTAG_TCLK */
+			gpio-export,name = "gpio20";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio21 {
+			/* JTAG_TRST_N */
+			gpio-export,name = "gpio21";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* ETH LEDs */
+		/*
+		gpio22 {
+			gpio-export,name = "gpio22";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio23 {
+			gpio-export,name = "gpio23";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio24 {
+			gpio-export,name = "gpio24";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio25 {
+			gpio-export,name = "gpio25";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		*/
+		gpio26 {
+			/* ETH4_LED */
+			gpio-export,name = "gpio26";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio27 {
+			/* spi_cs1 */
+			gpio-export,name = "gpio27";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart {
+	status = "okay";
+	reset-names = "gpio uartf";
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "led", "spi_cs1";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x17>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino-evb.dts b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino-evb.dts
new file mode 100644
index 0000000..88f4b0e
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino-evb.dts
@@ -0,0 +1,30 @@
+#include "rt5350_olimex_rt5350f-olinuxino.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "olimex,rt5350f-olinuxino-evb", "ralink,rt5350-soc";
+	model = "Olimex RT5350F-OLinuXino-EVB";
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		relay1 {
+			gpio-export,name = "relay1";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		relay2 {
+			gpio-export,name = "relay2";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		button {
+			gpio-export,name = "button";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dts b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dts
new file mode 100644
index 0000000..a2b4c8c
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dts
@@ -0,0 +1,6 @@
+#include "rt5350_olimex_rt5350f-olinuxino.dtsi"
+
+/ {
+	compatible = "olimex,rt5350f-olinuxino", "ralink,rt5350-soc";
+	model = "Olimex RT5350F-OLinuXino";
+};
diff --git a/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dtsi b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dtsi
new file mode 100644
index 0000000..7d85109
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_olimex_rt5350f-olinuxino.dtsi
@@ -0,0 +1,83 @@
+#include "rt5350.dtsi"
+
+/ {
+	compatible = "olimex,rt5350f-olinuxino", "ralink,rt5350-soc";
+
+	aliases {
+		serial0 = &uartlite;
+		serial1 = &uart;
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag";
+		function = "gpio";
+	};
+	uartf_gpio {
+		groups = "uartf";
+		function = "gpio uartf";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
+
+&i2c {
+	status = "okay";
+};
+
+&uart {
+	status = "okay";
+};
diff --git a/target/linux/ramips/dts/rt5350_omnima_miniembplug.dts b/target/linux/ramips/dts/rt5350_omnima_miniembplug.dts
new file mode 100644
index 0000000..499b555
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_omnima_miniembplug.dts
@@ -0,0 +1,113 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "omnima,miniembplug", "ralink,rt5350-soc";
+	model = "Omnima MiniEMBPlug";
+
+	leds {
+		compatible = "gpio-leds";
+
+		wlan {
+			label = "red:wlan";
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		mobile {
+			label = "green:mobile";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		mode-one {
+			label = "mode1";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		mode-two {
+			label = "mode2";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_planex_mzk-dp150n.dts b/target/linux/ramips/dts/rt5350_planex_mzk-dp150n.dts
new file mode 100644
index 0000000..d3d1ebe
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_planex_mzk-dp150n.dts
@@ -0,0 +1,104 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "planex,mzk-dp150n", "ralink,rt5350-soc";
+	model = "Planex MZK-DP150N";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&spi1 {
+	spidev@0 {
+		compatible = "linux,spidev";
+		spi-max-frequency = <10000000>;
+		reg = <0>;
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x17>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_m3.dts b/target/linux/ramips/dts/rt5350_poray_m3.dts
new file mode 100644
index 0000000..b6bad0a
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_m3.dts
@@ -0,0 +1,104 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "poray,m3", "ralink,rt5350-soc";
+	model = "Poray M3";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "blue:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <1>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_m4-4m.dts b/target/linux/ramips/dts/rt5350_poray_m4-4m.dts
new file mode 100644
index 0000000..f6f6a5a
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_m4-4m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_poray_m4.dtsi"
+
+/ {
+	compatible = "poray,m4-4m", "poray,m4", "ralink,rt5350-soc";
+	model = "Poray M4 (4M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_m4-8m.dts b/target/linux/ramips/dts/rt5350_poray_m4-8m.dts
new file mode 100644
index 0000000..2cf5891
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_m4-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_poray_m4.dtsi"
+
+/ {
+	compatible = "poray,m4-8m", "poray,m4", "ralink,rt5350-soc";
+	model = "Poray M4 (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_m4.dtsi b/target/linux/ramips/dts/rt5350_poray_m4.dtsi
new file mode 100644
index 0000000..9b36961
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_m4.dtsi
@@ -0,0 +1,56 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "poray,m4", "ralink,rt5350-soc";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			label = "blue:status";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <1>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_x5.dts b/target/linux/ramips/dts/rt5350_poray_x5.dts
new file mode 100644
index 0000000..9c00da8
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_x5.dts
@@ -0,0 +1,136 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "poray,x5", "ralink,rt5350-soc";
+	model = "Poray X5";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+
+		20 {
+			label = "green:20";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+
+		50 {
+			label = "green:50";
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		80 {
+			label = "green:80";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		bat {
+			label = "bat";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		mode {
+			label = "mode";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+			linux,input-type = <EV_SW>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb-mode {
+			gpio-export,name = "usb-mode";
+			gpio-export,output = <0>;
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <1>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_poray_x8.dts b/target/linux/ramips/dts/rt5350_poray_x8.dts
new file mode 100644
index 0000000..b60bb99
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_poray_x8.dts
@@ -0,0 +1,97 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "poray,x8", "ralink,rt5350-soc";
+	model = "Poray X8";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <1>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_tenda_3g150b.dts b/target/linux/ramips/dts/rt5350_tenda_3g150b.dts
new file mode 100644
index 0000000..35ccee1
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_tenda_3g150b.dts
@@ -0,0 +1,114 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "tenda,3g150b", "ralink,rt5350-soc";
+	model = "Tenda 3G150B";
+
+	aliases {
+		led-boot = &led_ap;
+		led-failsafe = &led_ap;
+		led-running = &led_ap;
+		led-upgrade = &led_ap;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_ap: ap {
+			label = "blue:ap";
+			gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+		};
+
+		3g {
+			label = "blue:3g";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+	ralink,led-polarity = <1>;
+};
diff --git a/target/linux/ramips/dts/rt5350_trendnet_tew-714tru.dts b/target/linux/ramips/dts/rt5350_trendnet_tew-714tru.dts
new file mode 100644
index 0000000..13d1a16
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_trendnet_tew-714tru.dts
@@ -0,0 +1,117 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "trendnet,tew-714tru", "ralink,rt5350-soc";
+	model = "TRENDnet TEW714TRU";
+
+	leds {
+		compatible = "gpio-leds";
+
+		usb {
+			label = "red:usb";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			trigger-sources = <&ohci_port1>, <&ehci_port1>;
+			linux,default-trigger = "usbport";
+		};
+
+		wifi {
+			label = "green:wifi";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		repeater {
+			gpio-export,name = "repeater_switch";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		wisp {
+			gpio-export,name = "wisp_switch";
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x1>;
+	mediatek,portdisable = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_unbranded_a5-v11.dts b/target/linux/ramips/dts/rt5350_unbranded_a5-v11.dts
new file mode 100644
index 0000000..089b856
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_unbranded_a5-v11.dts
@@ -0,0 +1,119 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "unbranded,a5-v11", "ralink,rt5350-soc";
+	model = "A5-V11";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		system {
+			label = "blue:system";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		led_power: power {
+			label = "red:power";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	gpio_export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		usb {
+			gpio-export,name = "usb";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		root_hub {
+			gpio-export,name = "root_hub";
+			gpio-export,output = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x1>;
+	mediatek,portdisable = <0x3e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_vocore_vocore-16m.dts b/target/linux/ramips/dts/rt5350_vocore_vocore-16m.dts
new file mode 100644
index 0000000..e28563c
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_vocore_vocore-16m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_vocore_vocore.dtsi"
+
+/ {
+	compatible = "vocore,vocore-16m", "vocore,vocore", "ralink,rt5350-soc";
+	model = "VoCore (16M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_vocore_vocore-8m.dts b/target/linux/ramips/dts/rt5350_vocore_vocore-8m.dts
new file mode 100644
index 0000000..4fa291a
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_vocore_vocore-8m.dts
@@ -0,0 +1,46 @@
+#include "rt5350_vocore_vocore.dtsi"
+
+/ {
+	compatible = "vocore,vocore-8m", "vocore,vocore", "ralink,rt5350-soc";
+	model = "VoCore (8M)";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_vocore_vocore.dtsi b/target/linux/ramips/dts/rt5350_vocore_vocore.dtsi
new file mode 100644
index 0000000..0c82919
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_vocore_vocore.dtsi
@@ -0,0 +1,195 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	compatible = "vocore,vocore", "ralink,rt5350-soc";
+
+	aliases {
+		led-boot = &led_status;
+		led-failsafe = &led_status;
+		led-running = &led_status;
+		led-upgrade = &led_status;
+		label-mac-device = &ethernet;
+	};
+
+	gpio-export {
+		compatible = "gpio-export";
+		#size-cells = <0>;
+
+		gpio0 {
+			gpio-export,name = "gpio0";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* UARTF */
+		gpio7 {
+			/* UARTF_RTS_N */
+			gpio-export,name = "gpio7";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio8 {
+			/* UARTF_TXD */
+			gpio-export,name = "gpio8";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio9 {
+			/* UARTF_CTS_N */
+			gpio-export,name = "gpio9";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio12 {
+			/* UARTF_DCD_N */
+			gpio-export,name = "gpio12";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio13 {
+			/* UARTF_DSR_N */
+			gpio-export,name = "gpio13";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio14 {
+			/* UARTF_RIN */
+			gpio-export,name = "gpio14";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* JTAG */
+		gpio17 {
+			/* JTAG_TDO */
+			gpio-export,name = "gpio17";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio18 {
+			/* JTAG_TDI */
+			gpio-export,name = "gpio18";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio19 {
+			/* JTAG_TMS */
+			gpio-export,name = "gpio19";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio20 {
+			/* JTAG_TCLK */
+			gpio-export,name = "gpio20";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio21 {
+			/* JTAG_TRST_N */
+			gpio-export,name = "gpio21";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+		};
+
+		/* ETH LEDs */
+		gpio22 {
+			/* ETH0_LED */
+			gpio-export,name = "gpio22";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio23 {
+			/* ETH1_LED */
+			gpio-export,name = "gpio23";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio24 {
+			/* ETH2_LED */
+			gpio-export,name = "gpio24";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio25 {
+			/* ETH3_LED */
+			gpio-export,name = "gpio25";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+		};
+
+		gpio26 {
+			/* ETH4_LED */
+			gpio-export,name = "gpio26";
+			gpio-export,direction_may_change = <1>;
+			gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_status: status {
+			/* UARTF_RXD */
+			label = "green:status";
+			gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+		};
+
+		eth {
+			/* UARTF_DTR_N */
+			label = "orange:eth";
+			gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&i2c {
+	status = "okay";
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uartf", "led";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x11>;
+	mediatek,portdisable = <0x2e>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
+
+&spi1 {
+	status = "okay";
+
+	spidev@0 {
+		compatible = "linux,spidev";
+		spi-max-frequency = <10000000>;
+		reg = <0>;
+	};
+};
diff --git a/target/linux/ramips/dts/rt5350_wansview_ncs601w.dts b/target/linux/ramips/dts/rt5350_wansview_ncs601w.dts
new file mode 100644
index 0000000..adb4034
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_wansview_ncs601w.dts
@@ -0,0 +1,65 @@
+#include "rt5350.dtsi"
+
+/ {
+	compatible = "wansview,ncs601w", "ralink,rt5350-soc";
+	model = "Wansview NCS601W";
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_wiznet_wizfi630a.dts b/target/linux/ramips/dts/rt5350_wiznet_wizfi630a.dts
new file mode 100644
index 0000000..2cb6101
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_wiznet_wizfi630a.dts
@@ -0,0 +1,142 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "wiznet,wizfi630a", "ralink,rt5350-soc";
+	model = "WIZnet WizFi630A";
+
+	aliases {
+		led-boot = &led_run;
+		led-failsafe = &led_run;
+		led-running = &led_run;
+		led-upgrade = &led_run;
+	};
+
+	chosen {
+		bootargs = "console=ttyS1,115200";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_run: run {
+			label = ":run";
+			gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = ":wps";
+			gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+		};
+
+		uart1 {
+			label = ":uart1";
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+
+		uart2 {
+			label = ":uart2";
+			gpios = <&gpio0 21 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		scm1 {
+			label = "SCM1";
+			gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_0>;
+		};
+
+		scm2 {
+			label = "SCM2";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			linux,code = <BTN_1>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				#size-cells = <1>;
+				label = "uboot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				#size-cells = <1>;
+				label = "uboot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				#size-cells = <1>;
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				#size-cells = <1>;
+				label = "firmware";
+				reg = <0x50000 0xfb0000>;
+			};
+		};
+	};
+};
+
+&uart {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uartf_pins>;
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag" ;
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portmap = <0x17>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_zorlik_zl5900v2.dts b/target/linux/ramips/dts/rt5350_zorlik_zl5900v2.dts
new file mode 100644
index 0000000..0879c11
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_zorlik_zl5900v2.dts
@@ -0,0 +1,100 @@
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zorlik,zl5900v2", "ralink,rt5350-soc";
+	model = "Zorlik ZL5900V2";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		lan {
+			label = "green:lan";
+			gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power {
+			label = "blue:power";
+			gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x4>;
+};
+
+&esw {
+	mediatek,portdisable = <0x2f>;
+};
+
+&wmac {
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
new file mode 100644
index 0000000..bc16e2c
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-lite-b.dts
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-lite-b", "ralink,rt5350-soc";
+	model = "ZyXEL Keenetic Lite Rev.B";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		wps {
+			label = "green:wps";
+			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys";
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <60000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x7b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	ralink,led-polarity = <1>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
new file mode 100644
index 0000000..eb7d7ed
--- /dev/null
+++ b/target/linux/ramips/dts/rt5350_zyxel_keenetic-start.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "rt5350.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "zyxel,keenetic-start", "ralink,rt5350-soc";
+	model = "ZyXEL Keenetic Start";
+
+	aliases {
+		led-boot = &led_power;
+		led-failsafe = &led_power;
+		led-running = &led_power;
+		led-upgrade = &led_power;
+		label-mac-device = &ethernet;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_power: power {
+			label = "green:power";
+			gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		internet {
+			label = "green:internet";
+			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	keys {
+		compatible = "gpio-keys-polled";
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+
+		wps {
+			label = "wps";
+			gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_WPS_BUTTON>;
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x0 0x30000>;
+				read-only;
+			};
+
+			partition@30000 {
+				label = "u-boot-env";
+				reg = <0x30000 0x10000>;
+				read-only;
+			};
+
+			factory: partition@40000 {
+				label = "factory";
+				reg = <0x40000 0x10000>;
+				read-only;
+			};
+
+			partition@50000 {
+				compatible = "denx,uimage";
+				label = "firmware";
+				reg = <0x50000 0x3b0000>;
+			};
+		};
+	};
+};
+
+&state_default {
+	gpio {
+		groups = "i2c", "jtag", "uartf";
+		function = "gpio";
+	};
+};
+
+&ethernet {
+	mtd-mac-address = <&factory 0x28>;
+};
+
+&esw {
+	mediatek,portmap = <0x2f>;
+	mediatek,led_polarity = <0x17>;
+};
+
+&wmac {
+	status = "okay";
+	ralink,led-polarity = <1>;
+	ralink,mtd-eeprom = <&factory 0x0>;
+};
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Kconfig b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Kconfig
new file mode 100644
index 0000000..d23ed77
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Kconfig
@@ -0,0 +1,12 @@
+config MTK_MMC
+	tristate "MTK SD/MMC"
+	depends on !MTD_NAND_RALINK
+
+config MTK_AEE_KDUMP
+	bool "MTK AEE KDUMP"
+	depends on MTK_MMC
+
+config MTK_MMC_CD_POLL
+	bool "Card Detect with Polling"
+	depends on MTK_MMC
+
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Makefile b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Makefile
new file mode 100644
index 0000000..caead0b
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/Makefile
@@ -0,0 +1,42 @@
+# Copyright Statement:
+#
+# This software/firmware and related documentation ("MediaTek Software") are
+# protected under relevant copyright laws. The information contained herein
+# is confidential and proprietary to MediaTek Inc. and/or its licensors.
+# Without the prior written permission of MediaTek inc. and/or its licensors,
+# any reproduction, modification, use or disclosure of MediaTek Software,
+# and information contained herein, in whole or in part, shall be strictly prohibited.
+#
+# MediaTek Inc. (C) 2010. All rights reserved.
+#
+# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+#
+# The following software/firmware and/or related documentation ("MediaTek Software")
+# have been modified by MediaTek Inc. All revisions are subject to any receiver's
+# applicable license agreements with MediaTek Inc.
+
+obj-$(CONFIG_MTK_MMC) += mtk_sd.o
+mtk_sd-objs := sd.o dbg.o
+ifeq ($(CONFIG_MTK_AEE_KDUMP),y)
+EXTRA_CFLAGS		+= -DMT6575_SD_DEBUG
+endif
+
+clean:
+	@rm -f *.o modules.order .*.cmd
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/board.h b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/board.h
new file mode 100644
index 0000000..a7d82f3
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/board.h
@@ -0,0 +1,63 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef __ARCH_ARM_MACH_BOARD_H
+#define __ARCH_ARM_MACH_BOARD_H
+
+#define MSDC_CD_PIN_EN      (1 << 0)  /* card detection pin is wired   */
+#define MSDC_WP_PIN_EN      (1 << 1)  /* write protection pin is wired */
+#define MSDC_RST_PIN_EN     (1 << 2)  /* emmc reset pin is wired       */
+#define MSDC_REMOVABLE      (1 << 5)  /* removable slot                */
+
+#define MSDC_SMPL_RISING    (0)
+#define MSDC_SMPL_FALLING   (1)
+
+#define MSDC_CMD_PIN        (0)
+#define MSDC_DAT_PIN        (1)
+#define MSDC_CD_PIN         (2)
+#define MSDC_WP_PIN         (3)
+#define MSDC_RST_PIN        (4)
+
+struct msdc_hw {
+	unsigned char  clk_src;          /* host clock source */
+	unsigned long  flags;            /* hardware capability flags */
+
+	/* config gpio pull mode */
+	void (*config_gpio_pin)(int type, int pull);
+};
+
+extern struct msdc_hw msdc0_hw;
+
+#endif /* __ARCH_ARM_MACH_BOARD_H */
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.c b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.c
new file mode 100644
index 0000000..d897b12
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.c
@@ -0,0 +1,306 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+// #include <mach/mt6575_gpt.h> /* --- by chhung */
+#include "dbg.h"
+#include "mt6575_sd.h"
+#include <linux/seq_file.h>
+
+static char cmd_buf[256];
+
+/* for debug zone */
+unsigned int sd_debug_zone[4] = {
+	0,
+	0,
+	0,
+	0
+};
+
+#if defined(MT6575_SD_DEBUG)
+/* for driver profile */
+#define TICKS_ONE_MS  (13000)
+u32 gpt_enable;
+u32 sdio_pro_enable;   /* make sure gpt is enabled */
+u32 sdio_pro_time;     /* no more than 30s */
+struct sdio_profile sdio_perfomance = {0};
+
+#if 0 /* --- chhung */
+void msdc_init_gpt(void)
+{
+	GPT_CONFIG config;
+
+	config.num  = GPT6;
+	config.mode = GPT_FREE_RUN;
+	config.clkSrc = GPT_CLK_SRC_SYS;
+	config.clkDiv = GPT_CLK_DIV_1;   /* 13MHz GPT6 */
+
+	if (GPT_Config(config) == FALSE)
+		return;
+
+	GPT_Start(GPT6);
+}
+#endif /* end of --- */
+
+u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32)
+{
+	u32 ret = 0;
+
+	if (new_H32 == old_H32) {
+		ret = new_L32 - old_L32;
+	} else if (new_H32 == (old_H32 + 1)) {
+		if (new_L32 > old_L32)
+			printk("msdc old_L<0x%x> new_L<0x%x>\n", old_L32, new_L32);
+		ret = (0xffffffff - old_L32);
+		ret += new_L32;
+	} else {
+		printk("msdc old_H<0x%x> new_H<0x%x>\n", old_H32, new_H32);
+	}
+
+	return ret;
+}
+
+void msdc_sdio_profile(struct sdio_profile *result)
+{
+	struct cmd_profile *cmd;
+	u32 i;
+
+	printk("sdio === performance dump ===\n");
+	printk("sdio === total execute tick<%d> time<%dms> Tx<%dB> Rx<%dB>\n",
+		result->total_tc, result->total_tc / TICKS_ONE_MS,
+		result->total_tx_bytes, result->total_rx_bytes);
+
+	/* CMD52 Dump */
+	cmd = &result->cmd52_rx;
+	printk("sdio === CMD52 Rx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
+	       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count);
+	cmd = &result->cmd52_tx;
+	printk("sdio === CMD52 Tx <%d>times tick<%d> Max<%d> Min<%d> Aver<%d>\n", cmd->count, cmd->tot_tc,
+	       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count);
+
+	/* CMD53 Rx bytes + block mode */
+	for (i = 0; i < 512; i++) {
+		cmd = &result->cmd53_rx_byte[i];
+		if (cmd->count) {
+			printk("sdio<%6d><%3dB>_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
+			       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
+			       cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+		}
+	}
+	for (i = 0; i < 100; i++) {
+		cmd = &result->cmd53_rx_blk[i];
+		if (cmd->count) {
+			printk("sdio<%6d><%3d>B_Rx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
+			       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
+			       cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+		}
+	}
+
+	/* CMD53 Tx bytes + block mode */
+	for (i = 0; i < 512; i++) {
+		cmd = &result->cmd53_tx_byte[i];
+		if (cmd->count) {
+			printk("sdio<%6d><%3dB>_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
+			       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
+			       cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+		}
+	}
+	for (i = 0; i < 100; i++) {
+		cmd = &result->cmd53_tx_blk[i];
+		if (cmd->count) {
+			printk("sdio<%6d><%3d>B_Tx_<%9d><%9d><%6d><%6d>_<%9dB><%2dM>\n", cmd->count, i, cmd->tot_tc,
+			       cmd->max_tc, cmd->min_tc, cmd->tot_tc / cmd->count,
+			       cmd->tot_bytes, (cmd->tot_bytes / 10) * 13 / (cmd->tot_tc / 10));
+		}
+	}
+
+	printk("sdio === performance dump done ===\n");
+}
+
+//========= sdio command table ===========
+void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks)
+{
+	struct sdio_profile *result = &sdio_perfomance;
+	struct cmd_profile *cmd;
+	u32 block;
+
+	if (sdio_pro_enable == 0)
+		return;
+
+	if (opcode == 52) {
+		cmd = bRx ?  &result->cmd52_rx : &result->cmd52_tx;
+	} else if (opcode == 53) {
+		if (sizes < 512) {
+			cmd = bRx ?  &result->cmd53_rx_byte[sizes] : &result->cmd53_tx_byte[sizes];
+		} else {
+			block = sizes / 512;
+			if (block >= 99) {
+				printk("cmd53 error blocks\n");
+				while (1)
+					;
+			}
+			cmd = bRx ?  &result->cmd53_rx_blk[block] : &result->cmd53_tx_blk[block];
+		}
+	} else {
+		return;
+	}
+
+	/* update the members */
+	if (ticks > cmd->max_tc)
+		cmd->max_tc = ticks;
+	if (cmd->min_tc == 0 || ticks < cmd->min_tc)
+		cmd->min_tc = ticks;
+	cmd->tot_tc += ticks;
+	cmd->tot_bytes += sizes;
+	cmd->count++;
+
+	if (bRx)
+		result->total_rx_bytes += sizes;
+	else
+		result->total_tx_bytes += sizes;
+	result->total_tc += ticks;
+
+	/* dump when total_tc > 30s */
+	if (result->total_tc >= sdio_pro_time * TICKS_ONE_MS * 1000) {
+		msdc_sdio_profile(result);
+		memset(result, 0, sizeof(struct sdio_profile));
+	}
+}
+
+//========== driver proc interface ===========
+static int msdc_debug_proc_read(struct seq_file *s, void *p)
+{
+	seq_puts(s, "\n=========================================\n");
+	seq_puts(s, "Index<0> + Id + Zone\n");
+	seq_puts(s, "-> PWR<9> WRN<8> | FIO<7> OPS<6> FUN<5> CFG<4> | INT<3> RSP<2> CMD<1> DMA<0>\n");
+	seq_puts(s, "-> echo 0 3 0x3ff >msdc_bebug -> host[3] debug zone set to 0x3ff\n");
+	seq_printf(s, "-> MSDC[0] Zone: 0x%.8x\n", sd_debug_zone[0]);
+	seq_printf(s, "-> MSDC[1] Zone: 0x%.8x\n", sd_debug_zone[1]);
+	seq_printf(s, "-> MSDC[2] Zone: 0x%.8x\n", sd_debug_zone[2]);
+	seq_printf(s, "-> MSDC[3] Zone: 0x%.8x\n", sd_debug_zone[3]);
+
+	seq_puts(s, "Index<3> + SDIO_PROFILE + TIME\n");
+	seq_puts(s, "-> echo 3 1 0x1E >msdc_bebug -> enable sdio_profile, 30s\n");
+	seq_printf(s, "-> SDIO_PROFILE<%d> TIME<%ds>\n", sdio_pro_enable, sdio_pro_time);
+	seq_puts(s, "=========================================\n\n");
+
+	return 0;
+}
+
+static ssize_t msdc_debug_proc_write(struct file *file,
+				const char __user *buf, size_t count, loff_t *data)
+{
+	int ret;
+
+	int cmd, p1, p2;
+	int id, zone;
+	int mode, size;
+
+	if (count == 0)
+		return -1;
+	if (count > 255)
+		count = 255;
+
+	if (copy_from_user(cmd_buf, buf, count))
+		return -EFAULT;
+
+	cmd_buf[count] = '\0';
+	printk("msdc Write %s\n", cmd_buf);
+
+	sscanf(cmd_buf, "%x %x %x", &cmd, &p1, &p2);
+
+	if (cmd == SD_TOOL_ZONE) {
+		id = p1;
+		zone = p2;
+		zone &= 0x3ff;
+		printk("msdc host_id<%d> zone<0x%.8x>\n", id, zone);
+		if (id >= 0 && id <= 3) {
+			sd_debug_zone[id] = zone;
+		} else if (id == 4) {
+			sd_debug_zone[0] = sd_debug_zone[1] = zone;
+			sd_debug_zone[2] = sd_debug_zone[3] = zone;
+		} else {
+			printk("msdc host_id error when set debug zone\n");
+		}
+	} else if (cmd == SD_TOOL_SDIO_PROFILE) {
+		if (p1 == 1) { /* enable profile */
+			if (gpt_enable == 0) {
+				// msdc_init_gpt(); /* --- by chhung */
+				gpt_enable = 1;
+			}
+			sdio_pro_enable = 1;
+			if (p2 == 0)
+				p2 = 1;
+			if (p2 >= 30)
+				p2 = 30;
+			sdio_pro_time = p2;
+		} else if (p1 == 0) {
+			/* todo */
+			sdio_pro_enable = 0;
+		}
+	}
+
+	return count;
+}
+
+static int msdc_debug_show(struct inode *inode, struct file *file)
+{
+	return single_open(file, msdc_debug_proc_read, NULL);
+}
+
+static const struct file_operations msdc_debug_fops = {
+	.owner		= THIS_MODULE,
+	.open		= msdc_debug_show,
+	.read		= seq_read,
+	.write		= msdc_debug_proc_write,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+void msdc_debug_proc_init(void)
+{
+	proc_create("msdc_debug", 0660, NULL, &msdc_debug_fops);
+}
+EXPORT_SYMBOL_GPL(msdc_debug_proc_init);
+#endif
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.h b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.h
new file mode 100644
index 0000000..5a25a69
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/dbg.h
@@ -0,0 +1,155 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+#ifndef __MT_MSDC_DEUBG__
+#define __MT_MSDC_DEUBG__
+
+//==========================
+extern u32 sdio_pro_enable;
+/* for a type command, e.g. CMD53, 2 blocks */
+struct cmd_profile {
+	u32 max_tc;    /* Max tick count */
+	u32 min_tc;
+	u32 tot_tc;    /* total tick count */
+	u32 tot_bytes;
+	u32 count;     /* the counts of the command */
+};
+
+/* dump when total_tc and total_bytes */
+struct sdio_profile {
+	u32 total_tc;         /* total tick count of CMD52 and CMD53 */
+	u32 total_tx_bytes;   /* total bytes of CMD53 Tx */
+	u32 total_rx_bytes;   /* total bytes of CMD53 Rx */
+
+	/*CMD52*/
+	struct cmd_profile cmd52_tx;
+	struct cmd_profile cmd52_rx;
+
+	/*CMD53 in byte unit */
+	struct cmd_profile cmd53_tx_byte[512];
+	struct cmd_profile cmd53_rx_byte[512];
+
+	/*CMD53 in block unit */
+	struct cmd_profile cmd53_tx_blk[100];
+	struct cmd_profile cmd53_rx_blk[100];
+};
+
+//==========================
+enum msdc_dbg {
+	SD_TOOL_ZONE = 0,
+	SD_TOOL_DMA_SIZE  = 1,
+	SD_TOOL_PM_ENABLE = 2,
+	SD_TOOL_SDIO_PROFILE = 3,
+};
+
+enum msdc_mode {
+	MODE_PIO = 0,
+	MODE_DMA = 1,
+	MODE_SIZE_DEP = 2,
+};
+
+/* Debug message event */
+#define DBG_EVT_NONE        (0)       /* No event */
+#define DBG_EVT_DMA         (1 << 0)  /* DMA related event */
+#define DBG_EVT_CMD         (1 << 1)  /* MSDC CMD related event */
+#define DBG_EVT_RSP         (1 << 2)  /* MSDC CMD RSP related event */
+#define DBG_EVT_INT         (1 << 3)  /* MSDC INT event */
+#define DBG_EVT_CFG         (1 << 4)  /* MSDC CFG event */
+#define DBG_EVT_FUC         (1 << 5)  /* Function event */
+#define DBG_EVT_OPS         (1 << 6)  /* Read/Write operation event */
+#define DBG_EVT_FIO         (1 << 7)  /* FIFO operation event */
+#define DBG_EVT_WRN         (1 << 8)  /* Warning event */
+#define DBG_EVT_PWR         (1 << 9)  /* Power event */
+#define DBG_EVT_ALL         (0xffffffff)
+
+#define DBG_EVT_MASK        (DBG_EVT_ALL)
+
+extern unsigned int sd_debug_zone[4];
+#define TAG "msdc"
+#if 0 /* +++ chhung */
+#define BUG_ON(x) \
+do { \
+	if (x) { \
+		printk("[BUG] %s LINE:%d FILE:%s\n", #x, __LINE__, __FILE__); \
+		while (1)						\
+			;						\
+	} \
+} while (0)
+#endif /* end of +++ */
+
+#define N_MSG(evt, fmt, args...)
+/*
+do {    \
+    if ((DBG_EVT_##evt) & sd_debug_zone[host->id]) { \
+        printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
+            host->id,  ##args , __FUNCTION__, __LINE__, current->comm, current->pid);	\
+    } \
+} while(0)
+*/
+
+#define ERR_MSG(fmt, args...) \
+do { \
+	printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
+	       host->id,  ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \
+} while (0);
+
+#if 1
+//defined CONFIG_MTK_MMC_CD_POLL
+#define INIT_MSG(fmt, args...)
+#define IRQ_MSG(fmt, args...)
+#else
+#define INIT_MSG(fmt, args...) \
+do { \
+	printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d> PID<%s><0x%x>\n", \
+	       host->id,  ##args, __FUNCTION__, __LINE__, current->comm, current->pid); \
+} while (0);
+
+/* PID in ISR in not corrent */
+#define IRQ_MSG(fmt, args...) \
+do { \
+	printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n",	\
+	       host->id,  ##args, __FUNCTION__, __LINE__);	\
+} while (0);
+#endif
+
+void msdc_debug_proc_init(void);
+
+#if 0 /* --- chhung */
+void msdc_init_gpt(void);
+extern void GPT_GetCounter64(UINT32 *cntL32, UINT32 *cntH32);
+#endif /* end of --- */
+u32 msdc_time_calc(u32 old_L32, u32 old_H32, u32 new_L32, u32 new_H32);
+void msdc_performance(u32 opcode, u32 sizes, u32 bRx, u32 ticks);
+
+#endif
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/mt6575_sd.h b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/mt6575_sd.h
new file mode 100644
index 0000000..33fa59a
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/mt6575_sd.h
@@ -0,0 +1,986 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#ifndef MT6575_SD_H
+#define MT6575_SD_H
+
+#include <linux/bitops.h>
+#include <linux/mmc/host.h>
+
+// #include <mach/mt6575_reg_base.h> /* --- by chhung */
+
+/*--------------------------------------------------------------------------*/
+/* Common Macro                                                             */
+/*--------------------------------------------------------------------------*/
+#define REG_ADDR(x)                 (base + OFFSET_##x)
+
+/*--------------------------------------------------------------------------*/
+/* Common Definition                                                        */
+/*--------------------------------------------------------------------------*/
+#define MSDC_FIFO_SZ            (128)
+#define MSDC_FIFO_THD           (64)  // (128)
+#define MSDC_NUM                (4)
+
+#define MSDC_MS                 (0)
+#define MSDC_SDMMC              (1)
+
+#define MSDC_MODE_UNKNOWN       (0)
+#define MSDC_MODE_PIO           (1)
+#define MSDC_MODE_DMA_BASIC     (2)
+#define MSDC_MODE_DMA_DESC      (3)
+#define MSDC_MODE_DMA_ENHANCED  (4)
+#define MSDC_MODE_MMC_STREAM    (5)
+
+#define MSDC_BUS_1BITS          (0)
+#define MSDC_BUS_4BITS          (1)
+#define MSDC_BUS_8BITS          (2)
+
+#define MSDC_BRUST_8B           (3)
+#define MSDC_BRUST_16B          (4)
+#define MSDC_BRUST_32B          (5)
+#define MSDC_BRUST_64B          (6)
+
+#define MSDC_PIN_PULL_NONE      (0)
+#define MSDC_PIN_PULL_DOWN      (1)
+#define MSDC_PIN_PULL_UP        (2)
+#define MSDC_PIN_KEEP           (3)
+
+#define MSDC_MAX_SCLK           (48000000) /* +/- by chhung */
+#define MSDC_MIN_SCLK           (260000)
+
+#define MSDC_AUTOCMD12          (0x0001)
+#define MSDC_AUTOCMD23          (0x0002)
+#define MSDC_AUTOCMD19          (0x0003)
+
+#define MSDC_EMMC_BOOTMODE0     (0)     /* Pull low CMD mode */
+#define MSDC_EMMC_BOOTMODE1     (1)     /* Reset CMD mode */
+
+enum {
+	RESP_NONE = 0,
+	RESP_R1,
+	RESP_R2,
+	RESP_R3,
+	RESP_R4,
+	RESP_R5,
+	RESP_R6,
+	RESP_R7,
+	RESP_R1B
+};
+
+/*--------------------------------------------------------------------------*/
+/* Register Offset                                                          */
+/*--------------------------------------------------------------------------*/
+#define OFFSET_MSDC_CFG         (0x0)
+#define OFFSET_MSDC_IOCON       (0x04)
+#define OFFSET_MSDC_PS          (0x08)
+#define OFFSET_MSDC_INT         (0x0c)
+#define OFFSET_MSDC_INTEN       (0x10)
+#define OFFSET_MSDC_FIFOCS      (0x14)
+#define OFFSET_MSDC_TXDATA      (0x18)
+#define OFFSET_MSDC_RXDATA      (0x1c)
+#define OFFSET_SDC_CFG          (0x30)
+#define OFFSET_SDC_CMD          (0x34)
+#define OFFSET_SDC_ARG          (0x38)
+#define OFFSET_SDC_STS          (0x3c)
+#define OFFSET_SDC_RESP0        (0x40)
+#define OFFSET_SDC_RESP1        (0x44)
+#define OFFSET_SDC_RESP2        (0x48)
+#define OFFSET_SDC_RESP3        (0x4c)
+#define OFFSET_SDC_BLK_NUM      (0x50)
+#define OFFSET_SDC_CSTS         (0x58)
+#define OFFSET_SDC_CSTS_EN      (0x5c)
+#define OFFSET_SDC_DCRC_STS     (0x60)
+#define OFFSET_EMMC_CFG0        (0x70)
+#define OFFSET_EMMC_CFG1        (0x74)
+#define OFFSET_EMMC_STS         (0x78)
+#define OFFSET_EMMC_IOCON       (0x7c)
+#define OFFSET_SDC_ACMD_RESP    (0x80)
+#define OFFSET_SDC_ACMD19_TRG   (0x84)
+#define OFFSET_SDC_ACMD19_STS   (0x88)
+#define OFFSET_MSDC_DMA_SA      (0x90)
+#define OFFSET_MSDC_DMA_CA      (0x94)
+#define OFFSET_MSDC_DMA_CTRL    (0x98)
+#define OFFSET_MSDC_DMA_CFG     (0x9c)
+#define OFFSET_MSDC_DBG_SEL     (0xa0)
+#define OFFSET_MSDC_DBG_OUT     (0xa4)
+#define OFFSET_MSDC_PATCH_BIT   (0xb0)
+#define OFFSET_MSDC_PATCH_BIT1  (0xb4)
+#define OFFSET_MSDC_PAD_CTL0    (0xe0)
+#define OFFSET_MSDC_PAD_CTL1    (0xe4)
+#define OFFSET_MSDC_PAD_CTL2    (0xe8)
+#define OFFSET_MSDC_PAD_TUNE    (0xec)
+#define OFFSET_MSDC_DAT_RDDLY0  (0xf0)
+#define OFFSET_MSDC_DAT_RDDLY1  (0xf4)
+#define OFFSET_MSDC_HW_DBG      (0xf8)
+#define OFFSET_MSDC_VERSION     (0x100)
+#define OFFSET_MSDC_ECO_VER     (0x104)
+
+/*--------------------------------------------------------------------------*/
+/* Register Address                                                         */
+/*--------------------------------------------------------------------------*/
+
+/* common register */
+#define MSDC_CFG                REG_ADDR(MSDC_CFG)
+#define MSDC_IOCON              REG_ADDR(MSDC_IOCON)
+#define MSDC_PS                 REG_ADDR(MSDC_PS)
+#define MSDC_INT                REG_ADDR(MSDC_INT)
+#define MSDC_INTEN              REG_ADDR(MSDC_INTEN)
+#define MSDC_FIFOCS             REG_ADDR(MSDC_FIFOCS)
+#define MSDC_TXDATA             REG_ADDR(MSDC_TXDATA)
+#define MSDC_RXDATA             REG_ADDR(MSDC_RXDATA)
+#define MSDC_PATCH_BIT0         REG_ADDR(MSDC_PATCH_BIT)
+
+/* sdmmc register */
+#define SDC_CFG                 REG_ADDR(SDC_CFG)
+#define SDC_CMD                 REG_ADDR(SDC_CMD)
+#define SDC_ARG                 REG_ADDR(SDC_ARG)
+#define SDC_STS                 REG_ADDR(SDC_STS)
+#define SDC_RESP0               REG_ADDR(SDC_RESP0)
+#define SDC_RESP1               REG_ADDR(SDC_RESP1)
+#define SDC_RESP2               REG_ADDR(SDC_RESP2)
+#define SDC_RESP3               REG_ADDR(SDC_RESP3)
+#define SDC_BLK_NUM             REG_ADDR(SDC_BLK_NUM)
+#define SDC_CSTS                REG_ADDR(SDC_CSTS)
+#define SDC_CSTS_EN             REG_ADDR(SDC_CSTS_EN)
+#define SDC_DCRC_STS            REG_ADDR(SDC_DCRC_STS)
+
+/* emmc register*/
+#define EMMC_CFG0               REG_ADDR(EMMC_CFG0)
+#define EMMC_CFG1               REG_ADDR(EMMC_CFG1)
+#define EMMC_STS                REG_ADDR(EMMC_STS)
+#define EMMC_IOCON              REG_ADDR(EMMC_IOCON)
+
+/* auto command register */
+#define SDC_ACMD_RESP           REG_ADDR(SDC_ACMD_RESP)
+#define SDC_ACMD19_TRG          REG_ADDR(SDC_ACMD19_TRG)
+#define SDC_ACMD19_STS          REG_ADDR(SDC_ACMD19_STS)
+
+/* dma register */
+#define MSDC_DMA_SA             REG_ADDR(MSDC_DMA_SA)
+#define MSDC_DMA_CA             REG_ADDR(MSDC_DMA_CA)
+#define MSDC_DMA_CTRL           REG_ADDR(MSDC_DMA_CTRL)
+#define MSDC_DMA_CFG            REG_ADDR(MSDC_DMA_CFG)
+
+/* pad ctrl register */
+#define MSDC_PAD_CTL0           REG_ADDR(MSDC_PAD_CTL0)
+#define MSDC_PAD_CTL1           REG_ADDR(MSDC_PAD_CTL1)
+#define MSDC_PAD_CTL2           REG_ADDR(MSDC_PAD_CTL2)
+
+/* data read delay */
+#define MSDC_DAT_RDDLY0         REG_ADDR(MSDC_DAT_RDDLY0)
+#define MSDC_DAT_RDDLY1         REG_ADDR(MSDC_DAT_RDDLY1)
+
+/* debug register */
+#define MSDC_DBG_SEL            REG_ADDR(MSDC_DBG_SEL)
+#define MSDC_DBG_OUT            REG_ADDR(MSDC_DBG_OUT)
+
+/* misc register */
+#define MSDC_PATCH_BIT          REG_ADDR(MSDC_PATCH_BIT)
+#define MSDC_PATCH_BIT1         REG_ADDR(MSDC_PATCH_BIT1)
+#define MSDC_PAD_TUNE           REG_ADDR(MSDC_PAD_TUNE)
+#define MSDC_HW_DBG             REG_ADDR(MSDC_HW_DBG)
+#define MSDC_VERSION            REG_ADDR(MSDC_VERSION)
+#define MSDC_ECO_VER            REG_ADDR(MSDC_ECO_VER) /* ECO Version */
+
+/*--------------------------------------------------------------------------*/
+/* Register Mask                                                            */
+/*--------------------------------------------------------------------------*/
+
+/* MSDC_CFG mask */
+#define MSDC_CFG_MODE           (0x1  << 0)     /* RW */
+#define MSDC_CFG_CKPDN          (0x1  << 1)     /* RW */
+#define MSDC_CFG_RST            (0x1  << 2)     /* RW */
+#define MSDC_CFG_PIO            (0x1  << 3)     /* RW */
+#define MSDC_CFG_CKDRVEN        (0x1  << 4)     /* RW */
+#define MSDC_CFG_BV18SDT        (0x1  << 5)     /* RW */
+#define MSDC_CFG_BV18PSS        (0x1  << 6)     /* R  */
+#define MSDC_CFG_CKSTB          (0x1  << 7)     /* R  */
+#define MSDC_CFG_CKDIV          (0xff << 8)     /* RW */
+#define MSDC_CFG_CKMOD          (0x3  << 16)    /* RW */
+
+/* MSDC_IOCON mask */
+#define MSDC_IOCON_SDR104CKS    (0x1  << 0)     /* RW */
+#define MSDC_IOCON_RSPL         (0x1  << 1)     /* RW */
+#define MSDC_IOCON_DSPL         (0x1  << 2)     /* RW */
+#define MSDC_IOCON_DDLSEL       (0x1  << 3)     /* RW */
+#define MSDC_IOCON_DDR50CKD     (0x1  << 4)     /* RW */
+#define MSDC_IOCON_DSPLSEL      (0x1  << 5)     /* RW */
+#define MSDC_IOCON_D0SPL        (0x1  << 16)    /* RW */
+#define MSDC_IOCON_D1SPL        (0x1  << 17)    /* RW */
+#define MSDC_IOCON_D2SPL        (0x1  << 18)    /* RW */
+#define MSDC_IOCON_D3SPL        (0x1  << 19)    /* RW */
+#define MSDC_IOCON_D4SPL        (0x1  << 20)    /* RW */
+#define MSDC_IOCON_D5SPL        (0x1  << 21)    /* RW */
+#define MSDC_IOCON_D6SPL        (0x1  << 22)    /* RW */
+#define MSDC_IOCON_D7SPL        (0x1  << 23)    /* RW */
+#define MSDC_IOCON_RISCSZ       (0x3  << 24)    /* RW */
+
+/* MSDC_PS mask */
+#define MSDC_PS_CDEN            (0x1  << 0)     /* RW */
+#define MSDC_PS_CDSTS           (0x1  << 1)     /* R  */
+#define MSDC_PS_CDDEBOUNCE      (0xf  << 12)    /* RW */
+#define MSDC_PS_DAT             (0xff << 16)    /* R  */
+#define MSDC_PS_CMD             (0x1  << 24)    /* R  */
+#define MSDC_PS_WP              (0x1UL << 31)    /* R  */
+
+/* MSDC_INT mask */
+#define MSDC_INT_MMCIRQ         (0x1  << 0)     /* W1C */
+#define MSDC_INT_CDSC           (0x1  << 1)     /* W1C */
+#define MSDC_INT_ACMDRDY        (0x1  << 3)     /* W1C */
+#define MSDC_INT_ACMDTMO        (0x1  << 4)     /* W1C */
+#define MSDC_INT_ACMDCRCERR     (0x1  << 5)     /* W1C */
+#define MSDC_INT_DMAQ_EMPTY     (0x1  << 6)     /* W1C */
+#define MSDC_INT_SDIOIRQ        (0x1  << 7)     /* W1C */
+#define MSDC_INT_CMDRDY         (0x1  << 8)     /* W1C */
+#define MSDC_INT_CMDTMO         (0x1  << 9)     /* W1C */
+#define MSDC_INT_RSPCRCERR      (0x1  << 10)    /* W1C */
+#define MSDC_INT_CSTA           (0x1  << 11)    /* R */
+#define MSDC_INT_XFER_COMPL     (0x1  << 12)    /* W1C */
+#define MSDC_INT_DXFER_DONE     (0x1  << 13)    /* W1C */
+#define MSDC_INT_DATTMO         (0x1  << 14)    /* W1C */
+#define MSDC_INT_DATCRCERR      (0x1  << 15)    /* W1C */
+#define MSDC_INT_ACMD19_DONE    (0x1  << 16)    /* W1C */
+
+/* MSDC_INTEN mask */
+#define MSDC_INTEN_MMCIRQ       (0x1  << 0)     /* RW */
+#define MSDC_INTEN_CDSC         (0x1  << 1)     /* RW */
+#define MSDC_INTEN_ACMDRDY      (0x1  << 3)     /* RW */
+#define MSDC_INTEN_ACMDTMO      (0x1  << 4)     /* RW */
+#define MSDC_INTEN_ACMDCRCERR   (0x1  << 5)     /* RW */
+#define MSDC_INTEN_DMAQ_EMPTY   (0x1  << 6)     /* RW */
+#define MSDC_INTEN_SDIOIRQ      (0x1  << 7)     /* RW */
+#define MSDC_INTEN_CMDRDY       (0x1  << 8)     /* RW */
+#define MSDC_INTEN_CMDTMO       (0x1  << 9)     /* RW */
+#define MSDC_INTEN_RSPCRCERR    (0x1  << 10)    /* RW */
+#define MSDC_INTEN_CSTA         (0x1  << 11)    /* RW */
+#define MSDC_INTEN_XFER_COMPL   (0x1  << 12)    /* RW */
+#define MSDC_INTEN_DXFER_DONE   (0x1  << 13)    /* RW */
+#define MSDC_INTEN_DATTMO       (0x1  << 14)    /* RW */
+#define MSDC_INTEN_DATCRCERR    (0x1  << 15)    /* RW */
+#define MSDC_INTEN_ACMD19_DONE  (0x1  << 16)    /* RW */
+
+/* MSDC_FIFOCS mask */
+#define MSDC_FIFOCS_RXCNT       (0xff << 0)     /* R */
+#define MSDC_FIFOCS_TXCNT       (0xff << 16)    /* R */
+#define MSDC_FIFOCS_CLR         (0x1UL << 31)    /* RW */
+
+/* SDC_CFG mask */
+#define SDC_CFG_SDIOINTWKUP     (0x1  << 0)     /* RW */
+#define SDC_CFG_INSWKUP         (0x1  << 1)     /* RW */
+#define SDC_CFG_BUSWIDTH        (0x3  << 16)    /* RW */
+#define SDC_CFG_SDIO            (0x1  << 19)    /* RW */
+#define SDC_CFG_SDIOIDE         (0x1  << 20)    /* RW */
+#define SDC_CFG_INTATGAP        (0x1  << 21)    /* RW */
+#define SDC_CFG_DTOC            (0xffUL << 24)  /* RW */
+
+/* SDC_CMD mask */
+#define SDC_CMD_OPC             (0x3f << 0)     /* RW */
+#define SDC_CMD_BRK             (0x1  << 6)     /* RW */
+#define SDC_CMD_RSPTYP          (0x7  << 7)     /* RW */
+#define SDC_CMD_DTYP            (0x3  << 11)    /* RW */
+#define SDC_CMD_DTYP            (0x3  << 11)    /* RW */
+#define SDC_CMD_RW              (0x1  << 13)    /* RW */
+#define SDC_CMD_STOP            (0x1  << 14)    /* RW */
+#define SDC_CMD_GOIRQ           (0x1  << 15)    /* RW */
+#define SDC_CMD_BLKLEN          (0xfff << 16)    /* RW */
+#define SDC_CMD_AUTOCMD         (0x3  << 28)    /* RW */
+#define SDC_CMD_VOLSWTH         (0x1  << 30)    /* RW */
+
+/* SDC_STS mask */
+#define SDC_STS_SDCBUSY         (0x1  << 0)     /* RW */
+#define SDC_STS_CMDBUSY         (0x1  << 1)     /* RW */
+#define SDC_STS_SWR_COMPL       (0x1  << 31)    /* RW */
+
+/* SDC_DCRC_STS mask */
+#define SDC_DCRC_STS_NEG        (0xf  << 8)     /* RO */
+#define SDC_DCRC_STS_POS        (0xff << 0)     /* RO */
+
+/* EMMC_CFG0 mask */
+#define EMMC_CFG0_BOOTSTART     (0x1  << 0)     /* W */
+#define EMMC_CFG0_BOOTSTOP      (0x1  << 1)     /* W */
+#define EMMC_CFG0_BOOTMODE      (0x1  << 2)     /* RW */
+#define EMMC_CFG0_BOOTACKDIS    (0x1  << 3)     /* RW */
+#define EMMC_CFG0_BOOTWDLY      (0x7  << 12)    /* RW */
+#define EMMC_CFG0_BOOTSUPP      (0x1  << 15)    /* RW */
+
+/* EMMC_CFG1 mask */
+#define EMMC_CFG1_BOOTDATTMC    (0xfffff << 0)  /* RW */
+#define EMMC_CFG1_BOOTACKTMC    (0xfffUL << 20) /* RW */
+
+/* EMMC_STS mask */
+#define EMMC_STS_BOOTCRCERR     (0x1  << 0)     /* W1C */
+#define EMMC_STS_BOOTACKERR     (0x1  << 1)     /* W1C */
+#define EMMC_STS_BOOTDATTMO     (0x1  << 2)     /* W1C */
+#define EMMC_STS_BOOTACKTMO     (0x1  << 3)     /* W1C */
+#define EMMC_STS_BOOTUPSTATE    (0x1  << 4)     /* R */
+#define EMMC_STS_BOOTACKRCV     (0x1  << 5)     /* W1C */
+#define EMMC_STS_BOOTDATRCV     (0x1  << 6)     /* R */
+
+/* EMMC_IOCON mask */
+#define EMMC_IOCON_BOOTRST      (0x1  << 0)     /* RW */
+
+/* SDC_ACMD19_TRG mask */
+#define SDC_ACMD19_TRG_TUNESEL  (0xf  << 0)     /* RW */
+
+/* MSDC_DMA_CTRL mask */
+#define MSDC_DMA_CTRL_START     (0x1  << 0)     /* W */
+#define MSDC_DMA_CTRL_STOP      (0x1  << 1)     /* W */
+#define MSDC_DMA_CTRL_RESUME    (0x1  << 2)     /* W */
+#define MSDC_DMA_CTRL_MODE      (0x1  << 8)     /* RW */
+#define MSDC_DMA_CTRL_LASTBUF   (0x1  << 10)    /* RW */
+#define MSDC_DMA_CTRL_BRUSTSZ   (0x7  << 12)    /* RW */
+#define MSDC_DMA_CTRL_XFERSZ    (0xffffUL << 16)/* RW */
+
+/* MSDC_DMA_CFG mask */
+#define MSDC_DMA_CFG_STS        (0x1  << 0)     /* R */
+#define MSDC_DMA_CFG_DECSEN     (0x1  << 1)     /* RW */
+#define MSDC_DMA_CFG_BDCSERR    (0x1  << 4)     /* R */
+#define MSDC_DMA_CFG_GPDCSERR   (0x1  << 5)     /* R */
+
+/* MSDC_PATCH_BIT mask */
+#define MSDC_PATCH_BIT_WFLSMODE (0x1  << 0)     /* RW */
+#define MSDC_PATCH_BIT_ODDSUPP  (0x1  << 1)     /* RW */
+#define MSDC_PATCH_BIT_CKGEN_CK (0x1  << 6)     /* E2: Fixed to 1 */
+#define MSDC_PATCH_BIT_IODSSEL  (0x1  << 16)    /* RW */
+#define MSDC_PATCH_BIT_IOINTSEL (0x1  << 17)    /* RW */
+#define MSDC_PATCH_BIT_BUSYDLY  (0xf  << 18)    /* RW */
+#define MSDC_PATCH_BIT_WDOD     (0xf  << 22)    /* RW */
+#define MSDC_PATCH_BIT_IDRTSEL  (0x1  << 26)    /* RW */
+#define MSDC_PATCH_BIT_CMDFSEL  (0x1  << 27)    /* RW */
+#define MSDC_PATCH_BIT_INTDLSEL (0x1  << 28)    /* RW */
+#define MSDC_PATCH_BIT_SPCPUSH  (0x1  << 29)    /* RW */
+#define MSDC_PATCH_BIT_DECRCTMO (0x1  << 30)    /* RW */
+
+/* MSDC_PATCH_BIT1 mask */
+#define MSDC_PATCH_BIT1_WRDAT_CRCS  (0x7 << 3)
+#define MSDC_PATCH_BIT1_CMD_RSP     (0x7 << 0)
+
+/* MSDC_PAD_CTL0 mask */
+#define MSDC_PAD_CTL0_CLKDRVN   (0x7  << 0)     /* RW */
+#define MSDC_PAD_CTL0_CLKDRVP   (0x7  << 4)     /* RW */
+#define MSDC_PAD_CTL0_CLKSR     (0x1  << 8)     /* RW */
+#define MSDC_PAD_CTL0_CLKPD     (0x1  << 16)    /* RW */
+#define MSDC_PAD_CTL0_CLKPU     (0x1  << 17)    /* RW */
+#define MSDC_PAD_CTL0_CLKSMT    (0x1  << 18)    /* RW */
+#define MSDC_PAD_CTL0_CLKIES    (0x1  << 19)    /* RW */
+#define MSDC_PAD_CTL0_CLKTDSEL  (0xf  << 20)    /* RW */
+#define MSDC_PAD_CTL0_CLKRDSEL  (0xffUL << 24)   /* RW */
+
+/* MSDC_PAD_CTL1 mask */
+#define MSDC_PAD_CTL1_CMDDRVN   (0x7  << 0)     /* RW */
+#define MSDC_PAD_CTL1_CMDDRVP   (0x7  << 4)     /* RW */
+#define MSDC_PAD_CTL1_CMDSR     (0x1  << 8)     /* RW */
+#define MSDC_PAD_CTL1_CMDPD     (0x1  << 16)    /* RW */
+#define MSDC_PAD_CTL1_CMDPU     (0x1  << 17)    /* RW */
+#define MSDC_PAD_CTL1_CMDSMT    (0x1  << 18)    /* RW */
+#define MSDC_PAD_CTL1_CMDIES    (0x1  << 19)    /* RW */
+#define MSDC_PAD_CTL1_CMDTDSEL  (0xf  << 20)    /* RW */
+#define MSDC_PAD_CTL1_CMDRDSEL  (0xffUL << 24)   /* RW */
+
+/* MSDC_PAD_CTL2 mask */
+#define MSDC_PAD_CTL2_DATDRVN   (0x7  << 0)     /* RW */
+#define MSDC_PAD_CTL2_DATDRVP   (0x7  << 4)     /* RW */
+#define MSDC_PAD_CTL2_DATSR     (0x1  << 8)     /* RW */
+#define MSDC_PAD_CTL2_DATPD     (0x1  << 16)    /* RW */
+#define MSDC_PAD_CTL2_DATPU     (0x1  << 17)    /* RW */
+#define MSDC_PAD_CTL2_DATIES    (0x1  << 19)    /* RW */
+#define MSDC_PAD_CTL2_DATSMT    (0x1  << 18)    /* RW */
+#define MSDC_PAD_CTL2_DATTDSEL  (0xf  << 20)    /* RW */
+#define MSDC_PAD_CTL2_DATRDSEL  (0xffUL << 24)   /* RW */
+
+/* MSDC_PAD_TUNE mask */
+#define MSDC_PAD_TUNE_DATWRDLY  (0x1F << 0)     /* RW */
+#define MSDC_PAD_TUNE_DATRRDLY  (0x1F << 8)     /* RW */
+#define MSDC_PAD_TUNE_CMDRDLY   (0x1F << 16)    /* RW */
+#define MSDC_PAD_TUNE_CMDRRDLY  (0x1FUL << 22)  /* RW */
+#define MSDC_PAD_TUNE_CLKTXDLY  (0x1FUL << 27)  /* RW */
+
+/* MSDC_DAT_RDDLY0/1 mask */
+#define MSDC_DAT_RDDLY0_D0      (0x1F << 0)     /* RW */
+#define MSDC_DAT_RDDLY0_D1      (0x1F << 8)     /* RW */
+#define MSDC_DAT_RDDLY0_D2      (0x1F << 16)    /* RW */
+#define MSDC_DAT_RDDLY0_D3      (0x1F << 24)    /* RW */
+
+#define MSDC_DAT_RDDLY1_D4      (0x1F << 0)     /* RW */
+#define MSDC_DAT_RDDLY1_D5      (0x1F << 8)     /* RW */
+#define MSDC_DAT_RDDLY1_D6      (0x1F << 16)    /* RW */
+#define MSDC_DAT_RDDLY1_D7      (0x1F << 24)    /* RW */
+
+#define MSDC_CKGEN_MSDC_DLY_SEL   (0x1F << 10)
+#define MSDC_INT_DAT_LATCH_CK_SEL  (0x7 << 7)
+#define MSDC_CKGEN_MSDC_CK_SEL     (0x1 << 6)
+#define CARD_READY_FOR_DATA             (1 << 8)
+#define CARD_CURRENT_STATE(x)           ((x & 0x00001E00) >> 9)
+
+/*--------------------------------------------------------------------------*/
+/* Descriptor Structure                                                     */
+/*--------------------------------------------------------------------------*/
+struct gpd {
+	u32  hwo:1; /* could be changed by hw */
+	u32  bdp:1;
+	u32  rsv0:6;
+	u32  chksum:8;
+	u32  intr:1;
+	u32  rsv1:15;
+	void *next;
+	void *ptr;
+	u32  buflen:16;
+	u32  extlen:8;
+	u32  rsv2:8;
+	u32  arg;
+	u32  blknum;
+	u32  cmd;
+};
+
+struct bd {
+	u32  eol:1;
+	u32  rsv0:7;
+	u32  chksum:8;
+	u32  rsv1:1;
+	u32  blkpad:1;
+	u32  dwpad:1;
+	u32  rsv2:13;
+	void *next;
+	void *ptr;
+	u32  buflen:16;
+	u32  rsv3:16;
+};
+
+/*--------------------------------------------------------------------------*/
+/* Register Debugging Structure                                             */
+/*--------------------------------------------------------------------------*/
+
+struct msdc_cfg_reg {
+	u32 msdc:1;
+	u32 ckpwn:1;
+	u32 rst:1;
+	u32 pio:1;
+	u32 ckdrven:1;
+	u32 start18v:1;
+	u32 pass18v:1;
+	u32 ckstb:1;
+	u32 ckdiv:8;
+	u32 ckmod:2;
+	u32 pad:14;
+};
+
+struct msdc_iocon_reg {
+	u32 sdr104cksel:1;
+	u32 rsmpl:1;
+	u32 dsmpl:1;
+	u32 ddlysel:1;
+	u32 ddr50ckd:1;
+	u32 dsplsel:1;
+	u32 pad1:10;
+	u32 d0spl:1;
+	u32 d1spl:1;
+	u32 d2spl:1;
+	u32 d3spl:1;
+	u32 d4spl:1;
+	u32 d5spl:1;
+	u32 d6spl:1;
+	u32 d7spl:1;
+	u32 riscsz:1;
+	u32 pad2:7;
+};
+
+struct msdc_ps_reg {
+	u32 cden:1;
+	u32 cdsts:1;
+	u32 pad1:10;
+	u32 cddebounce:4;
+	u32 dat:8;
+	u32 cmd:1;
+	u32 pad2:6;
+	u32 wp:1;
+};
+
+struct msdc_int_reg {
+	u32 mmcirq:1;
+	u32 cdsc:1;
+	u32 pad1:1;
+	u32 atocmdrdy:1;
+	u32 atocmdtmo:1;
+	u32 atocmdcrc:1;
+	u32 dmaqempty:1;
+	u32 sdioirq:1;
+	u32 cmdrdy:1;
+	u32 cmdtmo:1;
+	u32 rspcrc:1;
+	u32 csta:1;
+	u32 xfercomp:1;
+	u32 dxferdone:1;
+	u32 dattmo:1;
+	u32 datcrc:1;
+	u32 atocmd19done:1;
+	u32 pad2:15;
+};
+
+struct msdc_inten_reg {
+	u32 mmcirq:1;
+	u32 cdsc:1;
+	u32 pad1:1;
+	u32 atocmdrdy:1;
+	u32 atocmdtmo:1;
+	u32 atocmdcrc:1;
+	u32 dmaqempty:1;
+	u32 sdioirq:1;
+	u32 cmdrdy:1;
+	u32 cmdtmo:1;
+	u32 rspcrc:1;
+	u32 csta:1;
+	u32 xfercomp:1;
+	u32 dxferdone:1;
+	u32 dattmo:1;
+	u32 datcrc:1;
+	u32 atocmd19done:1;
+	u32 pad2:15;
+};
+
+struct msdc_fifocs_reg {
+	u32 rxcnt:8;
+	u32 pad1:8;
+	u32 txcnt:8;
+	u32 pad2:7;
+	u32 clr:1;
+};
+
+struct msdc_txdat_reg {
+	u32 val;
+};
+
+struct msdc_rxdat_reg {
+	u32 val;
+};
+
+struct sdc_cfg_reg {
+	u32 sdiowkup:1;
+	u32 inswkup:1;
+	u32 pad1:14;
+	u32 buswidth:2;
+	u32 pad2:1;
+	u32 sdio:1;
+	u32 sdioide:1;
+	u32 intblkgap:1;
+	u32 pad4:2;
+	u32 dtoc:8;
+};
+
+struct sdc_cmd_reg {
+	u32 cmd:6;
+	u32 brk:1;
+	u32 rsptyp:3;
+	u32 pad1:1;
+	u32 dtype:2;
+	u32 rw:1;
+	u32 stop:1;
+	u32 goirq:1;
+	u32 blklen:12;
+	u32 atocmd:2;
+	u32 volswth:1;
+	u32 pad2:1;
+};
+
+struct sdc_arg_reg {
+	u32 arg;
+};
+
+struct sdc_sts_reg {
+	u32 sdcbusy:1;
+	u32 cmdbusy:1;
+	u32 pad:29;
+	u32 swrcmpl:1;
+};
+
+struct sdc_resp0_reg {
+	u32 val;
+};
+
+struct sdc_resp1_reg {
+	u32 val;
+};
+
+struct sdc_resp2_reg {
+	u32 val;
+};
+
+struct sdc_resp3_reg {
+	u32 val;
+};
+
+struct sdc_blknum_reg {
+	u32 num;
+};
+
+struct sdc_csts_reg {
+	u32 sts;
+};
+
+struct sdc_cstsen_reg {
+	u32 sts;
+};
+
+struct sdc_datcrcsts_reg {
+	u32 datcrcsts:8;
+	u32 ddrcrcsts:4;
+	u32 pad:20;
+};
+
+struct emmc_cfg0_reg {
+	u32 bootstart:1;
+	u32 bootstop:1;
+	u32 bootmode:1;
+	u32 pad1:9;
+	u32 bootwaidly:3;
+	u32 bootsupp:1;
+	u32 pad2:16;
+};
+
+struct emmc_cfg1_reg {
+	u32 bootcrctmc:16;
+	u32 pad:4;
+	u32 bootacktmc:12;
+};
+
+struct emmc_sts_reg {
+	u32 bootcrcerr:1;
+	u32 bootackerr:1;
+	u32 bootdattmo:1;
+	u32 bootacktmo:1;
+	u32 bootupstate:1;
+	u32 bootackrcv:1;
+	u32 bootdatrcv:1;
+	u32 pad:25;
+};
+
+struct emmc_iocon_reg {
+	u32 bootrst:1;
+	u32 pad:31;
+};
+
+struct msdc_acmd_resp_reg {
+	u32 val;
+};
+
+struct msdc_acmd19_trg_reg {
+	u32 tunesel:4;
+	u32 pad:28;
+};
+
+struct msdc_acmd19_sts_reg {
+	u32 val;
+};
+
+struct msdc_dma_sa_reg {
+	u32 addr;
+};
+
+struct msdc_dma_ca_reg {
+	u32 addr;
+};
+
+struct msdc_dma_ctrl_reg {
+	u32 start:1;
+	u32 stop:1;
+	u32 resume:1;
+	u32 pad1:5;
+	u32 mode:1;
+	u32 pad2:1;
+	u32 lastbuf:1;
+	u32 pad3:1;
+	u32 brustsz:3;
+	u32 pad4:1;
+	u32 xfersz:16;
+};
+
+struct msdc_dma_cfg_reg {
+	u32 status:1;
+	u32 decsen:1;
+	u32 pad1:2;
+	u32 bdcsen:1;
+	u32 gpdcsen:1;
+	u32 pad2:26;
+};
+
+struct msdc_dbg_sel_reg {
+	u32 sel:16;
+	u32 pad2:16;
+};
+
+struct msdc_dbg_out_reg {
+	u32 val;
+};
+
+struct msdc_pad_ctl0_reg {
+	u32 clkdrvn:3;
+	u32 rsv0:1;
+	u32 clkdrvp:3;
+	u32 rsv1:1;
+	u32 clksr:1;
+	u32 rsv2:7;
+	u32 clkpd:1;
+	u32 clkpu:1;
+	u32 clksmt:1;
+	u32 clkies:1;
+	u32 clktdsel:4;
+	u32 clkrdsel:8;
+};
+
+struct msdc_pad_ctl1_reg {
+	u32 cmddrvn:3;
+	u32 rsv0:1;
+	u32 cmddrvp:3;
+	u32 rsv1:1;
+	u32 cmdsr:1;
+	u32 rsv2:7;
+	u32 cmdpd:1;
+	u32 cmdpu:1;
+	u32 cmdsmt:1;
+	u32 cmdies:1;
+	u32 cmdtdsel:4;
+	u32 cmdrdsel:8;
+};
+
+struct msdc_pad_ctl2_reg {
+	u32 datdrvn:3;
+	u32 rsv0:1;
+	u32 datdrvp:3;
+	u32 rsv1:1;
+	u32 datsr:1;
+	u32 rsv2:7;
+	u32 datpd:1;
+	u32 datpu:1;
+	u32 datsmt:1;
+	u32 daties:1;
+	u32 dattdsel:4;
+	u32 datrdsel:8;
+};
+
+struct msdc_pad_tune_reg {
+	u32 wrrxdly:3;
+	u32 pad1:5;
+	u32 rdrxdly:8;
+	u32 pad2:16;
+};
+
+struct msdc_dat_rddly0 {
+	u32 dat0:5;
+	u32 rsv0:3;
+	u32 dat1:5;
+	u32 rsv1:3;
+	u32 dat2:5;
+	u32 rsv2:3;
+	u32 dat3:5;
+	u32 rsv3:3;
+};
+
+struct msdc_dat_rddly1 {
+	u32 dat4:5;
+	u32 rsv4:3;
+	u32 dat5:5;
+	u32 rsv5:3;
+	u32 dat6:5;
+	u32 rsv6:3;
+	u32 dat7:5;
+	u32 rsv7:3;
+};
+
+struct msdc_hw_dbg_reg {
+	u32 dbg0sel:8;
+	u32 dbg1sel:6;
+	u32 pad1:2;
+	u32 dbg2sel:6;
+	u32 pad2:2;
+	u32 dbg3sel:6;
+	u32 pad3:2;
+};
+
+struct msdc_version_reg {
+	u32 val;
+};
+
+struct msdc_eco_ver_reg {
+	u32 val;
+};
+
+struct msdc_regs {
+	struct msdc_cfg_reg        msdc_cfg;      /* base+0x00h */
+	struct msdc_iocon_reg      msdc_iocon;    /* base+0x04h */
+	struct msdc_ps_reg         msdc_ps;       /* base+0x08h */
+	struct msdc_int_reg        msdc_int;      /* base+0x0ch */
+	struct msdc_inten_reg      msdc_inten;    /* base+0x10h */
+	struct msdc_fifocs_reg     msdc_fifocs;   /* base+0x14h */
+	struct msdc_txdat_reg      msdc_txdat;    /* base+0x18h */
+	struct msdc_rxdat_reg      msdc_rxdat;    /* base+0x1ch */
+	u32                 rsv1[4];
+	struct sdc_cfg_reg         sdc_cfg;       /* base+0x30h */
+	struct sdc_cmd_reg         sdc_cmd;       /* base+0x34h */
+	struct sdc_arg_reg         sdc_arg;       /* base+0x38h */
+	struct sdc_sts_reg         sdc_sts;       /* base+0x3ch */
+	struct sdc_resp0_reg       sdc_resp0;     /* base+0x40h */
+	struct sdc_resp1_reg       sdc_resp1;     /* base+0x44h */
+	struct sdc_resp2_reg       sdc_resp2;     /* base+0x48h */
+	struct sdc_resp3_reg       sdc_resp3;     /* base+0x4ch */
+	struct sdc_blknum_reg      sdc_blknum;    /* base+0x50h */
+	u32                 rsv2[1];
+	struct sdc_csts_reg        sdc_csts;      /* base+0x58h */
+	struct sdc_cstsen_reg      sdc_cstsen;    /* base+0x5ch */
+	struct sdc_datcrcsts_reg   sdc_dcrcsta;   /* base+0x60h */
+	u32                 rsv3[3];
+	struct emmc_cfg0_reg       emmc_cfg0;     /* base+0x70h */
+	struct emmc_cfg1_reg       emmc_cfg1;     /* base+0x74h */
+	struct emmc_sts_reg        emmc_sts;      /* base+0x78h */
+	struct emmc_iocon_reg      emmc_iocon;    /* base+0x7ch */
+	struct msdc_acmd_resp_reg  acmd_resp;     /* base+0x80h */
+	struct msdc_acmd19_trg_reg acmd19_trg;    /* base+0x84h */
+	struct msdc_acmd19_sts_reg acmd19_sts;    /* base+0x88h */
+	u32                 rsv4[1];
+	struct msdc_dma_sa_reg     dma_sa;        /* base+0x90h */
+	struct msdc_dma_ca_reg     dma_ca;        /* base+0x94h */
+	struct msdc_dma_ctrl_reg   dma_ctrl;      /* base+0x98h */
+	struct msdc_dma_cfg_reg    dma_cfg;       /* base+0x9ch */
+	struct msdc_dbg_sel_reg    dbg_sel;       /* base+0xa0h */
+	struct msdc_dbg_out_reg    dbg_out;       /* base+0xa4h */
+	u32                 rsv5[2];
+	u32                 patch0;        /* base+0xb0h */
+	u32                 patch1;        /* base+0xb4h */
+	u32                 rsv6[10];
+	struct msdc_pad_ctl0_reg   pad_ctl0;      /* base+0xe0h */
+	struct msdc_pad_ctl1_reg   pad_ctl1;      /* base+0xe4h */
+	struct msdc_pad_ctl2_reg   pad_ctl2;      /* base+0xe8h */
+	struct msdc_pad_tune_reg   pad_tune;      /* base+0xech */
+	struct msdc_dat_rddly0     dat_rddly0;    /* base+0xf0h */
+	struct msdc_dat_rddly1     dat_rddly1;    /* base+0xf4h */
+	struct msdc_hw_dbg_reg     hw_dbg;        /* base+0xf8h */
+	u32                 rsv7[1];
+	struct msdc_version_reg    version;       /* base+0x100h */
+	struct msdc_eco_ver_reg    eco_ver;       /* base+0x104h */
+};
+
+struct msdc_dma {
+	u32 sglen;                   /* size of scatter list */
+	struct scatterlist *sg;      /* I/O scatter list */
+	u8  mode;                    /* dma mode        */
+
+	struct gpd *gpd;                  /* pointer to gpd array */
+	struct bd  *bd;                   /* pointer to bd array */
+	dma_addr_t gpd_addr;         /* the physical address of gpd array */
+	dma_addr_t bd_addr;          /* the physical address of bd array */
+};
+
+struct msdc_host {
+	struct msdc_hw              *hw;
+
+	struct mmc_host             *mmc;           /* mmc structure */
+	struct mmc_command          *cmd;
+	struct mmc_data             *data;
+	struct mmc_request          *mrq;
+	int                         cmd_rsp;
+
+	int                         error;
+	spinlock_t                  lock;           /* mutex */
+	struct semaphore            sem;
+
+	u32                         blksz;          /* host block size */
+	void __iomem                *base;           /* host base address */
+	int                         id;             /* host id */
+	int                         pwr_ref;        /* core power reference count */
+
+	u32                         xfer_size;      /* total transferred size */
+
+	struct msdc_dma             dma;            /* dma channel */
+	u32                         dma_xfer_size;  /* dma transfer size in bytes */
+
+	u32                         timeout_ns;     /* data timeout ns */
+	u32                         timeout_clks;   /* data timeout clks */
+
+	int                         irq;            /* host interrupt */
+
+	struct delayed_work		card_delaywork;
+
+	struct completion           cmd_done;
+	struct completion           xfer_done;
+	struct pm_message           pm_state;
+
+	u32                         mclk;           /* mmc subsystem clock */
+	u32                         hclk;           /* host clock speed */
+	u32                         sclk;           /* SD/MS clock speed */
+	u8                          core_clkon;     /* Host core clock on ? */
+	u8                          card_clkon;     /* Card clock on ? */
+	u8                          core_power;     /* core power */
+	u8                          power_mode;     /* host power mode */
+	u8                          card_inserted;  /* card inserted ? */
+	u8                          suspend;        /* host suspended ? */
+	u8                          app_cmd;        /* for app command */
+	u32                         app_cmd_arg;
+};
+
+#define sdr_read8(reg)            readb(reg)
+#define sdr_read32(reg)           readl(reg)
+#define sdr_write8(reg, val)      writeb(val, reg)
+#define sdr_write32(reg, val)     writel(val, reg)
+
+static inline void sdr_set_bits(void __iomem *reg, u32 bs)
+{
+	u32 val = readl(reg);
+
+	val |= bs;
+	writel(val, reg);
+}
+
+static inline void sdr_clr_bits(void __iomem *reg, u32 bs)
+{
+	u32 val = readl(reg);
+
+	val &= ~bs;
+	writel(val, reg);
+}
+
+static inline void sdr_set_field(void __iomem *reg, u32 field, u32 val)
+{
+	unsigned int tv = readl(reg);
+
+	tv &= ~field;
+	tv |= ((val) << (ffs((unsigned int)field) - 1));
+	writel(tv, reg);
+}
+
+static inline void sdr_get_field(void __iomem *reg, u32 field, u32 *val)
+{
+	unsigned int tv = readl(reg);
+	*val = ((tv & field) >> (ffs((unsigned int)field) - 1));
+}
+
+#endif
diff --git a/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c
new file mode 100644
index 0000000..188e015
--- /dev/null
+++ b/target/linux/ramips/files/drivers/mmc/host/mtk-mmc/sd.c
@@ -0,0 +1,2461 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ *
+ * MediaTek Inc. (C) 2010. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ *
+ * The following software/firmware and/or related documentation ("MediaTek Software")
+ * have been modified by MediaTek Inc. All revisions are subject to any receiver's
+ * applicable license agreements with MediaTek Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sd.h>
+#include <linux/mmc/sdio.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "board.h"
+#include "dbg.h"
+#include "mt6575_sd.h"
+
+//#define IRQ_SDC 14	//MT7620 /*FIXME*/
+#ifdef CONFIG_SOC_MT7621
+#define RALINK_SYSCTL_BASE		0xbe000000
+#define RALINK_MSDC_BASE		0xbe130000
+#else
+#define RALINK_SYSCTL_BASE		0xb0000000
+#define RALINK_MSDC_BASE		0xb0130000
+#endif
+#define IRQ_SDC			22	/*FIXME*/
+
+#define DRV_NAME            "mtk-sd"
+
+#if defined(CONFIG_SOC_MT7620)
+#define HOST_MAX_MCLK       (48000000) /* +/- by chhung */
+#elif defined(CONFIG_SOC_MT7621)
+#define HOST_MAX_MCLK       (50000000) /* +/- by chhung */
+#endif
+#define HOST_MIN_MCLK       (260000)
+
+#define HOST_MAX_BLKSZ      (2048)
+
+#define MSDC_OCR_AVAIL      (MMC_VDD_28_29 | MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33)
+
+#define GPIO_PULL_DOWN      (0)
+#define GPIO_PULL_UP        (1)
+
+#if 0 /* --- by chhung */
+#define MSDC_CLKSRC_REG     (0xf100000C)
+#define PDN_REG           (0xF1000010)
+#endif /* end of --- */
+
+#define DEFAULT_DEBOUNCE    (8)       /* 8 cycles */
+#define DEFAULT_DTOC        (40)      /* data timeout counter. 65536x40 sclk. */
+
+#define CMD_TIMEOUT         (HZ / 10)     /* 100ms */
+#define DAT_TIMEOUT         (HZ / 2 * 5)  /* 500ms x5 */
+
+#define MAX_DMA_CNT         (64 * 1024 - 512)   /* a single transaction for WIFI may be 50K*/
+
+#define MAX_GPD_NUM         (1 + 1)  /* one null gpd */
+#define MAX_BD_NUM          (1024)
+#define MAX_BD_PER_GPD      (MAX_BD_NUM)
+
+#define MAX_HW_SGMTS        (MAX_BD_NUM)
+#define MAX_PHY_SGMTS       (MAX_BD_NUM)
+#define MAX_SGMT_SZ         (MAX_DMA_CNT)
+#define MAX_REQ_SZ          (MAX_SGMT_SZ * 8)
+
+static int cd_active_low = 1;
+
+//=================================
+#define PERI_MSDC0_PDN      (15)
+//#define PERI_MSDC1_PDN    (16)
+//#define PERI_MSDC2_PDN    (17)
+//#define PERI_MSDC3_PDN    (18)
+
+#if 0 /* --- by chhung */
+/* gate means clock power down */
+static int g_clk_gate = 0;
+#define msdc_gate_clock(id) \
+	do {					       \
+		g_clk_gate &= ~(1 << ((id) + PERI_MSDC0_PDN));	\
+	} while (0)
+/* not like power down register. 1 means clock on. */
+#define msdc_ungate_clock(id) \
+	do {					    \
+		g_clk_gate |= 1 << ((id) + PERI_MSDC0_PDN);	\
+	} while (0)
+
+// do we need sync object or not
+void msdc_clk_status(int *status)
+{
+	*status = g_clk_gate;
+}
+#endif /* end of --- */
+
+/* +++ by chhung */
+struct msdc_hw msdc0_hw = {
+	.clk_src        = 0,
+	.flags          = MSDC_CD_PIN_EN | MSDC_REMOVABLE,
+//	.flags          = MSDC_WP_PIN_EN | MSDC_CD_PIN_EN | MSDC_REMOVABLE,
+};
+
+/* end of +++ */
+
+static int msdc_rsp[] = {
+	0,  /* RESP_NONE */
+	1,  /* RESP_R1 */
+	2,  /* RESP_R2 */
+	3,  /* RESP_R3 */
+	4,  /* RESP_R4 */
+	1,  /* RESP_R5 */
+	1,  /* RESP_R6 */
+	1,  /* RESP_R7 */
+	7,  /* RESP_R1b */
+};
+
+#define msdc_txfifocnt()   ((sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_TXCNT) >> 16)
+#define msdc_rxfifocnt()   ((sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_RXCNT) >> 0)
+#define msdc_fifo_write32(v)   sdr_write32(MSDC_TXDATA, (v))
+#define msdc_fifo_write8(v)    sdr_write8(MSDC_TXDATA, (v))
+#define msdc_fifo_read32()   sdr_read32(MSDC_RXDATA)
+#define msdc_fifo_read8()    sdr_read8(MSDC_RXDATA)
+
+#define msdc_dma_on()        sdr_clr_bits(MSDC_CFG, MSDC_CFG_PIO)
+
+#define msdc_retry(expr, retry, cnt) \
+	do {								\
+		int backup = cnt;					\
+		while (retry) {						\
+			if (!(expr))					\
+				break;					\
+			if (cnt-- == 0) {				\
+				retry--; mdelay(1); cnt = backup;	\
+			}						\
+		}							\
+		WARN_ON(retry == 0);					\
+	} while (0)
+
+static void msdc_reset_hw(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+
+	sdr_set_bits(MSDC_CFG, MSDC_CFG_RST);
+	while (sdr_read32(MSDC_CFG) & MSDC_CFG_RST)
+		cpu_relax();
+}
+
+#define msdc_clr_int() \
+	do {							\
+		volatile u32 val = sdr_read32(MSDC_INT);	\
+		sdr_write32(MSDC_INT, val);			\
+	} while (0)
+
+#define msdc_clr_fifo() \
+	do {								\
+		int retry = 3, cnt = 1000;				\
+		sdr_set_bits(MSDC_FIFOCS, MSDC_FIFOCS_CLR);		\
+		msdc_retry(sdr_read32(MSDC_FIFOCS) & MSDC_FIFOCS_CLR, retry, cnt); \
+	} while (0)
+
+#define msdc_irq_save(val) \
+	do {					\
+		val = sdr_read32(MSDC_INTEN);	\
+		sdr_clr_bits(MSDC_INTEN, val);	\
+	} while (0)
+
+#define msdc_irq_restore(val) \
+	do {					\
+		sdr_set_bits(MSDC_INTEN, val);	\
+	} while (0)
+
+/* clock source for host: global */
+#if defined(CONFIG_SOC_MT7620)
+static u32 hclks[] = {48000000}; /* +/- by chhung */
+#elif defined(CONFIG_SOC_MT7621)
+static u32 hclks[] = {50000000}; /* +/- by chhung */
+#endif
+
+//============================================
+// the power for msdc host controller: global
+//    always keep the VMC on.
+//============================================
+#define msdc_vcore_on(host) \
+	do {								\
+		INIT_MSG("[+]VMC ref. count<%d>", ++host->pwr_ref);	\
+		(void)hwPowerOn(MT65XX_POWER_LDO_VMC, VOL_3300, "SD");	\
+	} while (0)
+#define msdc_vcore_off(host) \
+	do {								\
+		INIT_MSG("[-]VMC ref. count<%d>", --host->pwr_ref);	\
+		(void)hwPowerDown(MT65XX_POWER_LDO_VMC, "SD");		\
+	} while (0)
+
+//====================================
+// the vdd output for card: global
+//   always keep the VMCH on.
+//====================================
+#define msdc_vdd_on(host) \
+	do {								\
+		(void)hwPowerOn(MT65XX_POWER_LDO_VMCH, VOL_3300, "SD"); \
+	} while (0)
+#define msdc_vdd_off(host) \
+	do {							\
+		(void)hwPowerDown(MT65XX_POWER_LDO_VMCH, "SD"); \
+	} while (0)
+
+#define sdc_is_busy()          (sdr_read32(SDC_STS) & SDC_STS_SDCBUSY)
+#define sdc_is_cmd_busy()      (sdr_read32(SDC_STS) & SDC_STS_CMDBUSY)
+
+#define sdc_send_cmd(cmd, arg) \
+	do {					\
+		sdr_write32(SDC_ARG, (arg));	\
+		sdr_write32(SDC_CMD, (cmd));	\
+	} while (0)
+
+// can modify to read h/w register.
+//#define is_card_present(h)   ((sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1);
+#define is_card_present(h)     (((struct msdc_host *)(h))->card_inserted)
+
+/* +++ by chhung */
+#ifndef __ASSEMBLY__
+#define PHYSADDR(a)             (((unsigned long)(a)) & 0x1fffffff)
+#else
+#define PHYSADDR(a)             ((a) & 0x1fffffff)
+#endif
+/* end of +++ */
+static unsigned int msdc_do_command(struct msdc_host   *host,
+				    struct mmc_command *cmd,
+				    int                 tune,
+				    unsigned long       timeout);
+
+static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd);
+
+#ifdef MT6575_SD_DEBUG
+static void msdc_dump_card_status(struct msdc_host *host, u32 status)
+{
+/* N_MSG is currently a no-op */
+#if 0
+	static char *state[] = {
+		"Idle",			/* 0 */
+		"Ready",		/* 1 */
+		"Ident",		/* 2 */
+		"Stby",			/* 3 */
+		"Tran",			/* 4 */
+		"Data",			/* 5 */
+		"Rcv",			/* 6 */
+		"Prg",			/* 7 */
+		"Dis",			/* 8 */
+		"Reserved",		/* 9 */
+		"Reserved",		/* 10 */
+		"Reserved",		/* 11 */
+		"Reserved",		/* 12 */
+		"Reserved",		/* 13 */
+		"Reserved",		/* 14 */
+		"I/O mode",		/* 15 */
+	};
+#endif
+	if (status & R1_OUT_OF_RANGE)
+		N_MSG(RSP, "[CARD_STATUS] Out of Range");
+	if (status & R1_ADDRESS_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Address Error");
+	if (status & R1_BLOCK_LEN_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Block Len Error");
+	if (status & R1_ERASE_SEQ_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Erase Seq Error");
+	if (status & R1_ERASE_PARAM)
+		N_MSG(RSP, "[CARD_STATUS] Erase Param");
+	if (status & R1_WP_VIOLATION)
+		N_MSG(RSP, "[CARD_STATUS] WP Violation");
+	if (status & R1_CARD_IS_LOCKED)
+		N_MSG(RSP, "[CARD_STATUS] Card is Locked");
+	if (status & R1_LOCK_UNLOCK_FAILED)
+		N_MSG(RSP, "[CARD_STATUS] Lock/Unlock Failed");
+	if (status & R1_COM_CRC_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Command CRC Error");
+	if (status & R1_ILLEGAL_COMMAND)
+		N_MSG(RSP, "[CARD_STATUS] Illegal Command");
+	if (status & R1_CARD_ECC_FAILED)
+		N_MSG(RSP, "[CARD_STATUS] Card ECC Failed");
+	if (status & R1_CC_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] CC Error");
+	if (status & R1_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Error");
+	if (status & R1_UNDERRUN)
+		N_MSG(RSP, "[CARD_STATUS] Underrun");
+	if (status & R1_OVERRUN)
+		N_MSG(RSP, "[CARD_STATUS] Overrun");
+	if (status & R1_CID_CSD_OVERWRITE)
+		N_MSG(RSP, "[CARD_STATUS] CID/CSD Overwrite");
+	if (status & R1_WP_ERASE_SKIP)
+		N_MSG(RSP, "[CARD_STATUS] WP Eraser Skip");
+	if (status & R1_CARD_ECC_DISABLED)
+		N_MSG(RSP, "[CARD_STATUS] Card ECC Disabled");
+	if (status & R1_ERASE_RESET)
+		N_MSG(RSP, "[CARD_STATUS] Erase Reset");
+	if (status & R1_READY_FOR_DATA)
+		N_MSG(RSP, "[CARD_STATUS] Ready for Data");
+	if (status & R1_SWITCH_ERROR)
+		N_MSG(RSP, "[CARD_STATUS] Switch error");
+	if (status & R1_APP_CMD)
+		N_MSG(RSP, "[CARD_STATUS] App Command");
+
+	N_MSG(RSP, "[CARD_STATUS] '%s' State", state[R1_CURRENT_STATE(status)]);
+}
+
+static void msdc_dump_ocr_reg(struct msdc_host *host, u32 resp)
+{
+	if (resp & (1 << 7))
+		N_MSG(RSP, "[OCR] Low Voltage Range");
+	if (resp & (1 << 15))
+		N_MSG(RSP, "[OCR] 2.7-2.8 volt");
+	if (resp & (1 << 16))
+		N_MSG(RSP, "[OCR] 2.8-2.9 volt");
+	if (resp & (1 << 17))
+		N_MSG(RSP, "[OCR] 2.9-3.0 volt");
+	if (resp & (1 << 18))
+		N_MSG(RSP, "[OCR] 3.0-3.1 volt");
+	if (resp & (1 << 19))
+		N_MSG(RSP, "[OCR] 3.1-3.2 volt");
+	if (resp & (1 << 20))
+		N_MSG(RSP, "[OCR] 3.2-3.3 volt");
+	if (resp & (1 << 21))
+		N_MSG(RSP, "[OCR] 3.3-3.4 volt");
+	if (resp & (1 << 22))
+		N_MSG(RSP, "[OCR] 3.4-3.5 volt");
+	if (resp & (1 << 23))
+		N_MSG(RSP, "[OCR] 3.5-3.6 volt");
+	if (resp & (1 << 24))
+		N_MSG(RSP, "[OCR] Switching to 1.8V Accepted (S18A)");
+	if (resp & (1 << 30))
+		N_MSG(RSP, "[OCR] Card Capacity Status (CCS)");
+	if (resp & (1 << 31))
+		N_MSG(RSP, "[OCR] Card Power Up Status (Idle)");
+	else
+		N_MSG(RSP, "[OCR] Card Power Up Status (Busy)");
+}
+
+static void msdc_dump_rca_resp(struct msdc_host *host, u32 resp)
+{
+	u32 status = (((resp >> 15) & 0x1) << 23) |
+		     (((resp >> 14) & 0x1) << 22) |
+		     (((resp >> 13) & 0x1) << 19) |
+		     (resp & 0x1fff);
+
+	N_MSG(RSP, "[RCA] 0x%.4x", resp >> 16);
+	msdc_dump_card_status(host, status);
+}
+
+static void msdc_dump_io_resp(struct msdc_host *host, u32 resp)
+{
+	u32 flags = (resp >> 8) & 0xFF;
+#if 0
+	char *state[] = {"DIS", "CMD", "TRN", "RFU"};
+#endif
+	if (flags & (1 << 7))
+		N_MSG(RSP, "[IO] COM_CRC_ERR");
+	if (flags & (1 << 6))
+		N_MSG(RSP, "[IO] Illgal command");
+	if (flags & (1 << 3))
+		N_MSG(RSP, "[IO] Error");
+	if (flags & (1 << 2))
+		N_MSG(RSP, "[IO] RFU");
+	if (flags & (1 << 1))
+		N_MSG(RSP, "[IO] Function number error");
+	if (flags & (1 << 0))
+		N_MSG(RSP, "[IO] Out of range");
+
+	N_MSG(RSP, "[IO] State: %s, Data:0x%x", state[(resp >> 12) & 0x3], resp & 0xFF);
+}
+#endif
+
+static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
+{
+	void __iomem *base = host->base;
+	u32 timeout, clk_ns;
+
+	host->timeout_ns   = ns;
+	host->timeout_clks = clks;
+
+	clk_ns  = 1000000000UL / host->sclk;
+	timeout = ns / clk_ns + clks;
+	timeout = timeout >> 16; /* in 65536 sclk cycle unit */
+	timeout = timeout > 1 ? timeout - 1 : 0;
+	timeout = timeout > 255 ? 255 : timeout;
+
+	sdr_set_field(SDC_CFG, SDC_CFG_DTOC, timeout);
+
+	N_MSG(OPS, "Set read data timeout: %dns %dclks -> %d x 65536 cycles",
+	      ns, clks, timeout + 1);
+}
+
+static void msdc_tasklet_card(struct work_struct *work)
+{
+	struct msdc_host *host = (struct msdc_host *)container_of(work,
+				struct msdc_host, card_delaywork.work);
+	void __iomem *base = host->base;
+	u32 inserted;
+	u32 status = 0;
+    //u32 change = 0;
+
+	spin_lock(&host->lock);
+
+	status = sdr_read32(MSDC_PS);
+	if (cd_active_low)
+		inserted = (status & MSDC_PS_CDSTS) ? 0 : 1;
+	else
+		inserted = (status & MSDC_PS_CDSTS) ? 1 : 0;
+	if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
+		inserted = 1;
+
+#if 0
+	change = host->card_inserted ^ inserted;
+	host->card_inserted = inserted;
+
+	if (change && !host->suspend) {
+		if (inserted)
+			host->mmc->f_max = HOST_MAX_MCLK;  // work around
+		mmc_detect_change(host->mmc, msecs_to_jiffies(20));
+	}
+#else  /* Make sure: handle the last interrupt */
+	host->card_inserted = inserted;
+
+	if (!host->suspend) {
+		host->mmc->f_max = HOST_MAX_MCLK;
+		mmc_detect_change(host->mmc, msecs_to_jiffies(20));
+	}
+
+	IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed");
+#endif
+
+	spin_unlock(&host->lock);
+}
+
+#if 0 /* --- by chhung */
+/* For E2 only */
+static u8 clk_src_bit[4] = {
+	0, 3, 5, 7
+};
+
+static void msdc_select_clksrc(struct msdc_host *host, unsigned char clksrc)
+{
+	u32 val;
+	void __iomem *base = host->base;
+
+	BUG_ON(clksrc > 3);
+	INIT_MSG("set clock source to <%d>", clksrc);
+
+	val = sdr_read32(MSDC_CLKSRC_REG);
+	if (sdr_read32(MSDC_ECO_VER) >= 4) {
+		val &= ~(0x3  << clk_src_bit[host->id]);
+		val |= clksrc << clk_src_bit[host->id];
+	} else {
+		val &= ~0x3; val |= clksrc;
+	}
+	sdr_write32(MSDC_CLKSRC_REG, val);
+
+	host->hclk = hclks[clksrc];
+	host->hw->clk_src = clksrc;
+}
+#endif /* end of --- */
+
+static void msdc_set_mclk(struct msdc_host *host, int ddr, unsigned int hz)
+{
+	//struct msdc_hw *hw = host->hw;
+	void __iomem *base = host->base;
+	u32 mode;
+	u32 flags;
+	u32 div;
+	u32 sclk;
+	u32 hclk = host->hclk;
+	//u8  clksrc = hw->clk_src;
+
+	if (!hz) { // set mmc system clock to 0 ?
+		//ERR_MSG("set mclk to 0!!!");
+		msdc_reset_hw(host);
+		return;
+	}
+
+	msdc_irq_save(flags);
+
+	if (ddr) {
+		mode = 0x2; /* ddr mode and use divisor */
+		if (hz >= (hclk >> 2)) {
+			div  = 1;         /* mean div = 1/4 */
+			sclk = hclk >> 2; /* sclk = clk / 4 */
+		} else {
+			div  = (hclk + ((hz << 2) - 1)) / (hz << 2);
+			sclk = (hclk >> 2) / div;
+		}
+	} else if (hz >= hclk) { /* bug fix */
+		mode = 0x1; /* no divisor and divisor is ignored */
+		div  = 0;
+		sclk = hclk;
+	} else {
+		mode = 0x0; /* use divisor */
+		if (hz >= (hclk >> 1)) {
+			div  = 0;         /* mean div = 1/2 */
+			sclk = hclk >> 1; /* sclk = clk / 2 */
+		} else {
+			div  = (hclk + ((hz << 2) - 1)) / (hz << 2);
+			sclk = (hclk >> 2) / div;
+		}
+	}
+
+	/* set clock mode and divisor */
+	sdr_set_field(MSDC_CFG, MSDC_CFG_CKMOD, mode);
+	sdr_set_field(MSDC_CFG, MSDC_CFG_CKDIV, div);
+
+	/* wait clock stable */
+	while (!(sdr_read32(MSDC_CFG) & MSDC_CFG_CKSTB))
+		cpu_relax();
+
+	host->sclk = sclk;
+	host->mclk = hz;
+	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); // need?
+
+	INIT_MSG("================");
+	INIT_MSG("!!! Set<%dKHz> Source<%dKHz> -> sclk<%dKHz>", hz / 1000, hclk / 1000, sclk / 1000);
+	INIT_MSG("================");
+
+	msdc_irq_restore(flags);
+}
+
+/* Fix me. when need to abort */
+static void msdc_abort_data(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+	struct mmc_command *stop = host->mrq->stop;
+
+	ERR_MSG("Need to Abort.");
+
+	msdc_reset_hw(host);
+	msdc_clr_fifo();
+	msdc_clr_int();
+
+	// need to check FIFO count 0 ?
+
+	if (stop) {  /* try to stop, but may not success */
+		ERR_MSG("stop when abort CMD<%d>", stop->opcode);
+		(void)msdc_do_command(host, stop, 0, CMD_TIMEOUT);
+	}
+
+	//if (host->mclk >= 25000000) {
+	//      msdc_set_mclk(host, 0, host->mclk >> 1);
+	//}
+}
+
+#if 0 /* --- by chhung */
+static void msdc_pin_config(struct msdc_host *host, int mode)
+{
+	struct msdc_hw *hw = host->hw;
+	void __iomem *base = host->base;
+	int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
+
+	/* Config WP pin */
+	if (hw->flags & MSDC_WP_PIN_EN) {
+		if (hw->config_gpio_pin) /* NULL */
+			hw->config_gpio_pin(MSDC_WP_PIN, pull);
+	}
+
+	switch (mode) {
+	case MSDC_PIN_PULL_UP:
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 1); /* Check & FIXME */
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 1);
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 1);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
+		break;
+	case MSDC_PIN_PULL_DOWN:
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 1); /* Check & FIXME */
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 1);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 1);
+		break;
+	case MSDC_PIN_PULL_NONE:
+	default:
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPU, 0); /* Check & FIXME */
+		//sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKPD, 0); /* Check & FIXME */
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPU, 0);
+		sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDPD, 0);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPU, 0);
+		sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATPD, 0);
+		break;
+	}
+
+	N_MSG(CFG, "Pins mode(%d), down(%d), up(%d)",
+	      mode, MSDC_PIN_PULL_DOWN, MSDC_PIN_PULL_UP);
+}
+
+void msdc_pin_reset(struct msdc_host *host, int mode)
+{
+	struct msdc_hw *hw = (struct msdc_hw *)host->hw;
+	void __iomem *base = host->base;
+	int pull = (mode == MSDC_PIN_PULL_UP) ? GPIO_PULL_UP : GPIO_PULL_DOWN;
+
+	/* Config reset pin */
+	if (hw->flags & MSDC_RST_PIN_EN) {
+		if (hw->config_gpio_pin) /* NULL */
+			hw->config_gpio_pin(MSDC_RST_PIN, pull);
+
+		if (mode == MSDC_PIN_PULL_UP)
+			sdr_clr_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST);
+		else
+			sdr_set_bits(EMMC_IOCON, EMMC_IOCON_BOOTRST);
+	}
+}
+
+static void msdc_core_power(struct msdc_host *host, int on)
+{
+	N_MSG(CFG, "Turn %s %s power (copower: %d -> %d)",
+		on ? "on" : "off", "core", host->core_power, on);
+
+	if (on && host->core_power == 0) {
+		msdc_vcore_on(host);
+		host->core_power = 1;
+		msleep(1);
+	} else if (!on && host->core_power == 1) {
+		msdc_vcore_off(host);
+		host->core_power = 0;
+		msleep(1);
+	}
+}
+
+static void msdc_host_power(struct msdc_host *host, int on)
+{
+	N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "host");
+
+	if (on) {
+		//msdc_core_power(host, 1); // need do card detection.
+		msdc_pin_reset(host, MSDC_PIN_PULL_UP);
+	} else {
+		msdc_pin_reset(host, MSDC_PIN_PULL_DOWN);
+		//msdc_core_power(host, 0);
+	}
+}
+
+static void msdc_card_power(struct msdc_host *host, int on)
+{
+	N_MSG(CFG, "Turn %s %s power ", on ? "on" : "off", "card");
+
+	if (on) {
+		msdc_pin_config(host, MSDC_PIN_PULL_UP);
+		//msdc_vdd_on(host);  // need todo card detection.
+		msleep(1);
+	} else {
+		//msdc_vdd_off(host);
+		msdc_pin_config(host, MSDC_PIN_PULL_DOWN);
+		msleep(1);
+	}
+}
+
+static void msdc_set_power_mode(struct msdc_host *host, u8 mode)
+{
+	N_MSG(CFG, "Set power mode(%d)", mode);
+
+	if (host->power_mode == MMC_POWER_OFF && mode != MMC_POWER_OFF) {
+		msdc_host_power(host, 1);
+		msdc_card_power(host, 1);
+	} else if (host->power_mode != MMC_POWER_OFF && mode == MMC_POWER_OFF) {
+		msdc_card_power(host, 0);
+		msdc_host_power(host, 0);
+	}
+	host->power_mode = mode;
+}
+#endif /* end of --- */
+
+#ifdef CONFIG_PM
+/*
+   register as callback function of WIFI(combo_sdio_register_pm) .
+   can called by msdc_drv_suspend/resume too.
+*/
+static void msdc_pm(pm_message_t state, void *data)
+{
+	struct msdc_host *host = (struct msdc_host *)data;
+	int evt = state.event;
+
+	if (evt == PM_EVENT_USER_RESUME || evt == PM_EVENT_USER_SUSPEND) {
+		INIT_MSG("USR_%s: suspend<%d> power<%d>",
+			evt == PM_EVENT_USER_RESUME ? "EVENT_USER_RESUME" : "EVENT_USER_SUSPEND",
+			host->suspend, host->power_mode);
+	}
+
+	if (evt == PM_EVENT_SUSPEND || evt == PM_EVENT_USER_SUSPEND) {
+		if (host->suspend) /* already suspend */  /* default 0*/
+			return;
+
+		/* for memory card. already power off by mmc */
+		if (evt == PM_EVENT_SUSPEND && host->power_mode == MMC_POWER_OFF)
+			return;
+
+		host->suspend = 1;
+		host->pm_state = state;  /* default PMSG_RESUME */
+
+	} else if (evt == PM_EVENT_RESUME || evt == PM_EVENT_USER_RESUME) {
+		if (!host->suspend) {
+			//ERR_MSG("warning: already resume");
+			return;
+		}
+
+		/* No PM resume when USR suspend */
+		if (evt == PM_EVENT_RESUME && host->pm_state.event == PM_EVENT_USER_SUSPEND) {
+			ERR_MSG("PM Resume when in USR Suspend");		/* won't happen. */
+			return;
+		}
+
+		host->suspend = 0;
+		host->pm_state = state;
+
+	}
+}
+#endif
+
+/*--------------------------------------------------------------------------*/
+/* mmc_host_ops members                                                      */
+/*--------------------------------------------------------------------------*/
+static unsigned int msdc_command_start(struct msdc_host   *host,
+				       struct mmc_command *cmd,
+				       int                 tune,   /* not used */
+				       unsigned long       timeout)
+{
+	void __iomem *base = host->base;
+	u32 opcode = cmd->opcode;
+	u32 rawcmd;
+	u32 wints = MSDC_INT_CMDRDY  | MSDC_INT_RSPCRCERR  | MSDC_INT_CMDTMO  |
+		    MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO |
+		    MSDC_INT_ACMD19_DONE;
+
+	u32 resp;
+	unsigned long tmo;
+
+	/* Protocol layer does not provide response type, but our hardware needs
+	 * to know exact type, not just size!
+	 */
+	if (opcode == MMC_SEND_OP_COND || opcode == SD_APP_OP_COND) {
+		resp = RESP_R3;
+	} else if (opcode == MMC_SET_RELATIVE_ADDR) {
+		resp = (mmc_cmd_type(cmd) == MMC_CMD_BCR) ? RESP_R6 : RESP_R1;
+	} else if (opcode == MMC_FAST_IO) {
+		resp = RESP_R4;
+	} else if (opcode == MMC_GO_IRQ_STATE) {
+		resp = RESP_R5;
+	} else if (opcode == MMC_SELECT_CARD) {
+		resp = (cmd->arg != 0) ? RESP_R1B : RESP_NONE;
+	} else if (opcode == SD_IO_RW_DIRECT || opcode == SD_IO_RW_EXTENDED) {
+		resp = RESP_R1; /* SDIO workaround. */
+	} else if (opcode == SD_SEND_IF_COND && (mmc_cmd_type(cmd) == MMC_CMD_BCR)) {
+		resp = RESP_R1;
+	} else {
+		switch (mmc_resp_type(cmd)) {
+		case MMC_RSP_R1:
+			resp = RESP_R1;
+			break;
+		case MMC_RSP_R1B:
+			resp = RESP_R1B;
+			break;
+		case MMC_RSP_R2:
+			resp = RESP_R2;
+			break;
+		case MMC_RSP_R3:
+			resp = RESP_R3;
+			break;
+		case MMC_RSP_NONE:
+		default:
+			resp = RESP_NONE;
+			break;
+		}
+	}
+
+	cmd->error = 0;
+	/* rawcmd :
+	 * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 |
+	 * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode
+	 */
+	rawcmd = opcode | msdc_rsp[resp] << 7 | host->blksz << 16;
+
+	if (opcode == MMC_READ_MULTIPLE_BLOCK) {
+		rawcmd |= (2 << 11);
+	} else if (opcode == MMC_READ_SINGLE_BLOCK) {
+		rawcmd |= (1 << 11);
+	} else if (opcode == MMC_WRITE_MULTIPLE_BLOCK) {
+		rawcmd |= ((2 << 11) | (1 << 13));
+	} else if (opcode == MMC_WRITE_BLOCK) {
+		rawcmd |= ((1 << 11) | (1 << 13));
+	} else if (opcode == SD_IO_RW_EXTENDED) {
+		if (cmd->data->flags & MMC_DATA_WRITE)
+			rawcmd |= (1 << 13);
+		if (cmd->data->blocks > 1)
+			rawcmd |= (2 << 11);
+		else
+			rawcmd |= (1 << 11);
+	} else if (opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int)-1) {
+		rawcmd |= (1 << 14);
+	} else if ((opcode == SD_APP_SEND_SCR) ||
+		(opcode == SD_APP_SEND_NUM_WR_BLKS) ||
+		(opcode == SD_SWITCH && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) ||
+		(opcode == SD_APP_SD_STATUS && (mmc_cmd_type(cmd) == MMC_CMD_ADTC)) ||
+		(opcode == MMC_SEND_EXT_CSD && (mmc_cmd_type(cmd) == MMC_CMD_ADTC))) {
+		rawcmd |= (1 << 11);
+	} else if (opcode == MMC_STOP_TRANSMISSION) {
+		rawcmd |= (1 << 14);
+		rawcmd &= ~(0x0FFF << 16);
+	}
+
+	N_MSG(CMD, "CMD<%d><0x%.8x> Arg<0x%.8x>", opcode, rawcmd, cmd->arg);
+
+	tmo = jiffies + timeout;
+
+	if (opcode == MMC_SEND_STATUS) {
+		for (;;) {
+			if (!sdc_is_cmd_busy())
+				break;
+
+			if (time_after(jiffies, tmo)) {
+				ERR_MSG("XXX cmd_busy timeout: before CMD<%d>", opcode);
+				cmd->error = -ETIMEDOUT;
+				msdc_reset_hw(host);
+				goto end;
+			}
+		}
+	} else {
+		for (;;) {
+			if (!sdc_is_busy())
+				break;
+			if (time_after(jiffies, tmo)) {
+				ERR_MSG("XXX sdc_busy timeout: before CMD<%d>", opcode);
+				cmd->error = -ETIMEDOUT;
+				msdc_reset_hw(host);
+				goto end;
+			}
+		}
+	}
+
+	//BUG_ON(in_interrupt());
+	host->cmd     = cmd;
+	host->cmd_rsp = resp;
+
+	init_completion(&host->cmd_done);
+
+	sdr_set_bits(MSDC_INTEN, wints);
+	sdc_send_cmd(rawcmd, cmd->arg);
+
+end:
+	return cmd->error;
+}
+
+static unsigned int msdc_command_resp(struct msdc_host   *host,
+				      struct mmc_command *cmd,
+				      int                 tune,
+				      unsigned long       timeout)
+	__must_hold(&host->lock)
+{
+	void __iomem *base = host->base;
+	u32 opcode = cmd->opcode;
+	//u32 rawcmd;
+	u32 resp;
+	u32 wints = MSDC_INT_CMDRDY  | MSDC_INT_RSPCRCERR  | MSDC_INT_CMDTMO  |
+		    MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO |
+		    MSDC_INT_ACMD19_DONE;
+
+	resp = host->cmd_rsp;
+
+	BUG_ON(in_interrupt());
+	//init_completion(&host->cmd_done);
+	//sdr_set_bits(MSDC_INTEN, wints);
+
+	spin_unlock(&host->lock);
+	if (!wait_for_completion_timeout(&host->cmd_done, 10 * timeout)) {
+		ERR_MSG("XXX CMD<%d> wait_for_completion timeout ARG<0x%.8x>", opcode, cmd->arg);
+		cmd->error = -ETIMEDOUT;
+		msdc_reset_hw(host);
+	}
+	spin_lock(&host->lock);
+
+	sdr_clr_bits(MSDC_INTEN, wints);
+	host->cmd = NULL;
+
+//end:
+#ifdef MT6575_SD_DEBUG
+	switch (resp) {
+	case RESP_NONE:
+		N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)", opcode, cmd->error, resp);
+		break;
+	case RESP_R2:
+		N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= %.8x %.8x %.8x %.8x",
+			opcode, cmd->error, resp, cmd->resp[0], cmd->resp[1],
+			cmd->resp[2], cmd->resp[3]);
+		break;
+	default: /* Response types 1, 3, 4, 5, 6, 7(1b) */
+		N_MSG(RSP, "CMD_RSP(%d): %d RSP(%d)= 0x%.8x",
+			opcode, cmd->error, resp, cmd->resp[0]);
+		if (cmd->error == 0) {
+			switch (resp) {
+			case RESP_R1:
+			case RESP_R1B:
+				msdc_dump_card_status(host, cmd->resp[0]);
+				break;
+			case RESP_R3:
+				msdc_dump_ocr_reg(host, cmd->resp[0]);
+				break;
+			case RESP_R5:
+				msdc_dump_io_resp(host, cmd->resp[0]);
+				break;
+			case RESP_R6:
+				msdc_dump_rca_resp(host, cmd->resp[0]);
+				break;
+			}
+		}
+		break;
+	}
+#endif
+
+	/* do we need to save card's RCA when SD_SEND_RELATIVE_ADDR */
+
+	if (!tune)
+		return cmd->error;
+
+	/* memory card CRC */
+	if (host->hw->flags & MSDC_REMOVABLE && cmd->error == -EIO) {
+		if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */
+			msdc_abort_data(host);
+		} else {
+			/* do basic: reset*/
+			msdc_reset_hw(host);
+			msdc_clr_fifo();
+			msdc_clr_int();
+		}
+		cmd->error = msdc_tune_cmdrsp(host, cmd);
+	}
+
+	//  check DAT0
+	/* if (resp == RESP_R1B) {
+	   while ((sdr_read32(MSDC_PS) & 0x10000) != 0x10000);
+	   } */
+	/* CMD12 Error Handle */
+
+	return cmd->error;
+}
+
+static unsigned int msdc_do_command(struct msdc_host   *host,
+				    struct mmc_command *cmd,
+				    int                 tune,
+				    unsigned long       timeout)
+{
+	if (msdc_command_start(host, cmd, tune, timeout))
+		goto end;
+
+	if (msdc_command_resp(host, cmd, tune, timeout))
+		goto end;
+
+end:
+
+	N_MSG(CMD, "        return<%d> resp<0x%.8x>", cmd->error, cmd->resp[0]);
+	return cmd->error;
+}
+
+#if 0 /* --- by chhung */
+// DMA resume / start / stop
+static void msdc_dma_resume(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+
+	sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_RESUME, 1);
+
+	N_MSG(DMA, "DMA resume");
+}
+#endif /* end of --- */
+
+static void msdc_dma_start(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+	u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
+
+	sdr_set_bits(MSDC_INTEN, wints);
+	//dsb(); /* --- by chhung */
+	sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
+
+	N_MSG(DMA, "DMA start");
+}
+
+static void msdc_dma_stop(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+	//u32 retries=500;
+	u32 wints = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | MSDC_INTEN_DATCRCERR;
+
+	N_MSG(DMA, "DMA status: 0x%.8x", sdr_read32(MSDC_DMA_CFG));
+	//while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS);
+
+	sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1);
+	while (sdr_read32(MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
+		;
+
+	//dsb(); /* --- by chhung */
+	sdr_clr_bits(MSDC_INTEN, wints); /* Not just xfer_comp */
+
+	N_MSG(DMA, "DMA stop");
+}
+
+/* calc checksum */
+static u8 msdc_dma_calcs(u8 *buf, u32 len)
+{
+	u32 i, sum = 0;
+
+	for (i = 0; i < len; i++)
+		sum += buf[i];
+	return 0xFF - (u8)sum;
+}
+
+/* gpd bd setup + dma registers */
+static void msdc_dma_config(struct msdc_host *host, struct msdc_dma *dma)
+{
+	void __iomem *base = host->base;
+	//u32 i, j, num, bdlen, arg, xfersz;
+	u32 j, num;
+	struct scatterlist *sg;
+	struct gpd *gpd;
+	struct bd *bd;
+
+	switch (dma->mode) {
+	case MSDC_MODE_DMA_BASIC:
+		BUG_ON(host->xfer_size > 65535);
+		BUG_ON(dma->sglen != 1);
+		sdr_write32(MSDC_DMA_SA, PHYSADDR(sg_dma_address(sg)));
+		sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_LASTBUF, 1);
+//#if defined (CONFIG_RALINK_MT7620)
+		if (ralink_soc == MT762X_SOC_MT7620A)
+			sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_XFERSZ, sg_dma_len(sg));
+//#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
+		else
+			sdr_write32((void __iomem *)(RALINK_MSDC_BASE + 0xa8), sg_dma_len(sg));
+//#endif
+		sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ,
+			      MSDC_BRUST_64B);
+		sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 0);
+		break;
+	case MSDC_MODE_DMA_DESC:
+
+		/* calculate the required number of gpd */
+		num = (dma->sglen + MAX_BD_PER_GPD - 1) / MAX_BD_PER_GPD;
+		BUG_ON(num != 1);
+
+		gpd = dma->gpd;
+		bd  = dma->bd;
+
+		/* modify gpd*/
+		//gpd->intr = 0;
+		gpd->hwo = 1;  /* hw will clear it */
+		gpd->bdp = 1;
+		gpd->chksum = 0;  /* need to clear first. */
+		gpd->chksum = msdc_dma_calcs((u8 *)gpd, 16);
+
+		/* modify bd*/
+		for_each_sg(dma->sg, sg, dma->sglen, j) {
+			bd[j].blkpad = 0;
+			bd[j].dwpad = 0;
+			bd[j].ptr = (void *)sg_dma_address(sg);
+			bd[j].buflen = sg_dma_len(sg);
+
+			if (j == dma->sglen - 1)
+				bd[j].eol = 1;	/* the last bd */
+			else
+				bd[j].eol = 0;
+
+			bd[j].chksum = 0; /* checksume need to clear first */
+			bd[j].chksum = msdc_dma_calcs((u8 *)(&bd[j]), 16);
+		}
+
+		sdr_set_field(MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1);
+		sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_BRUSTSZ,
+			      MSDC_BRUST_64B);
+		sdr_set_field(MSDC_DMA_CTRL, MSDC_DMA_CTRL_MODE, 1);
+
+		sdr_write32(MSDC_DMA_SA, PHYSADDR((u32)dma->gpd_addr));
+		break;
+
+	default:
+		break;
+	}
+
+	N_MSG(DMA, "DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL));
+	N_MSG(DMA, "DMA_CFG  = 0x%x", sdr_read32(MSDC_DMA_CFG));
+	N_MSG(DMA, "DMA_SA   = 0x%x", sdr_read32(MSDC_DMA_SA));
+
+}
+
+static void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma,
+			   struct scatterlist *sg, unsigned int sglen)
+{
+	BUG_ON(sglen > MAX_BD_NUM); /* not support currently */
+
+	dma->sg = sg;
+	dma->sglen = sglen;
+
+	dma->mode = MSDC_MODE_DMA_DESC;
+
+	N_MSG(DMA, "DMA mode<%d> sglen<%d> xfersz<%d>", dma->mode, dma->sglen,
+	      host->xfer_size);
+
+	msdc_dma_config(host, dma);
+}
+
+static int msdc_do_request(struct mmc_host *mmc, struct mmc_request *mrq)
+	__must_hold(&host->lock)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	struct mmc_command *cmd;
+	struct mmc_data *data;
+	void __iomem *base = host->base;
+	//u32 intsts = 0;
+	int read = 1, send_type = 0;
+
+#define SND_DAT 0
+#define SND_CMD 1
+
+	BUG_ON(mmc == NULL);
+	BUG_ON(mrq == NULL);
+
+	host->error = 0;
+
+	cmd  = mrq->cmd;
+	data = mrq->cmd->data;
+
+#if 0 /* --- by chhung */
+	//if(host->id ==1){
+	N_MSG(OPS, "enable clock!");
+	msdc_ungate_clock(host->id);
+	//}
+#endif /* end of --- */
+
+	if (!data) {
+		send_type = SND_CMD;
+		if (msdc_do_command(host, cmd, 1, CMD_TIMEOUT) != 0)
+			goto done;
+	} else {
+		BUG_ON(data->blksz > HOST_MAX_BLKSZ);
+		send_type = SND_DAT;
+
+		data->error = 0;
+		read = data->flags & MMC_DATA_READ ? 1 : 0;
+		host->data = data;
+		host->xfer_size = data->blocks * data->blksz;
+		host->blksz = data->blksz;
+
+		if (read) {
+			if ((host->timeout_ns != data->timeout_ns) ||
+				(host->timeout_clks != data->timeout_clks)) {
+				msdc_set_timeout(host, data->timeout_ns, data->timeout_clks);
+			}
+		}
+
+		sdr_write32(SDC_BLK_NUM, data->blocks);
+		//msdc_clr_fifo();  /* no need */
+
+		msdc_dma_on();  /* enable DMA mode first!! */
+		init_completion(&host->xfer_done);
+
+		/* start the command first*/
+		if (msdc_command_start(host, cmd, 1, CMD_TIMEOUT) != 0)
+			goto done;
+
+		data->sg_count = dma_map_sg(mmc_dev(mmc), data->sg,
+					    data->sg_len,
+					    mmc_get_dma_dir(data));
+		msdc_dma_setup(host, &host->dma, data->sg,
+			       data->sg_count);
+
+		/* then wait command done */
+		if (msdc_command_resp(host, cmd, 1, CMD_TIMEOUT) != 0)
+			goto done;
+
+		/* for read, the data coming too fast, then CRC error
+		   start DMA no business with CRC. */
+		//init_completion(&host->xfer_done);
+		msdc_dma_start(host);
+
+		spin_unlock(&host->lock);
+		if (!wait_for_completion_timeout(&host->xfer_done, DAT_TIMEOUT)) {
+			ERR_MSG("XXX CMD<%d> wait xfer_done<%d> timeout!!", cmd->opcode, data->blocks * data->blksz);
+			ERR_MSG("    DMA_SA   = 0x%x", sdr_read32(MSDC_DMA_SA));
+			ERR_MSG("    DMA_CA   = 0x%x", sdr_read32(MSDC_DMA_CA));
+			ERR_MSG("    DMA_CTRL = 0x%x", sdr_read32(MSDC_DMA_CTRL));
+			ERR_MSG("    DMA_CFG  = 0x%x", sdr_read32(MSDC_DMA_CFG));
+			data->error = -ETIMEDOUT;
+
+			msdc_reset_hw(host);
+			msdc_clr_fifo();
+			msdc_clr_int();
+		}
+		spin_lock(&host->lock);
+		msdc_dma_stop(host);
+
+		/* Last: stop transfer */
+		if (data->stop) {
+			if (msdc_do_command(host, data->stop, 0, CMD_TIMEOUT) != 0)
+				goto done;
+		}
+	}
+
+done:
+	if (data != NULL) {
+		host->data = NULL;
+		dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len,
+			     mmc_get_dma_dir(data));
+		host->blksz = 0;
+
+#if 0 // don't stop twice!
+		if (host->hw->flags & MSDC_REMOVABLE && data->error) {
+			msdc_abort_data(host);
+			/* reset in IRQ, stop command has issued. -> No need */
+		}
+#endif
+
+		N_MSG(OPS, "CMD<%d> data<%s %s> blksz<%d> block<%d> error<%d>", cmd->opcode, (dma ? "dma" : "pio"),
+			(read ? "read " : "write"), data->blksz, data->blocks, data->error);
+	}
+
+#if 0 /* --- by chhung */
+#if 1
+	//if(host->id==1) {
+	if (send_type == SND_CMD) {
+		if (cmd->opcode == MMC_SEND_STATUS) {
+			if ((cmd->resp[0] & CARD_READY_FOR_DATA) || (CARD_CURRENT_STATE(cmd->resp[0]) != 7)) {
+				N_MSG(OPS, "disable clock, CMD13 IDLE");
+				msdc_gate_clock(host->id);
+			}
+		} else {
+			N_MSG(OPS, "disable clock, CMD<%d>", cmd->opcode);
+			msdc_gate_clock(host->id);
+		}
+	} else {
+		if (read) {
+			N_MSG(OPS, "disable clock!!! Read CMD<%d>", cmd->opcode);
+			msdc_gate_clock(host->id);
+		}
+	}
+	//}
+#else
+	msdc_gate_clock(host->id);
+#endif
+#endif /* end of --- */
+
+	if (mrq->cmd->error)
+		host->error = 0x001;
+	if (mrq->data && mrq->data->error)
+		host->error |= 0x010;
+	if (mrq->stop && mrq->stop->error)
+		host->error |= 0x100;
+
+	//if (host->error) ERR_MSG("host->error<%d>", host->error);
+
+	return host->error;
+}
+
+static int msdc_app_cmd(struct mmc_host *mmc, struct msdc_host *host)
+{
+	struct mmc_command cmd;
+	struct mmc_request mrq;
+	u32 err;
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+	cmd.opcode = MMC_APP_CMD;
+#if 0   /* bug: we meet mmc->card is null when ACMD6 */
+	cmd.arg = mmc->card->rca << 16;
+#else
+	cmd.arg = host->app_cmd_arg;
+#endif
+	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
+
+	memset(&mrq, 0, sizeof(struct mmc_request));
+	mrq.cmd = &cmd; cmd.mrq = &mrq;
+	cmd.data = NULL;
+
+	err = msdc_do_command(host, &cmd, 0, CMD_TIMEOUT);
+	return err;
+}
+
+static int msdc_tune_cmdrsp(struct msdc_host *host, struct mmc_command *cmd)
+{
+	int result = -1;
+	void __iomem *base = host->base;
+	u32 rsmpl, cur_rsmpl, orig_rsmpl;
+	u32 rrdly, cur_rrdly = 0xffffffff, orig_rrdly;
+	u32 skip = 1;
+
+	/* ==== don't support 3.0 now ====
+	   1: R_SMPL[1]
+	   2: PAD_CMD_RESP_RXDLY[26:22]
+	   ==========================*/
+
+	// save the previous tune result
+	sdr_get_field(MSDC_IOCON,    MSDC_IOCON_RSPL,        &orig_rsmpl);
+	sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, &orig_rrdly);
+
+	rrdly = 0;
+	do {
+		for (rsmpl = 0; rsmpl < 2; rsmpl++) {
+			/* Lv1: R_SMPL[1] */
+			cur_rsmpl = (orig_rsmpl + rsmpl) % 2;
+			if (skip == 1) {
+				skip = 0;
+				continue;
+			}
+			sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl);
+
+			if (host->app_cmd) {
+				result = msdc_app_cmd(host->mmc, host);
+				if (result) {
+					ERR_MSG("TUNE_CMD app_cmd<%d> failed: RESP_RXDLY<%d>,R_SMPL<%d>",
+						host->mrq->cmd->opcode, cur_rrdly, cur_rsmpl);
+					continue;
+				}
+			}
+			result = msdc_do_command(host, cmd, 0, CMD_TIMEOUT); // not tune.
+			ERR_MSG("TUNE_CMD<%d> %s PAD_CMD_RESP_RXDLY[26:22]<%d> R_SMPL[1]<%d>", cmd->opcode,
+				(result == 0) ? "PASS" : "FAIL", cur_rrdly, cur_rsmpl);
+
+			if (result == 0)
+				return 0;
+			if (result != -EIO) {
+				ERR_MSG("TUNE_CMD<%d> Error<%d> not -EIO", cmd->opcode, result);
+				return result;
+			}
+
+			/* should be EIO */
+			if (sdr_read32(SDC_CMD) & 0x1800) { /* check if has data phase */
+				msdc_abort_data(host);
+			}
+		}
+
+		/* Lv2: PAD_CMD_RESP_RXDLY[26:22] */
+		cur_rrdly = (orig_rrdly + rrdly + 1) % 32;
+		sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY, cur_rrdly);
+	} while (++rrdly < 32);
+
+	return result;
+}
+
+/* Support SD2.0 Only */
+static int msdc_tune_bread(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	void __iomem *base = host->base;
+	u32 ddr = 0;
+	u32 dcrc = 0;
+	u32 rxdly, cur_rxdly0, cur_rxdly1;
+	u32 dsmpl, cur_dsmpl,  orig_dsmpl;
+	u32 cur_dat0,  cur_dat1,  cur_dat2,  cur_dat3;
+	u32 cur_dat4,  cur_dat5,  cur_dat6,  cur_dat7;
+	u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3;
+	u32 orig_dat4, orig_dat5, orig_dat6, orig_dat7;
+	int result = -1;
+	u32 skip = 1;
+
+	sdr_get_field(MSDC_IOCON, MSDC_IOCON_DSPL, &orig_dsmpl);
+
+	/* Tune Method 2. */
+	sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
+
+	rxdly = 0;
+	do {
+		for (dsmpl = 0; dsmpl < 2; dsmpl++) {
+			cur_dsmpl = (orig_dsmpl + dsmpl) % 2;
+			if (skip == 1) {
+				skip = 0;
+				continue;
+			}
+			sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl);
+
+			if (host->app_cmd) {
+				result = msdc_app_cmd(host->mmc, host);
+				if (result) {
+					ERR_MSG("TUNE_BREAD app_cmd<%d> failed", host->mrq->cmd->opcode);
+					continue;
+				}
+			}
+			result = msdc_do_request(mmc, mrq);
+
+			sdr_get_field(SDC_DCRC_STS,
+				      SDC_DCRC_STS_POS | SDC_DCRC_STS_NEG,
+				      &dcrc); /* RO */
+			if (!ddr)
+				dcrc &= ~SDC_DCRC_STS_NEG;
+			ERR_MSG("TUNE_BREAD<%s> dcrc<0x%x> DATRDDLY0/1<0x%x><0x%x> dsmpl<0x%x>",
+				(result == 0 && dcrc == 0) ? "PASS" : "FAIL", dcrc,
+				sdr_read32(MSDC_DAT_RDDLY0), sdr_read32(MSDC_DAT_RDDLY1), cur_dsmpl);
+
+			/* Fix me: result is 0, but dcrc is still exist */
+			if (result == 0 && dcrc == 0) {
+				goto done;
+			} else {
+				/* there is a case: command timeout, and data phase not processed */
+				if (mrq->data->error != 0 &&
+				    mrq->data->error != -EIO) {
+					ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>",
+						result, mrq->cmd->error, mrq->data->error);
+					goto done;
+				}
+			}
+		}
+
+		cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0);
+		cur_rxdly1 = sdr_read32(MSDC_DAT_RDDLY1);
+
+		/* E1 ECO. YD: Reverse */
+		if (sdr_read32(MSDC_ECO_VER) >= 4) {
+			orig_dat0 = (cur_rxdly0 >> 24) & 0x1F;
+			orig_dat1 = (cur_rxdly0 >> 16) & 0x1F;
+			orig_dat2 = (cur_rxdly0 >>  8) & 0x1F;
+			orig_dat3 = (cur_rxdly0 >>  0) & 0x1F;
+			orig_dat4 = (cur_rxdly1 >> 24) & 0x1F;
+			orig_dat5 = (cur_rxdly1 >> 16) & 0x1F;
+			orig_dat6 = (cur_rxdly1 >>  8) & 0x1F;
+			orig_dat7 = (cur_rxdly1 >>  0) & 0x1F;
+		} else {
+			orig_dat0 = (cur_rxdly0 >>  0) & 0x1F;
+			orig_dat1 = (cur_rxdly0 >>  8) & 0x1F;
+			orig_dat2 = (cur_rxdly0 >> 16) & 0x1F;
+			orig_dat3 = (cur_rxdly0 >> 24) & 0x1F;
+			orig_dat4 = (cur_rxdly1 >>  0) & 0x1F;
+			orig_dat5 = (cur_rxdly1 >>  8) & 0x1F;
+			orig_dat6 = (cur_rxdly1 >> 16) & 0x1F;
+			orig_dat7 = (cur_rxdly1 >> 24) & 0x1F;
+		}
+
+		if (ddr) {
+			cur_dat0 = (dcrc & (1 << 0) || dcrc & (1 << 8))  ? ((orig_dat0 + 1) % 32) : orig_dat0;
+			cur_dat1 = (dcrc & (1 << 1) || dcrc & (1 << 9))  ? ((orig_dat1 + 1) % 32) : orig_dat1;
+			cur_dat2 = (dcrc & (1 << 2) || dcrc & (1 << 10)) ? ((orig_dat2 + 1) % 32) : orig_dat2;
+			cur_dat3 = (dcrc & (1 << 3) || dcrc & (1 << 11)) ? ((orig_dat3 + 1) % 32) : orig_dat3;
+		} else {
+			cur_dat0 = (dcrc & (1 << 0)) ? ((orig_dat0 + 1) % 32) : orig_dat0;
+			cur_dat1 = (dcrc & (1 << 1)) ? ((orig_dat1 + 1) % 32) : orig_dat1;
+			cur_dat2 = (dcrc & (1 << 2)) ? ((orig_dat2 + 1) % 32) : orig_dat2;
+			cur_dat3 = (dcrc & (1 << 3)) ? ((orig_dat3 + 1) % 32) : orig_dat3;
+		}
+		cur_dat4 = (dcrc & (1 << 4)) ? ((orig_dat4 + 1) % 32) : orig_dat4;
+		cur_dat5 = (dcrc & (1 << 5)) ? ((orig_dat5 + 1) % 32) : orig_dat5;
+		cur_dat6 = (dcrc & (1 << 6)) ? ((orig_dat6 + 1) % 32) : orig_dat6;
+		cur_dat7 = (dcrc & (1 << 7)) ? ((orig_dat7 + 1) % 32) : orig_dat7;
+
+		cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0);
+		cur_rxdly1 = (cur_dat4 << 24) | (cur_dat5 << 16) | (cur_dat6 << 8) | (cur_dat7 << 0);
+
+		sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0);
+		sdr_write32(MSDC_DAT_RDDLY1, cur_rxdly1);
+
+	} while (++rxdly < 32);
+
+done:
+	return result;
+}
+
+static int msdc_tune_bwrite(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	void __iomem *base = host->base;
+
+	u32 wrrdly, cur_wrrdly = 0xffffffff, orig_wrrdly;
+	u32 dsmpl,  cur_dsmpl,  orig_dsmpl;
+	u32 rxdly,  cur_rxdly0;
+	u32 orig_dat0, orig_dat1, orig_dat2, orig_dat3;
+	u32 cur_dat0,  cur_dat1,  cur_dat2,  cur_dat3;
+	int result = -1;
+	u32 skip = 1;
+
+	// MSDC_IOCON_DDR50CKD need to check. [Fix me]
+
+	sdr_get_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, &orig_wrrdly);
+	sdr_get_field(MSDC_IOCON,    MSDC_IOCON_DSPL,        &orig_dsmpl);
+
+	/* Tune Method 2. just DAT0 */
+	sdr_set_field(MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
+	cur_rxdly0 = sdr_read32(MSDC_DAT_RDDLY0);
+
+	/* E1 ECO. YD: Reverse */
+	if (sdr_read32(MSDC_ECO_VER) >= 4) {
+		orig_dat0 = (cur_rxdly0 >> 24) & 0x1F;
+		orig_dat1 = (cur_rxdly0 >> 16) & 0x1F;
+		orig_dat2 = (cur_rxdly0 >>  8) & 0x1F;
+		orig_dat3 = (cur_rxdly0 >>  0) & 0x1F;
+	} else {
+		orig_dat0 = (cur_rxdly0 >>  0) & 0x1F;
+		orig_dat1 = (cur_rxdly0 >>  8) & 0x1F;
+		orig_dat2 = (cur_rxdly0 >> 16) & 0x1F;
+		orig_dat3 = (cur_rxdly0 >> 24) & 0x1F;
+	}
+
+	rxdly = 0;
+	do {
+		wrrdly = 0;
+		do {
+			for (dsmpl = 0; dsmpl < 2; dsmpl++) {
+				cur_dsmpl = (orig_dsmpl + dsmpl) % 2;
+				if (skip == 1) {
+					skip = 0;
+					continue;
+				}
+				sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL, cur_dsmpl);
+
+				if (host->app_cmd) {
+					result = msdc_app_cmd(host->mmc, host);
+					if (result) {
+						ERR_MSG("TUNE_BWRITE app_cmd<%d> failed", host->mrq->cmd->opcode);
+						continue;
+					}
+				}
+				result = msdc_do_request(mmc, mrq);
+
+				ERR_MSG("TUNE_BWRITE<%s> DSPL<%d> DATWRDLY<%d> MSDC_DAT_RDDLY0<0x%x>",
+					result == 0 ? "PASS" : "FAIL",
+					cur_dsmpl, cur_wrrdly, cur_rxdly0);
+
+				if (result == 0) {
+					goto done;
+				} else {
+					/* there is a case: command timeout, and data phase not processed */
+					if (mrq->data->error != -EIO) {
+						ERR_MSG("TUNE_READ: result<0x%x> cmd_error<%d> data_error<%d>",
+							result, mrq->cmd->error, mrq->data->error);
+						goto done;
+					}
+				}
+			}
+			cur_wrrdly = (orig_wrrdly + wrrdly + 1) % 32;
+			sdr_set_field(MSDC_PAD_TUNE, MSDC_PAD_TUNE_DATWRDLY, cur_wrrdly);
+		} while (++wrrdly < 32);
+
+		cur_dat0 = (orig_dat0 + rxdly) % 32; /* only adjust bit-1 for crc */
+		cur_dat1 = orig_dat1;
+		cur_dat2 = orig_dat2;
+		cur_dat3 = orig_dat3;
+
+		cur_rxdly0 = (cur_dat0 << 24) | (cur_dat1 << 16) | (cur_dat2 << 8) | (cur_dat3 << 0);
+		sdr_write32(MSDC_DAT_RDDLY0, cur_rxdly0);
+	} while (++rxdly < 32);
+
+done:
+	return result;
+}
+
+static int msdc_get_card_status(struct mmc_host *mmc, struct msdc_host *host, u32 *status)
+{
+	struct mmc_command cmd;
+	struct mmc_request mrq;
+	u32 err;
+
+	memset(&cmd, 0, sizeof(struct mmc_command));
+	cmd.opcode = MMC_SEND_STATUS;
+	if (mmc->card) {
+		cmd.arg = mmc->card->rca << 16;
+	} else {
+		ERR_MSG("cmd13 mmc card is null");
+		cmd.arg = host->app_cmd_arg;
+	}
+	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
+
+	memset(&mrq, 0, sizeof(struct mmc_request));
+	mrq.cmd = &cmd; cmd.mrq = &mrq;
+	cmd.data = NULL;
+
+	err = msdc_do_command(host, &cmd, 1, CMD_TIMEOUT);
+
+	if (status)
+		*status = cmd.resp[0];
+
+	return err;
+}
+
+static int msdc_check_busy(struct mmc_host *mmc, struct msdc_host *host)
+{
+	u32 err = 0;
+	u32 status = 0;
+
+	do {
+		err = msdc_get_card_status(mmc, host, &status);
+		if (err)
+			return err;
+		/* need cmd12? */
+		ERR_MSG("cmd<13> resp<0x%x>", status);
+	} while (R1_CURRENT_STATE(status) == 7);
+
+	return err;
+}
+
+/* failed when msdc_do_request */
+static int msdc_tune_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	struct mmc_command *cmd;
+	struct mmc_data *data;
+	//u32 base = host->base;
+	int ret = 0, read;
+
+	cmd  = mrq->cmd;
+	data = mrq->cmd->data;
+
+	read = data->flags & MMC_DATA_READ ? 1 : 0;
+
+	if (read) {
+		if (data->error == -EIO)
+			ret = msdc_tune_bread(mmc, mrq);
+	} else {
+		ret = msdc_check_busy(mmc, host);
+		if (ret) {
+			ERR_MSG("XXX cmd13 wait program done failed");
+			return ret;
+		}
+		/* CRC and TO */
+		/* Fix me: don't care card status? */
+		ret = msdc_tune_bwrite(mmc, mrq);
+	}
+
+	return ret;
+}
+
+/* ops.request */
+static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+
+	//=== for sdio profile ===
+#if 0 /* --- by chhung */
+	u32 old_H32, old_L32, new_H32, new_L32;
+	u32 ticks = 0, opcode = 0, sizes = 0, bRx = 0;
+#endif /* end of --- */
+
+	WARN_ON(host->mrq);
+
+	/* start to process */
+	spin_lock(&host->lock);
+#if 0 /* --- by chhung */
+	if (sdio_pro_enable) {  //=== for sdio profile ===
+		if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53)
+			GPT_GetCounter64(&old_L32, &old_H32);
+	}
+#endif /* end of --- */
+
+	host->mrq = mrq;
+
+	if (msdc_do_request(mmc, mrq)) {
+		if (host->hw->flags & MSDC_REMOVABLE && ralink_soc == MT762X_SOC_MT7621AT && mrq->data && mrq->data->error)
+			msdc_tune_request(mmc, mrq);
+	}
+
+	/* ==== when request done, check if app_cmd ==== */
+	if (mrq->cmd->opcode == MMC_APP_CMD) {
+		host->app_cmd = 1;
+		host->app_cmd_arg = mrq->cmd->arg;  /* save the RCA */
+	} else {
+		host->app_cmd = 0;
+		//host->app_cmd_arg = 0;
+	}
+
+	host->mrq = NULL;
+
+#if 0 /* --- by chhung */
+	//=== for sdio profile ===
+	if (sdio_pro_enable) {
+		if (mrq->cmd->opcode == 52 || mrq->cmd->opcode == 53) {
+			GPT_GetCounter64(&new_L32, &new_H32);
+			ticks = msdc_time_calc(old_L32, old_H32, new_L32, new_H32);
+
+			opcode = mrq->cmd->opcode;
+			if (mrq->cmd->data) {
+				sizes = mrq->cmd->data->blocks * mrq->cmd->data->blksz;
+				bRx = mrq->cmd->data->flags & MMC_DATA_READ ? 1 : 0;
+			} else {
+				bRx = mrq->cmd->arg	& 0x80000000 ? 1 : 0;
+			}
+
+			if (!mrq->cmd->error)
+				msdc_performance(opcode, sizes, bRx, ticks);
+		}
+	}
+#endif /* end of --- */
+	spin_unlock(&host->lock);
+
+	mmc_request_done(mmc, mrq);
+
+	return;
+}
+
+/* called by ops.set_ios */
+static void msdc_set_buswidth(struct msdc_host *host, u32 width)
+{
+	void __iomem *base = host->base;
+	u32 val = sdr_read32(SDC_CFG);
+
+	val &= ~SDC_CFG_BUSWIDTH;
+
+	switch (width) {
+	default:
+	case MMC_BUS_WIDTH_1:
+		width = 1;
+		val |= (MSDC_BUS_1BITS << 16);
+		break;
+	case MMC_BUS_WIDTH_4:
+		val |= (MSDC_BUS_4BITS << 16);
+		break;
+	case MMC_BUS_WIDTH_8:
+		val |= (MSDC_BUS_8BITS << 16);
+		break;
+	}
+
+	sdr_write32(SDC_CFG, val);
+
+	N_MSG(CFG, "Bus Width = %d", width);
+}
+
+/* ops.set_ios */
+static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	void __iomem *base = host->base;
+	u32 ddr = 0;
+
+#ifdef MT6575_SD_DEBUG
+	static char *vdd[] = {
+		"1.50v", "1.55v", "1.60v", "1.65v", "1.70v", "1.80v", "1.90v",
+		"2.00v", "2.10v", "2.20v", "2.30v", "2.40v", "2.50v", "2.60v",
+		"2.70v", "2.80v", "2.90v", "3.00v", "3.10v", "3.20v", "3.30v",
+		"3.40v", "3.50v", "3.60v"
+	};
+	static char *power_mode[] = {
+		"OFF", "UP", "ON"
+	};
+	static char *bus_mode[] = {
+		"UNKNOWN", "OPENDRAIN", "PUSHPULL"
+	};
+	static char *timing[] = {
+		"LEGACY", "MMC_HS", "SD_HS"
+	};
+
+	printk("SET_IOS: CLK(%dkHz), BUS(%s), BW(%u), PWR(%s), VDD(%s), TIMING(%s)",
+		ios->clock / 1000, bus_mode[ios->bus_mode],
+		(ios->bus_width == MMC_BUS_WIDTH_4) ? 4 : 1,
+		power_mode[ios->power_mode], vdd[ios->vdd], timing[ios->timing]);
+#endif
+
+	msdc_set_buswidth(host, ios->bus_width);
+
+	/* Power control ??? */
+	switch (ios->power_mode) {
+	case MMC_POWER_OFF:
+	case MMC_POWER_UP:
+		// msdc_set_power_mode(host, ios->power_mode); /* --- by chhung */
+		break;
+	case MMC_POWER_ON:
+		host->power_mode = MMC_POWER_ON;
+		break;
+	default:
+		break;
+	}
+
+	/* Clock control */
+	if (host->mclk != ios->clock) {
+		if (ios->clock > 25000000) {
+			//if (!(host->hw->flags & MSDC_REMOVABLE)) {
+			INIT_MSG("SD data latch edge<%d>", MSDC_SMPL_FALLING);
+			sdr_set_field(MSDC_IOCON, MSDC_IOCON_RSPL,
+				      MSDC_SMPL_FALLING);
+			sdr_set_field(MSDC_IOCON, MSDC_IOCON_DSPL,
+				      MSDC_SMPL_FALLING);
+			//} /* for tuning debug */
+		} else { /* default value */
+			sdr_write32(MSDC_IOCON,      0x00000000);
+			// sdr_write32(MSDC_DAT_RDDLY0, 0x00000000);
+			sdr_write32(MSDC_DAT_RDDLY0, 0x10101010);		// for MT7620 E2 and afterward
+			sdr_write32(MSDC_DAT_RDDLY1, 0x00000000);
+			// sdr_write32(MSDC_PAD_TUNE,   0x00000000);
+			sdr_write32(MSDC_PAD_TUNE,   0x84101010);		// for MT7620 E2 and afterward
+		}
+		msdc_set_mclk(host, ddr, ios->clock);
+	}
+}
+
+/* ops.get_ro */
+static int msdc_ops_get_ro(struct mmc_host *mmc)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	void __iomem *base = host->base;
+	unsigned long flags;
+	int ro = 0;
+
+	if (host->hw->flags & MSDC_WP_PIN_EN) { /* set for card */
+		spin_lock_irqsave(&host->lock, flags);
+		ro = (sdr_read32(MSDC_PS) >> 31);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+	return ro;
+}
+
+/* ops.get_cd */
+static int msdc_ops_get_cd(struct mmc_host *mmc)
+{
+	struct msdc_host *host = mmc_priv(mmc);
+	void __iomem *base = host->base;
+	unsigned long flags;
+	int present = 1;
+
+	/* for sdio, MSDC_REMOVABLE not set, always return 1 */
+	if (!(host->hw->flags & MSDC_REMOVABLE)) {
+		/* For sdio, read H/W always get<1>, but may timeout some times */
+#if 1
+		host->card_inserted = 1;
+		return 1;
+#else
+		host->card_inserted = (host->pm_state.event == PM_EVENT_USER_RESUME) ? 1 : 0;
+		INIT_MSG("sdio ops_get_cd<%d>", host->card_inserted);
+		return host->card_inserted;
+#endif
+	}
+
+	/* MSDC_CD_PIN_EN set for card */
+	if (host->hw->flags & MSDC_CD_PIN_EN) {
+		spin_lock_irqsave(&host->lock, flags);
+#if 0
+		present = host->card_inserted;  /* why not read from H/W: Fix me*/
+#else
+		// CD
+		if (cd_active_low)
+			present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 0 : 1;
+		else
+			present = (sdr_read32(MSDC_PS) & MSDC_PS_CDSTS) ? 1 : 0;
+		if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
+			present = 1;
+		host->card_inserted = present;
+#endif
+		spin_unlock_irqrestore(&host->lock, flags);
+	} else {
+		present = 0; /* TODO? Check DAT3 pins for card detection */
+	}
+
+	INIT_MSG("ops_get_cd return<%d>", present);
+	return present;
+}
+
+static struct mmc_host_ops mt_msdc_ops = {
+	.request         = msdc_ops_request,
+	.set_ios         = msdc_ops_set_ios,
+	.get_ro          = msdc_ops_get_ro,
+	.get_cd          = msdc_ops_get_cd,
+};
+
+/*--------------------------------------------------------------------------*/
+/* interrupt handler                                                    */
+/*--------------------------------------------------------------------------*/
+static irqreturn_t msdc_irq(int irq, void *dev_id)
+{
+	struct msdc_host  *host = (struct msdc_host *)dev_id;
+	struct mmc_data   *data = host->data;
+	struct mmc_command *cmd = host->cmd;
+	void __iomem *base = host->base;
+
+	u32 cmdsts = MSDC_INT_RSPCRCERR  | MSDC_INT_CMDTMO  | MSDC_INT_CMDRDY  |
+		MSDC_INT_ACMDCRCERR | MSDC_INT_ACMDTMO | MSDC_INT_ACMDRDY |
+		MSDC_INT_ACMD19_DONE;
+	u32 datsts = MSDC_INT_DATCRCERR | MSDC_INT_DATTMO;
+
+	u32 intsts = sdr_read32(MSDC_INT);
+	u32 inten  = sdr_read32(MSDC_INTEN); inten &= intsts;
+
+	sdr_write32(MSDC_INT, intsts);  /* clear interrupts */
+	/* MSG will cause fatal error */
+
+	/* card change interrupt */
+	if (intsts & MSDC_INT_CDSC) {
+		if (host->mmc->caps & MMC_CAP_NEEDS_POLL)
+			return IRQ_HANDLED;
+		IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts);
+		schedule_delayed_work(&host->card_delaywork, HZ);
+		/* tuning when plug card ? */
+	}
+
+	/* sdio interrupt */
+	if (intsts & MSDC_INT_SDIOIRQ) {
+		IRQ_MSG("XXX MSDC_INT_SDIOIRQ");  /* seems not sdio irq */
+		//mmc_signal_sdio_irq(host->mmc);
+	}
+
+	/* transfer complete interrupt */
+	if (data != NULL) {
+		if (inten & MSDC_INT_XFER_COMPL) {
+			data->bytes_xfered = host->xfer_size;
+			complete(&host->xfer_done);
+		}
+
+		if (intsts & datsts) {
+			/* do basic reset, or stop command will sdc_busy */
+			msdc_reset_hw(host);
+			msdc_clr_fifo();
+			msdc_clr_int();
+
+			if (intsts & MSDC_INT_DATTMO) {
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode);
+				data->error = -ETIMEDOUT;
+			} else if (intsts & MSDC_INT_DATCRCERR) {
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, sdr_read32(SDC_DCRC_STS));
+				data->error = -EIO;
+			}
+
+			//if(sdr_read32(MSDC_INTEN) & MSDC_INT_XFER_COMPL) {
+			complete(&host->xfer_done); /* Read CRC come fast, XFER_COMPL not enabled */
+		}
+	}
+
+	/* command interrupts */
+	if ((cmd != NULL) && (intsts & cmdsts)) {
+		if ((intsts & MSDC_INT_CMDRDY) || (intsts & MSDC_INT_ACMDRDY) ||
+			(intsts & MSDC_INT_ACMD19_DONE)) {
+			u32 *rsp = &cmd->resp[0];
+
+			switch (host->cmd_rsp) {
+			case RESP_NONE:
+				break;
+			case RESP_R2:
+				*rsp++ = sdr_read32(SDC_RESP3); *rsp++ = sdr_read32(SDC_RESP2);
+				*rsp++ = sdr_read32(SDC_RESP1); *rsp++ = sdr_read32(SDC_RESP0);
+				break;
+			default: /* Response types 1, 3, 4, 5, 6, 7(1b) */
+				if ((intsts & MSDC_INT_ACMDRDY) || (intsts & MSDC_INT_ACMD19_DONE))
+					*rsp = sdr_read32(SDC_ACMD_RESP);
+				else
+					*rsp = sdr_read32(SDC_RESP0);
+				break;
+			}
+		} else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) {
+			if (intsts & MSDC_INT_ACMDCRCERR)
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode);
+			else
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode);
+			cmd->error = -EIO;
+		} else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) {
+			if (intsts & MSDC_INT_ACMDTMO)
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode);
+			else
+				IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode);
+			cmd->error = -ETIMEDOUT;
+			msdc_reset_hw(host);
+			msdc_clr_fifo();
+			msdc_clr_int();
+		}
+		complete(&host->cmd_done);
+	}
+
+	/* mmc irq interrupts */
+	if (intsts & MSDC_INT_MMCIRQ)
+		printk(KERN_INFO "msdc[%d] MMCIRQ: SDC_CSTS=0x%.8x\r\n", host->id, sdr_read32(SDC_CSTS));
+
+#ifdef MT6575_SD_DEBUG
+	{
+/*        msdc_int_reg *int_reg = (msdc_int_reg*)&intsts;*/
+		N_MSG(INT, "IRQ_EVT(0x%x): MMCIRQ(%d) CDSC(%d), ACRDY(%d), ACTMO(%d), ACCRE(%d) AC19DN(%d)",
+			intsts,
+			int_reg->mmcirq,
+			int_reg->cdsc,
+			int_reg->atocmdrdy,
+			int_reg->atocmdtmo,
+			int_reg->atocmdcrc,
+			int_reg->atocmd19done);
+		N_MSG(INT, "IRQ_EVT(0x%x): SDIO(%d) CMDRDY(%d), CMDTMO(%d), RSPCRC(%d), CSTA(%d)",
+			intsts,
+			int_reg->sdioirq,
+			int_reg->cmdrdy,
+			int_reg->cmdtmo,
+			int_reg->rspcrc,
+			int_reg->csta);
+		N_MSG(INT, "IRQ_EVT(0x%x): XFCMP(%d) DXDONE(%d), DATTMO(%d), DATCRC(%d), DMAEMP(%d)",
+			intsts,
+			int_reg->xfercomp,
+			int_reg->dxferdone,
+			int_reg->dattmo,
+			int_reg->datcrc,
+			int_reg->dmaqempty);
+	}
+#endif
+
+	return IRQ_HANDLED;
+}
+
+/*--------------------------------------------------------------------------*/
+/* platform_driver members                                                      */
+/*--------------------------------------------------------------------------*/
+/* called by msdc_drv_probe/remove */
+static void msdc_enable_cd_irq(struct msdc_host *host, int enable)
+{
+	struct msdc_hw *hw = host->hw;
+	void __iomem *base = host->base;
+
+	/* for sdio, not set */
+	if ((hw->flags & MSDC_CD_PIN_EN) == 0) {
+		/* Pull down card detection pin since it is not avaiable */
+		/*
+		  if (hw->config_gpio_pin)
+		  hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN);
+		*/
+		sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
+		sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
+		sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP);
+		return;
+	}
+
+	N_MSG(CFG, "CD IRQ Eanable(%d)", enable);
+
+	if (enable) {
+		/* card detection circuit relies on the core power so that the core power
+		 * shouldn't be turned off. Here adds a reference count to keep
+		 * the core power alive.
+		 */
+		//msdc_vcore_on(host); //did in msdc_init_hw()
+
+		if (hw->config_gpio_pin) /* NULL */
+			hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_UP);
+
+		sdr_set_field(MSDC_PS, MSDC_PS_CDDEBOUNCE, DEFAULT_DEBOUNCE);
+		sdr_set_bits(MSDC_PS, MSDC_PS_CDEN);
+		sdr_set_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
+		sdr_set_bits(SDC_CFG, SDC_CFG_INSWKUP);  /* not in document! Fix me */
+	} else {
+		if (hw->config_gpio_pin) /* NULL */
+			hw->config_gpio_pin(MSDC_CD_PIN, GPIO_PULL_DOWN);
+
+		sdr_clr_bits(SDC_CFG, SDC_CFG_INSWKUP);
+		sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
+		sdr_clr_bits(MSDC_INTEN, MSDC_INTEN_CDSC);
+
+		/* Here decreases a reference count to core power since card
+		 * detection circuit is shutdown.
+		 */
+		//msdc_vcore_off(host);
+	}
+}
+
+/* called by msdc_drv_probe */
+static void msdc_init_hw(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+
+	/* Power on */
+#if 0 /* --- by chhung */
+	msdc_vcore_on(host);
+	msdc_pin_reset(host, MSDC_PIN_PULL_UP);
+	msdc_select_clksrc(host, hw->clk_src);
+	enable_clock(PERI_MSDC0_PDN + host->id, "SD");
+	msdc_vdd_on(host);
+#endif /* end of --- */
+	/* Configure to MMC/SD mode */
+	sdr_set_field(MSDC_CFG, MSDC_CFG_MODE, MSDC_SDMMC);
+
+	/* Reset */
+	msdc_reset_hw(host);
+	msdc_clr_fifo();
+
+	/* Disable card detection */
+	sdr_clr_bits(MSDC_PS, MSDC_PS_CDEN);
+
+	/* Disable and clear all interrupts */
+	sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN));
+	sdr_write32(MSDC_INT, sdr_read32(MSDC_INT));
+
+#if 1
+	/* reset tuning parameter */
+	sdr_write32(MSDC_PAD_CTL0,   0x00090000);
+	sdr_write32(MSDC_PAD_CTL1,   0x000A0000);
+	sdr_write32(MSDC_PAD_CTL2,   0x000A0000);
+	// sdr_write32(MSDC_PAD_TUNE,   0x00000000);
+	sdr_write32(MSDC_PAD_TUNE,   0x84101010);		// for MT7620 E2 and afterward
+	// sdr_write32(MSDC_DAT_RDDLY0, 0x00000000);
+	sdr_write32(MSDC_DAT_RDDLY0, 0x10101010);		// for MT7620 E2 and afterward
+	sdr_write32(MSDC_DAT_RDDLY1, 0x00000000);
+	sdr_write32(MSDC_IOCON,      0x00000000);
+#if 0 // use MT7620 default value: 0x403c004f
+	sdr_write32(MSDC_PATCH_BIT0, 0x003C000F); /* bit0 modified: Rx Data Clock Source: 1 -> 2.0*/
+#endif
+
+	if (sdr_read32(MSDC_ECO_VER) >= 4) {
+		if (host->id == 1) {
+			sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_WRDAT_CRCS, 1);
+			sdr_set_field(MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMD_RSP,    1);
+
+			/* internal clock: latch read data */
+			sdr_set_bits(MSDC_PATCH_BIT0, MSDC_PATCH_BIT_CKGEN_CK);
+		}
+	}
+#endif
+
+	/* for safety, should clear SDC_CFG.SDIO_INT_DET_EN & set SDC_CFG.SDIO in
+	   pre-loader,uboot,kernel drivers. and SDC_CFG.SDIO_INT_DET_EN will be only
+	   set when kernel driver wants to use SDIO bus interrupt */
+	/* Configure to enable SDIO mode. it's must otherwise sdio cmd5 failed */
+	sdr_set_bits(SDC_CFG, SDC_CFG_SDIO);
+
+	/* disable detect SDIO device interupt function */
+	sdr_clr_bits(SDC_CFG, SDC_CFG_SDIOIDE);
+
+	/* eneable SMT for glitch filter */
+	sdr_set_bits(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKSMT);
+	sdr_set_bits(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDSMT);
+	sdr_set_bits(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATSMT);
+
+#if 1
+	/* set clk, cmd, dat pad driving */
+	sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 4);
+	sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 4);
+	sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 4);
+	sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 4);
+	sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 4);
+	sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 4);
+#else
+	sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVN, 0);
+	sdr_set_field(MSDC_PAD_CTL0, MSDC_PAD_CTL0_CLKDRVP, 0);
+	sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVN, 0);
+	sdr_set_field(MSDC_PAD_CTL1, MSDC_PAD_CTL1_CMDDRVP, 0);
+	sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVN, 0);
+	sdr_set_field(MSDC_PAD_CTL2, MSDC_PAD_CTL2_DATDRVP, 0);
+#endif
+
+	/* set sampling edge */
+
+	/* write crc timeout detection */
+	sdr_set_field(MSDC_PATCH_BIT0, 1 << 30, 1);
+
+	/* Configure to default data timeout */
+	sdr_set_field(SDC_CFG, SDC_CFG_DTOC, DEFAULT_DTOC);
+
+	msdc_set_buswidth(host, MMC_BUS_WIDTH_1);
+
+	N_MSG(FUC, "init hardware done!");
+}
+
+/* called by msdc_drv_remove */
+static void msdc_deinit_hw(struct msdc_host *host)
+{
+	void __iomem *base = host->base;
+
+	/* Disable and clear all interrupts */
+	sdr_clr_bits(MSDC_INTEN, sdr_read32(MSDC_INTEN));
+	sdr_write32(MSDC_INT, sdr_read32(MSDC_INT));
+
+	/* Disable card detection */
+	msdc_enable_cd_irq(host, 0);
+	// msdc_set_power_mode(host, MMC_POWER_OFF);   /* make sure power down */ /* --- by chhung */
+}
+
+/* init gpd and bd list in msdc_drv_probe */
+static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
+{
+	struct gpd *gpd = dma->gpd;
+	struct bd  *bd  = dma->bd;
+	int i;
+
+	/* we just support one gpd, but gpd->next must be set for desc
+	 * DMA. That's why we alloc 2 gpd structurs.
+	 */
+
+	memset(gpd, 0, sizeof(struct gpd) * 2);
+
+	gpd->bdp  = 1;   /* hwo, cs, bd pointer */
+	gpd->ptr = (void *)dma->bd_addr; /* physical address */
+	gpd->next = (void *)((u32)dma->gpd_addr + sizeof(struct gpd));
+
+	memset(bd, 0, sizeof(struct bd) * MAX_BD_NUM);
+	for (i = 0; i < (MAX_BD_NUM - 1); i++)
+		bd[i].next = (void *)(dma->bd_addr + sizeof(*bd) * (i + 1));
+}
+
+static int msdc_drv_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	__iomem void *base;
+	struct mmc_host *mmc;
+	struct msdc_host *host;
+	struct msdc_hw *hw;
+	int ret;
+
+	//FIXME: this should be done by pinconf and not by the sd driver
+	if ((ralink_soc == MT762X_SOC_MT7688 ||
+	     ralink_soc == MT762X_SOC_MT7628AN) &&
+	    (!(rt_sysc_r32(0x60) & BIT(15))))
+		rt_sysc_m32(0xf << 17, 0xf << 17, 0x3c);
+
+	hw = &msdc0_hw;
+
+	if (of_property_read_bool(pdev->dev.of_node, "mtk,wp-en"))
+		msdc0_hw.flags |= MSDC_WP_PIN_EN;
+
+	/* Allocate MMC host for this device */
+	mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
+	if (!mmc)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		ret = PTR_ERR(base);
+		goto host_free;
+	}
+
+	/* Set host parameters to mmc */
+	mmc->ops        = &mt_msdc_ops;
+	mmc->f_min      = HOST_MIN_MCLK;
+	mmc->f_max      = HOST_MAX_MCLK;
+	mmc->ocr_avail  = MSDC_OCR_AVAIL;
+
+	mmc->caps   = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
+
+	//TODO: read this as bus-width from dt (via mmc_of_parse)
+	mmc->caps  |= MMC_CAP_4_BIT_DATA;
+
+	cd_active_low = !of_property_read_bool(pdev->dev.of_node, "mediatek,cd-high");
+
+	if (of_property_read_bool(pdev->dev.of_node, "mediatek,cd-poll"))
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	/* MMC core transfer sizes tunable parameters */
+	mmc->max_segs      = MAX_HW_SGMTS;
+
+	mmc->max_seg_size  = MAX_SGMT_SZ;
+	mmc->max_blk_size  = HOST_MAX_BLKSZ;
+	mmc->max_req_size  = MAX_REQ_SZ;
+	mmc->max_blk_count = mmc->max_req_size;
+
+	host = mmc_priv(mmc);
+	host->hw        = hw;
+	host->mmc       = mmc;
+	host->id        = pdev->id;
+	if (host->id < 0 || host->id >= 4)
+		host->id = 0;
+	host->error     = 0;
+
+	host->irq       = platform_get_irq(pdev, 0);
+	if (host->irq < 0) {
+		ret = -EINVAL;
+		goto host_free;
+	}
+
+	host->base      = base;
+	host->mclk      = 0;                   /* mclk: the request clock of mmc sub-system */
+	host->hclk      = hclks[hw->clk_src];  /* hclk: clock of clock source to msdc controller */
+	host->sclk      = 0;                   /* sclk: the really clock after divition */
+	host->pm_state  = PMSG_RESUME;
+	host->suspend   = 0;
+	host->core_clkon = 0;
+	host->card_clkon = 0;
+	host->core_power = 0;
+	host->power_mode = MMC_POWER_OFF;
+//    host->card_inserted = hw->flags & MSDC_REMOVABLE ? 0 : 1;
+	host->timeout_ns = 0;
+	host->timeout_clks = DEFAULT_DTOC * 65536;
+
+	host->mrq = NULL;
+	//init_MUTEX(&host->sem); /* we don't need to support multiple threads access */
+
+	dma_coerce_mask_and_coherent(mmc_dev(mmc), DMA_BIT_MASK(32));
+
+	/* using dma_alloc_coherent*/  /* todo: using 1, for all 4 slots */
+	host->dma.gpd = dma_alloc_coherent(&pdev->dev,
+					   MAX_GPD_NUM * sizeof(struct gpd),
+					   &host->dma.gpd_addr, GFP_KERNEL);
+	host->dma.bd =  dma_alloc_coherent(&pdev->dev,
+					   MAX_BD_NUM  * sizeof(struct bd),
+					   &host->dma.bd_addr,  GFP_KERNEL);
+	if (!host->dma.gpd || !host->dma.bd) {
+		ret = -ENOMEM;
+		goto release_mem;
+	}
+	msdc_init_gpd_bd(host, &host->dma);
+
+	INIT_DELAYED_WORK(&host->card_delaywork, msdc_tasklet_card);
+	spin_lock_init(&host->lock);
+	msdc_init_hw(host);
+
+	/* TODO check weather flags 0 is correct, the mtk-sd driver uses
+	 * IRQF_TRIGGER_LOW | IRQF_ONESHOT for flags
+	 *
+	 * for flags 0 the trigger polarity is determined by the
+	 * device tree, but not the oneshot flag, but maybe it is also
+	 * not needed because the soc could be oneshot safe.
+	 */
+	ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, 0, pdev->name,
+			       host);
+	if (ret)
+		goto release;
+
+	platform_set_drvdata(pdev, mmc);
+
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto release;
+
+	/* Config card detection pin and enable interrupts */
+	if (hw->flags & MSDC_CD_PIN_EN) {  /* set for card */
+		msdc_enable_cd_irq(host, 1);
+	} else {
+		msdc_enable_cd_irq(host, 0);
+	}
+
+	return 0;
+
+release:
+	platform_set_drvdata(pdev, NULL);
+	msdc_deinit_hw(host);
+	cancel_delayed_work_sync(&host->card_delaywork);
+
+release_mem:
+	if (host->dma.gpd)
+		dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd),
+				  host->dma.gpd, host->dma.gpd_addr);
+	if (host->dma.bd)
+		dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct bd),
+				  host->dma.bd, host->dma.bd_addr);
+host_free:
+	mmc_free_host(mmc);
+
+	return ret;
+}
+
+/* 4 device share one driver, using "drvdata" to show difference */
+static int msdc_drv_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct msdc_host *host;
+
+	mmc  = platform_get_drvdata(pdev);
+	BUG_ON(!mmc);
+
+	host = mmc_priv(mmc);
+	BUG_ON(!host);
+
+	ERR_MSG("removed !!!");
+
+	platform_set_drvdata(pdev, NULL);
+	mmc_remove_host(host->mmc);
+	msdc_deinit_hw(host);
+
+	cancel_delayed_work_sync(&host->card_delaywork);
+
+	dma_free_coherent(&pdev->dev, MAX_GPD_NUM * sizeof(struct gpd),
+			  host->dma.gpd, host->dma.gpd_addr);
+	dma_free_coherent(&pdev->dev, MAX_BD_NUM  * sizeof(struct bd),
+			  host->dma.bd,  host->dma.bd_addr);
+
+	mmc_free_host(host->mmc);
+
+	return 0;
+}
+
+/* Fix me: Power Flow */
+#ifdef CONFIG_PM
+
+static void msdc_drv_pm(struct platform_device *pdev, pm_message_t state)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	if (mmc) {
+		struct msdc_host *host = mmc_priv(mmc);
+		msdc_pm(state, (void *)host);
+	}
+}
+
+static int msdc_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	if (state.event == PM_EVENT_SUSPEND)
+		msdc_drv_pm(pdev, state);
+	return 0;
+}
+
+static int msdc_drv_resume(struct platform_device *pdev)
+{
+	struct pm_message state;
+
+	state.event = PM_EVENT_RESUME;
+	msdc_drv_pm(pdev, state);
+	return 0;
+}
+#endif
+
+static const struct of_device_id mt7620_sdhci_match[] = {
+	{ .compatible = "ralink,mt7620-sdhci" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mt7620_sdhci_match);
+
+static struct platform_driver mt_msdc_driver = {
+	.probe   = msdc_drv_probe,
+	.remove  = msdc_drv_remove,
+#ifdef CONFIG_PM
+	.suspend = msdc_drv_suspend,
+	.resume  = msdc_drv_resume,
+#endif
+	.driver  = {
+		.name  = DRV_NAME,
+		.of_match_table = mt7620_sdhci_match,
+	},
+};
+
+/*--------------------------------------------------------------------------*/
+/* module init/exit                                                      */
+/*--------------------------------------------------------------------------*/
+static int __init mt_msdc_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&mt_msdc_driver);
+	if (ret) {
+		printk(KERN_ERR DRV_NAME ": Can't register driver");
+		return ret;
+	}
+
+#if defined(MT6575_SD_DEBUG)
+	msdc_debug_proc_init();
+#endif
+	return 0;
+}
+
+static void __exit mt_msdc_exit(void)
+{
+	platform_driver_unregister(&mt_msdc_driver);
+}
+
+module_init(mt_msdc_init);
+module_exit(mt_msdc_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek MT6575 SD/MMC Card Driver");
+MODULE_AUTHOR("Infinity Chen <infinity.chen@mediatek.com>");
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig
new file mode 100644
index 0000000..26e5e6d
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig
@@ -0,0 +1,58 @@
+config NET_VENDOR_RALINK
+	tristate "Ralink ethernet driver"
+	depends on RALINK
+	help
+	  This driver supports the ethernet mac inside Ralink WiSoCs
+
+config NET_RALINK_SOC
+	def_tristate NET_VENDOR_RALINK
+
+if NET_RALINK_SOC
+choice
+	prompt "MAC type"
+
+config NET_RALINK_RT2880
+	bool "RT2882"
+	depends on MIPS && SOC_RT288X
+
+config NET_RALINK_RT3050
+	bool "RT3050/MT7628"
+	depends on MIPS && (SOC_RT305X || SOC_MT7620)
+
+config NET_RALINK_RT3883
+	bool "RT3883"
+	depends on MIPS && SOC_RT3883
+
+config NET_RALINK_MT7620
+	bool "MT7620"
+	depends on MIPS && SOC_MT7620
+
+endchoice
+
+config NET_RALINK_HW_QOS
+	def_bool NET_RALINK_SOC
+	depends on NET_RALINK_MT7623
+
+config NET_RALINK_MDIO
+	def_bool NET_RALINK_SOC
+	depends on (NET_RALINK_RT2880 || NET_RALINK_RT3883 || NET_RALINK_MT7620)
+	select PHYLIB
+
+config NET_RALINK_MDIO_RT2880
+	def_bool NET_RALINK_SOC
+	depends on (NET_RALINK_RT2880 || NET_RALINK_RT3883)
+	select NET_RALINK_MDIO
+
+config NET_RALINK_MDIO_MT7620
+	def_bool NET_RALINK_SOC
+	depends on NET_RALINK_MT7620
+	select NET_RALINK_MDIO
+
+config NET_RALINK_ESW_RT3050
+	def_tristate NET_RALINK_SOC
+	depends on NET_RALINK_RT3050
+
+config NET_RALINK_GSW_MT7620
+	def_tristate NET_RALINK_SOC
+	depends on NET_RALINK_MT7620
+endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/Makefile b/target/linux/ramips/files/drivers/net/ethernet/ralink/Makefile
new file mode 100644
index 0000000..79d2dbf
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Ralink SoCs built-in ethernet macs
+#
+
+ralink-eth-y					+= mtk_eth_soc.o ethtool.o
+
+ralink-eth-$(CONFIG_NET_RALINK_MDIO)		+= mdio.o
+ralink-eth-$(CONFIG_NET_RALINK_MDIO_RT2880)	+= mdio_rt2880.o
+ralink-eth-$(CONFIG_NET_RALINK_MDIO_MT7620)	+= mdio_mt7620.o
+
+ralink-eth-$(CONFIG_NET_RALINK_RT2880)	+= soc_rt2880.o
+ralink-eth-$(CONFIG_NET_RALINK_RT3050)	+= soc_rt3050.o
+ralink-eth-$(CONFIG_NET_RALINK_RT3883)	+= soc_rt3883.o
+ralink-eth-$(CONFIG_NET_RALINK_MT7620)	+= soc_mt7620.o
+
+obj-$(CONFIG_NET_RALINK_ESW_RT3050)		+= esw_rt3050.o
+obj-$(CONFIG_NET_RALINK_GSW_MT7620)		+= gsw_mt7620.o mt7530.o
+obj-$(CONFIG_NET_RALINK_SOC)			+= ralink-eth.o
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
new file mode 100644
index 0000000..292f11a
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
@@ -0,0 +1,1465 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ *   Copyright (C) 2016 Vittorio Gambaletta <openwrt@vittgam.net>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <asm/mach-ralink/ralink_regs.h>
+#include <linux/of_irq.h>
+
+#include <linux/switch.h>
+
+#include "mtk_eth_soc.h"
+
+/* HW limitations for this switch:
+ * - No large frame support (PKT_MAX_LEN at most 1536)
+ * - Can't have untagged vlan and tagged vlan on one port at the same time,
+ *   though this might be possible using the undocumented PPE.
+ */
+
+#define RT305X_ESW_REG_ISR		0x00
+#define RT305X_ESW_REG_IMR		0x04
+#define RT305X_ESW_REG_FCT0		0x08
+#define RT305X_ESW_REG_PFC1		0x14
+#define RT305X_ESW_REG_ATS		0x24
+#define RT305X_ESW_REG_ATS0		0x28
+#define RT305X_ESW_REG_ATS1		0x2c
+#define RT305X_ESW_REG_ATS2		0x30
+#define RT305X_ESW_REG_PVIDC(_n)	(0x40 + 4 * (_n))
+#define RT305X_ESW_REG_VLANI(_n)	(0x50 + 4 * (_n))
+#define RT305X_ESW_REG_VMSC(_n)		(0x70 + 4 * (_n))
+#define RT305X_ESW_REG_POA		0x80
+#define RT305X_ESW_REG_FPA		0x84
+#define RT305X_ESW_REG_SOCPC		0x8c
+#define RT305X_ESW_REG_POC0		0x90
+#define RT305X_ESW_REG_POC1		0x94
+#define RT305X_ESW_REG_POC2		0x98
+#define RT305X_ESW_REG_SGC		0x9c
+#define RT305X_ESW_REG_STRT		0xa0
+#define RT305X_ESW_REG_PCR0		0xc0
+#define RT305X_ESW_REG_PCR1		0xc4
+#define RT305X_ESW_REG_FPA2		0xc8
+#define RT305X_ESW_REG_FCT2		0xcc
+#define RT305X_ESW_REG_SGC2		0xe4
+#define RT305X_ESW_REG_P0LED		0xa4
+#define RT305X_ESW_REG_P1LED		0xa8
+#define RT305X_ESW_REG_P2LED		0xac
+#define RT305X_ESW_REG_P3LED		0xb0
+#define RT305X_ESW_REG_P4LED		0xb4
+#define RT305X_ESW_REG_PXPC(_x)		(0xe8 + (4 * _x))
+#define RT305X_ESW_REG_P1PC		0xec
+#define RT305X_ESW_REG_P2PC		0xf0
+#define RT305X_ESW_REG_P3PC		0xf4
+#define RT305X_ESW_REG_P4PC		0xf8
+#define RT305X_ESW_REG_P5PC		0xfc
+
+#define RT305X_ESW_LED_LINK		0
+#define RT305X_ESW_LED_100M		1
+#define RT305X_ESW_LED_DUPLEX		2
+#define RT305X_ESW_LED_ACTIVITY		3
+#define RT305X_ESW_LED_COLLISION	4
+#define RT305X_ESW_LED_LINKACT		5
+#define RT305X_ESW_LED_DUPLCOLL		6
+#define RT305X_ESW_LED_10MACT		7
+#define RT305X_ESW_LED_100MACT		8
+/* Additional led states not in datasheet: */
+#define RT305X_ESW_LED_BLINK		10
+#define RT305X_ESW_LED_ON		12
+
+#define RT305X_ESW_LINK_S		25
+#define RT305X_ESW_DUPLEX_S		9
+#define RT305X_ESW_SPD_S		0
+
+#define RT305X_ESW_PCR0_WT_NWAY_DATA_S	16
+#define RT305X_ESW_PCR0_WT_PHY_CMD	BIT(13)
+#define RT305X_ESW_PCR0_CPU_PHY_REG_S	8
+
+#define RT305X_ESW_PCR1_WT_DONE		BIT(0)
+
+#define RT305X_ESW_ATS_TIMEOUT		(5 * HZ)
+#define RT305X_ESW_PHY_TIMEOUT		(5 * HZ)
+
+#define RT305X_ESW_PVIDC_PVID_M		0xfff
+#define RT305X_ESW_PVIDC_PVID_S		12
+
+#define RT305X_ESW_VLANI_VID_M		0xfff
+#define RT305X_ESW_VLANI_VID_S		12
+
+#define RT305X_ESW_VMSC_MSC_M		0xff
+#define RT305X_ESW_VMSC_MSC_S		8
+
+#define RT305X_ESW_SOCPC_DISUN2CPU_S	0
+#define RT305X_ESW_SOCPC_DISMC2CPU_S	8
+#define RT305X_ESW_SOCPC_DISBC2CPU_S	16
+#define RT305X_ESW_SOCPC_CRC_PADDING	BIT(25)
+
+#define RT305X_ESW_POC0_EN_BP_S		0
+#define RT305X_ESW_POC0_EN_FC_S		8
+#define RT305X_ESW_POC0_DIS_RMC2CPU_S	16
+#define RT305X_ESW_POC0_DIS_PORT_M	0x7f
+#define RT305X_ESW_POC0_DIS_PORT_S	23
+
+#define RT305X_ESW_POC2_UNTAG_EN_M	0xff
+#define RT305X_ESW_POC2_UNTAG_EN_S	0
+#define RT305X_ESW_POC2_ENAGING_S	8
+#define RT305X_ESW_POC2_DIS_UC_PAUSE_S	16
+
+#define RT305X_ESW_SGC2_DOUBLE_TAG_M	0x7f
+#define RT305X_ESW_SGC2_DOUBLE_TAG_S	0
+#define RT305X_ESW_SGC2_LAN_PMAP_M	0x3f
+#define RT305X_ESW_SGC2_LAN_PMAP_S	24
+
+#define RT305X_ESW_PFC1_EN_VLAN_M	0xff
+#define RT305X_ESW_PFC1_EN_VLAN_S	16
+#define RT305X_ESW_PFC1_EN_TOS_S	24
+
+#define RT305X_ESW_VLAN_NONE		0xfff
+
+#define RT305X_ESW_GSC_BC_STROM_MASK	0x3
+#define RT305X_ESW_GSC_BC_STROM_SHIFT	4
+
+#define RT305X_ESW_GSC_LED_FREQ_MASK	0x3
+#define RT305X_ESW_GSC_LED_FREQ_SHIFT	23
+
+#define RT305X_ESW_POA_LINK_MASK	0x1f
+#define RT305X_ESW_POA_LINK_SHIFT	25
+
+#define RT305X_ESW_PORT_ST_CHG		BIT(26)
+#define RT305X_ESW_PORT0		0
+#define RT305X_ESW_PORT1		1
+#define RT305X_ESW_PORT2		2
+#define RT305X_ESW_PORT3		3
+#define RT305X_ESW_PORT4		4
+#define RT305X_ESW_PORT5		5
+#define RT305X_ESW_PORT6		6
+
+#define RT305X_ESW_PORTS_NONE		0
+
+#define RT305X_ESW_PMAP_LLLLLL		0x3f
+#define RT305X_ESW_PMAP_LLLLWL		0x2f
+#define RT305X_ESW_PMAP_WLLLLL		0x3e
+
+#define RT305X_ESW_PORTS_INTERNAL					\
+		(BIT(RT305X_ESW_PORT0) | BIT(RT305X_ESW_PORT1) |	\
+		 BIT(RT305X_ESW_PORT2) | BIT(RT305X_ESW_PORT3) |	\
+		 BIT(RT305X_ESW_PORT4))
+
+#define RT305X_ESW_PORTS_NOCPU						\
+		(RT305X_ESW_PORTS_INTERNAL | BIT(RT305X_ESW_PORT5))
+
+#define RT305X_ESW_PORTS_CPU	BIT(RT305X_ESW_PORT6)
+
+#define RT305X_ESW_PORTS_ALL						\
+		(RT305X_ESW_PORTS_NOCPU | RT305X_ESW_PORTS_CPU)
+
+#define RT305X_ESW_NUM_VLANS		16
+#define RT305X_ESW_NUM_VIDS		4096
+#define RT305X_ESW_NUM_PORTS		7
+#define RT305X_ESW_NUM_LANWAN		6
+#define RT305X_ESW_NUM_LEDS		5
+
+#define RT5350_ESW_REG_PXTPC(_x)	(0x150 + (4 * _x))
+#define RT5350_EWS_REG_LED_POLARITY	0x168
+#define RT5350_RESET_EPHY		BIT(24)
+
+enum {
+	/* Global attributes. */
+	RT305X_ESW_ATTR_ENABLE_VLAN,
+	RT305X_ESW_ATTR_ALT_VLAN_DISABLE,
+	RT305X_ESW_ATTR_BC_STATUS,
+	RT305X_ESW_ATTR_LED_FREQ,
+	/* Port attributes. */
+	RT305X_ESW_ATTR_PORT_DISABLE,
+	RT305X_ESW_ATTR_PORT_DOUBLETAG,
+	RT305X_ESW_ATTR_PORT_UNTAG,
+	RT305X_ESW_ATTR_PORT_LED,
+	RT305X_ESW_ATTR_PORT_LAN,
+	RT305X_ESW_ATTR_PORT_RECV_BAD,
+	RT305X_ESW_ATTR_PORT_RECV_GOOD,
+	RT5350_ESW_ATTR_PORT_TR_BAD,
+	RT5350_ESW_ATTR_PORT_TR_GOOD,
+};
+
+struct esw_port {
+	bool	disable;
+	bool	doubletag;
+	bool	untag;
+	u8	led;
+	u16	pvid;
+};
+
+struct esw_vlan {
+	u8	ports;
+	u16	vid;
+};
+
+enum {
+	RT305X_ESW_VLAN_CONFIG_NONE = 0,
+	RT305X_ESW_VLAN_CONFIG_LLLLW,
+	RT305X_ESW_VLAN_CONFIG_WLLLL,
+};
+
+struct rt305x_esw {
+	struct device		*dev;
+	void __iomem		*base;
+	int			irq;
+
+	/* Protects against concurrent register r/w operations. */
+	spinlock_t		reg_rw_lock;
+
+	unsigned char		port_map;
+	unsigned char		port_disable;
+	unsigned int		reg_initval_fct2;
+	unsigned int		reg_initval_fpa2;
+	unsigned int		reg_led_polarity;
+
+	struct switch_dev	swdev;
+	bool			global_vlan_enable;
+	bool			alt_vlan_disable;
+	int			bc_storm_protect;
+	int			led_frequency;
+	struct esw_vlan vlans[RT305X_ESW_NUM_VLANS];
+	struct esw_port ports[RT305X_ESW_NUM_PORTS];
+
+};
+
+static inline void esw_w32(struct rt305x_esw *esw, u32 val, unsigned reg)
+{
+	__raw_writel(val, esw->base + reg);
+}
+
+static inline u32 esw_r32(struct rt305x_esw *esw, unsigned reg)
+{
+	return __raw_readl(esw->base + reg);
+}
+
+static inline void esw_rmw_raw(struct rt305x_esw *esw, unsigned reg,
+			       unsigned long mask, unsigned long val)
+{
+	unsigned long t;
+
+	t = __raw_readl(esw->base + reg) & ~mask;
+	__raw_writel(t | val, esw->base + reg);
+}
+
+static void esw_rmw(struct rt305x_esw *esw, unsigned reg,
+		    unsigned long mask, unsigned long val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&esw->reg_rw_lock, flags);
+	esw_rmw_raw(esw, reg, mask, val);
+	spin_unlock_irqrestore(&esw->reg_rw_lock, flags);
+}
+
+static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr,
+			    u32 phy_register, u32 write_data)
+{
+	unsigned long t_start = jiffies;
+	int ret = 0;
+
+	while (1) {
+		if (!(esw_r32(esw, RT305X_ESW_REG_PCR1) &
+		      RT305X_ESW_PCR1_WT_DONE))
+			break;
+		if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
+			ret = 1;
+			goto out;
+		}
+	}
+
+	write_data &= 0xffff;
+	esw_w32(esw, (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) |
+		      (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) |
+		      (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD,
+		RT305X_ESW_REG_PCR0);
+
+	t_start = jiffies;
+	while (1) {
+		if (esw_r32(esw, RT305X_ESW_REG_PCR1) &
+			    RT305X_ESW_PCR1_WT_DONE)
+			break;
+
+		if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
+			ret = 1;
+			break;
+		}
+	}
+out:
+	if (ret)
+		dev_err(esw->dev, "ramips_eth: MDIO timeout\n");
+	return ret;
+}
+
+static unsigned esw_get_vlan_id(struct rt305x_esw *esw, unsigned vlan)
+{
+	unsigned s;
+	unsigned val;
+
+	s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
+	val = esw_r32(esw, RT305X_ESW_REG_VLANI(vlan / 2));
+	val = (val >> s) & RT305X_ESW_VLANI_VID_M;
+
+	return val;
+}
+
+static void esw_set_vlan_id(struct rt305x_esw *esw, unsigned vlan, unsigned vid)
+{
+	unsigned s;
+
+	s = RT305X_ESW_VLANI_VID_S * (vlan % 2);
+	esw_rmw(esw,
+		       RT305X_ESW_REG_VLANI(vlan / 2),
+		       RT305X_ESW_VLANI_VID_M << s,
+		       (vid & RT305X_ESW_VLANI_VID_M) << s);
+}
+
+static unsigned esw_get_pvid(struct rt305x_esw *esw, unsigned port)
+{
+	unsigned s, val;
+
+	s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
+	val = esw_r32(esw, RT305X_ESW_REG_PVIDC(port / 2));
+	return (val >> s) & RT305X_ESW_PVIDC_PVID_M;
+}
+
+static void esw_set_pvid(struct rt305x_esw *esw, unsigned port, unsigned pvid)
+{
+	unsigned s;
+
+	s = RT305X_ESW_PVIDC_PVID_S * (port % 2);
+	esw_rmw(esw,
+		       RT305X_ESW_REG_PVIDC(port / 2),
+		       RT305X_ESW_PVIDC_PVID_M << s,
+		       (pvid & RT305X_ESW_PVIDC_PVID_M) << s);
+}
+
+static unsigned esw_get_vmsc(struct rt305x_esw *esw, unsigned vlan)
+{
+	unsigned s, val;
+
+	s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
+	val = esw_r32(esw, RT305X_ESW_REG_VMSC(vlan / 4));
+	val = (val >> s) & RT305X_ESW_VMSC_MSC_M;
+
+	return val;
+}
+
+static void esw_set_vmsc(struct rt305x_esw *esw, unsigned vlan, unsigned msc)
+{
+	unsigned s;
+
+	s = RT305X_ESW_VMSC_MSC_S * (vlan % 4);
+	esw_rmw(esw,
+		       RT305X_ESW_REG_VMSC(vlan / 4),
+		       RT305X_ESW_VMSC_MSC_M << s,
+		       (msc & RT305X_ESW_VMSC_MSC_M) << s);
+}
+
+static unsigned esw_get_port_disable(struct rt305x_esw *esw)
+{
+	unsigned reg;
+
+	reg = esw_r32(esw, RT305X_ESW_REG_POC0);
+	return (reg >> RT305X_ESW_POC0_DIS_PORT_S) &
+	       RT305X_ESW_POC0_DIS_PORT_M;
+}
+
+static void esw_set_port_disable(struct rt305x_esw *esw, unsigned disable_mask)
+{
+	unsigned old_mask;
+	unsigned enable_mask;
+	unsigned changed;
+	int i;
+
+	old_mask = esw_get_port_disable(esw);
+	changed = old_mask ^ disable_mask;
+	enable_mask = old_mask & disable_mask;
+
+	/* enable before writing to MII */
+	esw_rmw(esw, RT305X_ESW_REG_POC0,
+		       (RT305X_ESW_POC0_DIS_PORT_M <<
+			RT305X_ESW_POC0_DIS_PORT_S),
+		       enable_mask << RT305X_ESW_POC0_DIS_PORT_S);
+
+	for (i = 0; i < RT305X_ESW_NUM_LEDS; i++) {
+		if (!(changed & (1 << i)))
+			continue;
+		if (disable_mask & (1 << i)) {
+			/* disable */
+			rt305x_mii_write(esw, i, MII_BMCR,
+					 BMCR_PDOWN);
+		} else {
+			/* enable */
+			rt305x_mii_write(esw, i, MII_BMCR,
+					 BMCR_FULLDPLX |
+					 BMCR_ANENABLE |
+					 BMCR_ANRESTART |
+					 BMCR_SPEED100);
+		}
+	}
+
+	/* disable after writing to MII */
+	esw_rmw(esw, RT305X_ESW_REG_POC0,
+		       (RT305X_ESW_POC0_DIS_PORT_M <<
+			RT305X_ESW_POC0_DIS_PORT_S),
+		       disable_mask << RT305X_ESW_POC0_DIS_PORT_S);
+}
+
+static void esw_set_gsc(struct rt305x_esw *esw)
+{
+	esw_rmw(esw, RT305X_ESW_REG_SGC,
+		RT305X_ESW_GSC_BC_STROM_MASK << RT305X_ESW_GSC_BC_STROM_SHIFT,
+		esw->bc_storm_protect << RT305X_ESW_GSC_BC_STROM_SHIFT);
+	esw_rmw(esw, RT305X_ESW_REG_SGC,
+		RT305X_ESW_GSC_LED_FREQ_MASK << RT305X_ESW_GSC_LED_FREQ_SHIFT,
+		esw->led_frequency << RT305X_ESW_GSC_LED_FREQ_SHIFT);
+}
+
+static int esw_apply_config(struct switch_dev *dev);
+
+static void esw_hw_init(struct rt305x_esw *esw)
+{
+	int i;
+	u8 port_disable = 0;
+	u8 port_map = RT305X_ESW_PMAP_LLLLLL;
+
+	/* vodoo from original driver */
+	esw_w32(esw, 0xC8A07850, RT305X_ESW_REG_FCT0);
+	esw_w32(esw, 0x00000000, RT305X_ESW_REG_SGC2);
+	/* Port priority 1 for all ports, vlan enabled. */
+	esw_w32(esw, 0x00005555 |
+		     (RT305X_ESW_PORTS_ALL << RT305X_ESW_PFC1_EN_VLAN_S),
+		RT305X_ESW_REG_PFC1);
+
+	/* Enable all ports, Back Pressure and Flow Control */
+	esw_w32(esw, ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_BP_S) |
+		      (RT305X_ESW_PORTS_ALL << RT305X_ESW_POC0_EN_FC_S)),
+		RT305X_ESW_REG_POC0);
+
+	/* Enable Aging, and VLAN TAG removal */
+	esw_w32(esw, ((RT305X_ESW_PORTS_ALL << RT305X_ESW_POC2_ENAGING_S) |
+		      (RT305X_ESW_PORTS_NOCPU << RT305X_ESW_POC2_UNTAG_EN_S)),
+		RT305X_ESW_REG_POC2);
+
+	if (esw->reg_initval_fct2)
+		esw_w32(esw, esw->reg_initval_fct2, RT305X_ESW_REG_FCT2);
+	else
+		esw_w32(esw, 0x0002500c, RT305X_ESW_REG_FCT2);
+
+	/* 300s aging timer, max packet len 1536, broadcast storm prevention
+	 * disabled, disable collision abort, mac xor48 hash, 10 packet back
+	 * pressure jam, GMII disable was_transmit, back pressure disabled,
+	 * 30ms led flash, unmatched IGMP as broadcast, rmc tb fault to all
+	 * ports.
+	 */
+	esw_w32(esw, 0x0008a301, RT305X_ESW_REG_SGC);
+
+	/* Setup SoC Port control register */
+	esw_w32(esw,
+		(RT305X_ESW_SOCPC_CRC_PADDING |
+		(RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISUN2CPU_S) |
+		(RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISMC2CPU_S) |
+		(RT305X_ESW_PORTS_CPU << RT305X_ESW_SOCPC_DISBC2CPU_S)),
+		RT305X_ESW_REG_SOCPC);
+
+	/* ext phy base addr 31, enable port 5 polling, rx/tx clock skew 1,
+	 * turbo mii off, rgmi 3.3v off
+	 * port5: disabled
+	 * port6: enabled, gige, full-duplex, rx/tx-flow-control
+	 */
+	if (esw->reg_initval_fpa2)
+		esw_w32(esw, esw->reg_initval_fpa2, RT305X_ESW_REG_FPA2);
+	else
+		esw_w32(esw, 0x3f502b28, RT305X_ESW_REG_FPA2);
+	esw_w32(esw, 0x00000000, RT305X_ESW_REG_FPA);
+
+	/* Force Link/Activity on ports */
+	esw_w32(esw, 0x00000005, RT305X_ESW_REG_P0LED);
+	esw_w32(esw, 0x00000005, RT305X_ESW_REG_P1LED);
+	esw_w32(esw, 0x00000005, RT305X_ESW_REG_P2LED);
+	esw_w32(esw, 0x00000005, RT305X_ESW_REG_P3LED);
+	esw_w32(esw, 0x00000005, RT305X_ESW_REG_P4LED);
+
+	/* Copy disabled port configuration from device tree setup */
+	port_disable = esw->port_disable;
+
+	/* Disable nonexistent ports by reading the switch config
+	 * after having enabled all possible ports above
+	 */
+	port_disable |= esw_get_port_disable(esw);
+
+	for (i = 0; i < 6; i++)
+		esw->ports[i].disable = (port_disable & (1 << i)) != 0;
+
+	if (ralink_soc == RT305X_SOC_RT3352) {
+		/* reset EPHY */
+		fe_reset(RT5350_RESET_EPHY);
+
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+		for (i = 0; i < 5; i++) {
+			if (esw->ports[i].disable) {
+				rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
+			} else {
+				rt305x_mii_write(esw, i, MII_BMCR,
+						 BMCR_FULLDPLX |
+						 BMCR_ANENABLE |
+						 BMCR_SPEED100);
+			}
+			/* TX10 waveform coefficient LSB=0 disable PHY */
+			rt305x_mii_write(esw, i, 26, 0x1601);
+			/* TX100/TX10 AD/DA current bias */
+			rt305x_mii_write(esw, i, 29, 0x7016);
+			/* TX100 slew rate control */
+			rt305x_mii_write(esw, i, 30, 0x0038);
+		}
+
+		/* select global register */
+		rt305x_mii_write(esw, 0, 31, 0x0);
+		/* enlarge agcsel threshold 3 and threshold 2 */
+		rt305x_mii_write(esw, 0, 1, 0x4a40);
+		/* enlarge agcsel threshold 5 and threshold 4 */
+		rt305x_mii_write(esw, 0, 2, 0x6254);
+		/* enlarge agcsel threshold  */
+		rt305x_mii_write(esw, 0, 3, 0xa17f);
+		rt305x_mii_write(esw, 0, 12, 0x7eaa);
+		/* longer TP_IDL tail length */
+		rt305x_mii_write(esw, 0, 14, 0x65);
+		/* increased squelch pulse count threshold. */
+		rt305x_mii_write(esw, 0, 16, 0x0684);
+		/* set TX10 signal amplitude threshold to minimum */
+		rt305x_mii_write(esw, 0, 17, 0x0fe0);
+		/* set squelch amplitude to higher threshold */
+		rt305x_mii_write(esw, 0, 18, 0x40ba);
+		/* tune TP_IDL tail and head waveform, enable power
+		 * down slew rate control
+		 */
+		rt305x_mii_write(esw, 0, 22, 0x253f);
+		/* set PLL/Receive bias current are calibrated */
+		rt305x_mii_write(esw, 0, 27, 0x2fda);
+		/* change PLL/Receive bias current to internal(RT3350) */
+		rt305x_mii_write(esw, 0, 28, 0xc410);
+		/* change PLL bias current to internal(RT3052_MP3) */
+		rt305x_mii_write(esw, 0, 29, 0x598b);
+		/* select local register */
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+	} else if (ralink_soc == RT305X_SOC_RT5350) {
+		/* reset EPHY */
+		fe_reset(RT5350_RESET_EPHY);
+
+		/* set the led polarity */
+		esw_w32(esw, esw->reg_led_polarity & 0x1F,
+			RT5350_EWS_REG_LED_POLARITY);
+
+		/* local registers */
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+		for (i = 0; i < 5; i++) {
+			if (esw->ports[i].disable) {
+				rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
+			} else {
+				rt305x_mii_write(esw, i, MII_BMCR,
+						 BMCR_FULLDPLX |
+						 BMCR_ANENABLE |
+						 BMCR_SPEED100);
+			}
+			/* TX10 waveform coefficient LSB=0 disable PHY */
+			rt305x_mii_write(esw, i, 26, 0x1601);
+			/* TX100/TX10 AD/DA current bias */
+			rt305x_mii_write(esw, i, 29, 0x7015);
+			/* TX100 slew rate control */
+			rt305x_mii_write(esw, i, 30, 0x0038);
+		}
+
+		/* global registers */
+		rt305x_mii_write(esw, 0, 31, 0x0);
+		/* enlarge agcsel threshold 3 and threshold 2 */
+		rt305x_mii_write(esw, 0, 1, 0x4a40);
+		/* enlarge agcsel threshold 5 and threshold 4 */
+		rt305x_mii_write(esw, 0, 2, 0x6254);
+		/* enlarge agcsel threshold 6 */
+		rt305x_mii_write(esw, 0, 3, 0xa17f);
+		rt305x_mii_write(esw, 0, 12, 0x7eaa);
+		/* longer TP_IDL tail length */
+		rt305x_mii_write(esw, 0, 14, 0x65);
+		/* increased squelch pulse count threshold. */
+		rt305x_mii_write(esw, 0, 16, 0x0684);
+		/* set TX10 signal amplitude threshold to minimum */
+		rt305x_mii_write(esw, 0, 17, 0x0fe0);
+		/* set squelch amplitude to higher threshold */
+		rt305x_mii_write(esw, 0, 18, 0x40ba);
+		/* tune TP_IDL tail and head waveform, enable power
+		 * down slew rate control
+		 */
+		rt305x_mii_write(esw, 0, 22, 0x253f);
+		/* set PLL/Receive bias current are calibrated */
+		rt305x_mii_write(esw, 0, 27, 0x2fda);
+		/* change PLL/Receive bias current to internal(RT3350) */
+		rt305x_mii_write(esw, 0, 28, 0xc410);
+		/* change PLL bias current to internal(RT3052_MP3) */
+		rt305x_mii_write(esw, 0, 29, 0x598b);
+		/* select local register */
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+	} else if (ralink_soc == MT762X_SOC_MT7628AN || ralink_soc == MT762X_SOC_MT7688) {
+		int i;
+
+		/* reset EPHY */
+		fe_reset(RT5350_RESET_EPHY);
+
+		/* set the led polarity */
+		esw_w32(esw, esw->reg_led_polarity & 0x1F,
+			RT5350_EWS_REG_LED_POLARITY);
+
+		rt305x_mii_write(esw, 0, 31, 0x2000); /* change G2 page */
+		rt305x_mii_write(esw, 0, 26, 0x0020);
+
+		for (i = 0; i < 5; i++) {
+			rt305x_mii_write(esw, i, 31, 0x8000);
+			rt305x_mii_write(esw, i,  0, 0x3100);
+			rt305x_mii_write(esw, i, 30, 0xa000);
+			rt305x_mii_write(esw, i, 31, 0xa000);
+			rt305x_mii_write(esw, i, 16, 0x0606);
+			rt305x_mii_write(esw, i, 23, 0x0f0e);
+			rt305x_mii_write(esw, i, 24, 0x1610);
+			rt305x_mii_write(esw, i, 30, 0x1f15);
+			rt305x_mii_write(esw, i, 28, 0x6111);
+			rt305x_mii_write(esw, i, 31, 0x2000);
+			rt305x_mii_write(esw, i, 26, 0x0000);
+		}
+
+		/* 100Base AOI setting */
+		rt305x_mii_write(esw, 0, 31, 0x5000);
+		rt305x_mii_write(esw, 0, 19, 0x004a);
+		rt305x_mii_write(esw, 0, 20, 0x015a);
+		rt305x_mii_write(esw, 0, 21, 0x00ee);
+		rt305x_mii_write(esw, 0, 22, 0x0033);
+		rt305x_mii_write(esw, 0, 23, 0x020a);
+		rt305x_mii_write(esw, 0, 24, 0x0000);
+		rt305x_mii_write(esw, 0, 25, 0x024a);
+		rt305x_mii_write(esw, 0, 26, 0x035a);
+		rt305x_mii_write(esw, 0, 27, 0x02ee);
+		rt305x_mii_write(esw, 0, 28, 0x0233);
+		rt305x_mii_write(esw, 0, 29, 0x000a);
+		rt305x_mii_write(esw, 0, 30, 0x0000);
+	} else {
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+		for (i = 0; i < 5; i++) {
+			if (esw->ports[i].disable) {
+				rt305x_mii_write(esw, i, MII_BMCR, BMCR_PDOWN);
+			} else {
+				rt305x_mii_write(esw, i, MII_BMCR,
+						 BMCR_FULLDPLX |
+						 BMCR_ANENABLE |
+						 BMCR_SPEED100);
+			}
+			/* TX10 waveform coefficient */
+			rt305x_mii_write(esw, i, 26, 0x1601);
+			/* TX100/TX10 AD/DA current bias */
+			rt305x_mii_write(esw, i, 29, 0x7058);
+			/* TX100 slew rate control */
+			rt305x_mii_write(esw, i, 30, 0x0018);
+		}
+
+		/* PHY IOT */
+		/* select global register */
+		rt305x_mii_write(esw, 0, 31, 0x0);
+		/* tune TP_IDL tail and head waveform */
+		rt305x_mii_write(esw, 0, 22, 0x052f);
+		/* set TX10 signal amplitude threshold to minimum */
+		rt305x_mii_write(esw, 0, 17, 0x0fe0);
+		/* set squelch amplitude to higher threshold */
+		rt305x_mii_write(esw, 0, 18, 0x40ba);
+		/* longer TP_IDL tail length */
+		rt305x_mii_write(esw, 0, 14, 0x65);
+		/* select local register */
+		rt305x_mii_write(esw, 0, 31, 0x8000);
+	}
+
+	if (esw->port_map)
+		port_map = esw->port_map;
+	else
+		port_map = RT305X_ESW_PMAP_LLLLLL;
+
+	/* Unused HW feature, but still nice to be consistent here...
+	 * This is also exported to userspace ('lan' attribute) so it's
+	 * conveniently usable to decide which ports go into the wan vlan by
+	 * default.
+	 */
+	esw_rmw(esw, RT305X_ESW_REG_SGC2,
+		RT305X_ESW_SGC2_LAN_PMAP_M << RT305X_ESW_SGC2_LAN_PMAP_S,
+		port_map << RT305X_ESW_SGC2_LAN_PMAP_S);
+
+	/* make the switch leds blink */
+	for (i = 0; i < RT305X_ESW_NUM_LEDS; i++)
+		esw->ports[i].led = 0x05;
+
+	/* Apply the empty config. */
+	esw_apply_config(&esw->swdev);
+
+	/* Only unmask the port change interrupt */
+	esw_w32(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR);
+}
+
+static irqreturn_t esw_interrupt(int irq, void *_esw)
+{
+	struct rt305x_esw *esw = (struct rt305x_esw *)_esw;
+	u32 status;
+
+	status = esw_r32(esw, RT305X_ESW_REG_ISR);
+	if (status & RT305X_ESW_PORT_ST_CHG) {
+		u32 link = esw_r32(esw, RT305X_ESW_REG_POA);
+
+		link >>= RT305X_ESW_POA_LINK_SHIFT;
+		link &= RT305X_ESW_POA_LINK_MASK;
+		dev_info(esw->dev, "link changed 0x%02X\n", link);
+	}
+	esw_w32(esw, status, RT305X_ESW_REG_ISR);
+
+	return IRQ_HANDLED;
+}
+
+static int esw_apply_config(struct switch_dev *dev)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int i;
+	u8 disable = 0;
+	u8 doubletag = 0;
+	u8 en_vlan = 0;
+	u8 untag = 0;
+
+	for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
+		u32 vid, vmsc;
+		if (esw->global_vlan_enable) {
+			vid = esw->vlans[i].vid;
+			vmsc = esw->vlans[i].ports;
+		} else {
+			vid = RT305X_ESW_VLAN_NONE;
+			vmsc = RT305X_ESW_PORTS_NONE;
+		}
+		esw_set_vlan_id(esw, i, vid);
+		esw_set_vmsc(esw, i, vmsc);
+	}
+
+	for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) {
+		u32 pvid;
+		disable |= esw->ports[i].disable << i;
+		if (esw->global_vlan_enable) {
+			doubletag |= esw->ports[i].doubletag << i;
+			en_vlan   |= 1                       << i;
+			untag     |= esw->ports[i].untag     << i;
+			pvid       = esw->ports[i].pvid;
+		} else {
+			int x = esw->alt_vlan_disable ? 0 : 1;
+			doubletag |= x << i;
+			en_vlan   |= x << i;
+			untag     |= x << i;
+			pvid       = 0;
+		}
+		esw_set_pvid(esw, i, pvid);
+		if (i < RT305X_ESW_NUM_LEDS)
+			esw_w32(esw, esw->ports[i].led,
+				      RT305X_ESW_REG_P0LED + 4*i);
+	}
+
+	esw_set_gsc(esw);
+	esw_set_port_disable(esw, disable);
+	esw_rmw(esw, RT305X_ESW_REG_SGC2,
+		       (RT305X_ESW_SGC2_DOUBLE_TAG_M <<
+			RT305X_ESW_SGC2_DOUBLE_TAG_S),
+		       doubletag << RT305X_ESW_SGC2_DOUBLE_TAG_S);
+	esw_rmw(esw, RT305X_ESW_REG_PFC1,
+		       RT305X_ESW_PFC1_EN_VLAN_M << RT305X_ESW_PFC1_EN_VLAN_S,
+		       en_vlan << RT305X_ESW_PFC1_EN_VLAN_S);
+	esw_rmw(esw, RT305X_ESW_REG_POC2,
+		       RT305X_ESW_POC2_UNTAG_EN_M << RT305X_ESW_POC2_UNTAG_EN_S,
+		       untag << RT305X_ESW_POC2_UNTAG_EN_S);
+
+	if (!esw->global_vlan_enable) {
+		/*
+		 * Still need to put all ports into vlan 0 or they'll be
+		 * isolated.
+		 * NOTE: vlan 0 is special, no vlan tag is prepended
+		 */
+		esw_set_vlan_id(esw, 0, 0);
+		esw_set_vmsc(esw, 0, RT305X_ESW_PORTS_ALL);
+	}
+
+	return 0;
+}
+
+static int esw_reset_switch(struct switch_dev *dev)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	esw->global_vlan_enable = 0;
+	memset(esw->ports, 0, sizeof(esw->ports));
+	memset(esw->vlans, 0, sizeof(esw->vlans));
+	esw_hw_init(esw);
+
+	return 0;
+}
+
+static int esw_get_vlan_enable(struct switch_dev *dev,
+			   const struct switch_attr *attr,
+			   struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	val->value.i = esw->global_vlan_enable;
+
+	return 0;
+}
+
+static int esw_set_vlan_enable(struct switch_dev *dev,
+			   const struct switch_attr *attr,
+			   struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	esw->global_vlan_enable = val->value.i != 0;
+
+	return 0;
+}
+
+static int esw_get_alt_vlan_disable(struct switch_dev *dev,
+				const struct switch_attr *attr,
+				struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	val->value.i = esw->alt_vlan_disable;
+
+	return 0;
+}
+
+static int esw_set_alt_vlan_disable(struct switch_dev *dev,
+				const struct switch_attr *attr,
+				struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	esw->alt_vlan_disable = val->value.i != 0;
+
+	return 0;
+}
+
+static int
+rt305x_esw_set_bc_status(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	esw->bc_storm_protect = val->value.i & RT305X_ESW_GSC_BC_STROM_MASK;
+
+	return 0;
+}
+
+static int
+rt305x_esw_get_bc_status(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	val->value.i = esw->bc_storm_protect;
+
+	return 0;
+}
+
+static int
+rt305x_esw_set_led_freq(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	esw->led_frequency = val->value.i & RT305X_ESW_GSC_LED_FREQ_MASK;
+
+	return 0;
+}
+
+static int
+rt305x_esw_get_led_freq(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	val->value.i = esw->led_frequency;
+
+	return 0;
+}
+
+static int esw_get_port_link(struct switch_dev *dev,
+			 int port,
+			 struct switch_port_link *link)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	u32 speed, poa;
+
+	if (port < 0 || port >= RT305X_ESW_NUM_PORTS)
+		return -EINVAL;
+
+	poa = esw_r32(esw, RT305X_ESW_REG_POA) >> port;
+
+	link->link = (poa >> RT305X_ESW_LINK_S) & 1;
+	link->duplex = (poa >> RT305X_ESW_DUPLEX_S) & 1;
+	if (port < RT305X_ESW_NUM_LEDS) {
+		speed = (poa >> RT305X_ESW_SPD_S) & 1;
+	} else {
+		if (port == RT305X_ESW_NUM_PORTS - 1)
+			poa >>= 1;
+		speed = (poa >> RT305X_ESW_SPD_S) & 3;
+	}
+	switch (speed) {
+	case 0:
+		link->speed = SWITCH_PORT_SPEED_10;
+		break;
+	case 1:
+		link->speed = SWITCH_PORT_SPEED_100;
+		break;
+	case 2:
+	case 3: /* forced gige speed can be 2 or 3 */
+		link->speed = SWITCH_PORT_SPEED_1000;
+		break;
+	default:
+		link->speed = SWITCH_PORT_SPEED_UNKNOWN;
+		break;
+	}
+
+	return 0;
+}
+
+static int esw_get_port_bool(struct switch_dev *dev,
+			 const struct switch_attr *attr,
+			 struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int idx = val->port_vlan;
+	u32 x, reg, shift;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS)
+		return -EINVAL;
+
+	switch (attr->id) {
+	case RT305X_ESW_ATTR_PORT_DISABLE:
+		reg = RT305X_ESW_REG_POC0;
+		shift = RT305X_ESW_POC0_DIS_PORT_S;
+		break;
+	case RT305X_ESW_ATTR_PORT_DOUBLETAG:
+		reg = RT305X_ESW_REG_SGC2;
+		shift = RT305X_ESW_SGC2_DOUBLE_TAG_S;
+		break;
+	case RT305X_ESW_ATTR_PORT_UNTAG:
+		reg = RT305X_ESW_REG_POC2;
+		shift = RT305X_ESW_POC2_UNTAG_EN_S;
+		break;
+	case RT305X_ESW_ATTR_PORT_LAN:
+		reg = RT305X_ESW_REG_SGC2;
+		shift = RT305X_ESW_SGC2_LAN_PMAP_S;
+		if (idx >= RT305X_ESW_NUM_LANWAN)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	x = esw_r32(esw, reg);
+	val->value.i = (x >> (idx + shift)) & 1;
+
+	return 0;
+}
+
+static int esw_set_port_bool(struct switch_dev *dev,
+			 const struct switch_attr *attr,
+			 struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int idx = val->port_vlan;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS ||
+	    val->value.i < 0 || val->value.i > 1)
+		return -EINVAL;
+
+	switch (attr->id) {
+	case RT305X_ESW_ATTR_PORT_DISABLE:
+		esw->ports[idx].disable = val->value.i;
+		break;
+	case RT305X_ESW_ATTR_PORT_DOUBLETAG:
+		esw->ports[idx].doubletag = val->value.i;
+		break;
+	case RT305X_ESW_ATTR_PORT_UNTAG:
+		esw->ports[idx].untag = val->value.i;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int esw_get_port_recv_badgood(struct switch_dev *dev,
+				 const struct switch_attr *attr,
+				 struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int idx = val->port_vlan;
+	int shift = attr->id == RT305X_ESW_ATTR_PORT_RECV_GOOD ? 0 : 16;
+	u32 reg;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN)
+		return -EINVAL;
+	reg = esw_r32(esw, RT305X_ESW_REG_PXPC(idx));
+	val->value.i = (reg >> shift) & 0xffff;
+
+	return 0;
+}
+
+static int
+esw_get_port_tr_badgood(struct switch_dev *dev,
+				 const struct switch_attr *attr,
+				 struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	int idx = val->port_vlan;
+	int shift = attr->id == RT5350_ESW_ATTR_PORT_TR_GOOD ? 0 : 16;
+	u32 reg;
+
+	if ((ralink_soc != RT305X_SOC_RT5350) && (ralink_soc != MT762X_SOC_MT7628AN) && (ralink_soc != MT762X_SOC_MT7688))
+		return -EINVAL;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_LANWAN)
+		return -EINVAL;
+
+	reg = esw_r32(esw, RT5350_ESW_REG_PXTPC(idx));
+	val->value.i = (reg >> shift) & 0xffff;
+
+	return 0;
+}
+
+static int esw_get_port_led(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int idx = val->port_vlan;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_PORTS ||
+	    idx >= RT305X_ESW_NUM_LEDS)
+		return -EINVAL;
+
+	val->value.i = esw_r32(esw, RT305X_ESW_REG_P0LED + 4*idx);
+
+	return 0;
+}
+
+static int esw_set_port_led(struct switch_dev *dev,
+			const struct switch_attr *attr,
+			struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int idx = val->port_vlan;
+
+	if (idx < 0 || idx >= RT305X_ESW_NUM_LEDS)
+		return -EINVAL;
+
+	esw->ports[idx].led = val->value.i;
+
+	return 0;
+}
+
+static int esw_get_port_pvid(struct switch_dev *dev, int port, int *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	if (port >= RT305X_ESW_NUM_PORTS)
+		return -EINVAL;
+
+	*val = esw_get_pvid(esw, port);
+
+	return 0;
+}
+
+static int esw_set_port_pvid(struct switch_dev *dev, int port, int val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+
+	if (port >= RT305X_ESW_NUM_PORTS)
+		return -EINVAL;
+
+	esw->ports[port].pvid = val;
+
+	return 0;
+}
+
+static int esw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	u32 vmsc, poc2;
+	int vlan_idx = -1;
+	int i;
+
+	val->len = 0;
+
+	if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS)
+		return -EINVAL;
+
+	/* valid vlan? */
+	for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
+		if (esw_get_vlan_id(esw, i) == val->port_vlan &&
+		    esw_get_vmsc(esw, i) != RT305X_ESW_PORTS_NONE) {
+			vlan_idx = i;
+			break;
+		}
+	}
+
+	if (vlan_idx == -1)
+		return -EINVAL;
+
+	vmsc = esw_get_vmsc(esw, vlan_idx);
+	poc2 = esw_r32(esw, RT305X_ESW_REG_POC2);
+
+	for (i = 0; i < RT305X_ESW_NUM_PORTS; i++) {
+		struct switch_port *p;
+		int port_mask = 1 << i;
+
+		if (!(vmsc & port_mask))
+			continue;
+
+		p = &val->value.ports[val->len++];
+		p->id = i;
+		if (poc2 & (port_mask << RT305X_ESW_POC2_UNTAG_EN_S))
+			p->flags = 0;
+		else
+			p->flags = 1 << SWITCH_PORT_FLAG_TAGGED;
+	}
+
+	return 0;
+}
+
+static int esw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
+{
+	struct rt305x_esw *esw = container_of(dev, struct rt305x_esw, swdev);
+	int ports;
+	int vlan_idx = -1;
+	int i;
+
+	if (val->port_vlan < 0 || val->port_vlan >= RT305X_ESW_NUM_VIDS ||
+	    val->len > RT305X_ESW_NUM_PORTS)
+		return -EINVAL;
+
+	/* one of the already defined vlans? */
+	for (i = 0; i < RT305X_ESW_NUM_VLANS; i++) {
+		if (esw->vlans[i].vid == val->port_vlan &&
+		    esw->vlans[i].ports != RT305X_ESW_PORTS_NONE) {
+			vlan_idx = i;
+			break;
+		}
+	}
+
+	/* select a free slot */
+	for (i = 0; vlan_idx == -1 && i < RT305X_ESW_NUM_VLANS; i++) {
+		if (esw->vlans[i].ports == RT305X_ESW_PORTS_NONE)
+			vlan_idx = i;
+	}
+
+	/* bail if all slots are in use */
+	if (vlan_idx == -1)
+		return -EINVAL;
+
+	ports = RT305X_ESW_PORTS_NONE;
+	for (i = 0; i < val->len; i++) {
+		struct switch_port *p = &val->value.ports[i];
+		int port_mask = 1 << p->id;
+		bool untagged = !(p->flags & (1 << SWITCH_PORT_FLAG_TAGGED));
+
+		if (p->id >= RT305X_ESW_NUM_PORTS)
+			return -EINVAL;
+
+		ports |= port_mask;
+		esw->ports[p->id].untag = untagged;
+	}
+	esw->vlans[vlan_idx].ports = ports;
+	if (ports == RT305X_ESW_PORTS_NONE)
+		esw->vlans[vlan_idx].vid = RT305X_ESW_VLAN_NONE;
+	else
+		esw->vlans[vlan_idx].vid = val->port_vlan;
+
+	return 0;
+}
+
+static const struct switch_attr esw_global[] = {
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "enable_vlan",
+		.description = "VLAN mode (1:enabled)",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_ENABLE_VLAN,
+		.get = esw_get_vlan_enable,
+		.set = esw_set_vlan_enable,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "alternate_vlan_disable",
+		.description = "Use en_vlan instead of doubletag to disable"
+				" VLAN mode",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_ALT_VLAN_DISABLE,
+		.get = esw_get_alt_vlan_disable,
+		.set = esw_set_alt_vlan_disable,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "bc_storm_protect",
+		.description = "Global broadcast storm protection (0:Disable, 1:64 blocks, 2:96 blocks, 3:128 blocks)",
+		.max = 3,
+		.id = RT305X_ESW_ATTR_BC_STATUS,
+		.get = rt305x_esw_get_bc_status,
+		.set = rt305x_esw_set_bc_status,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "led_frequency",
+		.description = "LED Flash frequency (0:30mS, 1:60mS, 2:240mS, 3:480mS)",
+		.max = 3,
+		.id = RT305X_ESW_ATTR_LED_FREQ,
+		.get = rt305x_esw_get_led_freq,
+		.set = rt305x_esw_set_led_freq,
+	}
+};
+
+static const struct switch_attr esw_port[] = {
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "disable",
+		.description = "Port state (1:disabled)",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_PORT_DISABLE,
+		.get = esw_get_port_bool,
+		.set = esw_set_port_bool,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "doubletag",
+		.description = "Double tagging for incoming vlan packets "
+				"(1:enabled)",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_PORT_DOUBLETAG,
+		.get = esw_get_port_bool,
+		.set = esw_set_port_bool,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "untag",
+		.description = "Untag (1:strip outgoing vlan tag)",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_PORT_UNTAG,
+		.get = esw_get_port_bool,
+		.set = esw_set_port_bool,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "led",
+		.description = "LED mode (0:link, 1:100m, 2:duplex, 3:activity,"
+				" 4:collision, 5:linkact, 6:duplcoll, 7:10mact,"
+				" 8:100mact, 10:blink, 11:off, 12:on)",
+		.max = 15,
+		.id = RT305X_ESW_ATTR_PORT_LED,
+		.get = esw_get_port_led,
+		.set = esw_set_port_led,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "lan",
+		.description = "HW port group (0:wan, 1:lan)",
+		.max = 1,
+		.id = RT305X_ESW_ATTR_PORT_LAN,
+		.get = esw_get_port_bool,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "recv_bad",
+		.description = "Receive bad packet counter",
+		.id = RT305X_ESW_ATTR_PORT_RECV_BAD,
+		.get = esw_get_port_recv_badgood,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "recv_good",
+		.description = "Receive good packet counter",
+		.id = RT305X_ESW_ATTR_PORT_RECV_GOOD,
+		.get = esw_get_port_recv_badgood,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "tr_bad",
+
+		.description = "Transmit bad packet counter. rt5350 only",
+		.id = RT5350_ESW_ATTR_PORT_TR_BAD,
+		.get = esw_get_port_tr_badgood,
+	},
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "tr_good",
+
+		.description = "Transmit good packet counter. rt5350 only",
+		.id = RT5350_ESW_ATTR_PORT_TR_GOOD,
+		.get = esw_get_port_tr_badgood,
+	},
+};
+
+static const struct switch_attr esw_vlan[] = {
+};
+
+static const struct switch_dev_ops esw_ops = {
+	.attr_global = {
+		.attr = esw_global,
+		.n_attr = ARRAY_SIZE(esw_global),
+	},
+	.attr_port = {
+		.attr = esw_port,
+		.n_attr = ARRAY_SIZE(esw_port),
+	},
+	.attr_vlan = {
+		.attr = esw_vlan,
+		.n_attr = ARRAY_SIZE(esw_vlan),
+	},
+	.get_vlan_ports = esw_get_vlan_ports,
+	.set_vlan_ports = esw_set_vlan_ports,
+	.get_port_pvid = esw_get_port_pvid,
+	.set_port_pvid = esw_set_port_pvid,
+	.get_port_link = esw_get_port_link,
+	.apply_config = esw_apply_config,
+	.reset_switch = esw_reset_switch,
+};
+
+static int esw_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct device_node *np = pdev->dev.of_node;
+	const __be32 *port_map, *port_disable, *reg_init;
+	struct switch_dev *swdev;
+	struct rt305x_esw *esw;
+	int ret;
+
+	esw = devm_kzalloc(&pdev->dev, sizeof(*esw), GFP_KERNEL);
+	if (!esw)
+		return -ENOMEM;
+
+	esw->dev = &pdev->dev;
+	esw->irq = irq_of_parse_and_map(np, 0);
+	esw->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(esw->base))
+		return PTR_ERR(esw->base);
+
+	port_map = of_get_property(np, "mediatek,portmap", NULL);
+	if (port_map)
+		esw->port_map = be32_to_cpu(*port_map);
+
+	port_disable = of_get_property(np, "mediatek,portdisable", NULL);
+	if (port_disable)
+		esw->port_disable = be32_to_cpu(*port_disable);
+
+	reg_init = of_get_property(np, "ralink,fct2", NULL);
+	if (reg_init)
+		esw->reg_initval_fct2 = be32_to_cpu(*reg_init);
+
+	reg_init = of_get_property(np, "ralink,fpa2", NULL);
+	if (reg_init)
+		esw->reg_initval_fpa2 = be32_to_cpu(*reg_init);
+
+	reg_init = of_get_property(np, "mediatek,led_polarity", NULL);
+	if (reg_init)
+		esw->reg_led_polarity = be32_to_cpu(*reg_init);
+
+	swdev = &esw->swdev;
+	swdev->of_node = pdev->dev.of_node;
+	swdev->name = "rt305x-esw";
+	swdev->alias = "rt305x";
+	swdev->cpu_port = RT305X_ESW_PORT6;
+	swdev->ports = RT305X_ESW_NUM_PORTS;
+	swdev->vlans = RT305X_ESW_NUM_VIDS;
+	swdev->ops = &esw_ops;
+
+	ret = register_switch(swdev, NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "register_switch failed\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, esw);
+
+	spin_lock_init(&esw->reg_rw_lock);
+
+	esw_hw_init(esw);
+
+	reg_init = of_get_property(np, "ralink,rgmii", NULL);
+	if (reg_init && be32_to_cpu(*reg_init) == 1) {
+		/* 
+		 * External switch connected to RGMII interface. 
+		 * Unregister the switch device after initialization. 
+		 */
+		dev_err(&pdev->dev, "RGMII mode, not exporting switch device.\n");
+		unregister_switch(&esw->swdev);
+		platform_set_drvdata(pdev, NULL);
+		return -ENODEV;
+	}
+
+	ret = devm_request_irq(&pdev->dev, esw->irq, esw_interrupt, 0, "esw",
+			       esw);
+
+	if (!ret) {
+		esw_w32(esw, RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_ISR);
+		esw_w32(esw, ~RT305X_ESW_PORT_ST_CHG, RT305X_ESW_REG_IMR);
+	}
+
+	return ret;
+}
+
+static int esw_remove(struct platform_device *pdev)
+{
+	struct rt305x_esw *esw = platform_get_drvdata(pdev);
+
+	if (esw) {
+		esw_w32(esw, ~0, RT305X_ESW_REG_IMR);
+		platform_set_drvdata(pdev, NULL);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ralink_esw_match[] = {
+	{ .compatible = "ralink,rt3050-esw" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ralink_esw_match);
+
+static struct platform_driver esw_driver = {
+	.probe = esw_probe,
+	.remove = esw_remove,
+	.driver = {
+		.name = "rt3050-esw",
+		.owner = THIS_MODULE,
+		.of_match_table = ralink_esw_match,
+	},
+};
+
+module_platform_driver(esw_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Switch driver for RT305X SoC");
+MODULE_VERSION(MTK_FE_DRV_VERSION);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h
new file mode 100644
index 0000000..bbc8fbd
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.h
@@ -0,0 +1,29 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef _RALINK_ESW_RT3052_H__
+#define _RALINK_ESW_RT3052_H__
+
+#ifdef CONFIG_NET_RALINK_ESW_RT3052
+
+int __init mtk_switch_init(void);
+void mtk_switch_exit(void);
+
+#else
+
+static inline int __init mtk_switch_init(void) { return 0; }
+static inline void mtk_switch_exit(void) { }
+
+#endif
+#endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c
new file mode 100644
index 0000000..5732c28
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.c
@@ -0,0 +1,230 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include "mtk_eth_soc.h"
+
+static const char fe_gdma_str[][ETH_GSTRING_LEN] = {
+#define _FE(x...)	# x,
+FE_STAT_REG_DECLARE
+#undef _FE
+};
+
+static int fe_get_link_ksettings(struct net_device *ndev,
+			   struct ethtool_link_ksettings *cmd)
+{
+	struct fe_priv *priv = netdev_priv(ndev);
+
+	if (!priv->phy_dev)
+		return -ENODEV;
+
+	if (priv->phy_flags == FE_PHY_FLAG_ATTACH) {
+		if (phy_read_status(priv->phy_dev))
+			return -ENODEV;
+	}
+
+	phy_ethtool_ksettings_get(ndev->phydev, cmd);
+
+	return 0;
+}
+
+static int fe_set_link_ksettings(struct net_device *ndev,
+			   const struct ethtool_link_ksettings *cmd)
+{
+	struct fe_priv *priv = netdev_priv(ndev);
+
+	if (!priv->phy_dev)
+		goto out_sset;
+
+	if (cmd->base.phy_address != priv->phy_dev->mdio.addr) {
+		if (priv->phy->phy_node[cmd->base.phy_address]) {
+			priv->phy_dev = priv->phy->phy[cmd->base.phy_address];
+			priv->phy_flags = FE_PHY_FLAG_PORT;
+		} else if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, cmd->base.phy_address)) {
+			priv->phy_dev = mdiobus_get_phy(priv->mii_bus, cmd->base.phy_address);
+			priv->phy_flags = FE_PHY_FLAG_ATTACH;
+		} else {
+			goto out_sset;
+		}
+	}
+
+	return phy_ethtool_ksettings_set(ndev->phydev, cmd);
+
+out_sset:
+	return -ENODEV;
+}
+
+static void fe_get_drvinfo(struct net_device *dev,
+			   struct ethtool_drvinfo *info)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_soc_data *soc = priv->soc;
+
+	strlcpy(info->driver, priv->dev->driver->name, sizeof(info->driver));
+	strlcpy(info->version, MTK_FE_DRV_VERSION, sizeof(info->version));
+	strlcpy(info->bus_info, dev_name(priv->dev), sizeof(info->bus_info));
+
+	if (soc->reg_table[FE_REG_FE_COUNTER_BASE])
+		info->n_stats = ARRAY_SIZE(fe_gdma_str);
+}
+
+static u32 fe_get_msglevel(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	return priv->msg_enable;
+}
+
+static void fe_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	priv->msg_enable = value;
+}
+
+static int fe_nway_reset(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	if (!priv->phy_dev)
+		goto out_nway_reset;
+
+	return genphy_restart_aneg(priv->phy_dev);
+
+out_nway_reset:
+	return -EOPNOTSUPP;
+}
+
+static u32 fe_get_link(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	int err;
+
+	if (!priv->phy_dev)
+		goto out_get_link;
+
+	if (priv->phy_flags == FE_PHY_FLAG_ATTACH) {
+		err = genphy_update_link(priv->phy_dev);
+		if (err)
+			goto out_get_link;
+	}
+
+	return priv->phy_dev->link;
+
+out_get_link:
+	return ethtool_op_get_link(dev);
+}
+
+static int fe_set_ringparam(struct net_device *dev,
+			    struct ethtool_ringparam *ring)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	if ((ring->tx_pending < 2) ||
+	    (ring->rx_pending < 2) ||
+	    (ring->rx_pending > MAX_DMA_DESC) ||
+	    (ring->tx_pending > MAX_DMA_DESC))
+		return -EINVAL;
+
+	dev->netdev_ops->ndo_stop(dev);
+
+	priv->tx_ring.tx_ring_size = BIT(fls(ring->tx_pending) - 1);
+	priv->rx_ring.rx_ring_size = BIT(fls(ring->rx_pending) - 1);
+
+	dev->netdev_ops->ndo_open(dev);
+
+	return 0;
+}
+
+static void fe_get_ringparam(struct net_device *dev,
+			     struct ethtool_ringparam *ring)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	ring->rx_max_pending = MAX_DMA_DESC;
+	ring->tx_max_pending = MAX_DMA_DESC;
+	ring->rx_pending = priv->rx_ring.rx_ring_size;
+	ring->tx_pending = priv->tx_ring.tx_ring_size;
+}
+
+static void fe_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, *fe_gdma_str, sizeof(fe_gdma_str));
+		break;
+	}
+}
+
+static int fe_get_sset_count(struct net_device *dev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(fe_gdma_str);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void fe_get_ethtool_stats(struct net_device *dev,
+				 struct ethtool_stats *stats, u64 *data)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_hw_stats *hwstats = priv->hw_stats;
+	u64 *data_src, *data_dst;
+	unsigned int start;
+	int i;
+
+	if (netif_running(dev) && netif_device_present(dev)) {
+		if (spin_trylock(&hwstats->stats_lock)) {
+			fe_stats_update(priv);
+			spin_unlock(&hwstats->stats_lock);
+		}
+	}
+
+	do {
+		data_src = &hwstats->tx_bytes;
+		data_dst = data;
+		start = u64_stats_fetch_begin_irq(&hwstats->syncp);
+
+		for (i = 0; i < ARRAY_SIZE(fe_gdma_str); i++)
+			*data_dst++ = *data_src++;
+
+	} while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
+}
+
+static struct ethtool_ops fe_ethtool_ops = {
+	.get_link_ksettings	= fe_get_link_ksettings,
+	.set_link_ksettings	= fe_set_link_ksettings,
+	.get_drvinfo		= fe_get_drvinfo,
+	.get_msglevel		= fe_get_msglevel,
+	.set_msglevel		= fe_set_msglevel,
+	.nway_reset		= fe_nway_reset,
+	.get_link		= fe_get_link,
+	.set_ringparam		= fe_set_ringparam,
+	.get_ringparam		= fe_get_ringparam,
+};
+
+void fe_set_ethtool_ops(struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+	struct fe_soc_data *soc = priv->soc;
+
+	if (soc->reg_table[FE_REG_FE_COUNTER_BASE]) {
+		fe_ethtool_ops.get_strings = fe_get_strings;
+		fe_ethtool_ops.get_sset_count = fe_get_sset_count;
+		fe_ethtool_ops.get_ethtool_stats = fe_get_ethtool_stats;
+	}
+
+	netdev->ethtool_ops = &fe_ethtool_ops;
+}
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.h
new file mode 100644
index 0000000..6fd16f0
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/ethtool.h
@@ -0,0 +1,22 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef FE_ETHTOOL_H
+#define FE_ETHTOOL_H
+
+#include <linux/ethtool.h>
+
+void fe_set_ethtool_ops(struct net_device *netdev);
+
+#endif /* FE_ETHTOOL_H */
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
new file mode 100644
index 0000000..7c91e58
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.c
@@ -0,0 +1,280 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mii.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#include <ralink_regs.h>
+
+#include "mtk_eth_soc.h"
+#include "gsw_mt7620.h"
+
+void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg)
+{
+	iowrite32(val, gsw->base + reg);
+}
+
+u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg)
+{
+	return ioread32(gsw->base + reg);
+}
+
+static irqreturn_t gsw_interrupt_mt7620(int irq, void *_priv)
+{
+	struct fe_priv *priv = (struct fe_priv *)_priv;
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+	u32 status;
+	int i, max = (gsw->port4_ephy) ? (4) : (3);
+
+	status = mtk_switch_r32(gsw, GSW_REG_ISR);
+	if (status & PORT_IRQ_ST_CHG)
+		for (i = 0; i <= max; i++) {
+			u32 status = mtk_switch_r32(gsw, GSW_REG_PORT_STATUS(i));
+			int link = status & 0x1;
+
+			if (link != priv->link[i])
+				mt7620_print_link_state(priv, i, link,
+							(status >> 2) & 3,
+							(status & 0x2));
+
+			priv->link[i] = link;
+		}
+	mt7620_handle_carrier(priv);
+	mtk_switch_w32(gsw, status, GSW_REG_ISR);
+
+	return IRQ_HANDLED;
+}
+
+static void mt7620_hw_init(struct mt7620_gsw *gsw)
+{
+	u32 i;
+	u32 val;
+	u32 is_BGA = (rt_sysc_r32(SYSC_REG_CHIP_REV_ID) >> 16) & 1;
+
+	/* Internal ethernet requires PCIe RC mode */
+	rt_sysc_w32(rt_sysc_r32(SYSC_REG_CFG1) | PCIE_RC_MODE, SYSC_REG_CFG1);
+
+	mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_CKGCR) & ~(0x3 << 4), GSW_REG_CKGCR);
+
+	/* Enable MIB stats */
+	mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_MIB_CNT_EN) | (1 << 1), GSW_REG_MIB_CNT_EN);
+
+	if (gsw->ephy_disable) {
+		mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_GPC1) |
+			(gsw->ephy_base << 16) | (0x1f << 24),
+			GSW_REG_GPC1);
+
+		pr_info("gsw: internal ephy disabled\n");
+	} else if (gsw->ephy_base) {
+		mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_GPC1) |
+			(gsw->ephy_base << 16),
+			GSW_REG_GPC1);
+		fe_reset(MT7620A_RESET_EPHY);
+
+		pr_info("gsw: ephy base address: %d\n", gsw->ephy_base);
+	}
+
+	/* global page 4 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0x4000);
+
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 17, 0x7444);
+	if (is_BGA)
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 19, 0x0114);
+	else
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 19, 0x0117);
+
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 22, 0x10cf);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 25, 0x6212);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 26, 0x0777);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 29, 0x4000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 28, 0xc077);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 24, 0x0000);
+
+	/* global page 3 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0x3000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 17, 0x4838);
+
+	/* global page 2 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0x2000);
+	if (is_BGA) {
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 21, 0x0515);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 22, 0x0053);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 23, 0x00bf);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 24, 0x0aaf);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 25, 0x0fad);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 26, 0x0fc1);
+	} else {
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 21, 0x0517);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 22, 0x0fd2);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 23, 0x00bf);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 24, 0x0aab);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 25, 0x00ae);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 1, 26, 0x0fff);
+	}
+	/* global page 1 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0x1000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 17, 0xe7f8);
+
+	/* turn on all PHYs */
+	for (i = 0; i <= 4; i++) {
+		val = _mt7620_mii_read(gsw, gsw->ephy_base + i, MII_BMCR);
+		val &= ~BMCR_PDOWN;
+		val |= BMCR_ANRESTART | BMCR_ANENABLE | BMCR_SPEED100;
+		_mt7620_mii_write(gsw, gsw->ephy_base + i, MII_BMCR, val);
+	}
+
+	/* global page 0 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0x8000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 0, 30, 0xa000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 30, 0xa000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 2, 30, 0xa000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 3, 30, 0xa000);
+
+	_mt7620_mii_write(gsw, gsw->ephy_base + 0, 4, 0x05e1);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 4, 0x05e1);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 2, 4, 0x05e1);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 3, 4, 0x05e1);
+
+	/* global page 2 */
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 31, 0xa000);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 0, 16, 0x1111);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 1, 16, 0x1010);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 2, 16, 0x1515);
+	_mt7620_mii_write(gsw, gsw->ephy_base + 3, 16, 0x0f0f);
+
+	/* CPU Port6 Force Link 1G, FC ON */
+	mtk_switch_w32(gsw, 0x5e33b, GSW_REG_PORT_PMCR(6));
+
+	/* Set Port 6 as CPU Port */
+	mtk_switch_w32(gsw, 0x7f7f7fe0, 0x0010);
+
+	/* setup port 4 */
+	if (gsw->port4_ephy) {
+		val = rt_sysc_r32(SYSC_REG_CFG1);
+
+		val |= 3 << 14;
+		rt_sysc_w32(val, SYSC_REG_CFG1);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 4, 30, 0xa000);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 4, 4, 0x05e1);
+		_mt7620_mii_write(gsw, gsw->ephy_base + 4, 16, 0x1313);
+		pr_info("gsw: setting port4 to ephy mode\n");
+	}
+}
+
+static const struct of_device_id mediatek_gsw_match[] = {
+	{ .compatible = "mediatek,mt7620-gsw" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mediatek_gsw_match);
+
+int mtk_gsw_init(struct fe_priv *priv)
+{
+	struct device_node *eth_node = priv->dev->of_node;
+	struct device_node *phy_node, *mdiobus_node;
+	struct device_node *np = priv->switch_np;
+	struct platform_device *pdev = of_find_device_by_node(np);
+	struct mt7620_gsw *gsw;
+	const __be32 *id;
+	u8 val;
+
+	if (!pdev)
+		return -ENODEV;
+
+	if (!of_device_is_compatible(np, mediatek_gsw_match->compatible))
+		return -EINVAL;
+
+	gsw = platform_get_drvdata(pdev);
+	priv->soc->swpriv = gsw;
+
+	gsw->ephy_disable = of_property_read_bool(np, "mediatek,ephy-disable");
+
+	mdiobus_node = of_get_child_by_name(eth_node, "mdio-bus");
+	if (mdiobus_node) {
+		for_each_child_of_node(mdiobus_node, phy_node) {
+			id = of_get_property(phy_node, "reg", NULL);
+			if (id && (be32_to_cpu(*id) == 0x1f))
+				gsw->ephy_disable = true;
+		}
+
+		of_node_put(mdiobus_node);
+	}
+
+	gsw->port4_ephy = !of_property_read_bool(np, "mediatek,port4-gmac");
+
+	if (of_property_read_u8(np, "mediatek,ephy-base", &val) == 0)
+		gsw->ephy_base = val;
+	else
+		gsw->ephy_base = 0;
+
+	mt7620_hw_init(gsw);
+
+	if (gsw->irq) {
+		request_irq(gsw->irq, gsw_interrupt_mt7620, 0,
+			    "gsw", priv);
+		mtk_switch_w32(gsw, ~PORT_IRQ_ST_CHG, GSW_REG_IMR);
+	}
+
+	return 0;
+}
+
+static int mt7620_gsw_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct mt7620_gsw *gsw;
+
+	gsw = devm_kzalloc(&pdev->dev, sizeof(struct mt7620_gsw), GFP_KERNEL);
+	if (!gsw)
+		return -ENOMEM;
+
+	gsw->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(gsw->base))
+		return PTR_ERR(gsw->base);
+
+	gsw->dev = &pdev->dev;
+
+	gsw->irq = platform_get_irq(pdev, 0);
+
+	platform_set_drvdata(pdev, gsw);
+
+	return 0;
+}
+
+static int mt7620_gsw_remove(struct platform_device *pdev)
+{
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver gsw_driver = {
+	.probe = mt7620_gsw_probe,
+	.remove = mt7620_gsw_remove,
+	.driver = {
+		.name = "mt7620-gsw",
+		.owner = THIS_MODULE,
+		.of_match_table = mediatek_gsw_match,
+	},
+};
+
+module_platform_driver(gsw_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("GBit switch driver for Mediatek MT7620 SoC");
+MODULE_VERSION(MTK_FE_DRV_VERSION);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
new file mode 100644
index 0000000..cb5d098
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/gsw_mt7620.h
@@ -0,0 +1,120 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef _RALINK_GSW_MT7620_H__
+#define _RALINK_GSW_MT7620_H__
+
+#define GSW_REG_PHY_TIMEOUT	(5 * HZ)
+
+#define MT7620A_GSW_REG_PIAC	0x7004
+
+#define GSW_NUM_VLANS		16
+#define GSW_NUM_VIDS		4096
+#define GSW_NUM_PORTS		7
+#define GSW_PORT6		6
+
+#define GSW_MDIO_ACCESS		BIT(31)
+#define GSW_MDIO_READ		BIT(19)
+#define GSW_MDIO_WRITE		BIT(18)
+#define GSW_MDIO_START		BIT(16)
+#define GSW_MDIO_ADDR_SHIFT	20
+#define GSW_MDIO_REG_SHIFT	25
+
+#define GSW_REG_MIB_CNT_EN	0x4000
+
+#define GSW_REG_PORT_PMCR(x)	(0x3000 + (x * 0x100))
+#define GSW_REG_PORT_STATUS(x)	(0x3008 + (x * 0x100))
+#define GSW_REG_SMACCR0		0x3fE4
+#define GSW_REG_SMACCR1		0x3fE8
+#define GSW_REG_CKGCR		0x3ff0
+
+#define GSW_REG_IMR		0x7008
+#define GSW_REG_ISR		0x700c
+#define GSW_REG_GPC1		0x7014
+#define GSW_REG_GPC2		0x701c
+
+#define GSW_REG_GPCx_TXDELAY	BIT(3)
+#define GSW_REG_GPCx_RXDELAY	BIT(2)
+
+#define GSW_REG_MAC_P0_MCR	0x100
+#define GSW_REG_MAC_P1_MCR	0x200
+
+// Global MAC control register
+#define GSW_REG_GMACCR		0x30E0
+
+#define SYSC_REG_CHIP_REV_ID	0x0c
+#define SYSC_REG_CFG1		0x14
+#define PCIE_RC_MODE		BIT(8)
+#define SYSC_PAD_RGMII2_MDIO	0x58
+#define SYSC_GPIO_MODE		0x60
+
+#define PORT_IRQ_ST_CHG		0x7f
+
+#define ESW_PHY_POLLING		0x7000
+
+#define	PMCR_IPG		BIT(18)
+#define	PMCR_MAC_MODE		BIT(16)
+#define	PMCR_FORCE		BIT(15)
+#define	PMCR_TX_EN		BIT(14)
+#define	PMCR_RX_EN		BIT(13)
+#define	PMCR_BACKOFF		BIT(9)
+#define	PMCR_BACKPRES		BIT(8)
+#define	PMCR_RX_FC		BIT(5)
+#define	PMCR_TX_FC		BIT(4)
+#define	PMCR_SPEED(_x)		(_x << 2)
+#define	PMCR_DUPLEX		BIT(1)
+#define	PMCR_LINK		BIT(0)
+
+#define PHY_AN_EN		BIT(31)
+#define PHY_PRE_EN		BIT(30)
+#define PMY_MDC_CONF(_x)	((_x & 0x3f) << 24)
+
+
+enum {
+	/* Global attributes. */
+	GSW_ATTR_ENABLE_VLAN,
+	/* Port attributes. */
+	GSW_ATTR_PORT_UNTAG,
+};
+
+struct mt7620_gsw {
+	struct device		*dev;
+	void __iomem		*base;
+	int			irq;
+	bool			ephy_disable;
+	bool			port4_ephy;
+	unsigned long int	autopoll;
+	u16			ephy_base;
+};
+
+void mtk_switch_w32(struct mt7620_gsw *gsw, u32 val, unsigned reg);
+u32 mtk_switch_r32(struct mt7620_gsw *gsw, unsigned reg);
+int mtk_gsw_init(struct fe_priv *priv);
+
+int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
+int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
+void mt7620_mdio_link_adjust(struct fe_priv *priv, int port);
+int mt7620_has_carrier(struct fe_priv *priv);
+void mt7620_print_link_state(struct fe_priv *priv, int port, int link,
+			     int speed, int duplex);
+
+void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val);
+u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg);
+
+u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr,
+			     u32 phy_register, u32 write_data);
+u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg);
+void mt7620_handle_carrier(struct fe_priv *priv);
+
+#endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
new file mode 100644
index 0000000..f5b827e
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
@@ -0,0 +1,273 @@
+/*   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; version 2 of the License
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/phy.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio.h"
+
+static int fe_mdio_reset(struct mii_bus *bus)
+{
+	/* TODO */
+	return 0;
+}
+
+static void fe_phy_link_adjust(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&priv->phy->lock, flags);
+	for (i = 0; i < 8; i++) {
+		if (priv->phy->phy_node[i]) {
+			struct phy_device *phydev = priv->phy->phy[i];
+			int status_change = 0;
+
+			if (phydev->link)
+				if (priv->phy->duplex[i] != phydev->duplex ||
+				    priv->phy->speed[i] != phydev->speed)
+					status_change = 1;
+
+			if (phydev->link != priv->link[i])
+				status_change = 1;
+
+			switch (phydev->speed) {
+			case SPEED_1000:
+			case SPEED_100:
+			case SPEED_10:
+				priv->link[i] = phydev->link;
+				priv->phy->duplex[i] = phydev->duplex;
+				priv->phy->speed[i] = phydev->speed;
+
+				if (status_change &&
+				    priv->soc->mdio_adjust_link)
+					priv->soc->mdio_adjust_link(priv, i);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&priv->phy->lock, flags);
+}
+
+int fe_connect_phy_node(struct fe_priv *priv, struct device_node *phy_node, int port)
+{
+	const __be32 *_phy_addr = NULL;
+	struct phy_device *phydev;
+	int phy_mode;
+
+	_phy_addr = of_get_property(phy_node, "reg", NULL);
+
+	if (!_phy_addr || (be32_to_cpu(*_phy_addr) >= 0x20)) {
+		pr_err("%s: invalid phy id\n", phy_node->name);
+		return -EINVAL;
+	}
+
+	phy_mode = of_get_phy_mode(phy_node);
+	if (phy_mode < 0) {
+		dev_err(priv->dev, "incorrect phy-mode %d\n", phy_mode);
+		priv->phy->phy_node[port] = NULL;
+		return -EINVAL;
+	}
+
+	phydev = of_phy_connect(priv->netdev, phy_node, fe_phy_link_adjust,
+				0, phy_mode);
+	if (!phydev) {
+		dev_err(priv->dev, "could not connect to PHY\n");
+		priv->phy->phy_node[port] = NULL;
+		return -ENODEV;
+	}
+
+	phy_set_max_speed(phydev, SPEED_1000);
+	linkmode_copy(phydev->advertising, phydev->supported);
+	phydev->no_auto_carrier_off = 1;
+
+	dev_info(priv->dev,
+		 "connected port %d to PHY at %s [uid=%08x, driver=%s]\n",
+		 port, dev_name(&phydev->mdio.dev), phydev->phy_id,
+		 phydev->drv->name);
+
+	priv->phy->phy[port] = phydev;
+	priv->link[port] = 0;
+
+	return 0;
+}
+
+static void phy_init(struct fe_priv *priv, struct phy_device *phy)
+{
+	phy_attach(priv->netdev, dev_name(&phy->mdio.dev), PHY_INTERFACE_MODE_MII);
+
+	phy->autoneg = AUTONEG_ENABLE;
+	phy->speed = 0;
+	phy->duplex = 0;
+
+	phy_set_max_speed(phy, IS_ENABLED(CONFIG_NET_RALINK_MDIO_MT7620) ?
+				       SPEED_1000 :
+				       SPEED_100);
+	linkmode_copy(phy->advertising, phy->supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phy->advertising);
+
+	phy_start_aneg(phy);
+}
+
+static int fe_phy_connect(struct fe_priv *priv)
+{
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		if (priv->phy->phy_node[i]) {
+			if (!priv->phy_dev) {
+				priv->phy_dev = priv->phy->phy[i];
+				priv->phy_flags = FE_PHY_FLAG_PORT;
+			}
+		} else if (priv->mii_bus) {
+			struct phy_device *phydev;
+
+			phydev = mdiobus_get_phy(priv->mii_bus, i);
+			if (!phydev || phydev->attached_dev)
+				continue;
+
+			phy_init(priv, phydev);
+			if (!priv->phy_dev) {
+				priv->phy_dev = mdiobus_get_phy(priv->mii_bus, i);
+				priv->phy_flags = FE_PHY_FLAG_ATTACH;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void fe_phy_disconnect(struct fe_priv *priv)
+{
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		if (priv->phy->phy_fixed[i]) {
+			spin_lock_irqsave(&priv->phy->lock, flags);
+			priv->link[i] = 0;
+			if (priv->soc->mdio_adjust_link)
+				priv->soc->mdio_adjust_link(priv, i);
+			spin_unlock_irqrestore(&priv->phy->lock, flags);
+		} else if (priv->phy->phy[i]) {
+			phy_disconnect(priv->phy->phy[i]);
+		} else if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, i)) {
+			phy_detach(mdiobus_get_phy(priv->mii_bus, i));
+		}
+}
+
+static void fe_phy_start(struct fe_priv *priv)
+{
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < 8; i++) {
+		if (priv->phy->phy_fixed[i]) {
+			spin_lock_irqsave(&priv->phy->lock, flags);
+			priv->link[i] = 1;
+			if (priv->soc->mdio_adjust_link)
+				priv->soc->mdio_adjust_link(priv, i);
+			spin_unlock_irqrestore(&priv->phy->lock, flags);
+		} else if (priv->phy->phy[i]) {
+			phy_start(priv->phy->phy[i]);
+		}
+	}
+}
+
+static void fe_phy_stop(struct fe_priv *priv)
+{
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		if (priv->phy->phy_fixed[i]) {
+			spin_lock_irqsave(&priv->phy->lock, flags);
+			priv->link[i] = 0;
+			if (priv->soc->mdio_adjust_link)
+				priv->soc->mdio_adjust_link(priv, i);
+			spin_unlock_irqrestore(&priv->phy->lock, flags);
+		} else if (priv->phy->phy[i]) {
+			phy_stop(priv->phy->phy[i]);
+		}
+}
+
+static struct fe_phy phy_ralink = {
+	.connect = fe_phy_connect,
+	.disconnect = fe_phy_disconnect,
+	.start = fe_phy_start,
+	.stop = fe_phy_stop,
+};
+
+int fe_mdio_init(struct fe_priv *priv)
+{
+	struct device_node *mii_np;
+	int err;
+
+	if (!priv->soc->mdio_read || !priv->soc->mdio_write)
+		return 0;
+
+	spin_lock_init(&phy_ralink.lock);
+	priv->phy = &phy_ralink;
+
+	mii_np = of_get_child_by_name(priv->dev->of_node, "mdio-bus");
+	if (!mii_np) {
+		dev_err(priv->dev, "no %s child node found", "mdio-bus");
+		err = 0;
+		goto err_no_bus;
+	}
+
+	if (!of_device_is_available(mii_np)) {
+		err = 0;
+		goto err_put_node;
+	}
+
+	priv->mii_bus = mdiobus_alloc();
+	if (!priv->mii_bus) {
+		err = -ENOMEM;
+		goto err_put_node;
+	}
+
+	priv->mii_bus->name = "mdio";
+	priv->mii_bus->read = priv->soc->mdio_read;
+	priv->mii_bus->write = priv->soc->mdio_write;
+	priv->mii_bus->reset = fe_mdio_reset;
+	priv->mii_bus->priv = priv;
+	priv->mii_bus->parent = priv->dev;
+
+	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name);
+	err = of_mdiobus_register(priv->mii_bus, mii_np);
+	if (err)
+		goto err_free_bus;
+
+	return 0;
+
+err_free_bus:
+	kfree(priv->mii_bus);
+err_put_node:
+	of_node_put(mii_np);
+err_no_bus:
+	dev_err(priv->dev, "%s disabled", "mdio-bus");
+	priv->mii_bus = NULL;
+	return err;
+}
+
+void fe_mdio_cleanup(struct fe_priv *priv)
+{
+	if (!priv->mii_bus)
+		return;
+
+	mdiobus_unregister(priv->mii_bus);
+	of_node_put(priv->mii_bus->dev.of_node);
+	kfree(priv->mii_bus);
+}
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.h
new file mode 100644
index 0000000..d4a2a40
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.h
@@ -0,0 +1,28 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef _RALINK_MDIO_H__
+#define _RALINK_MDIO_H__
+
+#ifdef CONFIG_NET_RALINK_MDIO
+int fe_mdio_init(struct fe_priv *priv);
+void fe_mdio_cleanup(struct fe_priv *priv);
+int fe_connect_phy_node(struct fe_priv *priv,
+			struct device_node *phy_node,
+			int port);
+#else
+static inline int fe_mdio_init(struct fe_priv *priv) { return 0; }
+static inline void fe_mdio_cleanup(struct fe_priv *priv) {}
+#endif
+#endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_mt7620.c
new file mode 100644
index 0000000..9efe789
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_mt7620.c
@@ -0,0 +1,168 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include "mtk_eth_soc.h"
+#include "gsw_mt7620.h"
+#include "mdio.h"
+
+static int mt7620_mii_busy_wait(struct mt7620_gsw *gsw)
+{
+	unsigned long t_start = jiffies;
+
+	while (1) {
+		if (!(mtk_switch_r32(gsw, MT7620A_GSW_REG_PIAC) & GSW_MDIO_ACCESS))
+			return 0;
+		if (time_after(jiffies, t_start + GSW_REG_PHY_TIMEOUT))
+			break;
+	}
+
+	dev_err(gsw->dev, "mdio: MDIO timeout\n");
+	return -1;
+}
+
+u32 _mt7620_mii_write(struct mt7620_gsw *gsw, u32 phy_addr,
+			     u32 phy_register, u32 write_data)
+{
+	if (mt7620_mii_busy_wait(gsw))
+		return -1;
+
+	write_data &= 0xffff;
+
+	mtk_switch_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_WRITE |
+		(phy_register << GSW_MDIO_REG_SHIFT) |
+		(phy_addr << GSW_MDIO_ADDR_SHIFT) | write_data,
+		MT7620A_GSW_REG_PIAC);
+
+	if (mt7620_mii_busy_wait(gsw))
+		return -1;
+
+	return 0;
+}
+
+u32 _mt7620_mii_read(struct mt7620_gsw *gsw, int phy_addr, int phy_reg)
+{
+	u32 d;
+
+	if (mt7620_mii_busy_wait(gsw))
+		return 0xffff;
+
+	mtk_switch_w32(gsw, GSW_MDIO_ACCESS | GSW_MDIO_START | GSW_MDIO_READ |
+		(phy_reg << GSW_MDIO_REG_SHIFT) |
+		(phy_addr << GSW_MDIO_ADDR_SHIFT),
+		MT7620A_GSW_REG_PIAC);
+
+	if (mt7620_mii_busy_wait(gsw))
+		return 0xffff;
+
+	d = mtk_switch_r32(gsw, MT7620A_GSW_REG_PIAC) & 0xffff;
+
+	return d;
+}
+
+int mt7620_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
+{
+	struct fe_priv *priv = bus->priv;
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+
+	return _mt7620_mii_write(gsw, phy_addr, phy_reg, val);
+}
+
+int mt7620_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+	struct fe_priv *priv = bus->priv;
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+
+	return _mt7620_mii_read(gsw, phy_addr, phy_reg);
+}
+
+void mt7530_mdio_w32(struct mt7620_gsw *gsw, u32 reg, u32 val)
+{
+	_mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
+	_mt7620_mii_write(gsw, 0x1f, (reg >> 2) & 0xf,  val & 0xffff);
+	_mt7620_mii_write(gsw, 0x1f, 0x10, val >> 16);
+}
+
+u32 mt7530_mdio_r32(struct mt7620_gsw *gsw, u32 reg)
+{
+	u16 high, low;
+
+	_mt7620_mii_write(gsw, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
+	low = _mt7620_mii_read(gsw, 0x1f, (reg >> 2) & 0xf);
+	high = _mt7620_mii_read(gsw, 0x1f, 0x10);
+
+	return (high << 16) | (low & 0xffff);
+}
+
+static unsigned char *fe_speed_str(int speed)
+{
+	switch (speed) {
+	case 2:
+	case SPEED_1000:
+		return "1000";
+	case 1:
+	case SPEED_100:
+		return "100";
+	case 0:
+	case SPEED_10:
+		return "10";
+	}
+
+	return "? ";
+}
+
+int mt7620_has_carrier(struct fe_priv *priv)
+{
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+	int i;
+
+	for (i = 0; i < GSW_PORT6; i++)
+		if (mtk_switch_r32(gsw, GSW_REG_PORT_STATUS(i)) & 0x1)
+			return 1;
+	return 0;
+}
+
+
+void mt7620_handle_carrier(struct fe_priv *priv)
+{
+	if (!priv->phy)
+		return;
+
+	if (mt7620_has_carrier(priv))
+		netif_carrier_on(priv->netdev);
+	else
+		netif_carrier_off(priv->netdev);
+}
+
+void mt7620_print_link_state(struct fe_priv *priv, int port, int link,
+			     int speed, int duplex)
+{
+	if (link)
+		netdev_info(priv->netdev, "port %d link up (%sMbps/%s duplex)\n",
+			    port, fe_speed_str(speed),
+			    (duplex) ? "Full" : "Half");
+	else
+		netdev_info(priv->netdev, "port %d link down\n", port);
+}
+
+void mt7620_mdio_link_adjust(struct fe_priv *priv, int port)
+{
+	mt7620_print_link_state(priv, port, priv->link[port],
+				priv->phy->speed[port],
+				(priv->phy->duplex[port] == DUPLEX_FULL));
+	mt7620_handle_carrier(priv);
+}
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.c
new file mode 100644
index 0000000..8d82c8f
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.c
@@ -0,0 +1,222 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio_rt2880.h"
+#include "mdio.h"
+
+#define FE_MDIO_RETRY	1000
+
+static unsigned char *rt2880_speed_str(struct fe_priv *priv)
+{
+	switch (priv->phy->speed[0]) {
+	case SPEED_1000:
+		return "1000";
+	case SPEED_100:
+		return "100";
+	case SPEED_10:
+		return "10";
+	}
+
+	return "?";
+}
+
+void rt2880_mdio_link_adjust(struct fe_priv *priv, int port)
+{
+	u32 mdio_cfg;
+
+	if (!priv->link[0]) {
+		netif_carrier_off(priv->netdev);
+		netdev_info(priv->netdev, "link down\n");
+		return;
+	}
+
+	mdio_cfg = FE_MDIO_CFG_TX_CLK_SKEW_200 |
+		   FE_MDIO_CFG_RX_CLK_SKEW_200 |
+		   FE_MDIO_CFG_GP1_FRC_EN;
+
+	if (priv->phy->duplex[0] == DUPLEX_FULL)
+		mdio_cfg |= FE_MDIO_CFG_GP1_DUPLEX;
+
+	if (priv->phy->tx_fc[0])
+		mdio_cfg |= FE_MDIO_CFG_GP1_FC_TX;
+
+	if (priv->phy->rx_fc[0])
+		mdio_cfg |= FE_MDIO_CFG_GP1_FC_RX;
+
+	switch (priv->phy->speed[0]) {
+	case SPEED_10:
+		mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_10;
+		break;
+	case SPEED_100:
+		mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_100;
+		break;
+	case SPEED_1000:
+		mdio_cfg |= FE_MDIO_CFG_GP1_SPEED_1000;
+		break;
+	default:
+		BUG();
+	}
+
+	fe_w32(mdio_cfg, FE_MDIO_CFG);
+
+	netif_carrier_on(priv->netdev);
+	netdev_info(priv->netdev, "link up (%sMbps/%s duplex)\n",
+		    rt2880_speed_str(priv),
+		    (priv->phy->duplex[0] == DUPLEX_FULL) ? "Full" : "Half");
+}
+
+static int rt2880_mdio_wait_ready(struct fe_priv *priv)
+{
+	int retries;
+
+	retries = FE_MDIO_RETRY;
+	while (1) {
+		u32 t;
+
+		t = fe_r32(FE_MDIO_ACCESS);
+		if ((t & BIT(31)) == 0)
+			return 0;
+
+		if (retries-- == 0)
+			break;
+
+		udelay(1);
+	}
+
+	dev_err(priv->dev, "MDIO operation timed out\n");
+	return -ETIMEDOUT;
+}
+
+int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+	struct fe_priv *priv = bus->priv;
+	int err;
+	u32 t;
+
+	err = rt2880_mdio_wait_ready(priv);
+	if (err)
+		return 0xffff;
+
+	t = (phy_addr << 24) | (phy_reg << 16);
+	fe_w32(t, FE_MDIO_ACCESS);
+	t |= BIT(31);
+	fe_w32(t, FE_MDIO_ACCESS);
+
+	err = rt2880_mdio_wait_ready(priv);
+	if (err)
+		return 0xffff;
+
+	pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
+		 phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
+
+	return fe_r32(FE_MDIO_ACCESS) & 0xffff;
+}
+
+int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val)
+{
+	struct fe_priv *priv = bus->priv;
+	int err;
+	u32 t;
+
+	pr_debug("%s: addr=%04x, reg=%04x, value=%04x\n", __func__,
+		 phy_addr, phy_reg, fe_r32(FE_MDIO_ACCESS) & 0xffff);
+
+	err = rt2880_mdio_wait_ready(priv);
+	if (err)
+		return err;
+
+	t = (1 << 30) | (phy_addr << 24) | (phy_reg << 16) | val;
+	fe_w32(t, FE_MDIO_ACCESS);
+	t |= BIT(31);
+	fe_w32(t, FE_MDIO_ACCESS);
+
+	return rt2880_mdio_wait_ready(priv);
+}
+
+void rt2880_port_init(struct fe_priv *priv, struct device_node *np)
+{
+	const __be32 *id = of_get_property(np, "reg", NULL);
+	const __be32 *link;
+	int size;
+	int phy_mode;
+
+	if (!id || (be32_to_cpu(*id) != 0)) {
+		pr_err("%s: invalid port id\n", np->name);
+		return;
+	}
+
+	priv->phy->phy_fixed[0] = of_get_property(np,
+						  "mediatek,fixed-link", &size);
+	if (priv->phy->phy_fixed[0] &&
+	    (size != (4 * sizeof(*priv->phy->phy_fixed[0])))) {
+		pr_err("%s: invalid fixed link property\n", np->name);
+		priv->phy->phy_fixed[0] = NULL;
+		return;
+	}
+
+	phy_mode = of_get_phy_mode(np);
+	switch (phy_mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+		break;
+	case PHY_INTERFACE_MODE_MII:
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		break;
+	default:
+		if (!priv->phy->phy_fixed[0])
+			dev_err(priv->dev, "port %d - invalid phy mode\n",
+				priv->phy->speed[0]);
+		break;
+	}
+
+	priv->phy->phy_node[0] = of_parse_phandle(np, "phy-handle", 0);
+	if (!priv->phy->phy_node[0] && !priv->phy->phy_fixed[0])
+		return;
+
+	if (priv->phy->phy_fixed[0]) {
+		link = priv->phy->phy_fixed[0];
+		priv->phy->speed[0] = be32_to_cpup(link++);
+		priv->phy->duplex[0] = be32_to_cpup(link++);
+		priv->phy->tx_fc[0] = be32_to_cpup(link++);
+		priv->phy->rx_fc[0] = be32_to_cpup(link++);
+
+		priv->link[0] = 1;
+		switch (priv->phy->speed[0]) {
+		case SPEED_10:
+			break;
+		case SPEED_100:
+			break;
+		case SPEED_1000:
+			break;
+		default:
+			dev_err(priv->dev, "invalid link speed: %d\n",
+				priv->phy->speed[0]);
+			priv->phy->phy_fixed[0] = 0;
+			return;
+		}
+		dev_info(priv->dev, "using fixed link parameters\n");
+		rt2880_mdio_link_adjust(priv, 0);
+		return;
+	}
+
+	if (priv->phy->phy_node[0] && mdiobus_get_phy(priv->mii_bus, 0))
+		fe_connect_phy_node(priv, priv->phy->phy_node[0], 0);
+}
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.h
new file mode 100644
index 0000000..70e3442
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mdio_rt2880.h
@@ -0,0 +1,23 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef _RALINK_MDIO_RT2880_H__
+#define _RALINK_MDIO_RT2880_H__
+
+void rt2880_mdio_link_adjust(struct fe_priv *priv, int port);
+int rt2880_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg);
+int rt2880_mdio_write(struct mii_bus *bus, int phy_addr, int phy_reg, u16 val);
+void rt2880_port_init(struct fe_priv *priv, struct device_node *np);
+
+#endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
new file mode 100644
index 0000000..b4632d3
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
@@ -0,0 +1,1053 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
+ */
+
+#include <linux/if.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/netlink.h>
+#include <linux/bitops.h>
+#include <net/genetlink.h>
+#include <linux/switch.h>
+#include <linux/delay.h>
+#include <linux/phy.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/lockdep.h>
+#include <linux/workqueue.h>
+#include <linux/of_device.h>
+#include <asm/byteorder.h>
+
+#include "mt7530.h"
+
+#define MT7530_CPU_PORT		6
+#define MT7530_NUM_PORTS	8
+#define MT7530_NUM_VLANS	16
+#define MT7530_MAX_VID		4095
+#define MT7530_MIN_VID		0
+#define MT7530_NUM_ARL_RECORDS 2048
+#define ARL_LINE_LENGTH		30
+
+#define MT7530_PORT_MIB_TXB_ID	2	/* TxGOC */
+#define MT7530_PORT_MIB_RXB_ID	6	/* RxGOC */
+
+/* registers */
+#define REG_ESW_WT_MAC_MFC		0x10
+
+#define REG_ESW_WT_MAC_MFC_MIRROR_ENABLE	BIT(3)
+#define REG_ESW_WT_MAC_MFC_MIRROR_DEST_MASK	0x07
+
+#define REG_ESW_VLAN_VTCR		0x90
+#define REG_ESW_VLAN_VAWD1		0x94
+#define REG_ESW_VLAN_VAWD2		0x98
+#define REG_ESW_VLAN_VTIM(x)	(0x100 + 4 * ((x) / 2))
+
+#define REG_ESW_WT_MAC_ATC  0x80
+#define REG_ESW_TABLE_ATRD  0x8C
+#define REG_ESW_TABLE_TSRA1 0x84
+#define REG_ESW_TABLE_TSRA2 0x88
+
+#define REG_MAC_ATC_START  0x8004
+#define REG_MAC_ATC_NEXT   0x8005
+
+#define REG_MAC_ATC_BUSY      0x8000U
+#define REG_MAC_ATC_SRCH_HIT  0x2000U
+#define REG_MAC_ATC_SRCH_END  0x4000U
+#define REG_ATRD_VALID        0xff000000U
+#define REG_ATRD_PORT_MASK    0xff0U
+
+#define REG_ESW_VLAN_VAWD1_IVL_MAC	BIT(30)
+#define REG_ESW_VLAN_VAWD1_VTAG_EN	BIT(28)
+#define REG_ESW_VLAN_VAWD1_VALID	BIT(0)
+
+/* vlan egress mode */
+enum {
+	ETAG_CTRL_UNTAG	= 0,
+	ETAG_CTRL_TAG	= 2,
+	ETAG_CTRL_SWAP	= 1,
+	ETAG_CTRL_STACK	= 3,
+};
+
+#define REG_ESW_PORT_PCR(x)	(0x2004 | ((x) << 8))
+#define REG_ESW_PORT_PVC(x)	(0x2010 | ((x) << 8))
+#define REG_ESW_PORT_PPBV1(x)	(0x2014 | ((x) << 8))
+
+#define REG_ESW_PORT_PCR_MIRROR_SRC_RX_BIT	BIT(8)
+#define REG_ESW_PORT_PCR_MIRROR_SRC_TX_BIT	BIT(9)
+#define REG_ESW_PORT_PCR_MIRROR_SRC_RX_MASK	0x0100
+#define REG_ESW_PORT_PCR_MIRROR_SRC_TX_MASK	0x0200
+
+#define REG_HWTRAP		0x7804
+
+#define MIB_DESC(_s , _o, _n)   \
+	{                       \
+		.size = (_s),   \
+		.offset = (_o), \
+		.name = (_n),   \
+	}
+
+struct mt7xxx_mib_desc {
+	unsigned int size;
+	unsigned int offset;
+	const char *name;
+};
+
+static const struct mt7xxx_mib_desc mt7620_mibs[] = {
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT0, "PPE_AC_BCNT0"),
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT0, "PPE_AC_PCNT0"),
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT63, "PPE_AC_BCNT63"),
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT63, "PPE_AC_PCNT63"),
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT0, "PPE_MTR_CNT0"),
+	MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT63, "PPE_MTR_CNT63"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GBCNT, "GDM1_TX_GBCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GPCNT, "GDM1_TX_GPCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_SKIPCNT, "GDM1_TX_SKIPCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_COLCNT, "GDM1_TX_COLCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GBCNT1, "GDM1_RX_GBCNT1"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GPCNT1, "GDM1_RX_GPCNT1"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_OERCNT, "GDM1_RX_OERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FERCNT, "GDM1_RX_FERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_SERCNT, "GDM1_RX_SERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_LERCNT, "GDM1_RX_LERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_CERCNT, "GDM1_RX_CERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FCCNT, "GDM1_RX_FCCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GBCNT, "GDM2_TX_GBCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GPCNT, "GDM2_TX_GPCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_SKIPCNT, "GDM2_TX_SKIPCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_COLCNT, "GDM2_TX_COLCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GBCNT, "GDM2_RX_GBCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GPCNT, "GDM2_RX_GPCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_OERCNT, "GDM2_RX_OERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FERCNT, "GDM2_RX_FERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_SERCNT, "GDM2_RX_SERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_LERCNT, "GDM2_RX_LERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_CERCNT, "GDM2_RX_CERCNT"),
+	MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FCCNT, "GDM2_RX_FCCNT")
+};
+
+static const struct mt7xxx_mib_desc mt7620_port_mibs[] = {
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_TGPCN,  "TxGPC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_TBOCN,  "TxBOC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_TGOCN,  "TxGOC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_TEPCN,  "TxEPC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_RGPCN,  "RxGPC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_RBOCN,  "RxBOC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_RGOCN,  "RxGOC"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC1N, "RxEPC1"),
+	MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC2N, "RxEPC2")
+};
+
+enum {
+	/* Global attributes. */
+	MT7530_ATTR_ENABLE_VLAN,
+};
+
+struct mt7530_port_entry {
+	u16	pvid;
+	bool	mirror_rx;
+	bool	mirror_tx;
+};
+
+struct mt7530_vlan_entry {
+	u16	vid;
+	u8	member;
+	u8	etags;
+};
+
+struct mt7530_priv {
+	void __iomem		*base;
+	struct mii_bus		*bus;
+	struct switch_dev	swdev;
+
+	u8			mirror_dest_port;
+	bool			global_vlan_enable;
+	struct mt7530_vlan_entry	vlan_entries[MT7530_NUM_VLANS];
+	struct mt7530_port_entry	port_entries[MT7530_NUM_PORTS];
+	char arl_buf[MT7530_NUM_ARL_RECORDS * ARL_LINE_LENGTH + 1];
+};
+
+struct mt7530_mapping {
+	char	*name;
+	u16	pvids[MT7530_NUM_PORTS];
+	u8	members[MT7530_NUM_VLANS];
+	u8	etags[MT7530_NUM_VLANS];
+	u16	vids[MT7530_NUM_VLANS];
+} mt7530_defaults[] = {
+	{
+		.name = "llllw",
+		.pvids = { 1, 1, 1, 1, 2, 1, 1 },
+		.members = { 0, 0x6f, 0x50 },
+		.etags = { 0, 0x40, 0x40 },
+		.vids = { 0, 1, 2 },
+	}, {
+		.name = "wllll",
+		.pvids = { 2, 1, 1, 1, 1, 1, 1 },
+		.members = { 0, 0x7e, 0x41 },
+		.etags = { 0, 0x40, 0x40 },
+		.vids = { 0, 1, 2 },
+	}, {
+		.name = "lwlll",
+		.pvids = { 1, 2, 1, 1, 1, 1, 1 },
+		.members = { 0, 0x7d, 0x42 },
+		.etags = { 0, 0x40, 0x40 },
+		.vids = { 0, 1, 2 },
+	},
+};
+
+struct mt7530_mapping*
+mt7530_find_mapping(struct device_node *np)
+{
+	const char *map;
+	int i;
+
+	if (of_property_read_string(np, "mediatek,portmap", &map))
+		return NULL;
+
+	for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++)
+		if (!strcmp(map, mt7530_defaults[i].name))
+			return &mt7530_defaults[i];
+
+	return NULL;
+}
+
+static void
+mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map)
+{
+	int i = 0;
+
+	for (i = 0; i < MT7530_NUM_PORTS; i++)
+		mt7530->port_entries[i].pvid = map->pvids[i];
+
+	for (i = 0; i < MT7530_NUM_VLANS; i++) {
+		mt7530->vlan_entries[i].member = map->members[i];
+		mt7530->vlan_entries[i].etags = map->etags[i];
+		mt7530->vlan_entries[i].vid = map->vids[i];
+	}
+}
+
+static int
+mt7530_reset_switch(struct switch_dev *dev)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	int i;
+
+	memset(priv->port_entries, 0, sizeof(priv->port_entries));
+	memset(priv->vlan_entries, 0, sizeof(priv->vlan_entries));
+
+	/* set default vid of each vlan to the same number of vlan, so the vid
+	 * won't need be set explicitly.
+	 */
+	for (i = 0; i < MT7530_NUM_VLANS; i++) {
+		priv->vlan_entries[i].vid = i;
+	}
+
+	return 0;
+}
+
+static int
+mt7530_get_vlan_enable(struct switch_dev *dev,
+			   const struct switch_attr *attr,
+			   struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	val->value.i = priv->global_vlan_enable;
+
+	return 0;
+}
+
+static int
+mt7530_set_vlan_enable(struct switch_dev *dev,
+			   const struct switch_attr *attr,
+			   struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	priv->global_vlan_enable = val->value.i != 0;
+
+	return 0;
+}
+
+static u32
+mt7530_r32(struct mt7530_priv *priv, u32 reg)
+{
+	u32 val;
+	if (priv->bus) {
+		u16 high, low;
+
+		mutex_lock(&priv->bus->mdio_lock);
+		__mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
+		low = __mdiobus_read(priv->bus, 0x1f, (reg >> 2) & 0xf);
+		high = __mdiobus_read(priv->bus, 0x1f, 0x10);
+		mutex_unlock(&priv->bus->mdio_lock);
+
+		return (high << 16) | (low & 0xffff);
+	}
+
+	val = ioread32(priv->base + reg);
+	pr_debug("MT7530 MDIO Read [%04x]=%08x\n", reg, val);
+
+	return val;
+}
+
+static void
+mt7530_w32(struct mt7530_priv *priv, u32 reg, u32 val)
+{
+	if (priv->bus) {
+		mutex_lock(&priv->bus->mdio_lock);
+		__mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
+		__mdiobus_write(priv->bus, 0x1f, (reg >> 2) & 0xf,  val & 0xffff);
+		__mdiobus_write(priv->bus, 0x1f, 0x10, val >> 16);
+		mutex_unlock(&priv->bus->mdio_lock);
+		return;
+	}
+
+	pr_debug("MT7530 MDIO Write[%04x]=%08x\n", reg, val);
+	iowrite32(val, priv->base + reg);
+}
+
+static void
+mt7530_vtcr(struct mt7530_priv *priv, u32 cmd, u32 val)
+{
+	int i;
+
+	mt7530_w32(priv, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val);
+
+	for (i = 0; i < 20; i++) {
+		u32 val = mt7530_r32(priv, REG_ESW_VLAN_VTCR);
+
+		if ((val & BIT(31)) == 0)
+			break;
+
+		udelay(1000);
+	}
+	if (i == 20)
+		printk("mt7530: vtcr timeout\n");
+}
+
+static int
+mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	if (port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	*val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(port));
+	*val &= 0xfff;
+
+	return 0;
+}
+
+static int
+mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	if (port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	if (pvid < MT7530_MIN_VID || pvid > MT7530_MAX_VID)
+		return -EINVAL;
+
+	priv->port_entries[port].pvid = pvid;
+
+	return 0;
+}
+
+static int
+mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	u32 member;
+	u32 etags;
+	int i;
+
+	val->len = 0;
+
+	if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS)
+		return -EINVAL;
+
+	mt7530_vtcr(priv, 0, val->port_vlan);
+
+	member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1);
+	member >>= 16;
+	member &= 0xff;
+
+	etags = mt7530_r32(priv, REG_ESW_VLAN_VAWD2);
+
+	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		struct switch_port *p;
+		int etag;
+
+		if (!(member & BIT(i)))
+			continue;
+
+		p = &val->value.ports[val->len++];
+		p->id = i;
+
+		etag = (etags >> (i * 2)) & 0x3;
+
+		if (etag == ETAG_CTRL_TAG)
+			p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
+		else if (etag != ETAG_CTRL_UNTAG)
+			printk("vlan %d port %d egress tag control neither untag nor tag: %d.\n",
+					val->port_vlan, i, etag);
+	}
+
+	return 0;
+}
+
+static int
+mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	u8 member = 0;
+	u8 etags = 0;
+	int i;
+
+	if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS ||
+			val->len > MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	for (i = 0; i < val->len; i++) {
+		struct switch_port *p = &val->value.ports[i];
+
+		if (p->id >= MT7530_NUM_PORTS)
+			return -EINVAL;
+
+		member |= BIT(p->id);
+
+		if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
+			etags |= BIT(p->id);
+	}
+	priv->vlan_entries[val->port_vlan].member = member;
+	priv->vlan_entries[val->port_vlan].etags = etags;
+
+	return 0;
+}
+
+static int
+mt7530_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	int vlan;
+	u16 vid;
+
+	vlan = val->port_vlan;
+	vid = (u16)val->value.i;
+
+	if (vlan < 0 || vlan >= MT7530_NUM_VLANS)
+		return -EINVAL;
+
+	if (vid < MT7530_MIN_VID || vid > MT7530_MAX_VID)
+		return -EINVAL;
+
+	priv->vlan_entries[vlan].vid = vid;
+	return 0;
+}
+
+static int
+mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	u32 vid;
+	int vlan;
+
+	vlan = val->port_vlan;
+
+	vid = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
+	if (vlan & 1)
+		vid = vid >> 12;
+	vid &= 0xfff;
+
+	val->value.i = vid;
+	return 0;
+}
+
+static int
+mt7530_get_mirror_monitor_port(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	val->value.i = priv->mirror_dest_port;
+
+	return 0;
+}
+
+static int
+mt7530_set_mirror_monitor_port(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	priv->mirror_dest_port = val->value.i;
+
+	return 0;
+}
+
+static int
+mt7530_get_port_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	val->value.i =  priv->port_entries[val->port_vlan].mirror_rx;
+
+	return 0;
+}
+
+static int
+mt7530_set_port_mirror_rx(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	priv->port_entries[val->port_vlan].mirror_rx = val->value.i;
+
+	return 0;
+}
+
+static int
+mt7530_get_port_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	val->value.i =  priv->port_entries[val->port_vlan].mirror_tx;
+
+	return 0;
+}
+
+static int
+mt7530_set_port_mirror_tx(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	priv->port_entries[val->port_vlan].mirror_tx = val->value.i;
+
+	return 0;
+}
+
+static void
+mt7530_write_vlan_entry(struct mt7530_priv *priv, int vlan, u16 vid,
+	                    u8 ports, u8 etags)
+{
+	int port;
+	u32 val;
+
+	/* vid of vlan */
+	val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
+	if (vlan % 2 == 0) {
+		val &= 0xfff000;
+		val |= vid;
+	} else {
+		val &= 0xfff;
+		val |= (vid << 12);
+	}
+	mt7530_w32(priv, REG_ESW_VLAN_VTIM(vlan), val);
+
+	/* vlan port membership */
+	if (ports)
+		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
+			REG_ESW_VLAN_VAWD1_VTAG_EN | (ports << 16) |
+			REG_ESW_VLAN_VAWD1_VALID);
+	else
+		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
+
+	/* egress mode */
+	val = 0;
+	for (port = 0; port < MT7530_NUM_PORTS; port++) {
+		if (etags & BIT(port))
+			val |= ETAG_CTRL_TAG << (port * 2);
+		else
+			val |= ETAG_CTRL_UNTAG << (port * 2);
+	}
+	mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
+
+	/* write to vlan table */
+	mt7530_vtcr(priv, 1, vlan);
+}
+
+static int
+mt7530_apply_config(struct switch_dev *dev)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	int i, j;
+	u8 tag_ports;
+	u8 untag_ports;
+	bool is_mirror = false;
+
+	if (!priv->global_vlan_enable) {
+		for (i = 0; i < MT7530_NUM_PORTS; i++)
+			mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00400000);
+
+		mt7530_w32(priv, REG_ESW_PORT_PCR(MT7530_CPU_PORT), 0x00ff0000);
+
+		for (i = 0; i < MT7530_NUM_PORTS; i++)
+			mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x810000c0);
+
+		return 0;
+	}
+
+	/* set all ports as security mode */
+	for (i = 0; i < MT7530_NUM_PORTS; i++)
+		mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00ff0003);
+
+	/* check if a port is used in tag/untag vlan egress mode */
+	tag_ports = 0;
+	untag_ports = 0;
+
+	for (i = 0; i < MT7530_NUM_VLANS; i++) {
+		u8 member = priv->vlan_entries[i].member;
+		u8 etags = priv->vlan_entries[i].etags;
+
+		if (!member)
+			continue;
+
+		for (j = 0; j < MT7530_NUM_PORTS; j++) {
+			if (!(member & BIT(j)))
+				continue;
+
+			if (etags & BIT(j))
+				tag_ports |= 1u << j;
+			else
+				untag_ports |= 1u << j;
+		}
+	}
+
+	/* set all untag-only ports as transparent and the rest as user port */
+	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		u32 pvc_mode = 0x81000000;
+
+		if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
+			pvc_mode = 0x810000c0;
+
+		mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
+	}
+
+	/* first clear the swtich vlan table */
+	for (i = 0; i < MT7530_NUM_VLANS; i++)
+		mt7530_write_vlan_entry(priv, i, i, 0, 0);
+
+	/* now program only vlans with members to avoid
+	   clobbering remapped entries in later iterations */
+	for (i = 0; i < MT7530_NUM_VLANS; i++) {
+		u16 vid = priv->vlan_entries[i].vid;
+		u8 member = priv->vlan_entries[i].member;
+		u8 etags = priv->vlan_entries[i].etags;
+
+		if (member)
+			mt7530_write_vlan_entry(priv, i, vid, member, etags);
+	}
+
+	/* Port Default PVID */
+	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		int vlan = priv->port_entries[i].pvid;
+		u16 pvid = 0;
+		u32 val;
+
+		if (vlan < MT7530_NUM_VLANS && priv->vlan_entries[vlan].member)
+			pvid = priv->vlan_entries[vlan].vid;
+
+		val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(i));
+		val &= ~0xfff;
+		val |= pvid;
+		mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val);
+	}
+
+	/* set mirroring source port */
+	for (i = 0; i < MT7530_NUM_PORTS; i++)	{
+		u32 val = mt7530_r32(priv, REG_ESW_PORT_PCR(i));
+		if (priv->port_entries[i].mirror_rx) {
+			val |= REG_ESW_PORT_PCR_MIRROR_SRC_RX_BIT;
+			is_mirror = true;
+		}
+
+		if (priv->port_entries[i].mirror_tx) {
+			val |= REG_ESW_PORT_PCR_MIRROR_SRC_TX_BIT;
+			is_mirror = true;
+		}
+
+		mt7530_w32(priv, REG_ESW_PORT_PCR(i), val);
+	}
+
+	/* set mirroring monitor port */
+	if (is_mirror) {
+		u32 val = mt7530_r32(priv, REG_ESW_WT_MAC_MFC);
+		val |= REG_ESW_WT_MAC_MFC_MIRROR_ENABLE;
+		val &= ~REG_ESW_WT_MAC_MFC_MIRROR_DEST_MASK;
+		val |= priv->mirror_dest_port;
+		mt7530_w32(priv, REG_ESW_WT_MAC_MFC, val);
+	}
+
+	return 0;
+}
+
+static int
+mt7530_get_port_link(struct switch_dev *dev,  int port,
+			struct switch_port_link *link)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	u32 speed, pmsr;
+
+	if (port < 0 || port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port));
+
+	link->link = pmsr & 1;
+	link->duplex = (pmsr >> 1) & 1;
+	speed = (pmsr >> 2) & 3;
+
+	switch (speed) {
+	case 0:
+		link->speed = SWITCH_PORT_SPEED_10;
+		break;
+	case 1:
+		link->speed = SWITCH_PORT_SPEED_100;
+		break;
+	case 2:
+	case 3: /* forced gige speed can be 2 or 3 */
+		link->speed = SWITCH_PORT_SPEED_1000;
+		break;
+	default:
+		link->speed = SWITCH_PORT_SPEED_UNKNOWN;
+		break;
+	}
+
+	return 0;
+}
+
+static u64 get_mib_counter_7620(struct mt7530_priv *priv, int i)
+{
+	return mt7530_r32(priv, MT7620_MIB_COUNTER_BASE + mt7620_mibs[i].offset);
+}
+
+static u64 get_mib_counter_port_7620(struct mt7530_priv *priv, int i, int port)
+{
+	return mt7530_r32(priv,
+			MT7620_MIB_COUNTER_BASE_PORT +
+			(MT7620_MIB_COUNTER_PORT_OFFSET * port) +
+			mt7620_port_mibs[i].offset);
+}
+
+static int mt7530_sw_get_mib(struct switch_dev *dev,
+				  const struct switch_attr *attr,
+				  struct switch_val *val)
+{
+	static char buf[4096];
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	int i, len = 0;
+
+	len += snprintf(buf + len, sizeof(buf) - len, "Switch MIB counters\n");
+
+	for (i = 0; i < ARRAY_SIZE(mt7620_mibs); ++i) {
+		u64 counter;
+		len += snprintf(buf + len, sizeof(buf) - len,
+				"%-11s: ", mt7620_mibs[i].name);
+		counter = get_mib_counter_7620(priv, i);
+		len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
+				counter);
+	}
+
+	val->value.s = buf;
+	val->len = len;
+	return 0;
+}
+
+static char *mt7530_print_arl_table_row(u32 atrd,
+					u32 mac1,
+					u32 mac2,
+					char *buf,
+					size_t *size)
+{
+	int ret;
+	size_t port;
+	size_t i;
+	u8 port_map;
+	u8 mac[ETH_ALEN];
+
+	mac1 = ntohl(mac1);
+	mac2 = ntohl(mac2);
+	port_map = (u8)((atrd & REG_ATRD_PORT_MASK) >> 4);
+	memcpy(mac, &mac1, sizeof(mac1));
+	memcpy(mac + sizeof(mac1), &mac2, sizeof(mac) - sizeof(mac1));
+	for (port = 0, i = 1; port < MT7530_NUM_PORTS; ++port, i <<= 1) {
+		if (port_map & i) {
+			ret = snprintf(buf, *size, "Port %d: MAC %pM\n", port, mac);
+			if (ret >= *size || ret <= 0) {
+				*buf = 0;
+				buf = NULL;
+				goto out;
+			}
+			buf += ret;
+			*size = *size - ret;
+		}
+	}
+out:
+	return buf;
+}
+
+static int mt7530_get_arl_table(struct switch_dev *dev,
+				const struct switch_attr *attr,
+				struct switch_val *val)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	char *buf = priv->arl_buf;
+	size_t size = sizeof(priv->arl_buf);
+	size_t count = 0;
+	size_t retry_times = 100;
+	int ret;
+	u32 atc;
+
+	ret = snprintf(buf, size, "address resolution table\n");
+	if (ret >= size || ret <= 0) {
+		priv->arl_buf[0] = 0;
+		goto out;
+	}
+	buf += ret;
+	size = size - ret;
+
+	mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_START);
+
+	do {
+		atc = mt7530_r32(priv, REG_ESW_WT_MAC_ATC);
+		if (atc & REG_MAC_ATC_SRCH_HIT && !(atc & REG_MAC_ATC_BUSY)) {
+			u32 atrd;
+
+			++count;
+			atrd = mt7530_r32(priv, REG_ESW_TABLE_ATRD);
+			if (atrd & REG_ATRD_VALID) {
+				u32 mac1;
+				u32 mac2;
+
+				mac1 = mt7530_r32(priv, REG_ESW_TABLE_TSRA1);
+				mac2 = mt7530_r32(priv, REG_ESW_TABLE_TSRA2);
+
+				if (!(atc & REG_MAC_ATC_SRCH_END))
+					mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_NEXT);
+
+				buf = mt7530_print_arl_table_row(atrd, mac1, mac2, buf, &size);
+				if (!buf) {
+					pr_warn("%s: too many addresses\n", __func__);
+					goto out;
+				}
+			} else if (!(atc & REG_MAC_ATC_SRCH_END)) {
+				mt7530_w32(priv, REG_ESW_WT_MAC_ATC, REG_MAC_ATC_NEXT);
+			}
+		} else {
+			--retry_times;
+			usleep_range(1000, 5000);
+		}
+	} while (!(atc & REG_MAC_ATC_SRCH_END) &&
+		 count < MT7530_NUM_ARL_RECORDS &&
+		 retry_times > 0);
+out:
+	val->value.s = priv->arl_buf;
+	val->len = strlen(priv->arl_buf);
+
+	return 0;
+}
+
+static int mt7530_sw_get_port_mib(struct switch_dev *dev,
+				  const struct switch_attr *attr,
+				  struct switch_val *val)
+{
+	static char buf[4096];
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+	int i, len = 0;
+
+	if (val->port_vlan >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"Port %d MIB counters\n", val->port_vlan);
+
+	for (i = 0; i < ARRAY_SIZE(mt7620_port_mibs); ++i) {
+		u64 counter;
+		len += snprintf(buf + len, sizeof(buf) - len,
+				"%-11s: ", mt7620_port_mibs[i].name);
+		counter = get_mib_counter_port_7620(priv, i, val->port_vlan);
+		len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
+				counter);
+	}
+
+	val->value.s = buf;
+	val->len = len;
+	return 0;
+}
+
+static int mt7530_get_port_stats(struct switch_dev *dev, int port,
+					struct switch_port_stats *stats)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	if (port < 0 || port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	stats->tx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_TXB_ID, port);
+	stats->rx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_RXB_ID, port);
+
+	return 0;
+}
+
+static const struct switch_attr mt7530_global[] = {
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "enable_vlan",
+		.description = "VLAN mode (1:enabled)",
+		.max = 1,
+		.id = MT7530_ATTR_ENABLE_VLAN,
+		.get = mt7530_get_vlan_enable,
+		.set = mt7530_set_vlan_enable,
+	}, {
+		.type = SWITCH_TYPE_STRING,
+		.name = "mib",
+		.description = "Get MIB counters for switch",
+		.get = mt7530_sw_get_mib,
+		.set = NULL,
+	}, {
+		.type = SWITCH_TYPE_INT,
+		.name = "mirror_monitor_port",
+		.description = "Mirror monitor port",
+		.set = mt7530_set_mirror_monitor_port,
+		.get = mt7530_get_mirror_monitor_port,
+		.max = MT7530_NUM_PORTS - 1
+	},
+	{
+		.type = SWITCH_TYPE_STRING,
+		.name = "arl_table",
+		.description = "Get ARL table",
+		.set = NULL,
+		.get = mt7530_get_arl_table,
+	},
+};
+
+static const struct switch_attr mt7530_port[] = {
+	{
+		.type = SWITCH_TYPE_STRING,
+		.name = "mib",
+		.description = "Get MIB counters for port",
+		.get = mt7530_sw_get_port_mib,
+		.set = NULL,
+	}, {
+		.type = SWITCH_TYPE_INT,
+		.name = "enable_mirror_rx",
+		.description = "Enable mirroring of RX packets",
+		.set = mt7530_set_port_mirror_rx,
+		.get = mt7530_get_port_mirror_rx,
+		.max = 1,
+	}, {
+		.type = SWITCH_TYPE_INT,
+		.name = "enable_mirror_tx",
+		.description = "Enable mirroring of TX packets",
+		.set = mt7530_set_port_mirror_tx,
+		.get = mt7530_get_port_mirror_tx,
+		.max = 1,
+	},
+};
+
+static const struct switch_attr mt7530_vlan[] = {
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "vid",
+		.description = "VLAN ID (0-4094)",
+		.set = mt7530_set_vid,
+		.get = mt7530_get_vid,
+		.max = 4094,
+	},
+};
+
+static const struct switch_dev_ops mt7530_ops = {
+	.attr_global = {
+		.attr = mt7530_global,
+		.n_attr = ARRAY_SIZE(mt7530_global),
+	},
+	.attr_port = {
+		.attr = mt7530_port,
+		.n_attr = ARRAY_SIZE(mt7530_port),
+	},
+	.attr_vlan = {
+		.attr = mt7530_vlan,
+		.n_attr = ARRAY_SIZE(mt7530_vlan),
+	},
+	.get_vlan_ports = mt7530_get_vlan_ports,
+	.set_vlan_ports = mt7530_set_vlan_ports,
+	.get_port_pvid = mt7530_get_port_pvid,
+	.set_port_pvid = mt7530_set_port_pvid,
+	.get_port_link = mt7530_get_port_link,
+	.get_port_stats = mt7530_get_port_stats,
+	.apply_config = mt7530_apply_config,
+	.reset_switch = mt7530_reset_switch,
+};
+
+int
+mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan)
+{
+	struct switch_dev *swdev;
+	struct mt7530_priv *mt7530;
+	struct mt7530_mapping *map;
+	int ret;
+
+	mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL);
+	if (!mt7530)
+		return -ENOMEM;
+
+	mt7530->base = base;
+	mt7530->bus = bus;
+	mt7530->global_vlan_enable = vlan;
+
+	swdev = &mt7530->swdev;
+	if (bus) {
+		swdev->alias = "mt7530";
+		swdev->name = "mt7530";
+	} else {
+		swdev->alias = "mt7620";
+		swdev->name = "mt7620";
+	}
+	swdev->cpu_port = MT7530_CPU_PORT;
+	swdev->ports = MT7530_NUM_PORTS;
+	swdev->vlans = MT7530_NUM_VLANS;
+	swdev->ops = &mt7530_ops;
+
+	ret = register_switch(swdev, NULL);
+	if (ret) {
+		dev_err(dev, "failed to register mt7530\n");
+		return ret;
+	}
+
+
+	map = mt7530_find_mapping(dev->of_node);
+	if (map)
+		mt7530_apply_mapping(mt7530, map);
+	mt7530_apply_config(swdev);
+
+	/* magic vodoo */
+	if (bus && mt7530_r32(mt7530, REG_HWTRAP) !=  0x1117edf) {
+		dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
+		mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
+	}
+	dev_info(dev, "loaded %s driver\n", swdev->name);
+
+	return 0;
+}
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.h
new file mode 100644
index 0000000..53e1d2c
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.h
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
+ */
+
+#ifndef _MT7530_H__
+#define _MT7530_H__
+
+#define MT7620_MIB_COUNTER_BASE_PORT	0x4000
+#define MT7620_MIB_COUNTER_PORT_OFFSET	0x100
+#define MT7620_MIB_COUNTER_BASE	0x1010
+
+/* PPE Accounting Group #0 Byte Counter */
+#define MT7620_MIB_STATS_PPE_AC_BCNT0	0x000
+
+/* PPE Accounting Group #0 Packet Counter */
+#define MT7620_MIB_STATS_PPE_AC_PCNT0	0x004
+
+/* PPE Accounting Group #63 Byte Counter */
+#define MT7620_MIB_STATS_PPE_AC_BCNT63	0x1F8
+
+/* PPE Accounting Group #63 Packet Counter */
+#define MT7620_MIB_STATS_PPE_AC_PCNT63	0x1FC
+
+/* PPE Meter Group #0 */
+#define MT7620_MIB_STATS_PPE_MTR_CNT0	0x200
+
+/* PPE Meter Group #63 */
+#define MT7620_MIB_STATS_PPE_MTR_CNT63	0x2FC
+
+/* Transmit good byte count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_TX_GBCNT	0x300
+
+/* Transmit good packet count for CPU GDM (exclude flow control frames) */
+#define MT7620_MIB_STATS_GDM1_TX_GPCNT	0x304
+
+/* Transmit abort count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_TX_SKIPCNT	0x308
+
+/* Transmit collision count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_TX_COLCNT	0x30C
+
+/* Received good byte count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_GBCNT1	0x320
+
+/* Received good packet count for CPU GDM (exclude flow control frame) */
+#define MT7620_MIB_STATS_GDM1_RX_GPCNT1	0x324
+
+/* Received overflow error packet count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_OERCNT	0x328
+
+/* Received FCS error packet count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_FERCNT	0x32C
+
+/* Received too short error packet count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_SERCNT	0x330
+
+/* Received too long error packet count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_LERCNT	0x334
+
+/* Received IP/TCP/UDP checksum error packet count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_CERCNT	0x338
+
+/* Received flow control pkt count for CPU GDM */
+#define MT7620_MIB_STATS_GDM1_RX_FCCNT	0x33C
+
+/* Transmit good byte count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_TX_GBCNT	0x340
+
+/* Transmit good packet count for PPE GDM (exclude flow control frames) */
+#define MT7620_MIB_STATS_GDM2_TX_GPCNT	0x344
+
+/* Transmit abort count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_TX_SKIPCNT	0x348
+
+/* Transmit collision count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_TX_COLCNT	0x34C
+
+/* Received good byte count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_GBCNT	0x360
+
+/* Received good packet count for PPE GDM (exclude flow control frame) */
+#define MT7620_MIB_STATS_GDM2_RX_GPCNT	0x364
+
+/* Received overflow error packet count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_OERCNT	0x368
+
+/* Received FCS error packet count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_FERCNT	0x36C
+
+/* Received too short error packet count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_SERCNT	0x370
+
+/* Received too long error packet count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_LERCNT	0x374
+
+/* Received IP/TCP/UDP checksum error packet count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_CERCNT	0x378
+
+/* Received flow control pkt count for PPE GDM */
+#define MT7620_MIB_STATS_GDM2_RX_FCCNT	0x37C
+
+/* Tx Packet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_TGPCN	0x10
+
+/* Tx Bad Octet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_TBOCN	0x14
+
+/* Tx Good Octet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_TGOCN	0x18
+
+/* Tx Event Packet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_TEPCN	0x1C
+
+/* Rx Packet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_RGPCN	0x20
+
+/* Rx Bad Octet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_RBOCN	0x24
+
+/* Rx Good Octet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_RGOCN	0x28
+
+/* Rx Event Packet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_REPC1N	0x2C
+
+/* Rx Event Packet Counter of Port n */
+#define MT7620_MIB_STATS_PORT_REPC2N	0x30
+
+int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan);
+
+#endif
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
new file mode 100644
index 0000000..f8301ad
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.c
@@ -0,0 +1,1692 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <linux/clk.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/if_vlan.h>
+#include <linux/reset.h>
+#include <linux/tcp.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+#include <linux/netfilter.h>
+#include <net/netfilter/nf_flow_table.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio.h"
+#include "ethtool.h"
+
+#define	MAX_RX_LENGTH		1536
+#define FE_RX_ETH_HLEN		(VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
+#define FE_RX_HLEN		(NET_SKB_PAD + FE_RX_ETH_HLEN + NET_IP_ALIGN)
+#define DMA_DUMMY_DESC		0xffffffff
+#define FE_DEFAULT_MSG_ENABLE \
+		(NETIF_MSG_DRV | \
+		NETIF_MSG_PROBE | \
+		NETIF_MSG_LINK | \
+		NETIF_MSG_TIMER | \
+		NETIF_MSG_IFDOWN | \
+		NETIF_MSG_IFUP | \
+		NETIF_MSG_RX_ERR | \
+		NETIF_MSG_TX_ERR)
+
+#define TX_DMA_DESP2_DEF	(TX_DMA_LS0 | TX_DMA_DONE)
+#define TX_DMA_DESP4_DEF	(TX_DMA_QN(3) | TX_DMA_PN(1))
+#define NEXT_TX_DESP_IDX(X)	(((X) + 1) & (ring->tx_ring_size - 1))
+#define NEXT_RX_DESP_IDX(X)	(((X) + 1) & (ring->rx_ring_size - 1))
+
+#define SYSC_REG_RSTCTRL	0x34
+
+static int fe_msg_level = -1;
+module_param_named(msg_level, fe_msg_level, int, 0);
+MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
+
+static const u16 fe_reg_table_default[FE_REG_COUNT] = {
+	[FE_REG_PDMA_GLO_CFG] = FE_PDMA_GLO_CFG,
+	[FE_REG_PDMA_RST_CFG] = FE_PDMA_RST_CFG,
+	[FE_REG_DLY_INT_CFG] = FE_DLY_INT_CFG,
+	[FE_REG_TX_BASE_PTR0] = FE_TX_BASE_PTR0,
+	[FE_REG_TX_MAX_CNT0] = FE_TX_MAX_CNT0,
+	[FE_REG_TX_CTX_IDX0] = FE_TX_CTX_IDX0,
+	[FE_REG_TX_DTX_IDX0] = FE_TX_DTX_IDX0,
+	[FE_REG_RX_BASE_PTR0] = FE_RX_BASE_PTR0,
+	[FE_REG_RX_MAX_CNT0] = FE_RX_MAX_CNT0,
+	[FE_REG_RX_CALC_IDX0] = FE_RX_CALC_IDX0,
+	[FE_REG_RX_DRX_IDX0] = FE_RX_DRX_IDX0,
+	[FE_REG_FE_INT_ENABLE] = FE_FE_INT_ENABLE,
+	[FE_REG_FE_INT_STATUS] = FE_FE_INT_STATUS,
+	[FE_REG_FE_DMA_VID_BASE] = FE_DMA_VID0,
+	[FE_REG_FE_COUNTER_BASE] = FE_GDMA1_TX_GBCNT,
+	[FE_REG_FE_RST_GL] = FE_FE_RST_GL,
+};
+
+static const u16 *fe_reg_table = fe_reg_table_default;
+
+struct fe_work_t {
+	int bitnr;
+	void (*action)(struct fe_priv *);
+};
+
+static void __iomem *fe_base;
+
+void fe_w32(u32 val, unsigned reg)
+{
+	__raw_writel(val, fe_base + reg);
+}
+
+u32 fe_r32(unsigned reg)
+{
+	return __raw_readl(fe_base + reg);
+}
+
+void fe_reg_w32(u32 val, enum fe_reg reg)
+{
+	fe_w32(val, fe_reg_table[reg]);
+}
+
+u32 fe_reg_r32(enum fe_reg reg)
+{
+	return fe_r32(fe_reg_table[reg]);
+}
+
+void fe_m32(struct fe_priv *eth, u32 clear, u32 set, unsigned reg)
+{
+	u32 val;
+
+	spin_lock(&eth->page_lock);
+	val = __raw_readl(fe_base + reg);
+	val &= ~clear;
+	val |= set;
+	__raw_writel(val, fe_base + reg);
+	spin_unlock(&eth->page_lock);
+}
+
+void fe_reset(u32 reset_bits)
+{
+	u32 t;
+
+	t = rt_sysc_r32(SYSC_REG_RSTCTRL);
+	t |= reset_bits;
+	rt_sysc_w32(t, SYSC_REG_RSTCTRL);
+	usleep_range(10, 20);
+
+	t &= ~reset_bits;
+	rt_sysc_w32(t, SYSC_REG_RSTCTRL);
+	usleep_range(10, 20);
+}
+
+static inline void fe_int_disable(u32 mask)
+{
+	fe_reg_w32(fe_reg_r32(FE_REG_FE_INT_ENABLE) & ~mask,
+		   FE_REG_FE_INT_ENABLE);
+	/* flush write */
+	fe_reg_r32(FE_REG_FE_INT_ENABLE);
+}
+
+static inline void fe_int_enable(u32 mask)
+{
+	fe_reg_w32(fe_reg_r32(FE_REG_FE_INT_ENABLE) | mask,
+		   FE_REG_FE_INT_ENABLE);
+	/* flush write */
+	fe_reg_r32(FE_REG_FE_INT_ENABLE);
+}
+
+static inline void fe_hw_set_macaddr(struct fe_priv *priv, unsigned char *mac)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->page_lock, flags);
+	fe_w32((mac[0] << 8) | mac[1], FE_GDMA1_MAC_ADRH);
+	fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+	       FE_GDMA1_MAC_ADRL);
+	spin_unlock_irqrestore(&priv->page_lock, flags);
+}
+
+static int fe_set_mac_address(struct net_device *dev, void *p)
+{
+	int ret = eth_mac_addr(dev, p);
+
+	if (!ret) {
+		struct fe_priv *priv = netdev_priv(dev);
+
+		if (priv->soc->set_mac)
+			priv->soc->set_mac(priv, dev->dev_addr);
+		else
+			fe_hw_set_macaddr(priv, p);
+	}
+
+	return ret;
+}
+
+static inline int fe_max_frag_size(int mtu)
+{
+	/* make sure buf_size will be at least MAX_RX_LENGTH */
+	if (mtu + FE_RX_ETH_HLEN < MAX_RX_LENGTH)
+		mtu = MAX_RX_LENGTH - FE_RX_ETH_HLEN;
+
+	return SKB_DATA_ALIGN(FE_RX_HLEN + mtu) +
+		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+}
+
+static inline int fe_max_buf_size(int frag_size)
+{
+	int buf_size = frag_size - NET_SKB_PAD - NET_IP_ALIGN -
+		       SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+	BUG_ON(buf_size < MAX_RX_LENGTH);
+	return buf_size;
+}
+
+static inline void fe_get_rxd(struct fe_rx_dma *rxd, struct fe_rx_dma *dma_rxd)
+{
+	rxd->rxd1 = dma_rxd->rxd1;
+	rxd->rxd2 = dma_rxd->rxd2;
+	rxd->rxd3 = dma_rxd->rxd3;
+	rxd->rxd4 = dma_rxd->rxd4;
+}
+
+static inline void fe_set_txd(struct fe_tx_dma *txd, struct fe_tx_dma *dma_txd)
+{
+	dma_txd->txd1 = txd->txd1;
+	dma_txd->txd3 = txd->txd3;
+	dma_txd->txd4 = txd->txd4;
+	/* clean dma done flag last */
+	dma_txd->txd2 = txd->txd2;
+}
+
+static void fe_clean_rx(struct fe_priv *priv)
+{
+	struct fe_rx_ring *ring = &priv->rx_ring;
+	struct page *page;
+	int i;
+
+	if (ring->rx_data) {
+		for (i = 0; i < ring->rx_ring_size; i++)
+			if (ring->rx_data[i]) {
+				if (ring->rx_dma && ring->rx_dma[i].rxd1)
+					dma_unmap_single(priv->dev,
+							 ring->rx_dma[i].rxd1,
+							 ring->rx_buf_size,
+							 DMA_FROM_DEVICE);
+				skb_free_frag(ring->rx_data[i]);
+			}
+
+		kfree(ring->rx_data);
+		ring->rx_data = NULL;
+	}
+
+	if (ring->rx_dma) {
+		dma_free_coherent(priv->dev,
+				  ring->rx_ring_size * sizeof(*ring->rx_dma),
+				  ring->rx_dma,
+				  ring->rx_phys);
+		ring->rx_dma = NULL;
+	}
+
+	if (!ring->frag_cache.va)
+	    return;
+
+	page = virt_to_page(ring->frag_cache.va);
+	__page_frag_cache_drain(page, ring->frag_cache.pagecnt_bias);
+	memset(&ring->frag_cache, 0, sizeof(ring->frag_cache));
+}
+
+static int fe_alloc_rx(struct fe_priv *priv)
+{
+	struct fe_rx_ring *ring = &priv->rx_ring;
+	int i, pad;
+
+	ring->rx_data = kcalloc(ring->rx_ring_size, sizeof(*ring->rx_data),
+			GFP_KERNEL);
+	if (!ring->rx_data)
+		goto no_rx_mem;
+
+	for (i = 0; i < ring->rx_ring_size; i++) {
+		ring->rx_data[i] = page_frag_alloc(&ring->frag_cache,
+						   ring->frag_size,
+						   GFP_KERNEL);
+		if (!ring->rx_data[i])
+			goto no_rx_mem;
+	}
+
+	ring->rx_dma = dma_alloc_coherent(priv->dev,
+			ring->rx_ring_size * sizeof(*ring->rx_dma),
+			&ring->rx_phys,
+			GFP_ATOMIC | __GFP_ZERO);
+	if (!ring->rx_dma)
+		goto no_rx_mem;
+
+	if (priv->flags & FE_FLAG_RX_2B_OFFSET)
+		pad = 0;
+	else
+		pad = NET_IP_ALIGN;
+	for (i = 0; i < ring->rx_ring_size; i++) {
+		dma_addr_t dma_addr = dma_map_single(priv->dev,
+				ring->rx_data[i] + NET_SKB_PAD + pad,
+				ring->rx_buf_size,
+				DMA_FROM_DEVICE);
+		if (unlikely(dma_mapping_error(priv->dev, dma_addr)))
+			goto no_rx_mem;
+		ring->rx_dma[i].rxd1 = (unsigned int)dma_addr;
+
+		if (priv->flags & FE_FLAG_RX_SG_DMA)
+			ring->rx_dma[i].rxd2 = RX_DMA_PLEN0(ring->rx_buf_size);
+		else
+			ring->rx_dma[i].rxd2 = RX_DMA_LSO;
+	}
+	ring->rx_calc_idx = ring->rx_ring_size - 1;
+	/* make sure that all changes to the dma ring are flushed before we
+	 * continue
+	 */
+	wmb();
+
+	fe_reg_w32(ring->rx_phys, FE_REG_RX_BASE_PTR0);
+	fe_reg_w32(ring->rx_ring_size, FE_REG_RX_MAX_CNT0);
+	fe_reg_w32(ring->rx_calc_idx, FE_REG_RX_CALC_IDX0);
+	fe_reg_w32(FE_PST_DRX_IDX0, FE_REG_PDMA_RST_CFG);
+
+	return 0;
+
+no_rx_mem:
+	return -ENOMEM;
+}
+
+static void fe_txd_unmap(struct device *dev, struct fe_tx_buf *tx_buf)
+{
+	if (dma_unmap_len(tx_buf, dma_len0))
+		dma_unmap_page(dev,
+			       dma_unmap_addr(tx_buf, dma_addr0),
+			       dma_unmap_len(tx_buf, dma_len0),
+			       DMA_TO_DEVICE);
+
+	if (dma_unmap_len(tx_buf, dma_len1))
+		dma_unmap_page(dev,
+			       dma_unmap_addr(tx_buf, dma_addr1),
+			       dma_unmap_len(tx_buf, dma_len1),
+			       DMA_TO_DEVICE);
+
+	dma_unmap_len_set(tx_buf, dma_addr0, 0);
+	dma_unmap_len_set(tx_buf, dma_addr1, 0);
+	if (tx_buf->skb && (tx_buf->skb != (struct sk_buff *)DMA_DUMMY_DESC))
+		dev_kfree_skb_any(tx_buf->skb);
+	tx_buf->skb = NULL;
+}
+
+static void fe_clean_tx(struct fe_priv *priv)
+{
+	int i;
+	struct device *dev = priv->dev;
+	struct fe_tx_ring *ring = &priv->tx_ring;
+
+	if (ring->tx_buf) {
+		for (i = 0; i < ring->tx_ring_size; i++)
+			fe_txd_unmap(dev, &ring->tx_buf[i]);
+		kfree(ring->tx_buf);
+		ring->tx_buf = NULL;
+	}
+
+	if (ring->tx_dma) {
+		dma_free_coherent(dev,
+				  ring->tx_ring_size * sizeof(*ring->tx_dma),
+				  ring->tx_dma,
+				  ring->tx_phys);
+		ring->tx_dma = NULL;
+	}
+
+	netdev_reset_queue(priv->netdev);
+}
+
+static int fe_alloc_tx(struct fe_priv *priv)
+{
+	int i;
+	struct fe_tx_ring *ring = &priv->tx_ring;
+
+	ring->tx_free_idx = 0;
+	ring->tx_next_idx = 0;
+	ring->tx_thresh = max((unsigned long)ring->tx_ring_size >> 2,
+			      MAX_SKB_FRAGS);
+
+	ring->tx_buf = kcalloc(ring->tx_ring_size, sizeof(*ring->tx_buf),
+			GFP_KERNEL);
+	if (!ring->tx_buf)
+		goto no_tx_mem;
+
+	ring->tx_dma = dma_alloc_coherent(priv->dev,
+			ring->tx_ring_size * sizeof(*ring->tx_dma),
+			&ring->tx_phys,
+			GFP_ATOMIC | __GFP_ZERO);
+	if (!ring->tx_dma)
+		goto no_tx_mem;
+
+	for (i = 0; i < ring->tx_ring_size; i++) {
+		if (priv->soc->tx_dma)
+			priv->soc->tx_dma(&ring->tx_dma[i]);
+		ring->tx_dma[i].txd2 = TX_DMA_DESP2_DEF;
+	}
+	/* make sure that all changes to the dma ring are flushed before we
+	 * continue
+	 */
+	wmb();
+
+	fe_reg_w32(ring->tx_phys, FE_REG_TX_BASE_PTR0);
+	fe_reg_w32(ring->tx_ring_size, FE_REG_TX_MAX_CNT0);
+	fe_reg_w32(0, FE_REG_TX_CTX_IDX0);
+	fe_reg_w32(FE_PST_DTX_IDX0, FE_REG_PDMA_RST_CFG);
+
+	return 0;
+
+no_tx_mem:
+	return -ENOMEM;
+}
+
+static int fe_init_dma(struct fe_priv *priv)
+{
+	int err;
+
+	err = fe_alloc_tx(priv);
+	if (err)
+		return err;
+
+	err = fe_alloc_rx(priv);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void fe_free_dma(struct fe_priv *priv)
+{
+	fe_clean_tx(priv);
+	fe_clean_rx(priv);
+}
+
+void fe_stats_update(struct fe_priv *priv)
+{
+	struct fe_hw_stats *hwstats = priv->hw_stats;
+	unsigned int base = fe_reg_table[FE_REG_FE_COUNTER_BASE];
+	u64 stats;
+
+	u64_stats_update_begin(&hwstats->syncp);
+
+	if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+		hwstats->rx_bytes			+= fe_r32(base);
+		stats					=  fe_r32(base + 0x04);
+		if (stats)
+			hwstats->rx_bytes		+= (stats << 32);
+		hwstats->rx_packets			+= fe_r32(base + 0x08);
+		hwstats->rx_overflow			+= fe_r32(base + 0x10);
+		hwstats->rx_fcs_errors			+= fe_r32(base + 0x14);
+		hwstats->rx_short_errors		+= fe_r32(base + 0x18);
+		hwstats->rx_long_errors			+= fe_r32(base + 0x1c);
+		hwstats->rx_checksum_errors		+= fe_r32(base + 0x20);
+		hwstats->rx_flow_control_packets	+= fe_r32(base + 0x24);
+		hwstats->tx_skip			+= fe_r32(base + 0x28);
+		hwstats->tx_collisions			+= fe_r32(base + 0x2c);
+		hwstats->tx_bytes			+= fe_r32(base + 0x30);
+		stats					=  fe_r32(base + 0x34);
+		if (stats)
+			hwstats->tx_bytes		+= (stats << 32);
+		hwstats->tx_packets			+= fe_r32(base + 0x38);
+	} else {
+		hwstats->tx_bytes			+= fe_r32(base);
+		hwstats->tx_packets			+= fe_r32(base + 0x04);
+		hwstats->tx_skip			+= fe_r32(base + 0x08);
+		hwstats->tx_collisions			+= fe_r32(base + 0x0c);
+		hwstats->rx_bytes			+= fe_r32(base + 0x20);
+		hwstats->rx_packets			+= fe_r32(base + 0x24);
+		hwstats->rx_overflow			+= fe_r32(base + 0x28);
+		hwstats->rx_fcs_errors			+= fe_r32(base + 0x2c);
+		hwstats->rx_short_errors		+= fe_r32(base + 0x30);
+		hwstats->rx_long_errors			+= fe_r32(base + 0x34);
+		hwstats->rx_checksum_errors		+= fe_r32(base + 0x38);
+		hwstats->rx_flow_control_packets	+= fe_r32(base + 0x3c);
+	}
+
+	u64_stats_update_end(&hwstats->syncp);
+}
+
+static void fe_get_stats64(struct net_device *dev,
+				struct rtnl_link_stats64 *storage)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_hw_stats *hwstats = priv->hw_stats;
+	unsigned int base = fe_reg_table[FE_REG_FE_COUNTER_BASE];
+	unsigned int start;
+
+	if (!base) {
+		netdev_stats_to_stats64(storage, &dev->stats);
+		return;
+	}
+
+	if (netif_running(dev) && netif_device_present(dev)) {
+		if (spin_trylock_bh(&hwstats->stats_lock)) {
+			fe_stats_update(priv);
+			spin_unlock_bh(&hwstats->stats_lock);
+		}
+	}
+
+	do {
+		start = u64_stats_fetch_begin_irq(&hwstats->syncp);
+		storage->rx_packets = hwstats->rx_packets;
+		storage->tx_packets = hwstats->tx_packets;
+		storage->rx_bytes = hwstats->rx_bytes;
+		storage->tx_bytes = hwstats->tx_bytes;
+		storage->collisions = hwstats->tx_collisions;
+		storage->rx_length_errors = hwstats->rx_short_errors +
+			hwstats->rx_long_errors;
+		storage->rx_over_errors = hwstats->rx_overflow;
+		storage->rx_crc_errors = hwstats->rx_fcs_errors;
+		storage->rx_errors = hwstats->rx_checksum_errors;
+		storage->tx_aborted_errors = hwstats->tx_skip;
+	} while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
+
+	storage->tx_errors = priv->netdev->stats.tx_errors;
+	storage->rx_dropped = priv->netdev->stats.rx_dropped;
+	storage->tx_dropped = priv->netdev->stats.tx_dropped;
+}
+
+static int fe_vlan_rx_add_vid(struct net_device *dev,
+			      __be16 proto, u16 vid)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	u32 idx = (vid & 0xf);
+	u32 vlan_cfg;
+
+	if (!((fe_reg_table[FE_REG_FE_DMA_VID_BASE]) &&
+	      (dev->features & NETIF_F_HW_VLAN_CTAG_TX)))
+		return 0;
+
+	if (test_bit(idx, &priv->vlan_map)) {
+		netdev_warn(dev, "disable tx vlan offload\n");
+		dev->wanted_features &= ~NETIF_F_HW_VLAN_CTAG_TX;
+		netdev_update_features(dev);
+	} else {
+		vlan_cfg = fe_r32(fe_reg_table[FE_REG_FE_DMA_VID_BASE] +
+				((idx >> 1) << 2));
+		if (idx & 0x1) {
+			vlan_cfg &= 0xffff;
+			vlan_cfg |= (vid << 16);
+		} else {
+			vlan_cfg &= 0xffff0000;
+			vlan_cfg |= vid;
+		}
+		fe_w32(vlan_cfg, fe_reg_table[FE_REG_FE_DMA_VID_BASE] +
+				((idx >> 1) << 2));
+		set_bit(idx, &priv->vlan_map);
+	}
+
+	return 0;
+}
+
+static int fe_vlan_rx_kill_vid(struct net_device *dev,
+			       __be16 proto, u16 vid)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	u32 idx = (vid & 0xf);
+
+	if (!((fe_reg_table[FE_REG_FE_DMA_VID_BASE]) &&
+	      (dev->features & NETIF_F_HW_VLAN_CTAG_TX)))
+		return 0;
+
+	clear_bit(idx, &priv->vlan_map);
+
+	return 0;
+}
+
+static inline u32 fe_empty_txd(struct fe_tx_ring *ring)
+{
+	barrier();
+	return (u32)(ring->tx_ring_size -
+			((ring->tx_next_idx - ring->tx_free_idx) &
+			 (ring->tx_ring_size - 1)));
+}
+
+struct fe_map_state {
+	struct device *dev;
+	struct fe_tx_dma txd;
+	u32 def_txd4;
+	int ring_idx;
+	int i;
+};
+
+static void fe_tx_dma_write_desc(struct fe_tx_ring *ring, struct fe_map_state *st)
+{
+	fe_set_txd(&st->txd, &ring->tx_dma[st->ring_idx]);
+	memset(&st->txd, 0, sizeof(st->txd));
+	st->txd.txd4 = st->def_txd4;
+	st->ring_idx = NEXT_TX_DESP_IDX(st->ring_idx);
+}
+
+static int __fe_tx_dma_map_page(struct fe_tx_ring *ring, struct fe_map_state *st,
+				struct page *page, size_t offset, size_t size)
+{
+	struct device *dev = st->dev;
+	struct fe_tx_buf *tx_buf;
+	dma_addr_t mapped_addr;
+
+	mapped_addr = dma_map_page(dev, page, offset, size, DMA_TO_DEVICE);
+	if (unlikely(dma_mapping_error(dev, mapped_addr)))
+		return -EIO;
+
+	if (st->i && !(st->i & 1))
+	    fe_tx_dma_write_desc(ring, st);
+
+	tx_buf = &ring->tx_buf[st->ring_idx];
+	if (st->i & 1) {
+		st->txd.txd3 = mapped_addr;
+		st->txd.txd2 |= TX_DMA_PLEN1(size);
+		dma_unmap_addr_set(tx_buf, dma_addr1, mapped_addr);
+		dma_unmap_len_set(tx_buf, dma_len1, size);
+	} else {
+		tx_buf->skb = (struct sk_buff *)DMA_DUMMY_DESC;
+		st->txd.txd1 = mapped_addr;
+		st->txd.txd2 = TX_DMA_PLEN0(size);
+		dma_unmap_addr_set(tx_buf, dma_addr0, mapped_addr);
+		dma_unmap_len_set(tx_buf, dma_len0, size);
+	}
+	st->i++;
+
+	return 0;
+}
+
+static int fe_tx_dma_map_page(struct fe_tx_ring *ring, struct fe_map_state *st,
+			      struct page *page, size_t offset, size_t size)
+{
+	int cur_size;
+	int ret;
+
+	while (size > 0) {
+		cur_size = min_t(size_t, size, TX_DMA_BUF_LEN);
+
+		ret = __fe_tx_dma_map_page(ring, st, page, offset, cur_size);
+		if (ret)
+			return ret;
+
+		size -= cur_size;
+		offset += cur_size;
+	}
+
+	return 0;
+}
+
+static int fe_tx_dma_map_skb(struct fe_tx_ring *ring, struct fe_map_state *st,
+			     struct sk_buff *skb)
+{
+	struct page *page = virt_to_page(skb->data);
+	size_t offset = offset_in_page(skb->data);
+	size_t size = skb_headlen(skb);
+
+	return fe_tx_dma_map_page(ring, st, page, offset, size);
+}
+
+static inline struct sk_buff *
+fe_next_frag(struct sk_buff *head, struct sk_buff *skb)
+{
+	if (skb != head)
+		return skb->next;
+
+	if (skb_has_frag_list(skb))
+		return skb_shinfo(skb)->frag_list;
+
+	return NULL;
+}
+
+
+static int fe_tx_map_dma(struct sk_buff *skb, struct net_device *dev,
+			 int tx_num, struct fe_tx_ring *ring)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_map_state st = {
+		.dev = priv->dev,
+		.ring_idx = ring->tx_next_idx,
+	};
+	struct sk_buff *head = skb;
+	struct fe_tx_buf *tx_buf;
+	unsigned int nr_frags;
+	int i, j;
+
+	/* init tx descriptor */
+	if (priv->soc->tx_dma)
+		priv->soc->tx_dma(&st.txd);
+	else
+		st.txd.txd4 = TX_DMA_DESP4_DEF;
+	st.def_txd4 = st.txd.txd4;
+
+	/* TX Checksum offload */
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		st.txd.txd4 |= TX_DMA_CHKSUM;
+
+	/* VLAN header offload */
+	if (skb_vlan_tag_present(skb)) {
+		u16 tag = skb_vlan_tag_get(skb);
+
+		if (IS_ENABLED(CONFIG_SOC_MT7621))
+			st.txd.txd4 |= TX_DMA_INS_VLAN_MT7621 | tag;
+		else
+			st.txd.txd4 |= TX_DMA_INS_VLAN |
+				((tag >> VLAN_PRIO_SHIFT) << 4) |
+				(tag & 0xF);
+	}
+
+	/* TSO: fill MSS info in tcp checksum field */
+	if (skb_is_gso(skb)) {
+		if (skb_cow_head(skb, 0)) {
+			netif_warn(priv, tx_err, dev,
+				   "GSO expand head fail.\n");
+			goto err_out;
+		}
+		if (skb_shinfo(skb)->gso_type &
+				(SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+			st.txd.txd4 |= TX_DMA_TSO;
+			tcp_hdr(skb)->check = htons(skb_shinfo(skb)->gso_size);
+		}
+	}
+
+next_frag:
+	if (skb_headlen(skb) && fe_tx_dma_map_skb(ring, &st, skb))
+		goto err_dma;
+
+	/* TX SG offload */
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	for (i = 0; i < nr_frags; i++) {
+		skb_frag_t *frag;
+
+		frag = &skb_shinfo(skb)->frags[i];
+		if (fe_tx_dma_map_page(ring, &st, skb_frag_page(frag),
+				       skb_frag_off(frag), skb_frag_size(frag)))
+			goto err_dma;
+	}
+
+	skb = fe_next_frag(head, skb);
+	if (skb)
+		goto next_frag;
+
+	/* set last segment */
+	if (st.i & 0x1)
+		st.txd.txd2 |= TX_DMA_LS0;
+	else
+		st.txd.txd2 |= TX_DMA_LS1;
+
+	/* store skb to cleanup */
+	tx_buf = &ring->tx_buf[st.ring_idx];
+	tx_buf->skb = head;
+
+	netdev_sent_queue(dev, head->len);
+	skb_tx_timestamp(head);
+
+	fe_tx_dma_write_desc(ring, &st);
+	ring->tx_next_idx = st.ring_idx;
+
+	/* make sure that all changes to the dma ring are flushed before we
+	 * continue
+	 */
+	wmb();
+	if (unlikely(fe_empty_txd(ring) <= ring->tx_thresh)) {
+		netif_stop_queue(dev);
+		smp_mb();
+		if (unlikely(fe_empty_txd(ring) > ring->tx_thresh))
+			netif_wake_queue(dev);
+	}
+
+	if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)) || !netdev_xmit_more())
+		fe_reg_w32(ring->tx_next_idx, FE_REG_TX_CTX_IDX0);
+
+	return 0;
+
+err_dma:
+	j = ring->tx_next_idx;
+	for (i = 0; i < tx_num; i++) {
+		/* unmap dma */
+		fe_txd_unmap(priv->dev, &ring->tx_buf[j]);
+		ring->tx_dma[j].txd2 = TX_DMA_DESP2_DEF;
+
+		j = NEXT_TX_DESP_IDX(j);
+	}
+	/* make sure that all changes to the dma ring are flushed before we
+	 * continue
+	 */
+	wmb();
+
+err_out:
+	return -1;
+}
+
+static inline int fe_skb_padto(struct sk_buff *skb, struct fe_priv *priv)
+{
+	unsigned int len;
+	int ret;
+
+	ret = 0;
+	if (unlikely(skb->len < VLAN_ETH_ZLEN)) {
+		if ((priv->flags & FE_FLAG_PADDING_64B) &&
+		    !(priv->flags & FE_FLAG_PADDING_BUG))
+			return ret;
+
+		if (skb_vlan_tag_present(skb))
+			len = ETH_ZLEN;
+		else if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+			len = VLAN_ETH_ZLEN;
+		else if (!(priv->flags & FE_FLAG_PADDING_64B))
+			len = ETH_ZLEN;
+		else
+			return ret;
+
+		if (skb->len < len) {
+			ret = skb_pad(skb, len - skb->len);
+			if (ret < 0)
+				return ret;
+			skb->len = len;
+			skb_set_tail_pointer(skb, len);
+		}
+	}
+
+	return ret;
+}
+
+static inline int fe_cal_txd_req(struct sk_buff *skb)
+{
+	struct sk_buff *head = skb;
+	int i, nfrags = 0;
+	skb_frag_t *frag;
+
+next_frag:
+	nfrags++;
+	if (skb_is_gso(skb)) {
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			frag = &skb_shinfo(skb)->frags[i];
+			nfrags += DIV_ROUND_UP(skb_frag_size(frag), TX_DMA_BUF_LEN);
+		}
+	} else {
+		nfrags += skb_shinfo(skb)->nr_frags;
+	}
+
+	skb = fe_next_frag(head, skb);
+	if (skb)
+		goto next_frag;
+
+	return DIV_ROUND_UP(nfrags, 2);
+}
+
+static int fe_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_tx_ring *ring = &priv->tx_ring;
+	struct net_device_stats *stats = &dev->stats;
+	int tx_num;
+	int len = skb->len;
+
+	if (fe_skb_padto(skb, priv)) {
+		netif_warn(priv, tx_err, dev, "tx padding failed!\n");
+		return NETDEV_TX_OK;
+	}
+
+	tx_num = fe_cal_txd_req(skb);
+	if (unlikely(fe_empty_txd(ring) <= tx_num)) {
+		netif_stop_queue(dev);
+		netif_err(priv, tx_queued, dev,
+			  "Tx Ring full when queue awake!\n");
+		return NETDEV_TX_BUSY;
+	}
+
+	if (fe_tx_map_dma(skb, dev, tx_num, ring) < 0) {
+		stats->tx_dropped++;
+	} else {
+		stats->tx_packets++;
+		stats->tx_bytes += len;
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static int fe_poll_rx(struct napi_struct *napi, int budget,
+		      struct fe_priv *priv, u32 rx_intr)
+{
+	struct net_device *netdev = priv->netdev;
+	struct net_device_stats *stats = &netdev->stats;
+	struct fe_soc_data *soc = priv->soc;
+	struct fe_rx_ring *ring = &priv->rx_ring;
+	int idx = ring->rx_calc_idx;
+	u32 checksum_bit;
+	struct sk_buff *skb;
+	u8 *data, *new_data;
+	struct fe_rx_dma *rxd, trxd;
+	int done = 0, pad;
+
+	if (netdev->features & NETIF_F_RXCSUM)
+		checksum_bit = soc->checksum_bit;
+	else
+		checksum_bit = 0;
+
+	if (priv->flags & FE_FLAG_RX_2B_OFFSET)
+		pad = 0;
+	else
+		pad = NET_IP_ALIGN;
+
+	while (done < budget) {
+		unsigned int pktlen;
+		dma_addr_t dma_addr;
+
+		idx = NEXT_RX_DESP_IDX(idx);
+		rxd = &ring->rx_dma[idx];
+		data = ring->rx_data[idx];
+
+		fe_get_rxd(&trxd, rxd);
+		if (!(trxd.rxd2 & RX_DMA_DONE))
+			break;
+
+		/* alloc new buffer */
+		new_data = page_frag_alloc(&ring->frag_cache, ring->frag_size,
+					   GFP_ATOMIC);
+		if (unlikely(!new_data)) {
+			stats->rx_dropped++;
+			goto release_desc;
+		}
+		dma_addr = dma_map_single(priv->dev,
+					  new_data + NET_SKB_PAD + pad,
+					  ring->rx_buf_size,
+					  DMA_FROM_DEVICE);
+		if (unlikely(dma_mapping_error(priv->dev, dma_addr))) {
+			skb_free_frag(new_data);
+			goto release_desc;
+		}
+
+		/* receive data */
+		skb = build_skb(data, ring->frag_size);
+		if (unlikely(!skb)) {
+			skb_free_frag(new_data);
+			goto release_desc;
+		}
+		skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
+
+		dma_unmap_single(priv->dev, trxd.rxd1,
+				 ring->rx_buf_size, DMA_FROM_DEVICE);
+		pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
+		skb->dev = netdev;
+		skb_put(skb, pktlen);
+		if (trxd.rxd4 & checksum_bit)
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb_checksum_none_assert(skb);
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
+		    RX_DMA_VID(trxd.rxd3))
+			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+					       RX_DMA_VID(trxd.rxd3));
+
+		stats->rx_packets++;
+		stats->rx_bytes += pktlen;
+
+		napi_gro_receive(napi, skb);
+
+		ring->rx_data[idx] = new_data;
+		rxd->rxd1 = (unsigned int)dma_addr;
+
+release_desc:
+		if (priv->flags & FE_FLAG_RX_SG_DMA)
+			rxd->rxd2 = RX_DMA_PLEN0(ring->rx_buf_size);
+		else
+			rxd->rxd2 = RX_DMA_LSO;
+
+		ring->rx_calc_idx = idx;
+		/* make sure that all changes to the dma ring are flushed before
+		 * we continue
+		 */
+		wmb();
+		fe_reg_w32(ring->rx_calc_idx, FE_REG_RX_CALC_IDX0);
+		done++;
+	}
+
+	if (done < budget)
+		fe_reg_w32(rx_intr, FE_REG_FE_INT_STATUS);
+
+	return done;
+}
+
+static int fe_poll_tx(struct fe_priv *priv, int budget, u32 tx_intr,
+		      int *tx_again)
+{
+	struct net_device *netdev = priv->netdev;
+	unsigned int bytes_compl = 0;
+	struct sk_buff *skb;
+	struct fe_tx_buf *tx_buf;
+	int done = 0;
+	u32 idx, hwidx;
+	struct fe_tx_ring *ring = &priv->tx_ring;
+
+	idx = ring->tx_free_idx;
+	hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);
+
+	while ((idx != hwidx) && budget) {
+		tx_buf = &ring->tx_buf[idx];
+		skb = tx_buf->skb;
+
+		if (!skb)
+			break;
+
+		if (skb != (struct sk_buff *)DMA_DUMMY_DESC) {
+			bytes_compl += skb->len;
+			done++;
+			budget--;
+		}
+		fe_txd_unmap(priv->dev, tx_buf);
+		idx = NEXT_TX_DESP_IDX(idx);
+	}
+	ring->tx_free_idx = idx;
+
+	if (idx == hwidx) {
+		/* read hw index again make sure no new tx packet */
+		hwidx = fe_reg_r32(FE_REG_TX_DTX_IDX0);
+		if (idx == hwidx)
+			fe_reg_w32(tx_intr, FE_REG_FE_INT_STATUS);
+		else
+			*tx_again = 1;
+	} else {
+		*tx_again = 1;
+	}
+
+	if (done) {
+		netdev_completed_queue(netdev, done, bytes_compl);
+		smp_mb();
+		if (unlikely(netif_queue_stopped(netdev) &&
+			     (fe_empty_txd(ring) > ring->tx_thresh)))
+			netif_wake_queue(netdev);
+	}
+
+	return done;
+}
+
+static int fe_poll(struct napi_struct *napi, int budget)
+{
+	struct fe_priv *priv = container_of(napi, struct fe_priv, rx_napi);
+	struct fe_hw_stats *hwstat = priv->hw_stats;
+	int tx_done, rx_done, tx_again;
+	u32 status, fe_status, status_reg, mask;
+	u32 tx_intr, rx_intr, status_intr;
+
+	status = fe_reg_r32(FE_REG_FE_INT_STATUS);
+	fe_status = status;
+	tx_intr = priv->soc->tx_int;
+	rx_intr = priv->soc->rx_int;
+	status_intr = priv->soc->status_int;
+	tx_done = 0;
+	rx_done = 0;
+	tx_again = 0;
+
+	if (fe_reg_table[FE_REG_FE_INT_STATUS2]) {
+		fe_status = fe_reg_r32(FE_REG_FE_INT_STATUS2);
+		status_reg = FE_REG_FE_INT_STATUS2;
+	} else {
+		status_reg = FE_REG_FE_INT_STATUS;
+	}
+
+	if (status & tx_intr)
+		tx_done = fe_poll_tx(priv, budget, tx_intr, &tx_again);
+
+	if (status & rx_intr)
+		rx_done = fe_poll_rx(napi, budget, priv, rx_intr);
+
+	if (unlikely(fe_status & status_intr)) {
+		if (hwstat && spin_trylock(&hwstat->stats_lock)) {
+			fe_stats_update(priv);
+			spin_unlock(&hwstat->stats_lock);
+		}
+		fe_reg_w32(status_intr, status_reg);
+	}
+
+	if (unlikely(netif_msg_intr(priv))) {
+		mask = fe_reg_r32(FE_REG_FE_INT_ENABLE);
+		netdev_info(priv->netdev,
+			    "done tx %d, rx %d, intr 0x%08x/0x%x\n",
+			    tx_done, rx_done, status, mask);
+	}
+
+	if (!tx_again && (rx_done < budget)) {
+		status = fe_reg_r32(FE_REG_FE_INT_STATUS);
+		if (status & (tx_intr | rx_intr)) {
+			/* let napi poll again */
+			rx_done = budget;
+			goto poll_again;
+		}
+
+		napi_complete_done(napi, rx_done);
+		fe_int_enable(tx_intr | rx_intr);
+	} else {
+		rx_done = budget;
+	}
+
+poll_again:
+	return rx_done;
+}
+
+static void fe_tx_timeout(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct fe_tx_ring *ring = &priv->tx_ring;
+
+	priv->netdev->stats.tx_errors++;
+	netif_err(priv, tx_err, dev,
+		  "transmit timed out\n");
+	netif_info(priv, drv, dev, "dma_cfg:%08x\n",
+		   fe_reg_r32(FE_REG_PDMA_GLO_CFG));
+	netif_info(priv, drv, dev, "tx_ring=%d, "
+		   "base=%08x, max=%u, ctx=%u, dtx=%u, fdx=%hu, next=%hu\n",
+		   0, fe_reg_r32(FE_REG_TX_BASE_PTR0),
+		   fe_reg_r32(FE_REG_TX_MAX_CNT0),
+		   fe_reg_r32(FE_REG_TX_CTX_IDX0),
+		   fe_reg_r32(FE_REG_TX_DTX_IDX0),
+		   ring->tx_free_idx,
+		   ring->tx_next_idx);
+	netif_info(priv, drv, dev,
+		   "rx_ring=%d, base=%08x, max=%u, calc=%u, drx=%u\n",
+		   0, fe_reg_r32(FE_REG_RX_BASE_PTR0),
+		   fe_reg_r32(FE_REG_RX_MAX_CNT0),
+		   fe_reg_r32(FE_REG_RX_CALC_IDX0),
+		   fe_reg_r32(FE_REG_RX_DRX_IDX0));
+
+	if (!test_and_set_bit(FE_FLAG_RESET_PENDING, priv->pending_flags))
+		schedule_work(&priv->pending_work);
+}
+
+static irqreturn_t fe_handle_irq(int irq, void *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	u32 status, int_mask;
+
+	status = fe_reg_r32(FE_REG_FE_INT_STATUS);
+
+	if (unlikely(!status))
+		return IRQ_NONE;
+
+	int_mask = (priv->soc->rx_int | priv->soc->tx_int);
+	if (likely(status & int_mask)) {
+		if (likely(napi_schedule_prep(&priv->rx_napi))) {
+			fe_int_disable(int_mask);
+			__napi_schedule(&priv->rx_napi);
+		}
+	} else {
+		fe_reg_w32(status, FE_REG_FE_INT_STATUS);
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void fe_poll_controller(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	u32 int_mask = priv->soc->tx_int | priv->soc->rx_int;
+
+	fe_int_disable(int_mask);
+	fe_handle_irq(dev->irq, dev);
+	fe_int_enable(int_mask);
+}
+#endif
+
+int fe_set_clock_cycle(struct fe_priv *priv)
+{
+	unsigned long sysclk = priv->sysclk;
+
+	sysclk /= FE_US_CYC_CNT_DIVISOR;
+	sysclk <<= FE_US_CYC_CNT_SHIFT;
+
+	fe_w32((fe_r32(FE_FE_GLO_CFG) &
+			~(FE_US_CYC_CNT_MASK << FE_US_CYC_CNT_SHIFT)) |
+			sysclk,
+			FE_FE_GLO_CFG);
+	return 0;
+}
+
+void fe_fwd_config(struct fe_priv *priv)
+{
+	u32 fwd_cfg;
+
+	fwd_cfg = fe_r32(FE_GDMA1_FWD_CFG);
+
+	/* disable jumbo frame */
+	if (priv->flags & FE_FLAG_JUMBO_FRAME)
+		fwd_cfg &= ~FE_GDM1_JMB_EN;
+
+	/* set unicast/multicast/broadcast frame to cpu */
+	fwd_cfg &= ~0xffff;
+
+	fe_w32(fwd_cfg, FE_GDMA1_FWD_CFG);
+}
+
+static void fe_rxcsum_config(bool enable)
+{
+	if (enable)
+		fe_w32(fe_r32(FE_GDMA1_FWD_CFG) | (FE_GDM1_ICS_EN |
+					FE_GDM1_TCS_EN | FE_GDM1_UCS_EN),
+				FE_GDMA1_FWD_CFG);
+	else
+		fe_w32(fe_r32(FE_GDMA1_FWD_CFG) & ~(FE_GDM1_ICS_EN |
+					FE_GDM1_TCS_EN | FE_GDM1_UCS_EN),
+				FE_GDMA1_FWD_CFG);
+}
+
+static void fe_txcsum_config(bool enable)
+{
+	if (enable)
+		fe_w32(fe_r32(FE_CDMA_CSG_CFG) | (FE_ICS_GEN_EN |
+					FE_TCS_GEN_EN | FE_UCS_GEN_EN),
+				FE_CDMA_CSG_CFG);
+	else
+		fe_w32(fe_r32(FE_CDMA_CSG_CFG) & ~(FE_ICS_GEN_EN |
+					FE_TCS_GEN_EN | FE_UCS_GEN_EN),
+				FE_CDMA_CSG_CFG);
+}
+
+void fe_csum_config(struct fe_priv *priv)
+{
+	struct net_device *dev = priv_netdev(priv);
+
+	fe_txcsum_config((dev->features & NETIF_F_IP_CSUM));
+	fe_rxcsum_config((dev->features & NETIF_F_RXCSUM));
+}
+
+static int fe_hw_init(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	int i, err;
+
+	err = devm_request_irq(priv->dev, dev->irq, fe_handle_irq, 0,
+			       dev_name(priv->dev), dev);
+	if (err)
+		return err;
+
+	if (priv->soc->set_mac)
+		priv->soc->set_mac(priv, dev->dev_addr);
+	else
+		fe_hw_set_macaddr(priv, dev->dev_addr);
+
+	/* disable delay interrupt */
+	fe_reg_w32(0, FE_REG_DLY_INT_CFG);
+
+	fe_int_disable(priv->soc->tx_int | priv->soc->rx_int);
+
+	/* frame engine will push VLAN tag regarding to VIDX feild in Tx desc */
+	if (fe_reg_table[FE_REG_FE_DMA_VID_BASE])
+		for (i = 0; i < 16; i += 2)
+			fe_w32(((i + 1) << 16) + i,
+			       fe_reg_table[FE_REG_FE_DMA_VID_BASE] +
+			       (i * 2));
+
+	if (priv->soc->fwd_config(priv))
+		netdev_err(dev, "unable to get clock\n");
+
+	if (fe_reg_table[FE_REG_FE_RST_GL]) {
+		fe_reg_w32(1, FE_REG_FE_RST_GL);
+		fe_reg_w32(0, FE_REG_FE_RST_GL);
+	}
+
+	return 0;
+}
+
+static int fe_open(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	u32 val;
+	int err;
+
+	err = fe_init_dma(priv);
+	if (err) {
+		fe_free_dma(priv);
+		return err;
+	}
+
+	spin_lock_irqsave(&priv->page_lock, flags);
+
+	val = FE_TX_WB_DDONE | FE_RX_DMA_EN | FE_TX_DMA_EN;
+	if (priv->flags & FE_FLAG_RX_2B_OFFSET)
+		val |= FE_RX_2B_OFFSET;
+	val |= priv->soc->pdma_glo_cfg;
+	fe_reg_w32(val, FE_REG_PDMA_GLO_CFG);
+
+	spin_unlock_irqrestore(&priv->page_lock, flags);
+
+	if (priv->phy)
+		priv->phy->start(priv);
+
+	if (priv->soc->has_carrier && priv->soc->has_carrier(priv))
+		netif_carrier_on(dev);
+
+	napi_enable(&priv->rx_napi);
+	fe_int_enable(priv->soc->tx_int | priv->soc->rx_int);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int fe_stop(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+	int i;
+
+	netif_tx_disable(dev);
+	fe_int_disable(priv->soc->tx_int | priv->soc->rx_int);
+	napi_disable(&priv->rx_napi);
+
+	if (priv->phy)
+		priv->phy->stop(priv);
+
+	spin_lock_irqsave(&priv->page_lock, flags);
+
+	fe_reg_w32(fe_reg_r32(FE_REG_PDMA_GLO_CFG) &
+		     ~(FE_TX_WB_DDONE | FE_RX_DMA_EN | FE_TX_DMA_EN),
+		     FE_REG_PDMA_GLO_CFG);
+	spin_unlock_irqrestore(&priv->page_lock, flags);
+
+	/* wait dma stop */
+	for (i = 0; i < 10; i++) {
+		if (fe_reg_r32(FE_REG_PDMA_GLO_CFG) &
+				(FE_TX_DMA_BUSY | FE_RX_DMA_BUSY)) {
+			msleep(20);
+			continue;
+		}
+		break;
+	}
+
+	fe_free_dma(priv);
+
+	return 0;
+}
+
+static void fe_reset_phy(struct fe_priv *priv)
+{
+	int err, msec = 30;
+	struct gpio_desc *phy_reset;
+
+	phy_reset = devm_gpiod_get_optional(priv->dev, "phy-reset",
+					    GPIOD_OUT_HIGH);
+	if (!phy_reset)
+		return;
+
+	if (IS_ERR(phy_reset)) {
+		dev_err(priv->dev, "Error acquiring reset gpio pins: %ld\n",
+			PTR_ERR(phy_reset));
+		return;
+	}
+
+	err = of_property_read_u32(priv->dev->of_node, "phy-reset-duration",
+				   &msec);
+	if (!err && msec > 1000)
+		msec = 30;
+
+	if (msec > 20)
+		msleep(msec);
+	else
+		usleep_range(msec * 1000, msec * 1000 + 1000);
+
+	gpiod_set_value(phy_reset, 0);
+}
+
+static int __init fe_init(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	struct device_node *port;
+	const char *mac_addr;
+	int err;
+
+	priv->soc->reset_fe();
+
+	if (priv->soc->switch_init)
+		if (priv->soc->switch_init(priv)) {
+			netdev_err(dev, "failed to initialize switch core\n");
+			return -ENODEV;
+		}
+
+	fe_reset_phy(priv);
+
+	mac_addr = of_get_mac_address(priv->dev->of_node);
+	if (!IS_ERR_OR_NULL(mac_addr))
+		ether_addr_copy(dev->dev_addr, mac_addr);
+
+	/* If the mac address is invalid, use random mac address  */
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		eth_hw_addr_random(dev);
+		dev_err(priv->dev, "generated random MAC address %pM\n",
+			dev->dev_addr);
+	}
+
+	err = fe_mdio_init(priv);
+	if (err)
+		return err;
+
+	if (priv->soc->port_init)
+		for_each_child_of_node(priv->dev->of_node, port)
+			if (of_device_is_compatible(port, "mediatek,eth-port") &&
+			    of_device_is_available(port))
+				priv->soc->port_init(priv, port);
+
+	if (priv->phy) {
+		err = priv->phy->connect(priv);
+		if (err)
+			goto err_phy_disconnect;
+	}
+
+	err = fe_hw_init(dev);
+	if (err)
+		goto err_phy_disconnect;
+
+	if ((priv->flags & FE_FLAG_HAS_SWITCH) && priv->soc->switch_config)
+		priv->soc->switch_config(priv);
+
+	return 0;
+
+err_phy_disconnect:
+	if (priv->phy)
+		priv->phy->disconnect(priv);
+	fe_mdio_cleanup(priv);
+
+	return err;
+}
+
+static void fe_uninit(struct net_device *dev)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	if (priv->phy)
+		priv->phy->disconnect(priv);
+	fe_mdio_cleanup(priv);
+
+	fe_reg_w32(0, FE_REG_FE_INT_ENABLE);
+	free_irq(dev->irq, dev);
+}
+
+static int fe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+
+	if (!priv->phy_dev)
+		return -ENODEV;
+
+
+	return phy_mii_ioctl(priv->phy_dev, ifr, cmd);
+}
+
+static int fe_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct fe_priv *priv = netdev_priv(dev);
+	int frag_size, old_mtu;
+	u32 fwd_cfg;
+
+	old_mtu = dev->mtu;
+	dev->mtu = new_mtu;
+
+	if (!(priv->flags & FE_FLAG_JUMBO_FRAME))
+		return 0;
+
+	/* return early if the buffer sizes will not change */
+	if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN)
+		return 0;
+	if (old_mtu > ETH_DATA_LEN && new_mtu > ETH_DATA_LEN)
+		return 0;
+
+	if (new_mtu <= ETH_DATA_LEN)
+		priv->rx_ring.frag_size = fe_max_frag_size(ETH_DATA_LEN);
+	else
+		priv->rx_ring.frag_size = PAGE_SIZE;
+	priv->rx_ring.rx_buf_size = fe_max_buf_size(priv->rx_ring.frag_size);
+
+	if (!netif_running(dev))
+		return 0;
+
+	fe_stop(dev);
+	if (!IS_ENABLED(CONFIG_SOC_MT7621)) {
+		fwd_cfg = fe_r32(FE_GDMA1_FWD_CFG);
+		if (new_mtu <= ETH_DATA_LEN) {
+			fwd_cfg &= ~FE_GDM1_JMB_EN;
+		} else {
+			frag_size = fe_max_frag_size(new_mtu);
+			fwd_cfg &= ~(FE_GDM1_JMB_LEN_MASK << FE_GDM1_JMB_LEN_SHIFT);
+			fwd_cfg |= (DIV_ROUND_UP(frag_size, 1024) <<
+			FE_GDM1_JMB_LEN_SHIFT) | FE_GDM1_JMB_EN;
+		}
+		fe_w32(fwd_cfg, FE_GDMA1_FWD_CFG);
+	}
+
+	return fe_open(dev);
+}
+
+static const struct net_device_ops fe_netdev_ops = {
+	.ndo_init		= fe_init,
+	.ndo_uninit		= fe_uninit,
+	.ndo_open		= fe_open,
+	.ndo_stop		= fe_stop,
+	.ndo_start_xmit		= fe_start_xmit,
+	.ndo_set_mac_address	= fe_set_mac_address,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= fe_do_ioctl,
+	.ndo_change_mtu		= fe_change_mtu,
+	.ndo_tx_timeout		= fe_tx_timeout,
+	.ndo_get_stats64        = fe_get_stats64,
+	.ndo_vlan_rx_add_vid	= fe_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= fe_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= fe_poll_controller,
+#endif
+};
+
+static void fe_reset_pending(struct fe_priv *priv)
+{
+	struct net_device *dev = priv->netdev;
+	int err;
+
+	rtnl_lock();
+	fe_stop(dev);
+
+	err = fe_open(dev);
+	if (err) {
+		netif_alert(priv, ifup, dev,
+			    "Driver up/down cycle failed, closing device.\n");
+		dev_close(dev);
+	}
+	rtnl_unlock();
+}
+
+static const struct fe_work_t fe_work[] = {
+	{FE_FLAG_RESET_PENDING, fe_reset_pending},
+};
+
+static void fe_pending_work(struct work_struct *work)
+{
+	struct fe_priv *priv = container_of(work, struct fe_priv, pending_work);
+	int i;
+	bool pending;
+
+	for (i = 0; i < ARRAY_SIZE(fe_work); i++) {
+		pending = test_and_clear_bit(fe_work[i].bitnr,
+					     priv->pending_flags);
+		if (pending)
+			fe_work[i].action(priv);
+	}
+}
+
+static int fe_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	const struct of_device_id *match;
+	struct fe_soc_data *soc;
+	struct net_device *netdev;
+	struct fe_priv *priv;
+	struct clk *sysclk;
+	int err, napi_weight;
+
+	device_reset(&pdev->dev);
+
+	match = of_match_device(of_fe_match, &pdev->dev);
+	soc = (struct fe_soc_data *)match->data;
+
+	if (soc->reg_table)
+		fe_reg_table = soc->reg_table;
+	else
+		soc->reg_table = fe_reg_table;
+
+	fe_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(fe_base)) {
+		err = -EADDRNOTAVAIL;
+		goto err_out;
+	}
+
+	netdev = alloc_etherdev(sizeof(*priv));
+	if (!netdev) {
+		dev_err(&pdev->dev, "alloc_etherdev failed\n");
+		err = -ENOMEM;
+		goto err_iounmap;
+	}
+
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+	netdev->netdev_ops = &fe_netdev_ops;
+	netdev->base_addr = (unsigned long)fe_base;
+
+	netdev->irq = platform_get_irq(pdev, 0);
+	if (netdev->irq < 0) {
+		dev_err(&pdev->dev, "no IRQ resource found\n");
+		err = -ENXIO;
+		goto err_free_dev;
+	}
+
+	if (soc->init_data)
+		soc->init_data(soc, netdev);
+	netdev->vlan_features = netdev->hw_features &
+				~(NETIF_F_HW_VLAN_CTAG_TX |
+				  NETIF_F_HW_VLAN_CTAG_RX);
+	netdev->features |= netdev->hw_features;
+
+	if (IS_ENABLED(CONFIG_SOC_MT7621))
+		netdev->max_mtu = 2048;
+
+	/* fake rx vlan filter func. to support tx vlan offload func */
+	if (fe_reg_table[FE_REG_FE_DMA_VID_BASE])
+		netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+
+	priv = netdev_priv(netdev);
+	spin_lock_init(&priv->page_lock);
+	if (fe_reg_table[FE_REG_FE_COUNTER_BASE]) {
+		priv->hw_stats = kzalloc(sizeof(*priv->hw_stats), GFP_KERNEL);
+		if (!priv->hw_stats) {
+			err = -ENOMEM;
+			goto err_free_dev;
+		}
+		spin_lock_init(&priv->hw_stats->stats_lock);
+	}
+
+	sysclk = devm_clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(sysclk)) {
+		priv->sysclk = clk_get_rate(sysclk);
+	} else if ((priv->flags & FE_FLAG_CALIBRATE_CLK)) {
+		dev_err(&pdev->dev, "this soc needs a clk for calibration\n");
+		err = -ENXIO;
+		goto err_free_dev;
+	}
+
+	priv->switch_np = of_parse_phandle(pdev->dev.of_node, "mediatek,switch", 0);
+	if ((priv->flags & FE_FLAG_HAS_SWITCH) && !priv->switch_np) {
+		dev_err(&pdev->dev, "failed to read switch phandle\n");
+		err = -ENODEV;
+		goto err_free_dev;
+	}
+
+	priv->netdev = netdev;
+	priv->dev = &pdev->dev;
+	priv->soc = soc;
+	priv->msg_enable = netif_msg_init(fe_msg_level, FE_DEFAULT_MSG_ENABLE);
+	priv->rx_ring.frag_size = fe_max_frag_size(ETH_DATA_LEN);
+	priv->rx_ring.rx_buf_size = fe_max_buf_size(priv->rx_ring.frag_size);
+	priv->tx_ring.tx_ring_size = NUM_DMA_DESC;
+	priv->rx_ring.rx_ring_size = NUM_DMA_DESC;
+	INIT_WORK(&priv->pending_work, fe_pending_work);
+	u64_stats_init(&priv->hw_stats->syncp);
+
+	napi_weight = 16;
+	if (priv->flags & FE_FLAG_NAPI_WEIGHT) {
+		napi_weight *= 4;
+		priv->tx_ring.tx_ring_size *= 4;
+		priv->rx_ring.rx_ring_size *= 4;
+	}
+	netif_napi_add(netdev, &priv->rx_napi, fe_poll, napi_weight);
+	fe_set_ethtool_ops(netdev);
+
+	err = register_netdev(netdev);
+	if (err) {
+		dev_err(&pdev->dev, "error bringing up device\n");
+		goto err_free_dev;
+	}
+
+	platform_set_drvdata(pdev, netdev);
+
+	netif_info(priv, probe, netdev, "mediatek frame engine at 0x%08lx, irq %d\n",
+		   netdev->base_addr, netdev->irq);
+
+	return 0;
+
+err_free_dev:
+	free_netdev(netdev);
+err_iounmap:
+	devm_iounmap(&pdev->dev, fe_base);
+err_out:
+	return err;
+}
+
+static int fe_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct fe_priv *priv = netdev_priv(dev);
+
+	netif_napi_del(&priv->rx_napi);
+	kfree(priv->hw_stats);
+
+	cancel_work_sync(&priv->pending_work);
+
+	unregister_netdev(dev);
+	free_netdev(dev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver fe_driver = {
+	.probe = fe_probe,
+	.remove = fe_remove,
+	.driver = {
+		.name = "mtk_soc_eth",
+		.owner = THIS_MODULE,
+		.of_match_table = of_fe_match,
+	},
+};
+
+module_platform_driver(fe_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Ethernet driver for Ralink SoC");
+MODULE_VERSION(MTK_FE_DRV_VERSION);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h
new file mode 100644
index 0000000..c8517f9
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h
@@ -0,0 +1,527 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#ifndef FE_ETH_H
+#define FE_ETH_H
+
+#include <linux/mii.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/phy.h>
+#include <linux/ethtool.h>
+#include <linux/version.h>
+
+enum fe_reg {
+	FE_REG_PDMA_GLO_CFG = 0,
+	FE_REG_PDMA_RST_CFG,
+	FE_REG_DLY_INT_CFG,
+	FE_REG_TX_BASE_PTR0,
+	FE_REG_TX_MAX_CNT0,
+	FE_REG_TX_CTX_IDX0,
+	FE_REG_TX_DTX_IDX0,
+	FE_REG_RX_BASE_PTR0,
+	FE_REG_RX_MAX_CNT0,
+	FE_REG_RX_CALC_IDX0,
+	FE_REG_RX_DRX_IDX0,
+	FE_REG_FE_INT_ENABLE,
+	FE_REG_FE_INT_STATUS,
+	FE_REG_FE_DMA_VID_BASE,
+	FE_REG_FE_COUNTER_BASE,
+	FE_REG_FE_RST_GL,
+	FE_REG_FE_INT_STATUS2,
+	FE_REG_COUNT
+};
+
+enum fe_work_flag {
+	FE_FLAG_RESET_PENDING,
+	FE_FLAG_MAX
+};
+
+#define MTK_FE_DRV_VERSION		"0.2"
+
+/* power of 2 to let NEXT_TX_DESP_IDX work */
+#define NUM_DMA_DESC		BIT(10)
+#define MAX_DMA_DESC		0xfff
+
+#define FE_DELAY_EN_INT		0x80
+#define FE_DELAY_MAX_INT	0x04
+#define FE_DELAY_MAX_TOUT	0x04
+#define FE_DELAY_TIME		20
+#define FE_DELAY_CHAN		(((FE_DELAY_EN_INT | FE_DELAY_MAX_INT) << 8) | \
+				 FE_DELAY_MAX_TOUT)
+#define FE_DELAY_INIT		((FE_DELAY_CHAN << 16) | FE_DELAY_CHAN)
+#define FE_PSE_FQFC_CFG_INIT	0x80504000
+#define FE_PSE_FQFC_CFG_256Q	0xff908000
+
+/* interrupt bits */
+#define FE_CNT_PPE_AF		BIT(31)
+#define FE_CNT_GDM_AF		BIT(29)
+#define FE_PSE_P2_FC		BIT(26)
+#define FE_PSE_BUF_DROP		BIT(24)
+#define FE_GDM_OTHER_DROP	BIT(23)
+#define FE_PSE_P1_FC		BIT(22)
+#define FE_PSE_P0_FC		BIT(21)
+#define FE_PSE_FQ_EMPTY		BIT(20)
+#define FE_GE1_STA_CHG		BIT(18)
+#define FE_TX_COHERENT		BIT(17)
+#define FE_RX_COHERENT		BIT(16)
+#define FE_TX_DONE_INT3		BIT(11)
+#define FE_TX_DONE_INT2		BIT(10)
+#define FE_TX_DONE_INT1		BIT(9)
+#define FE_TX_DONE_INT0		BIT(8)
+#define FE_RX_DONE_INT0		BIT(2)
+#define FE_TX_DLY_INT		BIT(1)
+#define FE_RX_DLY_INT		BIT(0)
+
+#define FE_RX_DONE_INT		FE_RX_DONE_INT0
+#define FE_TX_DONE_INT		(FE_TX_DONE_INT0 | FE_TX_DONE_INT1 | \
+				 FE_TX_DONE_INT2 | FE_TX_DONE_INT3)
+
+#define RT5350_RX_DLY_INT	BIT(30)
+#define RT5350_TX_DLY_INT	BIT(28)
+#define RT5350_RX_DONE_INT1	BIT(17)
+#define RT5350_RX_DONE_INT0	BIT(16)
+#define RT5350_TX_DONE_INT3	BIT(3)
+#define RT5350_TX_DONE_INT2	BIT(2)
+#define RT5350_TX_DONE_INT1	BIT(1)
+#define RT5350_TX_DONE_INT0	BIT(0)
+
+#define RT5350_RX_DONE_INT	(RT5350_RX_DONE_INT0 | RT5350_RX_DONE_INT1)
+#define RT5350_TX_DONE_INT	(RT5350_TX_DONE_INT0 | RT5350_TX_DONE_INT1 | \
+				 RT5350_TX_DONE_INT2 | RT5350_TX_DONE_INT3)
+
+/* registers */
+#define FE_FE_OFFSET		0x0000
+#define FE_GDMA_OFFSET		0x0020
+#define FE_PSE_OFFSET		0x0040
+#define FE_GDMA2_OFFSET		0x0060
+#define FE_CDMA_OFFSET		0x0080
+#define FE_DMA_VID0		0x00a8
+#define FE_PDMA_OFFSET		0x0100
+#define FE_PPE_OFFSET		0x0200
+#define FE_CMTABLE_OFFSET	0x0400
+#define FE_POLICYTABLE_OFFSET	0x1000
+
+#define RT5350_PDMA_OFFSET	0x0800
+#define RT5350_SDM_OFFSET	0x0c00
+
+#define FE_MDIO_ACCESS		(FE_FE_OFFSET + 0x00)
+#define FE_MDIO_CFG		(FE_FE_OFFSET + 0x04)
+#define FE_FE_GLO_CFG		(FE_FE_OFFSET + 0x08)
+#define FE_FE_RST_GL		(FE_FE_OFFSET + 0x0C)
+#define FE_FE_INT_STATUS	(FE_FE_OFFSET + 0x10)
+#define FE_FE_INT_ENABLE	(FE_FE_OFFSET + 0x14)
+#define FE_MDIO_CFG2		(FE_FE_OFFSET + 0x18)
+#define FE_FOC_TS_T		(FE_FE_OFFSET + 0x1C)
+
+#define	FE_GDMA1_FWD_CFG	(FE_GDMA_OFFSET + 0x00)
+#define FE_GDMA1_SCH_CFG	(FE_GDMA_OFFSET + 0x04)
+#define FE_GDMA1_SHPR_CFG	(FE_GDMA_OFFSET + 0x08)
+#define FE_GDMA1_MAC_ADRL	(FE_GDMA_OFFSET + 0x0C)
+#define FE_GDMA1_MAC_ADRH	(FE_GDMA_OFFSET + 0x10)
+
+#define	FE_GDMA2_FWD_CFG	(FE_GDMA2_OFFSET + 0x00)
+#define FE_GDMA2_SCH_CFG	(FE_GDMA2_OFFSET + 0x04)
+#define FE_GDMA2_SHPR_CFG	(FE_GDMA2_OFFSET + 0x08)
+#define FE_GDMA2_MAC_ADRL	(FE_GDMA2_OFFSET + 0x0C)
+#define FE_GDMA2_MAC_ADRH	(FE_GDMA2_OFFSET + 0x10)
+
+#define FE_PSE_FQ_CFG		(FE_PSE_OFFSET + 0x00)
+#define FE_CDMA_FC_CFG		(FE_PSE_OFFSET + 0x04)
+#define FE_GDMA1_FC_CFG		(FE_PSE_OFFSET + 0x08)
+#define FE_GDMA2_FC_CFG		(FE_PSE_OFFSET + 0x0C)
+
+#define FE_CDMA_CSG_CFG		(FE_CDMA_OFFSET + 0x00)
+#define FE_CDMA_SCH_CFG		(FE_CDMA_OFFSET + 0x04)
+
+#ifdef CONFIG_SOC_MT7621
+#define MT7620A_GDMA_OFFSET		0x0500
+#else
+#define MT7620A_GDMA_OFFSET		0x0600
+#endif
+#define	MT7620A_GDMA1_FWD_CFG		(MT7620A_GDMA_OFFSET + 0x00)
+#define MT7620A_FE_GDMA1_SCH_CFG	(MT7620A_GDMA_OFFSET + 0x04)
+#define MT7620A_FE_GDMA1_SHPR_CFG	(MT7620A_GDMA_OFFSET + 0x08)
+#define MT7620A_FE_GDMA1_MAC_ADRL	(MT7620A_GDMA_OFFSET + 0x0C)
+#define MT7620A_FE_GDMA1_MAC_ADRH	(MT7620A_GDMA_OFFSET + 0x10)
+
+#define MT7620A_RESET_FE	BIT(21)
+#define MT7620A_RESET_ESW	BIT(23)
+#define MT7620A_RESET_EPHY	BIT(24)
+
+#define RT5350_TX_BASE_PTR0	(RT5350_PDMA_OFFSET + 0x00)
+#define RT5350_TX_MAX_CNT0	(RT5350_PDMA_OFFSET + 0x04)
+#define RT5350_TX_CTX_IDX0	(RT5350_PDMA_OFFSET + 0x08)
+#define RT5350_TX_DTX_IDX0	(RT5350_PDMA_OFFSET + 0x0C)
+#define RT5350_TX_BASE_PTR1	(RT5350_PDMA_OFFSET + 0x10)
+#define RT5350_TX_MAX_CNT1	(RT5350_PDMA_OFFSET + 0x14)
+#define RT5350_TX_CTX_IDX1	(RT5350_PDMA_OFFSET + 0x18)
+#define RT5350_TX_DTX_IDX1	(RT5350_PDMA_OFFSET + 0x1C)
+#define RT5350_TX_BASE_PTR2	(RT5350_PDMA_OFFSET + 0x20)
+#define RT5350_TX_MAX_CNT2	(RT5350_PDMA_OFFSET + 0x24)
+#define RT5350_TX_CTX_IDX2	(RT5350_PDMA_OFFSET + 0x28)
+#define RT5350_TX_DTX_IDX2	(RT5350_PDMA_OFFSET + 0x2C)
+#define RT5350_TX_BASE_PTR3	(RT5350_PDMA_OFFSET + 0x30)
+#define RT5350_TX_MAX_CNT3	(RT5350_PDMA_OFFSET + 0x34)
+#define RT5350_TX_CTX_IDX3	(RT5350_PDMA_OFFSET + 0x38)
+#define RT5350_TX_DTX_IDX3	(RT5350_PDMA_OFFSET + 0x3C)
+#define RT5350_RX_BASE_PTR0	(RT5350_PDMA_OFFSET + 0x100)
+#define RT5350_RX_MAX_CNT0	(RT5350_PDMA_OFFSET + 0x104)
+#define RT5350_RX_CALC_IDX0	(RT5350_PDMA_OFFSET + 0x108)
+#define RT5350_RX_DRX_IDX0	(RT5350_PDMA_OFFSET + 0x10C)
+#define RT5350_RX_BASE_PTR1	(RT5350_PDMA_OFFSET + 0x110)
+#define RT5350_RX_MAX_CNT1	(RT5350_PDMA_OFFSET + 0x114)
+#define RT5350_RX_CALC_IDX1	(RT5350_PDMA_OFFSET + 0x118)
+#define RT5350_RX_DRX_IDX1	(RT5350_PDMA_OFFSET + 0x11C)
+#define RT5350_PDMA_GLO_CFG	(RT5350_PDMA_OFFSET + 0x204)
+#define RT5350_PDMA_RST_CFG	(RT5350_PDMA_OFFSET + 0x208)
+#define RT5350_DLY_INT_CFG	(RT5350_PDMA_OFFSET + 0x20c)
+#define RT5350_FE_INT_STATUS	(RT5350_PDMA_OFFSET + 0x220)
+#define RT5350_FE_INT_ENABLE	(RT5350_PDMA_OFFSET + 0x228)
+#define RT5350_PDMA_SCH_CFG	(RT5350_PDMA_OFFSET + 0x280)
+
+#define FE_PDMA_GLO_CFG		(FE_PDMA_OFFSET + 0x00)
+#define FE_PDMA_RST_CFG		(FE_PDMA_OFFSET + 0x04)
+#define FE_PDMA_SCH_CFG		(FE_PDMA_OFFSET + 0x08)
+#define FE_DLY_INT_CFG		(FE_PDMA_OFFSET + 0x0C)
+#define FE_TX_BASE_PTR0		(FE_PDMA_OFFSET + 0x10)
+#define FE_TX_MAX_CNT0		(FE_PDMA_OFFSET + 0x14)
+#define FE_TX_CTX_IDX0		(FE_PDMA_OFFSET + 0x18)
+#define FE_TX_DTX_IDX0		(FE_PDMA_OFFSET + 0x1C)
+#define FE_TX_BASE_PTR1		(FE_PDMA_OFFSET + 0x20)
+#define FE_TX_MAX_CNT1		(FE_PDMA_OFFSET + 0x24)
+#define FE_TX_CTX_IDX1		(FE_PDMA_OFFSET + 0x28)
+#define FE_TX_DTX_IDX1		(FE_PDMA_OFFSET + 0x2C)
+#define FE_RX_BASE_PTR0		(FE_PDMA_OFFSET + 0x30)
+#define FE_RX_MAX_CNT0		(FE_PDMA_OFFSET + 0x34)
+#define FE_RX_CALC_IDX0		(FE_PDMA_OFFSET + 0x38)
+#define FE_RX_DRX_IDX0		(FE_PDMA_OFFSET + 0x3C)
+#define FE_TX_BASE_PTR2		(FE_PDMA_OFFSET + 0x40)
+#define FE_TX_MAX_CNT2		(FE_PDMA_OFFSET + 0x44)
+#define FE_TX_CTX_IDX2		(FE_PDMA_OFFSET + 0x48)
+#define FE_TX_DTX_IDX2		(FE_PDMA_OFFSET + 0x4C)
+#define FE_TX_BASE_PTR3		(FE_PDMA_OFFSET + 0x50)
+#define FE_TX_MAX_CNT3		(FE_PDMA_OFFSET + 0x54)
+#define FE_TX_CTX_IDX3		(FE_PDMA_OFFSET + 0x58)
+#define FE_TX_DTX_IDX3		(FE_PDMA_OFFSET + 0x5C)
+#define FE_RX_BASE_PTR1		(FE_PDMA_OFFSET + 0x60)
+#define FE_RX_MAX_CNT1		(FE_PDMA_OFFSET + 0x64)
+#define FE_RX_CALC_IDX1		(FE_PDMA_OFFSET + 0x68)
+#define FE_RX_DRX_IDX1		(FE_PDMA_OFFSET + 0x6C)
+
+/* Switch DMA configuration */
+#define RT5350_SDM_CFG		(RT5350_SDM_OFFSET + 0x00)
+#define RT5350_SDM_RRING	(RT5350_SDM_OFFSET + 0x04)
+#define RT5350_SDM_TRING	(RT5350_SDM_OFFSET + 0x08)
+#define RT5350_SDM_MAC_ADRL	(RT5350_SDM_OFFSET + 0x0C)
+#define RT5350_SDM_MAC_ADRH	(RT5350_SDM_OFFSET + 0x10)
+#define RT5350_SDM_TPCNT	(RT5350_SDM_OFFSET + 0x100)
+#define RT5350_SDM_TBCNT	(RT5350_SDM_OFFSET + 0x104)
+#define RT5350_SDM_RPCNT	(RT5350_SDM_OFFSET + 0x108)
+#define RT5350_SDM_RBCNT	(RT5350_SDM_OFFSET + 0x10C)
+#define RT5350_SDM_CS_ERR	(RT5350_SDM_OFFSET + 0x110)
+
+#define RT5350_SDM_ICS_EN	BIT(16)
+#define RT5350_SDM_TCS_EN	BIT(17)
+#define RT5350_SDM_UCS_EN	BIT(18)
+
+/* MDIO_CFG register bits */
+#define FE_MDIO_CFG_AUTO_POLL_EN	BIT(29)
+#define FE_MDIO_CFG_GP1_BP_EN		BIT(16)
+#define FE_MDIO_CFG_GP1_FRC_EN		BIT(15)
+#define FE_MDIO_CFG_GP1_SPEED_10	(0 << 13)
+#define FE_MDIO_CFG_GP1_SPEED_100	(1 << 13)
+#define FE_MDIO_CFG_GP1_SPEED_1000	(2 << 13)
+#define FE_MDIO_CFG_GP1_DUPLEX		BIT(12)
+#define FE_MDIO_CFG_GP1_FC_TX		BIT(11)
+#define FE_MDIO_CFG_GP1_FC_RX		BIT(10)
+#define FE_MDIO_CFG_GP1_LNK_DWN		BIT(9)
+#define FE_MDIO_CFG_GP1_AN_FAIL		BIT(8)
+#define FE_MDIO_CFG_MDC_CLK_DIV_1	(0 << 6)
+#define FE_MDIO_CFG_MDC_CLK_DIV_2	(1 << 6)
+#define FE_MDIO_CFG_MDC_CLK_DIV_4	(2 << 6)
+#define FE_MDIO_CFG_MDC_CLK_DIV_8	(3 << 6)
+#define FE_MDIO_CFG_TURBO_MII_FREQ	BIT(5)
+#define FE_MDIO_CFG_TURBO_MII_MODE	BIT(4)
+#define FE_MDIO_CFG_RX_CLK_SKEW_0	(0 << 2)
+#define FE_MDIO_CFG_RX_CLK_SKEW_200	(1 << 2)
+#define FE_MDIO_CFG_RX_CLK_SKEW_400	(2 << 2)
+#define FE_MDIO_CFG_RX_CLK_SKEW_INV	(3 << 2)
+#define FE_MDIO_CFG_TX_CLK_SKEW_0	0
+#define FE_MDIO_CFG_TX_CLK_SKEW_200	1
+#define FE_MDIO_CFG_TX_CLK_SKEW_400	2
+#define FE_MDIO_CFG_TX_CLK_SKEW_INV	3
+
+/* uni-cast port */
+#define FE_GDM1_JMB_LEN_MASK	0xf
+#define FE_GDM1_JMB_LEN_SHIFT	28
+#define FE_GDM1_ICS_EN		BIT(22)
+#define FE_GDM1_TCS_EN		BIT(21)
+#define FE_GDM1_UCS_EN		BIT(20)
+#define FE_GDM1_JMB_EN		BIT(19)
+#define FE_GDM1_STRPCRC		BIT(16)
+#define FE_GDM1_UFRC_P_CPU	(0 << 12)
+#define FE_GDM1_UFRC_P_GDMA1	(1 << 12)
+#define FE_GDM1_UFRC_P_PPE	(6 << 12)
+
+/* checksums */
+#define FE_ICS_GEN_EN		BIT(2)
+#define FE_UCS_GEN_EN		BIT(1)
+#define FE_TCS_GEN_EN		BIT(0)
+
+/* dma ring */
+#define FE_PST_DRX_IDX0		BIT(16)
+#define FE_PST_DTX_IDX3		BIT(3)
+#define FE_PST_DTX_IDX2		BIT(2)
+#define FE_PST_DTX_IDX1		BIT(1)
+#define FE_PST_DTX_IDX0		BIT(0)
+
+#define FE_RX_2B_OFFSET		BIT(31)
+#define FE_TX_WB_DDONE		BIT(6)
+#define FE_RX_DMA_BUSY		BIT(3)
+#define FE_TX_DMA_BUSY		BIT(1)
+#define FE_RX_DMA_EN		BIT(2)
+#define FE_TX_DMA_EN		BIT(0)
+
+#define FE_PDMA_SIZE_4DWORDS	(0 << 4)
+#define FE_PDMA_SIZE_8DWORDS	(1 << 4)
+#define FE_PDMA_SIZE_16DWORDS	(2 << 4)
+
+#define FE_US_CYC_CNT_MASK	0xff
+#define FE_US_CYC_CNT_SHIFT	0x8
+#define FE_US_CYC_CNT_DIVISOR	1000000
+
+/* rxd2 */
+#define RX_DMA_DONE		BIT(31)
+#define RX_DMA_LSO		BIT(30)
+#define RX_DMA_PLEN0(_x)	(((_x) & 0x3fff) << 16)
+#define RX_DMA_GET_PLEN0(_x)	(((_x) >> 16) & 0x3fff)
+#define RX_DMA_TAG		BIT(15)
+/* rxd3 */
+#define RX_DMA_TPID(_x)		(((_x) >> 16) & 0xffff)
+#define RX_DMA_VID(_x)		((_x) & 0xffff)
+/* rxd4 */
+#define RX_DMA_L4VALID		BIT(30)
+
+struct fe_rx_dma {
+	unsigned int rxd1;
+	unsigned int rxd2;
+	unsigned int rxd3;
+	unsigned int rxd4;
+} __packed __aligned(4);
+
+#define TX_DMA_BUF_LEN		0x3fff
+#define TX_DMA_PLEN0_MASK	(TX_DMA_BUF_LEN << 16)
+#define TX_DMA_PLEN0(_x)	(((_x) & TX_DMA_BUF_LEN) << 16)
+#define TX_DMA_PLEN1(_x)	((_x) & TX_DMA_BUF_LEN)
+#define TX_DMA_GET_PLEN0(_x)    (((_x) >> 16) & TX_DMA_BUF_LEN)
+#define TX_DMA_GET_PLEN1(_x)    ((_x) & TX_DMA_BUF_LEN)
+#define TX_DMA_LS1		BIT(14)
+#define TX_DMA_LS0		BIT(30)
+#define TX_DMA_DONE		BIT(31)
+
+#define TX_DMA_INS_VLAN_MT7621	BIT(16)
+#define TX_DMA_INS_VLAN		BIT(7)
+#define TX_DMA_INS_PPPOE	BIT(12)
+#define TX_DMA_QN(_x)		((_x) << 16)
+#define TX_DMA_PN(_x)		((_x) << 24)
+#define TX_DMA_QN_MASK		TX_DMA_QN(0x7)
+#define TX_DMA_PN_MASK		TX_DMA_PN(0x7)
+#define TX_DMA_UDF		BIT(20)
+#define TX_DMA_CHKSUM		(0x7 << 29)
+#define TX_DMA_TSO		BIT(28)
+
+/* frame engine counters */
+#define FE_PPE_AC_BCNT0		(FE_CMTABLE_OFFSET + 0x00)
+#define FE_GDMA1_TX_GBCNT	(FE_CMTABLE_OFFSET + 0x300)
+#define FE_GDMA2_TX_GBCNT	(FE_GDMA1_TX_GBCNT + 0x40)
+
+/* phy device flags */
+#define FE_PHY_FLAG_PORT	BIT(0)
+#define FE_PHY_FLAG_ATTACH	BIT(1)
+
+struct fe_tx_dma {
+	unsigned int txd1;
+	unsigned int txd2;
+	unsigned int txd3;
+	unsigned int txd4;
+} __packed __aligned(4);
+
+struct fe_priv;
+
+struct fe_phy {
+	/* make sure that phy operations are atomic */
+	spinlock_t		lock;
+
+	struct phy_device	*phy[8];
+	struct device_node	*phy_node[8];
+	const __be32		*phy_fixed[8];
+	int			duplex[8];
+	int			speed[8];
+	int			tx_fc[8];
+	int			rx_fc[8];
+	int (*connect)(struct fe_priv *priv);
+	void (*disconnect)(struct fe_priv *priv);
+	void (*start)(struct fe_priv *priv);
+	void (*stop)(struct fe_priv *priv);
+};
+
+struct fe_soc_data {
+	const u16 *reg_table;
+
+	void (*init_data)(struct fe_soc_data *data, struct net_device *netdev);
+	void (*reset_fe)(void);
+	void (*set_mac)(struct fe_priv *priv, unsigned char *mac);
+	int (*fwd_config)(struct fe_priv *priv);
+	void (*tx_dma)(struct fe_tx_dma *txd);
+	int (*switch_init)(struct fe_priv *priv);
+	int (*switch_config)(struct fe_priv *priv);
+	void (*port_init)(struct fe_priv *priv, struct device_node *port);
+	int (*has_carrier)(struct fe_priv *priv);
+	int (*mdio_init)(struct fe_priv *priv);
+	void (*mdio_cleanup)(struct fe_priv *priv);
+	int (*mdio_write)(struct mii_bus *bus, int phy_addr, int phy_reg,
+			  u16 val);
+	int (*mdio_read)(struct mii_bus *bus, int phy_addr, int phy_reg);
+	void (*mdio_adjust_link)(struct fe_priv *priv, int port);
+
+	void *swpriv;
+	u32 pdma_glo_cfg;
+	u32 rx_int;
+	u32 tx_int;
+	u32 status_int;
+	u32 checksum_bit;
+};
+
+#define FE_FLAG_PADDING_64B		BIT(0)
+#define FE_FLAG_PADDING_BUG		BIT(1)
+#define FE_FLAG_JUMBO_FRAME		BIT(2)
+#define FE_FLAG_RX_2B_OFFSET		BIT(3)
+#define FE_FLAG_RX_SG_DMA		BIT(4)
+#define FE_FLAG_NAPI_WEIGHT		BIT(6)
+#define FE_FLAG_CALIBRATE_CLK		BIT(7)
+#define FE_FLAG_HAS_SWITCH		BIT(8)
+
+#define FE_STAT_REG_DECLARE		\
+	_FE(tx_bytes)			\
+	_FE(tx_packets)			\
+	_FE(tx_skip)			\
+	_FE(tx_collisions)		\
+	_FE(rx_bytes)			\
+	_FE(rx_packets)			\
+	_FE(rx_overflow)		\
+	_FE(rx_fcs_errors)		\
+	_FE(rx_short_errors)		\
+	_FE(rx_long_errors)		\
+	_FE(rx_checksum_errors)		\
+	_FE(rx_flow_control_packets)
+
+struct fe_hw_stats {
+	/* make sure that stats operations are atomic */
+	spinlock_t stats_lock;
+
+	struct u64_stats_sync syncp;
+#define _FE(x) u64 x;
+	FE_STAT_REG_DECLARE
+#undef _FE
+};
+
+struct fe_tx_buf {
+	struct sk_buff *skb;
+	DEFINE_DMA_UNMAP_ADDR(dma_addr0);
+	DEFINE_DMA_UNMAP_ADDR(dma_addr1);
+	u16 dma_len0;
+	u16 dma_len1;
+};
+
+struct fe_tx_ring {
+	struct fe_tx_dma *tx_dma;
+	struct fe_tx_buf *tx_buf;
+	dma_addr_t tx_phys;
+	u16 tx_ring_size;
+	u16 tx_free_idx;
+	u16 tx_next_idx;
+	u16 tx_thresh;
+};
+
+struct fe_rx_ring {
+	struct page_frag_cache frag_cache;
+	struct fe_rx_dma *rx_dma;
+	u8 **rx_data;
+	dma_addr_t rx_phys;
+	u16 rx_ring_size;
+	u16 frag_size;
+	u16 rx_buf_size;
+	u16 rx_calc_idx;
+};
+
+struct fe_priv {
+	/* make sure that register operations are atomic */
+	spinlock_t			page_lock;
+
+	struct fe_soc_data		*soc;
+	struct net_device		*netdev;
+	struct device_node		*switch_np;
+	u32				msg_enable;
+	u32				flags;
+
+	struct device			*dev;
+	unsigned long			sysclk;
+
+	struct fe_rx_ring		rx_ring;
+	struct napi_struct		rx_napi;
+
+	struct fe_tx_ring               tx_ring;
+
+	struct fe_phy			*phy;
+	struct mii_bus			*mii_bus;
+	struct phy_device		*phy_dev;
+	u32				phy_flags;
+
+	int				link[8];
+
+	struct fe_hw_stats		*hw_stats;
+	unsigned long			vlan_map;
+	struct work_struct		pending_work;
+	DECLARE_BITMAP(pending_flags, FE_FLAG_MAX);
+
+	struct reset_control		*rst_ppe;
+	struct mtk_foe_entry		*foe_table;
+	dma_addr_t			foe_table_phys;
+	struct flow_offload __rcu	**foe_flow_table;
+};
+
+extern const struct of_device_id of_fe_match[];
+
+void fe_w32(u32 val, unsigned reg);
+void fe_m32(struct fe_priv *priv, u32 clear, u32 set, unsigned reg);
+u32 fe_r32(unsigned reg);
+
+int fe_set_clock_cycle(struct fe_priv *priv);
+void fe_csum_config(struct fe_priv *priv);
+void fe_stats_update(struct fe_priv *priv);
+void fe_fwd_config(struct fe_priv *priv);
+void fe_reg_w32(u32 val, enum fe_reg reg);
+u32 fe_reg_r32(enum fe_reg reg);
+
+void fe_reset(u32 reset_bits);
+
+static inline void *priv_netdev(struct fe_priv *priv)
+{
+	return (char *)priv - ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
+}
+
+
+#endif /* FE_ETH_H */
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c
new file mode 100644
index 0000000..2470e7a
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_mt7620.c
@@ -0,0 +1,374 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/if_vlan.h>
+#include <linux/of_net.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include <mt7620.h>
+#include "mtk_eth_soc.h"
+#include "gsw_mt7620.h"
+#include "mt7530.h"
+#include "mdio.h"
+
+#define MT7620A_CDMA_CSG_CFG	0x400
+#define MT7620_DMA_VID		(MT7620A_CDMA_CSG_CFG | 0x30)
+#define MT7620_L4_VALID		BIT(23)
+
+#define MT7620_TX_DMA_UDF	BIT(15)
+#define TX_DMA_FP_BMAP		((0xff) << 19)
+
+#define CDMA_ICS_EN		BIT(2)
+#define CDMA_UCS_EN		BIT(1)
+#define CDMA_TCS_EN		BIT(0)
+
+#define GDMA_ICS_EN		BIT(22)
+#define GDMA_TCS_EN		BIT(21)
+#define GDMA_UCS_EN		BIT(20)
+
+/* frame engine counters */
+#define MT7620_REG_MIB_OFFSET	0x1000
+#define MT7620_PPE_AC_BCNT0	(MT7620_REG_MIB_OFFSET + 0x00)
+#define MT7620_GDM1_TX_GBCNT	(MT7620_REG_MIB_OFFSET + 0x300)
+#define MT7620_GDM2_TX_GBCNT	(MT7620_GDM1_TX_GBCNT + 0x40)
+
+#define GSW_REG_GDMA1_MAC_ADRL	0x508
+#define GSW_REG_GDMA1_MAC_ADRH	0x50C
+
+#define MT7621_FE_RST_GL	(FE_FE_OFFSET + 0x04)
+#define MT7620_FE_INT_STATUS2	(FE_FE_OFFSET + 0x08)
+
+/* FE_INT_STATUS reg on mt7620 define CNT_GDM1_AF at BIT(29)
+ * but after test it should be BIT(13).
+ */
+#define MT7620_FE_GDM1_AF	BIT(13)
+
+static const u16 mt7620_reg_table[FE_REG_COUNT] = {
+	[FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
+	[FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
+	[FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
+	[FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
+	[FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
+	[FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
+	[FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0,
+	[FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
+	[FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
+	[FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
+	[FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0,
+	[FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
+	[FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
+	[FE_REG_FE_DMA_VID_BASE] = MT7620_DMA_VID,
+	[FE_REG_FE_COUNTER_BASE] = MT7620_GDM1_TX_GBCNT,
+	[FE_REG_FE_RST_GL] = MT7621_FE_RST_GL,
+	[FE_REG_FE_INT_STATUS2] = MT7620_FE_INT_STATUS2,
+};
+
+static int mt7620_gsw_config(struct fe_priv *priv)
+{
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *) priv->soc->swpriv;
+	u32 val;
+
+	/* is the mt7530 internal or external */
+	if (priv->mii_bus && mdiobus_get_phy(priv->mii_bus, 0x1f)) {
+		mt7530_probe(priv->dev, gsw->base, NULL, 0);
+		mt7530_probe(priv->dev, NULL, priv->mii_bus, 1);
+
+		/* magic values from original SDK */
+		val = mt7530_mdio_r32(gsw, 0x7830);
+		val &= ~BIT(0);
+		val |= BIT(1);
+		mt7530_mdio_w32(gsw, 0x7830, val);
+
+		val = mt7530_mdio_r32(gsw, 0x7a40);
+		val &= ~BIT(30);
+		mt7530_mdio_w32(gsw, 0x7a40, val);
+
+		mt7530_mdio_w32(gsw, 0x7a78, 0x855);
+
+		pr_info("mt7530: mdio central align\n");
+	} else {
+		mt7530_probe(priv->dev, gsw->base, NULL, 1);
+	}
+
+	return 0;
+}
+
+static void mt7620_set_mac(struct fe_priv *priv, unsigned char *mac)
+{
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->page_lock, flags);
+	mtk_switch_w32(gsw, (mac[0] << 8) | mac[1], GSW_REG_SMACCR1);
+	mtk_switch_w32(gsw, (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+		GSW_REG_SMACCR0);
+	spin_unlock_irqrestore(&priv->page_lock, flags);
+}
+
+static void mt7620_auto_poll(struct mt7620_gsw *gsw, int port)
+{
+	int phy;
+	int lsb = -1, msb = 0;
+
+	for_each_set_bit(phy, &gsw->autopoll, 32) {
+		if (lsb < 0)
+			lsb = phy;
+		msb = phy;
+	}
+
+	if (lsb == msb && port ==  4)
+		msb++;
+	else if (lsb == msb && port ==  5)
+		lsb--;
+
+	mtk_switch_w32(gsw, PHY_AN_EN | PHY_PRE_EN | PMY_MDC_CONF(5) |
+		(msb << 8) | lsb, ESW_PHY_POLLING);
+}
+
+static void mt7620_port_init(struct fe_priv *priv, struct device_node *np)
+{
+	struct mt7620_gsw *gsw = (struct mt7620_gsw *)priv->soc->swpriv;
+	const __be32 *_id = of_get_property(np, "reg", NULL);
+	const __be32 *phy_addr;
+	int phy_mode, size, id;
+	int shift = 12;
+	u32 val, mask = 0;
+	u32 val_delay = 0;
+	u32 mask_delay = GSW_REG_GPCx_TXDELAY | GSW_REG_GPCx_RXDELAY;
+	int min = (gsw->port4_ephy) ? (5) : (4);
+
+	if (!_id || (be32_to_cpu(*_id) < min) || (be32_to_cpu(*_id) > 5)) {
+		if (_id)
+			pr_err("%s: invalid port id %d\n", np->name,
+			       be32_to_cpu(*_id));
+		else
+			pr_err("%s: invalid port id\n", np->name);
+		return;
+	}
+
+	id = be32_to_cpu(*_id);
+
+	if (id == 4)
+		shift = 14;
+
+	priv->phy->phy_fixed[id] = of_get_property(np, "mediatek,fixed-link",
+						   &size);
+	if (priv->phy->phy_fixed[id] &&
+	    (size != (4 * sizeof(*priv->phy->phy_fixed[id])))) {
+		pr_err("%s: invalid fixed link property\n", np->name);
+		priv->phy->phy_fixed[id] = NULL;
+	}
+
+	phy_mode = of_get_phy_mode(np);
+	switch (phy_mode) {
+	case PHY_INTERFACE_MODE_RGMII:
+		mask = 0;
+		/* Do not touch rx/tx delay in this state to avoid problems with
+		 * backward compability.
+		 */
+		mask_delay = 0;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		mask = 0;
+		val_delay |= GSW_REG_GPCx_TXDELAY;
+		val_delay &= ~GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		mask = 0;
+		val_delay &= ~GSW_REG_GPCx_TXDELAY;
+		val_delay &= ~GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		mask = 0;
+		val_delay |= GSW_REG_GPCx_TXDELAY;
+		val_delay |= GSW_REG_GPCx_RXDELAY;
+		break;
+	case PHY_INTERFACE_MODE_MII:
+		mask = 1;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		mask = 2;
+		break;
+	default:
+		dev_err(priv->dev, "port %d - invalid phy mode\n", id);
+		return;
+	}
+
+	val = rt_sysc_r32(SYSC_REG_CFG1);
+	val &= ~(3 << shift);
+	val |= mask << shift;
+	rt_sysc_w32(val, SYSC_REG_CFG1);
+
+	if (id == 4) {
+		val = mtk_switch_r32(gsw, GSW_REG_GPC2);
+		val &= ~(mask_delay);
+		val |= val_delay & mask_delay;
+		mtk_switch_w32(gsw, val, GSW_REG_GPC2);
+	}
+	else if (id == 5) {
+		val = mtk_switch_r32(gsw, GSW_REG_GPC1);
+		val &= ~(mask_delay);
+		val |= val_delay & mask_delay;
+		mtk_switch_w32(gsw, val, GSW_REG_GPC1);
+	}
+
+	if (priv->phy->phy_fixed[id]) {
+		const __be32 *link = priv->phy->phy_fixed[id];
+		int tx_fc, rx_fc;
+		u32 val = 0;
+
+		priv->phy->speed[id] = be32_to_cpup(link++);
+		tx_fc = be32_to_cpup(link++);
+		rx_fc = be32_to_cpup(link++);
+		priv->phy->duplex[id] = be32_to_cpup(link++);
+		priv->link[id] = 1;
+
+		switch (priv->phy->speed[id]) {
+		case SPEED_10:
+			val = 0;
+			break;
+		case SPEED_100:
+			val = 1;
+			break;
+		case SPEED_1000:
+			val = 2;
+			break;
+		default:
+			dev_err(priv->dev, "port %d - invalid link speed: %d\n",
+				id, priv->phy->speed[id]);
+			priv->phy->phy_fixed[id] = 0;
+			return;
+		}
+		val = PMCR_SPEED(val);
+		val |= PMCR_LINK | PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
+			PMCR_TX_EN | PMCR_FORCE | PMCR_MAC_MODE | PMCR_IPG;
+		if (tx_fc)
+			val |= PMCR_TX_FC;
+		if (rx_fc)
+			val |= PMCR_RX_FC;
+		if (priv->phy->duplex[id])
+			val |= PMCR_DUPLEX;
+		mtk_switch_w32(gsw, val, GSW_REG_PORT_PMCR(id));
+		dev_info(priv->dev, "port %d - using fixed link parameters\n", id);
+		return;
+	}
+
+	priv->phy->phy_node[id] = of_parse_phandle(np, "phy-handle", 0);
+	if (!priv->phy->phy_node[id]) {
+		dev_err(priv->dev, "port %d - missing phy handle\n", id);
+		return;
+	}
+
+	phy_addr = of_get_property(priv->phy->phy_node[id], "reg", NULL);
+	if (phy_addr && mdiobus_get_phy(priv->mii_bus, be32_to_cpup(phy_addr))) {
+		u32 val = PMCR_BACKPRES | PMCR_BACKOFF | PMCR_RX_EN |
+			PMCR_TX_EN |  PMCR_MAC_MODE | PMCR_IPG;
+
+		mtk_switch_w32(gsw, val, GSW_REG_PORT_PMCR(id));
+		fe_connect_phy_node(priv, priv->phy->phy_node[id], id);
+		gsw->autopoll |= BIT(be32_to_cpup(phy_addr));
+		mt7620_auto_poll(gsw,id);
+	}
+}
+
+static void mt7620_fe_reset(void)
+{
+	fe_reset(MT7620A_RESET_FE | MT7620A_RESET_ESW);
+}
+
+static void mt7620_rxcsum_config(bool enable)
+{
+	if (enable)
+		fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) | (GDMA_ICS_EN |
+					GDMA_TCS_EN | GDMA_UCS_EN),
+				MT7620A_GDMA1_FWD_CFG);
+	else
+		fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~(GDMA_ICS_EN |
+					GDMA_TCS_EN | GDMA_UCS_EN),
+				MT7620A_GDMA1_FWD_CFG);
+}
+
+static void mt7620_txcsum_config(bool enable)
+{
+	if (enable)
+		fe_w32(fe_r32(MT7620A_CDMA_CSG_CFG) | (CDMA_ICS_EN |
+					CDMA_UCS_EN | CDMA_TCS_EN),
+				MT7620A_CDMA_CSG_CFG);
+	else
+		fe_w32(fe_r32(MT7620A_CDMA_CSG_CFG) & ~(CDMA_ICS_EN |
+					CDMA_UCS_EN | CDMA_TCS_EN),
+				MT7620A_CDMA_CSG_CFG);
+}
+
+static int mt7620_fwd_config(struct fe_priv *priv)
+{
+	struct net_device *dev = priv_netdev(priv);
+
+	fe_w32(fe_r32(MT7620A_GDMA1_FWD_CFG) & ~7, MT7620A_GDMA1_FWD_CFG);
+
+	mt7620_txcsum_config((dev->features & NETIF_F_IP_CSUM));
+	mt7620_rxcsum_config((dev->features & NETIF_F_RXCSUM));
+
+	return 0;
+}
+
+static void mt7620_tx_dma(struct fe_tx_dma *txd)
+{
+}
+
+static void mt7620_init_data(struct fe_soc_data *data,
+			     struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+
+	priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_RX_2B_OFFSET |
+		FE_FLAG_RX_SG_DMA | FE_FLAG_HAS_SWITCH;
+
+	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+		NETIF_F_HW_VLAN_CTAG_TX;
+	if (mt7620_get_eco() >= 5)
+		netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+			NETIF_F_IPV6_CSUM;
+}
+
+static struct fe_soc_data mt7620_data = {
+	.init_data = mt7620_init_data,
+	.reset_fe = mt7620_fe_reset,
+	.set_mac = mt7620_set_mac,
+	.fwd_config = mt7620_fwd_config,
+	.tx_dma = mt7620_tx_dma,
+	.switch_init = mtk_gsw_init,
+	.switch_config = mt7620_gsw_config,
+	.port_init = mt7620_port_init,
+	.reg_table = mt7620_reg_table,
+	.pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,
+	.rx_int = RT5350_RX_DONE_INT,
+	.tx_int = RT5350_TX_DONE_INT,
+	.status_int = MT7620_FE_GDM1_AF,
+	.checksum_bit = MT7620_L4_VALID,
+	.has_carrier = mt7620_has_carrier,
+	.mdio_read = mt7620_mdio_read,
+	.mdio_write = mt7620_mdio_write,
+	.mdio_adjust_link = mt7620_mdio_link_adjust,
+};
+
+const struct of_device_id of_fe_match[] = {
+	{ .compatible = "mediatek,mt7620-eth", .data = &mt7620_data },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_fe_match);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt2880.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt2880.c
new file mode 100644
index 0000000..6c89c99
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt2880.c
@@ -0,0 +1,76 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio_rt2880.h"
+
+#define RT2880_RESET_FE			BIT(18)
+
+static void rt2880_init_data(struct fe_soc_data *data,
+			     struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+
+	priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
+		FE_FLAG_JUMBO_FRAME | FE_FLAG_CALIBRATE_CLK;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_TX;
+	/* this should work according to the datasheet but actually does not*/
+	/* netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; */
+}
+
+void rt2880_fe_reset(void)
+{
+	fe_reset(RT2880_RESET_FE);
+}
+
+static int rt2880_fwd_config(struct fe_priv *priv)
+{
+	int ret;
+
+	ret = fe_set_clock_cycle(priv);
+	if (ret)
+		return ret;
+
+	fe_fwd_config(priv);
+	fe_w32(FE_PSE_FQFC_CFG_INIT, FE_PSE_FQ_CFG);
+	fe_csum_config(priv);
+
+	return ret;
+}
+
+struct fe_soc_data rt2880_data = {
+	.init_data = rt2880_init_data,
+	.reset_fe = rt2880_fe_reset,
+	.fwd_config = rt2880_fwd_config,
+	.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
+	.checksum_bit = RX_DMA_L4VALID,
+	.rx_int = FE_RX_DONE_INT,
+	.tx_int = FE_TX_DONE_INT,
+	.status_int = FE_CNT_GDM_AF,
+	.mdio_read = rt2880_mdio_read,
+	.mdio_write = rt2880_mdio_write,
+	.mdio_adjust_link = rt2880_mdio_link_adjust,
+	.port_init = rt2880_port_init,
+};
+
+const struct of_device_id of_fe_match[] = {
+	{ .compatible = "ralink,rt2880-eth", .data = &rt2880_data },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_fe_match);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c
new file mode 100644
index 0000000..914b814
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c
@@ -0,0 +1,158 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio_rt2880.h"
+
+#define RT305X_RESET_FE         BIT(21)
+#define RT305X_RESET_ESW        BIT(23)
+
+static const u16 rt5350_reg_table[FE_REG_COUNT] = {
+	[FE_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
+	[FE_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
+	[FE_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
+	[FE_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
+	[FE_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
+	[FE_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
+	[FE_REG_TX_DTX_IDX0] = RT5350_TX_DTX_IDX0,
+	[FE_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
+	[FE_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
+	[FE_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
+	[FE_REG_RX_DRX_IDX0] = RT5350_RX_DRX_IDX0,
+	[FE_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
+	[FE_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
+	[FE_REG_FE_RST_GL] = 0,
+	[FE_REG_FE_DMA_VID_BASE] = 0,
+};
+
+static void rt305x_init_data(struct fe_soc_data *data,
+			     struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+
+	priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
+		FE_FLAG_CALIBRATE_CLK | FE_FLAG_HAS_SWITCH;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX;
+}
+
+static int rt3050_fwd_config(struct fe_priv *priv)
+{
+	int ret;
+
+	if (ralink_soc != RT305X_SOC_RT3052) {
+		ret = fe_set_clock_cycle(priv);
+		if (ret)
+			return ret;
+	}
+
+	fe_fwd_config(priv);
+	if (ralink_soc != RT305X_SOC_RT3352)
+		fe_w32(FE_PSE_FQFC_CFG_INIT, FE_PSE_FQ_CFG);
+	fe_csum_config(priv);
+
+	return 0;
+}
+
+static void rt305x_fe_reset(void)
+{
+	fe_reset(RT305X_RESET_FE);
+}
+
+static void rt5350_init_data(struct fe_soc_data *data,
+			     struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+
+	priv->flags = FE_FLAG_HAS_SWITCH;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM;
+}
+
+static void rt5350_set_mac(struct fe_priv *priv, unsigned char *mac)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->page_lock, flags);
+	fe_w32((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH);
+	fe_w32((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+	       RT5350_SDM_MAC_ADRL);
+	spin_unlock_irqrestore(&priv->page_lock, flags);
+}
+
+static void rt5350_rxcsum_config(bool enable)
+{
+	if (enable)
+		fe_w32(fe_r32(RT5350_SDM_CFG) | (RT5350_SDM_ICS_EN |
+				RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN),
+				RT5350_SDM_CFG);
+	else
+		fe_w32(fe_r32(RT5350_SDM_CFG) & ~(RT5350_SDM_ICS_EN |
+				RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN),
+				RT5350_SDM_CFG);
+}
+
+static int rt5350_fwd_config(struct fe_priv *priv)
+{
+	struct net_device *dev = priv_netdev(priv);
+
+	rt5350_rxcsum_config((dev->features & NETIF_F_RXCSUM));
+
+	return 0;
+}
+
+static void rt5350_tx_dma(struct fe_tx_dma *txd)
+{
+	txd->txd4 = 0;
+}
+
+static void rt5350_fe_reset(void)
+{
+	fe_reset(RT305X_RESET_FE | RT305X_RESET_ESW);
+}
+
+static struct fe_soc_data rt3050_data = {
+	.init_data = rt305x_init_data,
+	.reset_fe = rt305x_fe_reset,
+	.fwd_config = rt3050_fwd_config,
+	.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
+	.checksum_bit = RX_DMA_L4VALID,
+	.rx_int = FE_RX_DONE_INT,
+	.tx_int = FE_TX_DONE_INT,
+	.status_int = FE_CNT_GDM_AF,
+};
+
+static struct fe_soc_data rt5350_data = {
+	.init_data = rt5350_init_data,
+	.reg_table = rt5350_reg_table,
+	.reset_fe = rt5350_fe_reset,
+	.set_mac = rt5350_set_mac,
+	.fwd_config = rt5350_fwd_config,
+	.tx_dma = rt5350_tx_dma,
+	.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
+	.checksum_bit = RX_DMA_L4VALID,
+	.rx_int = RT5350_RX_DONE_INT,
+	.tx_int = RT5350_TX_DONE_INT,
+};
+
+const struct of_device_id of_fe_match[] = {
+	{ .compatible = "ralink,rt3050-eth", .data = &rt3050_data },
+	{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_fe_match);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3883.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3883.c
new file mode 100644
index 0000000..4935b7f
--- /dev/null
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3883.c
@@ -0,0 +1,75 @@
+/*   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; version 2 of the License
+ *
+ *   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.
+ *
+ *   Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ *   Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ *   Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ */
+
+#include <linux/module.h>
+
+#include <asm/mach-ralink/ralink_regs.h>
+
+#include "mtk_eth_soc.h"
+#include "mdio_rt2880.h"
+
+#define RT3883_RSTCTRL_FE		BIT(21)
+
+static void rt3883_fe_reset(void)
+{
+	fe_reset(RT3883_RSTCTRL_FE);
+}
+
+static int rt3883_fwd_config(struct fe_priv *priv)
+{
+	int ret;
+
+	ret = fe_set_clock_cycle(priv);
+	if (ret)
+		return ret;
+
+	fe_fwd_config(priv);
+	fe_w32(FE_PSE_FQFC_CFG_256Q, FE_PSE_FQ_CFG);
+	fe_csum_config(priv);
+
+	return ret;
+}
+
+static void rt3883_init_data(struct fe_soc_data *data,
+			     struct net_device *netdev)
+{
+	struct fe_priv *priv = netdev_priv(netdev);
+
+	priv->flags = FE_FLAG_PADDING_64B | FE_FLAG_PADDING_BUG |
+		FE_FLAG_JUMBO_FRAME | FE_FLAG_CALIBRATE_CLK;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX;
+}
+
+static struct fe_soc_data rt3883_data = {
+	.init_data = rt3883_init_data,
+	.reset_fe = rt3883_fe_reset,
+	.fwd_config = rt3883_fwd_config,
+	.pdma_glo_cfg = FE_PDMA_SIZE_8DWORDS,
+	.rx_int = FE_RX_DONE_INT,
+	.tx_int = FE_TX_DONE_INT,
+	.status_int = FE_CNT_GDM_AF,
+	.checksum_bit = RX_DMA_L4VALID,
+	.mdio_read = rt2880_mdio_read,
+	.mdio_write = rt2880_mdio_write,
+	.mdio_adjust_link = rt2880_mdio_link_adjust,
+	.port_init = rt2880_port_init,
+};
+
+const struct of_device_id of_fe_match[] = {
+	{ .compatible = "ralink,rt3883-eth", .data = &rt3883_data },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, of_fe_match);
diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
new file mode 100644
index 0000000..5937970
--- /dev/null
+++ b/target/linux/ramips/image/Makefile
@@ -0,0 +1,206 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2008-2011 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+DEVICE_VARS += LOADER_TYPE LOADER_FLASH_OFFS
+DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID
+DEVICE_VARS += BUFFALO_TAG_PLATFORM BUFFALO_TAG_VERSION BUFFALO_TAG_MINOR
+DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK
+DEVICE_VARS += SERCOMM_HWNAME SERCOMM_HWID SERCOMM_HWVER SERCOMM_SWVER
+DEVICE_VARS += SERCOMM_PAD JCG_MAXSIZE
+
+loadaddr-y := 0x80000000
+loadaddr-$(CONFIG_TARGET_ramips_rt288x) := 0x88000000
+loadaddr-$(CONFIG_TARGET_ramips_mt7621) := 0x80001000
+
+ldrplatform-y := ralink
+ldrplatform-$(CONFIG_TARGET_ramips_mt7621) := mt7621
+
+ldrflashstart-y := 0x1c000000
+ldrflashstart-$(CONFIG_TARGET_ramips_mt7621) := 0x1fc00000
+
+KERNEL_LOADADDR := $(loadaddr-y)
+LOADER_PLATFORM := $(ldrplatform-y)
+LOADER_FLASH_START := $(ldrflashstart-y)
+
+KERNEL_DTB = kernel-bin | append-dtb | lzma
+
+define Build/edimax-header
+	$(STAGING_DIR_HOST)/bin/mkedimaximg -i $@ -o $@.new $(1)
+	@mv $@.new $@
+endef
+
+define Build/jcg-header
+	$(STAGING_DIR_HOST)/bin/jcgimage -v $(1) \
+		$(if $(JCG_MAXSIZE), -m $$(($(subst k, * 1024,$(JCG_MAXSIZE)))),) \
+		-u $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/loader-common
+	rm -rf $@.src
+	$(MAKE) -C lzma-loader \
+		PKG_BUILD_DIR="$@.src" \
+		TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \
+		BOARD="$(BOARDNAME)" PLATFORM="$(LOADER_PLATFORM)" \
+		LZMA_TEXT_START=0x81800000 LOADADDR=$(KERNEL_LOADADDR) \
+		$(1) compile loader.$(LOADER_TYPE)
+	mv "$@.$(LOADER_TYPE)" "$@"
+	rm -rf $@.src
+endef
+
+define Build/loader-kernel
+	$(call Build/loader-common,LOADER_DATA="$@")
+endef
+
+define Build/loader-okli-compile
+	$(call Build/loader-common, \
+		FLASH_START=$(LOADER_FLASH_START) \
+		FLASH_OFFS=$(LOADER_FLASH_OFFS) \
+		FLASH_MAX=0 \
+	)
+endef
+
+define Build/append-loader-okli
+	cat "$(KDIR)/loader-$(word 1,$(1)).$(LOADER_TYPE)" >> "$@"
+endef
+
+# combine kernel and rootfs into one image
+# mkdlinkfw <type> <optional extra arguments to mkdlinkfw binary>
+define Build/mkdlinkfw
+	-$(STAGING_DIR_HOST)/bin/mkdlinkfw \
+		-k $(IMAGE_KERNEL) \
+		-r $(IMAGE_ROOTFS) \
+		-o $@ \
+		$(if $(DLINK_IMAGE_OFFSET), -O $(DLINK_IMAGE_OFFSET)) \
+		-s $(DLINK_FIRMWARE_SIZE)
+endef
+
+define Build/mkdlinkfw-factory
+	-$(STAGING_DIR_HOST)/bin/mkdlinkfw \
+		-m $(DLINK_ROM_ID) -f $(DLINK_FAMILY_MEMBER) \
+		-F $@ \
+		-o $@.new \
+		$(if $(DLINK_IMAGE_OFFSET), -O $(DLINK_IMAGE_OFFSET)) \
+		-s $(DLINK_FIRMWARE_SIZE)
+	mv $@.new $@
+endef
+
+define Build/netis-tail
+	echo -n $(1) >> $@
+	echo -n $(UIMAGE_NAME)-yun | $(STAGING_DIR_HOST)/bin/mkhash md5 | \
+		sed 's/../\\\\x&/g' | xargs echo -ne >> $@
+endef
+
+define Build/poray-header
+	$(STAGING_DIR_HOST)/bin/mkporayfw $(1) -f $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/relocate-kernel
+	rm -rf $@.relocate
+	$(CP) ../../generic/image/relocate $@.relocate
+	$(MAKE) -C $@.relocate KERNEL_ADDR=$(KERNEL_LOADADDR) CROSS_COMPILE=$(TARGET_CROSS)
+	( \
+		dd if=$@.relocate/loader.bin bs=32 conv=sync && \
+		perl -e '@s = stat("$@"); print pack("V", @s[7])' && \
+		cat $@ \
+	) > $@.new
+	mv $@.new $@
+	rm -rf $@.relocate
+endef
+
+define Build/sercom-footer
+	$(call Build/sercom-seal,-f)
+endef
+
+define Build/sercom-seal
+	$(STAGING_DIR_HOST)/bin/mksercommfw \
+		-i $@ \
+		-b $(SERCOMM_HWID) \
+		-r $(SERCOMM_HWVER) \
+		-v $(SERCOMM_SWVER) \
+		$(1)
+endef
+
+define Build/sign-dlink-ru
+	sign_dlink_ru $@ $1 $2
+	mv $@.new $@
+endef
+
+define Build/trx
+	$(STAGING_DIR_HOST)/bin/trx $(1) \
+		-o $@ \
+		-m $$(($(subst k, * 1024,$(IMAGE_SIZE)))) \
+		-f $(IMAGE_KERNEL) \
+		-a 4 -f $(IMAGE_ROOTFS)
+endef
+
+define Build/uimage-padhdr
+	uimage_padhdr $(if $(1),-l $(1)) -i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/umedia-header
+	fix-u-media-header -T 0x46 -B $(1) -i $@ -o $@.new && mv $@.new $@
+endef
+
+define Build/wrg-header
+	mkwrgimg -i $@ -d "/dev/mtdblock/2" -s $(1) -o $@.new
+	mv $@.new $@
+endef
+
+define Build/zyimage
+	$(STAGING_DIR_HOST)/bin/zyimage $(1) $@
+endef
+
+define Device/Default
+  PROFILES = Default
+  KERNEL := $(KERNEL_DTB) | uImage lzma
+  SOC := $(DEFAULT_SOC)
+  DEVICE_DTS_DIR := ../dts
+  DEVICE_DTS = $$(SOC)_$(1)
+  IMAGES := sysupgrade.bin
+  COMPILE :=
+  sysupgrade_bin := append-kernel | append-rootfs | pad-rootfs
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata | check-size
+endef
+
+define Device/netgear_sercomm_nor
+  BLOCKSIZE := 64k
+  DEVICE_VENDOR := NETGEAR
+  IMAGES += factory.img
+  IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE) | append-rootfs | \
+	pad-rootfs
+  IMAGE/sysupgrade.bin := $$(IMAGE/default) | append-metadata | check-size
+  IMAGE/factory.img := pad-extra $$$$(SERCOMM_PAD) | $$(IMAGE/default) | \
+	pad-to $$$$(BLOCKSIZE) | sercom-footer | pad-to 128 | \
+	zip $$$$(SERCOMM_HWNAME).bin | sercom-seal
+endef
+
+define Device/seama
+  SEAMA_MTDBLOCK := 2
+  IMAGES += factory.bin
+
+  # 64 bytes offset:
+  # - 28 bytes seama_header
+  # - 36 bytes of META data (4-bytes aligned)
+  IMAGE/default := append-kernel | pad-offset $$$$(BLOCKSIZE) 64 | append-rootfs
+  IMAGE/sysupgrade.bin := \
+	$$(IMAGE/default) | seama | pad-rootfs | append-metadata | check-size
+  IMAGE/factory.bin := \
+	$$(IMAGE/default) | pad-rootfs -x 64 | seama | seama-seal | check-size
+  SEAMA_SIGNATURE :=
+endef
+
+define Device/uimage-lzma-loader
+  LOADER_TYPE := bin
+  KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | uImage none
+endef
+
+include $(SUBTARGET).mk
+
+$(eval $(call BuildImage))
diff --git a/target/linux/ramips/image/common-tp-link.mk b/target/linux/ramips/image/common-tp-link.mk
new file mode 100644
index 0000000..07ad1ea
--- /dev/null
+++ b/target/linux/ramips/image/common-tp-link.mk
@@ -0,0 +1,44 @@
+DEVICE_VARS += TPLINK_FLASHLAYOUT TPLINK_HWID TPLINK_HWREV TPLINK_HWREVADD
+DEVICE_VARS += TPLINK_HVERSION TPLINK_BOARD_ID TPLINK_HEADER_VERSION
+
+define Device/tplink-v1
+  DEVICE_VENDOR := TP-Link
+  TPLINK_FLASHLAYOUT :=
+  TPLINK_HWID :=
+  TPLINK_HWREV := 0x1
+  TPLINK_HEADER_VERSION := 1
+  KERNEL := $(KERNEL_DTB)
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v1-header -e -O
+  IMAGES += factory.bin
+  IMAGE/factory.bin := tplink-v1-image factory -e -O
+  IMAGE/sysupgrade.bin := tplink-v1-image sysupgrade -e -O | append-metadata | \
+	check-size
+endef
+
+define Device/tplink-v2
+  DEVICE_VENDOR := TP-Link
+  TPLINK_FLASHLAYOUT :=
+  TPLINK_HWID :=
+  TPLINK_HWREV := 0x1
+  TPLINK_HWREVADD := 0x0
+  TPLINK_HVERSION := 3
+  KERNEL := $(KERNEL_DTB)
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | tplink-v2-header -e
+  IMAGES += factory.bin
+  IMAGE/factory.bin := tplink-v2-image -e
+  IMAGE/sysupgrade.bin := tplink-v2-image -s -e | append-metadata | \
+	check-size
+endef
+
+define Device/tplink-safeloader
+  DEVICE_VENDOR := TP-Link
+  TPLINK_BOARD_ID :=
+  TPLINK_HWID := 0x0
+  TPLINK_HWREV := 0x0
+  TPLINK_HEADER_VERSION := 1
+  KERNEL := $(KERNEL_DTB) | tplink-v1-header -e -O
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := append-rootfs | tplink-safeloader sysupgrade | \
+	append-metadata | check-size
+  IMAGE/factory.bin := append-rootfs | tplink-safeloader factory
+endef
diff --git a/target/linux/ramips/image/lzma-loader/Makefile b/target/linux/ramips/image/lzma-loader/Makefile
new file mode 100644
index 0000000..4cf700d
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+# Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+LZMA_TEXT_START	:= 0x80a00000
+LOADER		:= loader.bin
+LOADER_NAME	:= $(basename $(notdir $(LOADER)))
+LOADER_DATA 	:=
+TARGET_DIR	:=
+FLASH_START	:=
+FLASH_OFFS	:=
+FLASH_MAX	:=
+BOARD		:=
+PLATFORM	:=
+
+ifeq ($(TARGET_DIR),)
+TARGET_DIR	:= $(KDIR)
+endif
+
+LOADER_BIN	:= $(TARGET_DIR)/$(LOADER_NAME).bin
+LOADER_GZ	:= $(TARGET_DIR)/$(LOADER_NAME).gz
+LOADER_ELF	:= $(TARGET_DIR)/$(LOADER_NAME).elf
+
+PKG_NAME := lzma-loader
+PKG_BUILD_DIR := $(KDIR)/$(PKG_NAME)
+
+.PHONY : loader-compile loader.bin loader.elf loader.gz
+
+$(PKG_BUILD_DIR)/.prepared:
+	mkdir $(PKG_BUILD_DIR)
+	$(CP) ./src/* $(PKG_BUILD_DIR)/
+	touch $@
+
+loader-compile: $(PKG_BUILD_DIR)/.prepared
+	$(MAKE) -C $(PKG_BUILD_DIR) CROSS_COMPILE="$(TARGET_CROSS)" \
+		LZMA_TEXT_START=$(LZMA_TEXT_START) \
+		LOADER_DATA=$(LOADER_DATA) \
+		FLASH_START=$(FLASH_START) \
+		FLASH_OFFS=$(FLASH_OFFS) \
+		FLASH_MAX=$(FLASH_MAX) \
+		BOARD="$(BOARD)" \
+		PLATFORM="$(PLATFORM)" \
+		clean all
+
+loader.gz: $(PKG_BUILD_DIR)/loader.bin
+	gzip -nc9 $< > $(LOADER_GZ)
+
+loader.elf: $(PKG_BUILD_DIR)/loader.elf
+	$(CP) $< $(LOADER_ELF)
+
+loader.bin: $(PKG_BUILD_DIR)/loader.bin
+	$(CP) $< $(LOADER_BIN)
+
+download:
+prepare: $(PKG_BUILD_DIR)/.prepared
+compile: loader-compile
+
+install:
+
+clean:
+	rm -rf $(PKG_BUILD_DIR)
+
diff --git a/target/linux/ramips/image/lzma-loader/src/LzmaDecode.c b/target/linux/ramips/image/lzma-loader/src/LzmaDecode.c
new file mode 100644
index 0000000..cb83453
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/LzmaDecode.c
@@ -0,0 +1,584 @@
+/*
+  LzmaDecode.c
+  LZMA Decoder (optimized for Speed version)
+  
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this Code, expressly permits you to 
+  statically or dynamically link your Code (or bind by name) to the 
+  interfaces of this file without subjecting your linked Code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#include "LzmaDecode.h"
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+  { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#ifdef _LZMA_IN_CB
+
+#define RC_TEST { if (Buffer == BufferLim) \
+  { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
+  BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
+
+#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
+
+#else
+
+#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+ 
+#endif
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+
+#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
+  { UpdateBit0(p); mi <<= 1; A0; } else \
+  { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 
+  
+#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)               
+
+#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
+  { int i = numLevels; res = 1; \
+  do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
+  res -= (1 << numLevels); }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
+{
+  unsigned char prop0;
+  if (size < LZMA_PROPERTIES_SIZE)
+    return LZMA_RESULT_DATA_ERROR;
+  prop0 = propsData[0];
+  if (prop0 >= (9 * 5 * 5))
+    return LZMA_RESULT_DATA_ERROR;
+  {
+    for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
+    for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
+    propsRes->lc = prop0;
+    /*
+    unsigned char remainder = (unsigned char)(prop0 / 9);
+    propsRes->lc = prop0 % 9;
+    propsRes->pb = remainder / 5;
+    propsRes->lp = remainder % 5;
+    */
+  }
+
+  #ifdef _LZMA_OUT_READ
+  {
+    int i;
+    propsRes->DictionarySize = 0;
+    for (i = 0; i < 4; i++)
+      propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
+    if (propsRes->DictionarySize == 0)
+      propsRes->DictionarySize = 1;
+  }
+  #endif
+  return LZMA_RESULT_OK;
+}
+
+#define kLzmaStreamWasFinishedId (-1)
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *InCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
+{
+  CProb *p = vs->Probs;
+  SizeT nowPos = 0;
+  Byte previousByte = 0;
+  UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
+  UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
+  int lc = vs->Properties.lc;
+
+  #ifdef _LZMA_OUT_READ
+  
+  UInt32 Range = vs->Range;
+  UInt32 Code = vs->Code;
+  #ifdef _LZMA_IN_CB
+  const Byte *Buffer = vs->Buffer;
+  const Byte *BufferLim = vs->BufferLim;
+  #else
+  const Byte *Buffer = inStream;
+  const Byte *BufferLim = inStream + inSize;
+  #endif
+  int state = vs->State;
+  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
+  int len = vs->RemainLen;
+  UInt32 globalPos = vs->GlobalPos;
+  UInt32 distanceLimit = vs->DistanceLimit;
+
+  Byte *dictionary = vs->Dictionary;
+  UInt32 dictionarySize = vs->Properties.DictionarySize;
+  UInt32 dictionaryPos = vs->DictionaryPos;
+
+  Byte tempDictionary[4];
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+  if (len == kLzmaStreamWasFinishedId)
+    return LZMA_RESULT_OK;
+
+  if (dictionarySize == 0)
+  {
+    dictionary = tempDictionary;
+    dictionarySize = 1;
+    tempDictionary[0] = vs->TempDictionary[0];
+  }
+
+  if (len == kLzmaNeedInitId)
+  {
+    {
+      UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+      UInt32 i;
+      for (i = 0; i < numProbs; i++)
+        p[i] = kBitModelTotal >> 1; 
+      rep0 = rep1 = rep2 = rep3 = 1;
+      state = 0;
+      globalPos = 0;
+      distanceLimit = 0;
+      dictionaryPos = 0;
+      dictionary[dictionarySize - 1] = 0;
+      #ifdef _LZMA_IN_CB
+      RC_INIT;
+      #else
+      RC_INIT(inStream, inSize);
+      #endif
+    }
+    len = 0;
+  }
+  while(len != 0 && nowPos < outSize)
+  {
+    UInt32 pos = dictionaryPos - rep0;
+    if (pos >= dictionarySize)
+      pos += dictionarySize;
+    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
+    if (++dictionaryPos == dictionarySize)
+      dictionaryPos = 0;
+    len--;
+  }
+  if (dictionaryPos == 0)
+    previousByte = dictionary[dictionarySize - 1];
+  else
+    previousByte = dictionary[dictionaryPos - 1];
+
+  #else /* if !_LZMA_OUT_READ */
+
+  int state = 0;
+  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+  int len = 0;
+  const Byte *Buffer;
+  const Byte *BufferLim;
+  UInt32 Range;
+  UInt32 Code;
+
+  #ifndef _LZMA_IN_CB
+  *inSizeProcessed = 0;
+  #endif
+  *outSizeProcessed = 0;
+
+  {
+    UInt32 i;
+    UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
+    for (i = 0; i < numProbs; i++)
+      p[i] = kBitModelTotal >> 1;
+  }
+  
+  #ifdef _LZMA_IN_CB
+  RC_INIT;
+  #else
+  RC_INIT(inStream, inSize);
+  #endif
+
+  #endif /* _LZMA_OUT_READ */
+
+  while(nowPos < outSize)
+  {
+    CProb *prob;
+    UInt32 bound;
+    int posState = (int)(
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & posStateMask);
+
+    prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
+    IfBit0(prob)
+    {
+      int symbol = 1;
+      UpdateBit0(prob)
+      prob = p + Literal + (LZMA_LIT_SIZE * 
+        (((
+        (nowPos 
+        #ifdef _LZMA_OUT_READ
+        + globalPos
+        #endif
+        )
+        & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+      if (state >= kNumLitStates)
+      {
+        int matchByte;
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        matchByte = dictionary[pos];
+        #else
+        matchByte = outStream[nowPos - rep0];
+        #endif
+        do
+        {
+          int bit;
+          CProb *probLit;
+          matchByte <<= 1;
+          bit = (matchByte & 0x100);
+          probLit = prob + 0x100 + bit + symbol;
+          RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
+        }
+        while (symbol < 0x100);
+      }
+      while (symbol < 0x100)
+      {
+        CProb *probLit = prob + symbol;
+        RC_GET_BIT(probLit, symbol)
+      }
+      previousByte = (Byte)symbol;
+
+      outStream[nowPos++] = previousByte;
+      #ifdef _LZMA_OUT_READ
+      if (distanceLimit < dictionarySize)
+        distanceLimit++;
+
+      dictionary[dictionaryPos] = previousByte;
+      if (++dictionaryPos == dictionarySize)
+        dictionaryPos = 0;
+      #endif
+      if (state < 4) state = 0;
+      else if (state < 10) state -= 3;
+      else state -= 6;
+    }
+    else             
+    {
+      UpdateBit1(prob);
+      prob = p + IsRep + state;
+      IfBit0(prob)
+      {
+        UpdateBit0(prob);
+        rep3 = rep2;
+        rep2 = rep1;
+        rep1 = rep0;
+        state = state < kNumLitStates ? 0 : 3;
+        prob = p + LenCoder;
+      }
+      else
+      {
+        UpdateBit1(prob);
+        prob = p + IsRepG0 + state;
+        IfBit0(prob)
+        {
+          UpdateBit0(prob);
+          prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
+          IfBit0(prob)
+          {
+            #ifdef _LZMA_OUT_READ
+            UInt32 pos;
+            #endif
+            UpdateBit0(prob);
+            
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit == 0)
+            #else
+            if (nowPos == 0)
+            #endif
+              return LZMA_RESULT_DATA_ERROR;
+            
+            state = state < kNumLitStates ? 9 : 11;
+            #ifdef _LZMA_OUT_READ
+            pos = dictionaryPos - rep0;
+            if (pos >= dictionarySize)
+              pos += dictionarySize;
+            previousByte = dictionary[pos];
+            dictionary[dictionaryPos] = previousByte;
+            if (++dictionaryPos == dictionarySize)
+              dictionaryPos = 0;
+            #else
+            previousByte = outStream[nowPos - rep0];
+            #endif
+            outStream[nowPos++] = previousByte;
+            #ifdef _LZMA_OUT_READ
+            if (distanceLimit < dictionarySize)
+              distanceLimit++;
+            #endif
+
+            continue;
+          }
+          else
+          {
+            UpdateBit1(prob);
+          }
+        }
+        else
+        {
+          UInt32 distance;
+          UpdateBit1(prob);
+          prob = p + IsRepG1 + state;
+          IfBit0(prob)
+          {
+            UpdateBit0(prob);
+            distance = rep1;
+          }
+          else 
+          {
+            UpdateBit1(prob);
+            prob = p + IsRepG2 + state;
+            IfBit0(prob)
+            {
+              UpdateBit0(prob);
+              distance = rep2;
+            }
+            else
+            {
+              UpdateBit1(prob);
+              distance = rep3;
+              rep3 = rep2;
+            }
+            rep2 = rep1;
+          }
+          rep1 = rep0;
+          rep0 = distance;
+        }
+        state = state < kNumLitStates ? 8 : 11;
+        prob = p + RepLenCoder;
+      }
+      {
+        int numBits, offset;
+        CProb *probLen = prob + LenChoice;
+        IfBit0(probLen)
+        {
+          UpdateBit0(probLen);
+          probLen = prob + LenLow + (posState << kLenNumLowBits);
+          offset = 0;
+          numBits = kLenNumLowBits;
+        }
+        else
+        {
+          UpdateBit1(probLen);
+          probLen = prob + LenChoice2;
+          IfBit0(probLen)
+          {
+            UpdateBit0(probLen);
+            probLen = prob + LenMid + (posState << kLenNumMidBits);
+            offset = kLenNumLowSymbols;
+            numBits = kLenNumMidBits;
+          }
+          else
+          {
+            UpdateBit1(probLen);
+            probLen = prob + LenHigh;
+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
+            numBits = kLenNumHighBits;
+          }
+        }
+        RangeDecoderBitTreeDecode(probLen, numBits, len);
+        len += offset;
+      }
+
+      if (state < 4)
+      {
+        int posSlot;
+        state += kNumLitStates;
+        prob = p + PosSlot +
+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
+            kNumPosSlotBits);
+        RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
+        if (posSlot >= kStartPosModelIndex)
+        {
+          int numDirectBits = ((posSlot >> 1) - 1);
+          rep0 = (2 | ((UInt32)posSlot & 1));
+          if (posSlot < kEndPosModelIndex)
+          {
+            rep0 <<= numDirectBits;
+            prob = p + SpecPos + rep0 - posSlot - 1;
+          }
+          else
+          {
+            numDirectBits -= kNumAlignBits;
+            do
+            {
+              RC_NORMALIZE
+              Range >>= 1;
+              rep0 <<= 1;
+              if (Code >= Range)
+              {
+                Code -= Range;
+                rep0 |= 1;
+              }
+            }
+            while (--numDirectBits != 0);
+            prob = p + Align;
+            rep0 <<= kNumAlignBits;
+            numDirectBits = kNumAlignBits;
+          }
+          {
+            int i = 1;
+            int mi = 1;
+            do
+            {
+              CProb *prob3 = prob + mi;
+              RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
+              i <<= 1;
+            }
+            while(--numDirectBits != 0);
+          }
+        }
+        else
+          rep0 = posSlot;
+        if (++rep0 == (UInt32)(0))
+        {
+          /* it's for stream version */
+          len = kLzmaStreamWasFinishedId;
+          break;
+        }
+      }
+
+      len += kMatchMinLen;
+      #ifdef _LZMA_OUT_READ
+      if (rep0 > distanceLimit) 
+      #else
+      if (rep0 > nowPos)
+      #endif
+        return LZMA_RESULT_DATA_ERROR;
+
+      #ifdef _LZMA_OUT_READ
+      if (dictionarySize - distanceLimit > (UInt32)len)
+        distanceLimit += len;
+      else
+        distanceLimit = dictionarySize;
+      #endif
+
+      do
+      {
+        #ifdef _LZMA_OUT_READ
+        UInt32 pos = dictionaryPos - rep0;
+        if (pos >= dictionarySize)
+          pos += dictionarySize;
+        previousByte = dictionary[pos];
+        dictionary[dictionaryPos] = previousByte;
+        if (++dictionaryPos == dictionarySize)
+          dictionaryPos = 0;
+        #else
+        previousByte = outStream[nowPos - rep0];
+        #endif
+        len--;
+        outStream[nowPos++] = previousByte;
+      }
+      while(len != 0 && nowPos < outSize);
+    }
+  }
+  RC_NORMALIZE;
+
+  #ifdef _LZMA_OUT_READ
+  vs->Range = Range;
+  vs->Code = Code;
+  vs->DictionaryPos = dictionaryPos;
+  vs->GlobalPos = globalPos + (UInt32)nowPos;
+  vs->DistanceLimit = distanceLimit;
+  vs->Reps[0] = rep0;
+  vs->Reps[1] = rep1;
+  vs->Reps[2] = rep2;
+  vs->Reps[3] = rep3;
+  vs->State = state;
+  vs->RemainLen = len;
+  vs->TempDictionary[0] = tempDictionary[0];
+  #endif
+
+  #ifdef _LZMA_IN_CB
+  vs->Buffer = Buffer;
+  vs->BufferLim = BufferLim;
+  #else
+  *inSizeProcessed = (SizeT)(Buffer - inStream);
+  #endif
+  *outSizeProcessed = nowPos;
+  return LZMA_RESULT_OK;
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/LzmaDecode.h b/target/linux/ramips/image/lzma-loader/src/LzmaDecode.h
new file mode 100644
index 0000000..2870eeb
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/LzmaDecode.h
@@ -0,0 +1,113 @@
+/* 
+  LzmaDecode.h
+  LZMA Decoder interface
+
+  LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
+  http://www.7-zip.org/
+
+  LZMA SDK is licensed under two licenses:
+  1) GNU Lesser General Public License (GNU LGPL)
+  2) Common Public License (CPL)
+  It means that you can select one of these two licenses and 
+  follow rules of that license.
+
+  SPECIAL EXCEPTION:
+  Igor Pavlov, as the author of this code, expressly permits you to 
+  statically or dynamically link your code (or bind by name) to the 
+  interfaces of this file without subjecting your linked code to the 
+  terms of the CPL or GNU LGPL. Any modifications or additions 
+  to this file, however, are subject to the LGPL or CPL terms.
+*/
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+#include "LzmaTypes.h"
+
+/* #define _LZMA_IN_CB */
+/* Use callback for input data */
+
+/* #define _LZMA_OUT_READ */
+/* Use read function for output data */
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs, 
+   but memory usage will be doubled in that case */
+
+/* #define _LZMA_LOC_OPT */
+/* Enable local speed optimizations inside code */
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define LZMA_RESULT_OK 0
+#define LZMA_RESULT_DATA_ERROR 1
+
+#ifdef _LZMA_IN_CB
+typedef struct _ILzmaInCallback
+{
+  int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
+} ILzmaInCallback;
+#endif
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#define LZMA_PROPERTIES_SIZE 5
+
+typedef struct _CLzmaProperties
+{
+  int lc;
+  int lp;
+  int pb;
+  #ifdef _LZMA_OUT_READ
+  UInt32 DictionarySize;
+  #endif
+}CLzmaProperties;
+
+int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
+
+#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
+
+#define kLzmaNeedInitId (-2)
+
+typedef struct _CLzmaDecoderState
+{
+  CLzmaProperties Properties;
+  CProb *Probs;
+
+  #ifdef _LZMA_IN_CB
+  const unsigned char *Buffer;
+  const unsigned char *BufferLim;
+  #endif
+
+  #ifdef _LZMA_OUT_READ
+  unsigned char *Dictionary;
+  UInt32 Range;
+  UInt32 Code;
+  UInt32 DictionaryPos;
+  UInt32 GlobalPos;
+  UInt32 DistanceLimit;
+  UInt32 Reps[4];
+  int State;
+  int RemainLen;
+  unsigned char TempDictionary[4];
+  #endif
+} CLzmaDecoderState;
+
+#ifdef _LZMA_OUT_READ
+#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
+#endif
+
+int LzmaDecode(CLzmaDecoderState *vs,
+    #ifdef _LZMA_IN_CB
+    ILzmaInCallback *inCallback,
+    #else
+    const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
+    #endif
+    unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
+
+#endif
diff --git a/target/linux/ramips/image/lzma-loader/src/LzmaTypes.h b/target/linux/ramips/image/lzma-loader/src/LzmaTypes.h
new file mode 100644
index 0000000..9c27290
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/LzmaTypes.h
@@ -0,0 +1,45 @@
+/* 
+LzmaTypes.h 
+
+Types for LZMA Decoder
+
+This file written and distributed to public domain by Igor Pavlov.
+This file is part of LZMA SDK 4.40 (2006-05-01)
+*/
+
+#ifndef __LZMATYPES_H
+#define __LZMATYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif 
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif 
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef unsigned long UInt32;
+#else
+typedef unsigned int UInt32;
+#endif
+#endif 
+
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
+#endif
diff --git a/target/linux/ramips/image/lzma-loader/src/Makefile b/target/linux/ramips/image/lzma-loader/src/Makefile
new file mode 100644
index 0000000..97fd6da
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/Makefile
@@ -0,0 +1,114 @@
+#
+# Makefile for the LZMA compressed kernel loader for
+# Atheros AR7XXX/AR9XXX based boards
+#
+# Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+#
+# Some parts of this file was based on the OpenWrt specific lzma-loader
+# for the BCM47xx and ADM5120 based boards:
+#	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org)
+#	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com>
+#	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+#
+
+LOADADDR	:=
+LZMA_TEXT_START	:= 0x80a00000
+LOADER_DATA	:=
+BOARD		:=
+FLASH_START	:=
+FLASH_OFFS	:=
+FLASH_MAX	:=
+PLATFORM	:=
+CACHE_FLAGS	:=
+
+CC		:= $(CROSS_COMPILE)gcc
+LD		:= $(CROSS_COMPILE)ld
+OBJCOPY		:= $(CROSS_COMPILE)objcopy
+OBJDUMP		:= $(CROSS_COMPILE)objdump
+
+
+include $(PLATFORM).mk
+
+BIN_FLAGS	:= -O binary -R .reginfo -R .note -R .comment -R .mdebug \
+		   -R .MIPS.abiflags -S
+
+CFLAGS		= -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \
+		  -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 \
+		  -mno-abicalls -fno-pic -ffunction-sections -pipe -mlong-calls \
+		  -fno-common -ffreestanding -fhonour-copts -nostartfiles \
+		  -mabi=32 -march=mips32r2 \
+		  -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap
+CFLAGS		+= -D_LZMA_PROB32
+CFLAGS		+= -flto
+CFLAGS		+= $(CACHE_FLAGS)
+
+ASFLAGS		= $(CFLAGS) -D__ASSEMBLY__
+
+LDFLAGS		= -static -Wl,--gc-sections -Wl,-no-warn-mismatch
+LDFLAGS		+= -Wl,-e,startup -T loader.lds -Wl,-Ttext,$(LZMA_TEXT_START)
+LDFLAGS		+= -flto -fwhole-program -Wl,-z,max-page-size=4096
+
+O_FORMAT 	= $(shell $(OBJDUMP) -i | head -2 | grep elf32)
+
+OBJECTS		:= head.o loader.o cache.o board-$(PLATFORM).o printf.o LzmaDecode.o
+
+ifneq ($(strip $(LOADER_DATA)),)
+OBJECTS		+= data.o
+CFLAGS		+= -DLZMA_WRAPPER=1 -DLOADADDR=$(LOADADDR)
+endif
+
+ifneq ($(strip $(KERNEL_CMDLINE)),)
+CFLAGS		+= -DCONFIG_KERNEL_CMDLINE='"$(KERNEL_CMDLINE)"'
+endif
+
+ifneq ($(strip $(FLASH_START)),)
+CFLAGS		+= -DCONFIG_FLASH_START=$(FLASH_START)
+endif
+
+ifneq ($(strip $(FLASH_OFFS)),)
+CFLAGS		+= -DCONFIG_FLASH_OFFS=$(FLASH_OFFS)
+endif
+
+ifneq ($(strip $(FLASH_MAX)),)
+CFLAGS		+= -DCONFIG_FLASH_MAX=$(FLASH_MAX)
+endif
+
+all: loader.elf
+
+# Don't build dependencies, this may die if $(CC) isn't gcc
+dep:
+
+install:
+
+%.o : %.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+%.o : %.S
+	$(CC) $(ASFLAGS) -c -o $@ $<
+
+data.o: $(LOADER_DATA)
+	$(LD) -r -b binary --oformat $(O_FORMAT) -T lzma-data.lds -o $@ $<
+
+loader: $(OBJECTS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS)
+
+loader.bin: loader
+	$(OBJCOPY) $(BIN_FLAGS) $< $@
+
+loader2.o: loader.bin
+	$(LD) -r -b binary --oformat $(O_FORMAT) -o $@ $<
+
+loader.elf: loader2.o
+	$(LD) -e startup -T loader2.lds -Ttext $(LOADADDR) -z max-page-size=4096 -o $@ $<
+
+mrproper: clean
+
+clean:
+	rm -f loader *.elf *.bin *.o
+
+
+
diff --git a/target/linux/ramips/image/lzma-loader/src/board-mt7621.c b/target/linux/ramips/image/lzma-loader/src/board-mt7621.c
new file mode 100644
index 0000000..b90b2ed
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/board-mt7621.c
@@ -0,0 +1,39 @@
+/*
+ * Arch specific code for mt7621 based boards, based on code for Ralink boards
+ *
+ * Copyright (C) 2018 Tobias Schramm <tobleminer@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "config.h"
+
+#define READREG(r)		*(volatile uint32_t *)(r)
+#define WRITEREG(r,v)		*(volatile uint32_t *)(r) = v
+
+#define KSEG1ADDR(_x)		(((_x) & 0x1fffffff) | 0xa0000000)
+
+#define UART_BASE		0xBE000C00
+
+#define UART_TBR_OFFSET		0x00
+#define UART_LSR_OFFSET		0x14
+
+#define UART_LSR_TEMT		(1 << 6)
+
+#define UART_READ(r)		READREG(UART_BASE + (r))
+#define UART_WRITE(r,v)		WRITEREG(UART_BASE + (r), (v))
+
+void board_putc(int ch)
+{
+	while (((UART_READ(UART_LSR_OFFSET)) & UART_LSR_TEMT) == 0);
+	UART_WRITE(UART_TBR_OFFSET, ch);
+	while (((UART_READ(UART_LSR_OFFSET)) & UART_LSR_TEMT) == 0);
+}
+
+void board_init(void)
+{
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/board-ralink.c b/target/linux/ramips/image/lzma-loader/src/board-ralink.c
new file mode 100644
index 0000000..7c947ec
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/board-ralink.c
@@ -0,0 +1,42 @@
+/*
+ * Arch specific code for Ralink based boards
+ *
+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <stddef.h>
+#include "config.h"
+
+#define READREG(r)		*(volatile unsigned int *)(r)
+#define WRITEREG(r,v)		*(volatile unsigned int *)(r) = v
+
+#define KSEG1ADDR(_x)		(((_x) & 0x1fffffff) | 0xa0000000)
+
+#ifdef CONFIG_SOC_RT288X
+#define UART_BASE		0xb0300c00
+#else
+#define UART_BASE		0xb0000c00
+#endif
+
+#define UART_TX			1
+#define UART_LSR		7
+
+#define UART_LSR_THRE		0x20
+
+#define UART_READ(r)		READREG(UART_BASE + 4 * (r))
+#define UART_WRITE(r,v)		WRITEREG(UART_BASE + 4 * (r), (v))
+
+void board_putc(int ch)
+{
+	while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
+	UART_WRITE(UART_TX, ch);
+	while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0);
+}
+
+void board_init(void)
+{
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/cache.c b/target/linux/ramips/image/lzma-loader/src/cache.c
new file mode 100644
index 0000000..28cc848
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/cache.c
@@ -0,0 +1,43 @@
+/*
+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * The cache manipulation routine has been taken from the U-Boot project.
+ *	(C) Copyright 2003
+ *	Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include "cache.h"
+#include "cacheops.h"
+#include "config.h"
+
+#define cache_op(op,addr)						\
+	__asm__ __volatile__(						\
+	"	.set	push					\n"	\
+	"	.set	noreorder				\n"	\
+	"	.set	mips3\n\t				\n"	\
+	"	cache	%0, %1					\n"	\
+	"	.set	pop					\n"	\
+	:								\
+	: "i" (op), "R" (*(unsigned char *)(addr)))
+
+void flush_cache(unsigned long start_addr, unsigned long size)
+{
+	unsigned long lsize = CONFIG_CACHELINE_SIZE;
+	unsigned long addr = start_addr & ~(lsize - 1);
+	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
+
+	while (1) {
+		cache_op(Hit_Writeback_Inv_D, addr);
+		cache_op(Hit_Invalidate_I, addr);
+		if (addr == aend)
+			break;
+		addr += lsize;
+	}
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/cache.h b/target/linux/ramips/image/lzma-loader/src/cache.h
new file mode 100644
index 0000000..506a235
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/cache.h
@@ -0,0 +1,17 @@
+/*
+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __CACHE_H
+#define __CACHE_H
+
+void flush_cache(unsigned long start_addr, unsigned long size);
+
+#endif /* __CACHE_H */
diff --git a/target/linux/ramips/image/lzma-loader/src/cacheops.h b/target/linux/ramips/image/lzma-loader/src/cacheops.h
new file mode 100644
index 0000000..70bcad7
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/cacheops.h
@@ -0,0 +1,85 @@
+/*
+ * Cache operations for the cache instruction.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef	__ASM_CACHEOPS_H
+#define	__ASM_CACHEOPS_H
+
+/*
+ * Cache Operations available on all MIPS processors with R4000-style caches
+ */
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+#define Index_Load_Tag_I	0x04
+#define Index_Load_Tag_D	0x05
+#define Index_Store_Tag_I	0x08
+#define Index_Store_Tag_D	0x09
+#if defined(CONFIG_CPU_LOONGSON2)
+#define Hit_Invalidate_I	0x00
+#else
+#define Hit_Invalidate_I	0x10
+#endif
+#define Hit_Invalidate_D	0x11
+#define Hit_Writeback_Inv_D	0x15
+
+/*
+ * R4000-specific cacheops
+ */
+#define Create_Dirty_Excl_D	0x0d
+#define Fill			0x14
+#define Hit_Writeback_I		0x18
+#define Hit_Writeback_D		0x19
+
+/*
+ * R4000SC and R4400SC-specific cacheops
+ */
+#define Index_Invalidate_SI     0x02
+#define Index_Writeback_Inv_SD  0x03
+#define Index_Load_Tag_SI	0x06
+#define Index_Load_Tag_SD	0x07
+#define Index_Store_Tag_SI	0x0A
+#define Index_Store_Tag_SD	0x0B
+#define Create_Dirty_Excl_SD	0x0f
+#define Hit_Invalidate_SI	0x12
+#define Hit_Invalidate_SD	0x13
+#define Hit_Writeback_Inv_SD	0x17
+#define Hit_Writeback_SD	0x1b
+#define Hit_Set_Virtual_SI	0x1e
+#define Hit_Set_Virtual_SD	0x1f
+
+/*
+ * R5000-specific cacheops
+ */
+#define R5K_Page_Invalidate_S	0x17
+
+/*
+ * RM7000-specific cacheops
+ */
+#define Page_Invalidate_T	0x16
+
+/*
+ * R10000-specific cacheops
+ *
+ * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
+ * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
+ */
+#define Index_Writeback_Inv_S	0x03
+#define Index_Load_Tag_S	0x07
+#define Index_Store_Tag_S	0x0B
+#define Hit_Invalidate_S	0x13
+#define Cache_Barrier		0x14
+#define Hit_Writeback_Inv_S	0x17
+#define Index_Load_Data_I	0x18
+#define Index_Load_Data_D	0x19
+#define Index_Load_Data_S	0x1b
+#define Index_Store_Data_I	0x1c
+#define Index_Store_Data_D	0x1d
+#define Index_Store_Data_S	0x1f
+
+#endif	/* __ASM_CACHEOPS_H */
diff --git a/target/linux/ramips/image/lzma-loader/src/config.h b/target/linux/ramips/image/lzma-loader/src/config.h
new file mode 100644
index 0000000..b7719e9
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/config.h
@@ -0,0 +1,27 @@
+/*
+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+#ifndef CONFIG_FLASH_OFFS
+#define CONFIG_FLASH_OFFS	0
+#endif
+
+#ifndef CONFIG_FLASH_MAX
+#define CONFIG_FLASH_MAX	0
+#endif
+
+#ifndef CONFIG_FLASH_STEP
+#define CONFIG_FLASH_STEP	0x1000
+#endif
+
+#endif /* _CONFIG_H_ */
diff --git a/target/linux/ramips/image/lzma-loader/src/cp0regdef.h b/target/linux/ramips/image/lzma-loader/src/cp0regdef.h
new file mode 100644
index 0000000..c1188ad
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/cp0regdef.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ *
+ * Copyright (C) 2001, Monta Vista Software
+ * Author: jsun@mvista.com or jsun@junsun.net
+ */
+#ifndef _cp0regdef_h_
+#define _cp0regdef_h_
+
+#define CP0_INDEX $0
+#define CP0_RANDOM $1
+#define CP0_ENTRYLO0 $2
+#define CP0_ENTRYLO1 $3
+#define CP0_CONTEXT $4
+#define CP0_PAGEMASK $5
+#define CP0_WIRED $6
+#define CP0_BADVADDR $8
+#define CP0_COUNT $9
+#define CP0_ENTRYHI $10
+#define CP0_COMPARE $11
+#define CP0_STATUS $12
+#define CP0_CAUSE $13
+#define CP0_EPC $14
+#define CP0_PRID $15
+#define CP0_CONFIG $16
+#define CP0_LLADDR $17
+#define CP0_WATCHLO $18
+#define CP0_WATCHHI $19
+#define CP0_XCONTEXT $20
+#define CP0_FRAMEMASK $21
+#define CP0_DIAGNOSTIC $22
+#define CP0_PERFORMANCE $25
+#define CP0_ECC $26
+#define CP0_CACHEERR $27
+#define CP0_TAGLO $28
+#define CP0_TAGHI $29
+#define CP0_ERROREPC $30
+
+#endif
diff --git a/target/linux/ramips/image/lzma-loader/src/head.S b/target/linux/ramips/image/lzma-loader/src/head.S
new file mode 100644
index 0000000..47a7c9b
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/head.S
@@ -0,0 +1,121 @@
+/*
+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Some parts of this code was based on the OpenWrt specific lzma-loader
+ * for the BCM47xx and ADM5120 based boards:
+ *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org)
+ *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include "cp0regdef.h"
+#include "cacheops.h"
+#include "config.h"
+
+#define KSEG0		0x80000000
+
+	.macro	ehb
+	sll     zero, 3
+	.endm
+
+	.text
+
+LEAF(startup)
+	.set noreorder
+	.set mips32
+
+	mtc0	zero, CP0_WATCHLO	# clear watch registers
+	mtc0	zero, CP0_WATCHHI
+	mtc0	zero, CP0_CAUSE		# clear before writing status register
+
+	mfc0	t0, CP0_STATUS
+	li	t1, 0x1000001f
+	or	t0, t1
+	xori	t0, 0x1f
+	mtc0	t0, CP0_STATUS
+	ehb
+
+	mtc0	zero, CP0_COUNT
+	mtc0	zero, CP0_COMPARE
+	ehb
+
+	la	t0, __reloc_label	# get linked address of label
+	bal	__reloc_label		# branch and link to label to
+	nop				# get actual address
+__reloc_label:
+	subu	t0, ra, t0		# get reloc_delta
+
+	beqz	t0, __reloc_done         # if delta is 0 we are in the right place
+	nop
+
+	/* Copy our code to the right place */
+	la	t1, _code_start		# get linked address of _code_start
+	la	t2, _code_end		# get linked address of _code_end
+	addu	t0, t0, t1		# calculate actual address of _code_start
+
+__reloc_copy:
+	lw	t3, 0(t0)
+	sw	t3, 0(t1)
+	add	t1, 4
+	blt	t1, t2, __reloc_copy
+	add	t0, 4
+
+	/* flush cache */
+	la	t0, _code_start
+	la	t1, _code_end
+
+	li	t2, ~(CONFIG_CACHELINE_SIZE - 1)
+	and	t0, t2
+	and	t1, t2
+	li	t2, CONFIG_CACHELINE_SIZE
+
+	b	__flush_check
+	nop
+
+__flush_line:
+	cache	Hit_Writeback_Inv_D, 0(t0)
+	cache	Hit_Invalidate_I, 0(t0)
+	add	t0, t2
+
+__flush_check:
+	bne	t0, t1, __flush_line
+	nop
+
+	sync
+
+__reloc_done:
+
+	/* clear bss */
+	la	t0, _bss_start
+	la	t1, _bss_end
+	b	__bss_check
+	nop
+
+__bss_fill:
+	sw	zero, 0(t0)
+	addi	t0, 4
+
+__bss_check:
+	bne	t0, t1, __bss_fill
+	nop
+
+	/* Setup new "C" stack */
+	la	sp, _stack
+
+	/* reserve stack space for a0-a3 registers */
+	subu	sp, 16
+
+	/* jump to the decompressor routine */
+	la	t0, loader_main
+	jr	t0
+	nop
+
+	.set reorder
+END(startup)
diff --git a/target/linux/ramips/image/lzma-loader/src/lantiq.mk b/target/linux/ramips/image/lzma-loader/src/lantiq.mk
new file mode 100644
index 0000000..4137645
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/lantiq.mk
@@ -0,0 +1 @@
+CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(32 * 1024)" -DCONFIG_CACHELINE_SIZE=32
diff --git a/target/linux/ramips/image/lzma-loader/src/loader.c b/target/linux/ramips/image/lzma-loader/src/loader.c
new file mode 100644
index 0000000..a3513ec
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/loader.c
@@ -0,0 +1,262 @@
+/*
+ * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Some parts of this code was based on the OpenWrt specific lzma-loader
+ * for the BCM47xx and ADM5120 based boards:
+ *	Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org)
+ *	Copyright (C) 2005 Mineharu Takahara <mtakahar@yahoo.com>
+ *	Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
+ *
+ * The image_header structure has been taken from the U-Boot project.
+ *	(C) Copyright 2008 Semihalf
+ *	(C) Copyright 2000-2005
+ *	Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "config.h"
+#include "cache.h"
+#include "printf.h"
+#include "LzmaDecode.h"
+
+#define KSEG0			0x80000000
+#define KSEG1			0xa0000000
+
+#define KSEG1ADDR(a)		((((unsigned)(a)) & 0x1fffffffU) | KSEG1)
+
+#undef LZMA_DEBUG
+
+#ifdef LZMA_DEBUG
+#  define DBG(f, a...)	printf(f, ## a)
+#else
+#  define DBG(f, a...)	do {} while (0)
+#endif
+
+#define IH_MAGIC_OKLI		0x4f4b4c49	/* 'OKLI' */
+
+#define IH_NMLEN		32	/* Image Name Length		*/
+
+typedef struct image_header {
+	uint32_t	ih_magic;	/* Image Header Magic Number	*/
+	uint32_t	ih_hcrc;	/* Image Header CRC Checksum	*/
+	uint32_t	ih_time;	/* Image Creation Timestamp	*/
+	uint32_t	ih_size;	/* Image Data Size		*/
+	uint32_t	ih_load;	/* Data	 Load  Address		*/
+	uint32_t	ih_ep;		/* Entry Point Address		*/
+	uint32_t	ih_dcrc;	/* Image Data CRC Checksum	*/
+	uint8_t		ih_os;		/* Operating System		*/
+	uint8_t		ih_arch;	/* CPU architecture		*/
+	uint8_t		ih_type;	/* Image Type			*/
+	uint8_t		ih_comp;	/* Compression Type		*/
+	uint8_t		ih_name[IH_NMLEN];	/* Image Name		*/
+} image_header_t;
+
+/* beyond the image end, size not known in advance */
+extern unsigned char workspace[];
+extern void board_init(void);
+
+static CLzmaDecoderState lzma_state;
+static unsigned char *lzma_data;
+static unsigned long lzma_datasize;
+static unsigned long lzma_outsize;
+static unsigned long kernel_la;
+
+#ifdef CONFIG_KERNEL_CMDLINE
+#define kernel_argc	2
+static const char kernel_cmdline[] = CONFIG_KERNEL_CMDLINE;
+static const char *kernel_argv[] = {
+	NULL,
+	kernel_cmdline,
+	NULL,
+};
+#endif /* CONFIG_KERNEL_CMDLINE */
+
+static void halt(void)
+{
+	printf("\nSystem halted!\n");
+	for(;;);
+}
+
+static __inline__ unsigned long get_be32(void *buf)
+{
+	unsigned char *p = buf;
+
+	return (((unsigned long) p[0] << 24) +
+	        ((unsigned long) p[1] << 16) +
+	        ((unsigned long) p[2] << 8) +
+	        (unsigned long) p[3]);
+}
+
+static __inline__ unsigned char lzma_get_byte(void)
+{
+	unsigned char c;
+
+	lzma_datasize--;
+	c = *lzma_data++;
+
+	return c;
+}
+
+static int lzma_init_props(void)
+{
+	unsigned char props[LZMA_PROPERTIES_SIZE];
+	int res;
+	int i;
+
+	/* read lzma properties */
+	for (i = 0; i < LZMA_PROPERTIES_SIZE; i++)
+		props[i] = lzma_get_byte();
+
+	/* read the lower half of uncompressed size in the header */
+	lzma_outsize = ((SizeT) lzma_get_byte()) +
+		       ((SizeT) lzma_get_byte() << 8) +
+		       ((SizeT) lzma_get_byte() << 16) +
+		       ((SizeT) lzma_get_byte() << 24);
+
+	/* skip rest of the header (upper half of uncompressed size) */
+	for (i = 0; i < 4; i++)
+		lzma_get_byte();
+
+	res = LzmaDecodeProperties(&lzma_state.Properties, props,
+					LZMA_PROPERTIES_SIZE);
+	return res;
+}
+
+static int lzma_decompress(unsigned char *outStream)
+{
+	SizeT ip, op;
+	int ret;
+
+	lzma_state.Probs = (CProb *) workspace;
+
+	ret = LzmaDecode(&lzma_state, lzma_data, lzma_datasize, &ip, outStream,
+			 lzma_outsize, &op);
+
+	if (ret != LZMA_RESULT_OK) {
+		int i;
+
+		DBG("LzmaDecode error %d at %08x, osize:%d ip:%d op:%d\n",
+		    ret, lzma_data + ip, lzma_outsize, ip, op);
+
+		for (i = 0; i < 16; i++)
+			DBG("%02x ", lzma_data[ip + i]);
+
+		DBG("\n");
+	}
+
+	return ret;
+}
+
+#if (LZMA_WRAPPER)
+static void lzma_init_data(void)
+{
+	extern unsigned char _lzma_data_start[];
+	extern unsigned char _lzma_data_end[];
+
+	kernel_la = LOADADDR;
+	lzma_data = _lzma_data_start;
+	lzma_datasize = _lzma_data_end - _lzma_data_start;
+}
+#else
+static void lzma_init_data(void)
+{
+	struct image_header *hdr = NULL;
+	unsigned char *flash_base;
+	unsigned long flash_ofs;
+	unsigned long kernel_ofs;
+	unsigned long kernel_size;
+
+	flash_base = (unsigned char *) KSEG1ADDR(CONFIG_FLASH_START);
+
+	printf("Looking for OpenWrt image... ");
+
+	for (flash_ofs = CONFIG_FLASH_OFFS;
+	     flash_ofs <= (CONFIG_FLASH_OFFS + CONFIG_FLASH_MAX);
+	     flash_ofs += CONFIG_FLASH_STEP) {
+		unsigned long magic;
+		unsigned char *p;
+
+		p = flash_base + flash_ofs;
+		magic = get_be32(p);
+		if (magic == IH_MAGIC_OKLI) {
+			hdr = (struct image_header *) p;
+			break;
+		}
+	}
+
+	if (hdr == NULL) {
+		printf("not found!\n");
+		halt();
+	}
+
+	printf("found at 0x%08x\n", flash_base + flash_ofs);
+
+	kernel_ofs = sizeof(struct image_header);
+	kernel_size = get_be32(&hdr->ih_size);
+	kernel_la = get_be32(&hdr->ih_load);
+
+	lzma_data = flash_base + flash_ofs + kernel_ofs;
+	lzma_datasize = kernel_size;
+}
+#endif /* (LZMA_WRAPPER) */
+
+void loader_main(unsigned long reg_a0, unsigned long reg_a1,
+		 unsigned long reg_a2, unsigned long reg_a3)
+{
+	void (*kernel_entry) (unsigned long, unsigned long, unsigned long,
+			      unsigned long);
+	int res;
+
+	board_init();
+
+	printf("\n\nOpenWrt kernel loader for MIPS based SoC\n");
+	printf("Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>\n");
+
+	lzma_init_data();
+
+	res = lzma_init_props();
+	if (res != LZMA_RESULT_OK) {
+		printf("Incorrect LZMA stream properties!\n");
+		halt();
+	}
+
+	printf("Decompressing kernel... ");
+
+	res = lzma_decompress((unsigned char *) kernel_la);
+	if (res != LZMA_RESULT_OK) {
+		printf("failed, ");
+		switch (res) {
+		case LZMA_RESULT_DATA_ERROR:
+			printf("data error!\n");
+			break;
+		default:
+			printf("unknown error %d!\n", res);
+		}
+		halt();
+	} else {
+		printf("done!\n");
+	}
+
+	flush_cache(kernel_la, lzma_outsize);
+
+	printf("Starting kernel at %08x...\n\n", kernel_la);
+
+#ifdef CONFIG_KERNEL_CMDLINE
+	reg_a0 = kernel_argc;
+	reg_a1 = (unsigned long) kernel_argv;
+	reg_a2 = 0;
+	reg_a3 = 0;
+#endif
+
+	kernel_entry = (void *) kernel_la;
+	kernel_entry(reg_a0, reg_a1, reg_a2, reg_a3);
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/loader.lds b/target/linux/ramips/image/lzma-loader/src/loader.lds
new file mode 100644
index 0000000..80cc7ca
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/loader.lds
@@ -0,0 +1,35 @@
+OUTPUT_ARCH(mips)
+SECTIONS {
+	.text : {
+		_code_start = .;
+		*(.text)
+		*(.text.*)
+		*(.rodata)
+		*(.rodata.*)
+		*(.data.lzma)
+	}
+
+	. = ALIGN(32);
+	.data : {
+		*(.data)
+		*(.data.*)
+		. = . + 524288;		/* workaround for buggy bootloaders */
+	}
+
+	. = ALIGN(32);
+	_code_end = .;
+
+	_bss_start = .;
+	.bss : {
+		*(.bss)
+		*(.bss.*)
+	}
+
+	. = ALIGN(32);
+	_bss_end = .;
+
+	. = . + 8192;
+	_stack = .;
+
+	workspace = .;
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/loader2.lds b/target/linux/ramips/image/lzma-loader/src/loader2.lds
new file mode 100644
index 0000000..db0bb46
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/loader2.lds
@@ -0,0 +1,10 @@
+OUTPUT_ARCH(mips)
+SECTIONS {
+	.text : {
+		startup = .;
+		*(.text)
+		*(.text.*)
+		*(.data)
+		*(.data.*)
+	}
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/lzma-data.lds b/target/linux/ramips/image/lzma-loader/src/lzma-data.lds
new file mode 100644
index 0000000..abf756b
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/lzma-data.lds
@@ -0,0 +1,8 @@
+OUTPUT_ARCH(mips)
+SECTIONS {
+	.data.lzma : {
+		_lzma_data_start = .;
+		*(.data)
+		_lzma_data_end = .;
+	}
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/mt7621.mk b/target/linux/ramips/image/lzma-loader/src/mt7621.mk
new file mode 100644
index 0000000..3ff5fdd
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/mt7621.mk
@@ -0,0 +1 @@
+CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(16 * 1024)" -DCONFIG_CACHELINE_SIZE=32
diff --git a/target/linux/ramips/image/lzma-loader/src/printf.c b/target/linux/ramips/image/lzma-loader/src/printf.c
new file mode 100644
index 0000000..7bb5a86
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/printf.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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	"printf.h"
+
+extern void board_putc(int ch);
+
+/* this is the maximum width for a variable */
+#define		LP_MAX_BUF	256
+
+/* macros */
+#define		IsDigit(x)	( ((x) >= '0') && ((x) <= '9') )
+#define		Ctod(x)		( (x) - '0')
+
+/* forward declaration */
+static int PrintChar(char *, char, int, int);
+static int PrintString(char *, char *, int, int);
+static int PrintNum(char *, unsigned long, int, int, int, int, char, int);
+
+/* private variable */
+static const char theFatalMsg[] = "fatal error in lp_Print!";
+
+/* -*-
+ * A low level printf() function.
+ */
+static void
+lp_Print(void (*output)(void *, char *, int),
+	 void * arg,
+	 char *fmt,
+	 va_list ap)
+{
+
+#define 	OUTPUT(arg, s, l)  \
+  { if (((l) < 0) || ((l) > LP_MAX_BUF)) { \
+       (*output)(arg, (char*)theFatalMsg, sizeof(theFatalMsg)-1); for(;;); \
+    } else { \
+      (*output)(arg, s, l); \
+    } \
+  }
+
+    char buf[LP_MAX_BUF];
+
+    char c;
+    char *s;
+    long int num;
+
+    int longFlag;
+    int negFlag;
+    int width;
+    int prec;
+    int ladjust;
+    char padc;
+
+    int length;
+
+    for(;;) {
+	{
+	    /* scan for the next '%' */
+	    char *fmtStart = fmt;
+	    while ( (*fmt != '\0') && (*fmt != '%')) {
+		fmt ++;
+	    }
+
+	    /* flush the string found so far */
+	    OUTPUT(arg, fmtStart, fmt-fmtStart);
+
+	    /* are we hitting the end? */
+	    if (*fmt == '\0') break;
+	}
+
+	/* we found a '%' */
+	fmt ++;
+
+	/* check for long */
+	if (*fmt == 'l') {
+	    longFlag = 1;
+	    fmt ++;
+	} else {
+	    longFlag = 0;
+	}
+
+	/* check for other prefixes */
+	width = 0;
+	prec = -1;
+	ladjust = 0;
+	padc = ' ';
+
+	if (*fmt == '-') {
+	    ladjust = 1;
+	    fmt ++;
+	}
+
+	if (*fmt == '0') {
+	    padc = '0';
+	    fmt++;
+	}
+
+	if (IsDigit(*fmt)) {
+	    while (IsDigit(*fmt)) {
+		width = 10 * width + Ctod(*fmt++);
+	    }
+	}
+
+	if (*fmt == '.') {
+	    fmt ++;
+	    if (IsDigit(*fmt)) {
+		prec = 0;
+		while (IsDigit(*fmt)) {
+		    prec = prec*10 + Ctod(*fmt++);
+		}
+	    }
+	}
+
+
+	/* check format flag */
+	negFlag = 0;
+	switch (*fmt) {
+	 case 'b':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 2, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'd':
+	 case 'D':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    if (num < 0) {
+		num = - num;
+		negFlag = 1;
+	    }
+	    length = PrintNum(buf, num, 10, negFlag, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'o':
+	 case 'O':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 8, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'u':
+	 case 'U':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 10, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'x':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 0);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'X':
+	    if (longFlag) {
+		num = va_arg(ap, long int);
+	    } else {
+		num = va_arg(ap, int);
+	    }
+	    length = PrintNum(buf, num, 16, 0, width, ladjust, padc, 1);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 'c':
+	    c = (char)va_arg(ap, int);
+	    length = PrintChar(buf, c, width, ladjust);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case 's':
+	    s = (char*)va_arg(ap, char *);
+	    length = PrintString(buf, s, width, ladjust);
+	    OUTPUT(arg, buf, length);
+	    break;
+
+	 case '\0':
+	    fmt --;
+	    break;
+
+	 default:
+	    /* output this char as it is */
+	    OUTPUT(arg, fmt, 1);
+	}	/* switch (*fmt) */
+
+	fmt ++;
+    }		/* for(;;) */
+
+    /* special termination call */
+    OUTPUT(arg, "\0", 1);
+}
+
+
+/* --------------- local help functions --------------------- */
+static int
+PrintChar(char * buf, char c, int length, int ladjust)
+{
+    int i;
+
+    if (length < 1) length = 1;
+    if (ladjust) {
+	*buf = c;
+	for (i=1; i< length; i++) buf[i] = ' ';
+    } else {
+	for (i=0; i< length-1; i++) buf[i] = ' ';
+	buf[length - 1] = c;
+    }
+    return length;
+}
+
+static int
+PrintString(char * buf, char* s, int length, int ladjust)
+{
+    int i;
+    int len=0;
+    char* s1 = s;
+    while (*s1++) len++;
+    if (length < len) length = len;
+
+    if (ladjust) {
+	for (i=0; i< len; i++) buf[i] = s[i];
+	for (i=len; i< length; i++) buf[i] = ' ';
+    } else {
+	for (i=0; i< length-len; i++) buf[i] = ' ';
+	for (i=length-len; i < length; i++) buf[i] = s[i-length+len];
+    }
+    return length;
+}
+
+static int
+PrintNum(char * buf, unsigned long u, int base, int negFlag,
+	 int length, int ladjust, char padc, int upcase)
+{
+    /* algorithm :
+     *  1. prints the number from left to right in reverse form.
+     *  2. fill the remaining spaces with padc if length is longer than
+     *     the actual length
+     *     TRICKY : if left adjusted, no "0" padding.
+     *		    if negtive, insert  "0" padding between "0" and number.
+     *  3. if (!ladjust) we reverse the whole string including paddings
+     *  4. otherwise we only reverse the actual string representing the num.
+     */
+
+    int actualLength =0;
+    char *p = buf;
+    int i;
+
+    do {
+	int tmp = u %base;
+	if (tmp <= 9) {
+	    *p++ = '0' + tmp;
+	} else if (upcase) {
+	    *p++ = 'A' + tmp - 10;
+	} else {
+	    *p++ = 'a' + tmp - 10;
+	}
+	u /= base;
+    } while (u != 0);
+
+    if (negFlag) {
+	*p++ = '-';
+    }
+
+    /* figure out actual length and adjust the maximum length */
+    actualLength = p - buf;
+    if (length < actualLength) length = actualLength;
+
+    /* add padding */
+    if (ladjust) {
+	padc = ' ';
+    }
+    if (negFlag && !ladjust && (padc == '0')) {
+	for (i = actualLength-1; i< length-1; i++) buf[i] = padc;
+	buf[length -1] = '-';
+    } else {
+	for (i = actualLength; i< length; i++) buf[i] = padc;
+    }
+
+
+    /* prepare to reverse the string */
+    {
+	int begin = 0;
+	int end;
+	if (ladjust) {
+	    end = actualLength - 1;
+	} else {
+	    end = length -1;
+	}
+
+	while (end > begin) {
+	    char tmp = buf[begin];
+	    buf[begin] = buf[end];
+	    buf[end] = tmp;
+	    begin ++;
+	    end --;
+	}
+    }
+
+    /* adjust the string pointer */
+    return length;
+}
+
+static void printf_output(void *arg, char *s, int l)
+{
+    int i;
+
+    // special termination call
+    if ((l==1) && (s[0] == '\0')) return;
+
+    for (i=0; i< l; i++) {
+	board_putc(s[i]);
+	if (s[i] == '\n') board_putc('\r');
+    }
+}
+
+void printf(char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    lp_Print(printf_output, 0, fmt, ap);
+    va_end(ap);
+}
diff --git a/target/linux/ramips/image/lzma-loader/src/printf.h b/target/linux/ramips/image/lzma-loader/src/printf.h
new file mode 100644
index 0000000..9b1c1df
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/printf.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * 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.
+ *
+ */
+
+#ifndef _printf_h_
+#define _printf_h_
+
+#include <stdarg.h>
+void printf(char *fmt, ...);
+
+#endif /* _printf_h_ */
diff --git a/target/linux/ramips/image/lzma-loader/src/ralink.mk b/target/linux/ramips/image/lzma-loader/src/ralink.mk
new file mode 100644
index 0000000..3ff5fdd
--- /dev/null
+++ b/target/linux/ramips/image/lzma-loader/src/ralink.mk
@@ -0,0 +1 @@
+CACHE_FLAGS+=-DCONFIG_ICACHE_SIZE="(32 * 1024)" -DCONFIG_DCACHE_SIZE="(16 * 1024)" -DCONFIG_CACHELINE_SIZE=32
diff --git a/target/linux/ramips/image/mt7620.mk b/target/linux/ramips/image/mt7620.mk
new file mode 100644
index 0000000..1fc7597
--- /dev/null
+++ b/target/linux/ramips/image/mt7620.mk
@@ -0,0 +1,1320 @@
+#
+# MT7620A Profiles
+#
+
+include ./common-tp-link.mk
+
+DEVICE_VARS += DLINK_ROM_ID DLINK_FAMILY_MEMBER DLINK_FIRMWARE_SIZE DLINK_IMAGE_OFFSET
+
+define Build/elecom-header
+	cp $@ $(KDIR)/v_0.0.0.bin
+	( \
+		mkhash md5 $(KDIR)/v_0.0.0.bin && \
+		echo 458 \
+	) | mkhash md5 > $(KDIR)/v_0.0.0.md5
+	$(STAGING_DIR_HOST)/bin/tar -c \
+		$(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \
+		--owner=0 --group=0 -f $@ -C $(KDIR) v_0.0.0.bin v_0.0.0.md5
+endef
+
+define Device/aigale_ai-br100
+  SOC := mt7620a
+  IMAGE_SIZE := 7936k
+  DEVICE_VENDOR := Aigale
+  DEVICE_MODEL := Ai-BR100
+  DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += ai-br100
+endef
+TARGET_DEVICES += aigale_ai-br100
+
+define Device/alfa-network_ac1200rm
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ALFA Network
+  DEVICE_MODEL := AC1200RM
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci uboot-envtools
+  SUPPORTED_DEVICES += ac1200rm
+endef
+TARGET_DEVICES += alfa-network_ac1200rm
+
+define Device/alfa-network_r36m-e4g
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ALFA Network
+  DEVICE_MODEL := R36M-E4G
+  DEVICE_PACKAGES := kmod-i2c-ralink kmod-usb2 kmod-usb-ohci uboot-envtools \
+	uqmi
+  SUPPORTED_DEVICES += r36m-e4g
+endef
+TARGET_DEVICES += alfa-network_r36m-e4g
+
+define Device/alfa-network_tube-e4g
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ALFA Network
+  DEVICE_MODEL := Tube-E4G
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci uboot-envtools uqmi -iwinfo \
+	-kmod-rt2800-soc -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += tube-e4g
+endef
+TARGET_DEVICES += alfa-network_tube-e4g
+
+define Device/amit_jboot
+  DLINK_IMAGE_OFFSET := 0x10000
+  KERNEL := $(KERNEL_DTB)
+  KERNEL_SIZE := 2048k
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := mkdlinkfw | pad-rootfs | append-metadata
+  IMAGE/factory.bin := mkdlinkfw | pad-rootfs | mkdlinkfw-factory
+  DEVICE_PACKAGES := jboot-tools kmod-usb2 kmod-usb-ohci
+endef
+
+define Device/asus_rp-n53
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RP-N53
+  DEVICE_PACKAGES := kmod-rt2800-pci
+  SUPPORTED_DEVICES += rp-n53
+endef
+TARGET_DEVICES += asus_rp-n53
+
+define Device/asus_rt-ac51u
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-AC51U
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += rt-ac51u
+endef
+TARGET_DEVICES += asus_rt-ac51u
+
+define Device/asus_rt-ac54u
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-AC54U
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += asus_rt-ac54u
+
+define Device/asus_rt-n12p
+  SOC := mt7620n
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N11P/RT-N12+/RT-N12Eb1
+  SUPPORTED_DEVICES += rt-n12p
+endef
+TARGET_DEVICES += asus_rt-n12p
+
+define Device/asus_rt-n14u
+  SOC := mt7620n
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N14u
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += rt-n14u
+endef
+TARGET_DEVICES += asus_rt-n14u
+
+define Device/bdcom_wap2100-sk
+  SOC := mt7620a
+  IMAGE_SIZE := 15808k
+  DEVICE_VENDOR := BDCOM
+  DEVICE_MODEL := WAP2100-SK (ZTE ZXECS EBG3130)
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mt76x2 kmod-mt76x0e \
+	kmod-sdhci-mt7620 kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += bdcom_wap2100-sk
+
+define Device/buffalo_whr-1166d
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WHR-1166D
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += whr-1166d
+endef
+TARGET_DEVICES += buffalo_whr-1166d
+
+define Device/buffalo_whr-300hp2
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WHR-300HP2
+  SUPPORTED_DEVICES += whr-300hp2
+endef
+TARGET_DEVICES += buffalo_whr-300hp2
+
+define Device/buffalo_whr-600d
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WHR-600D
+  DEVICE_PACKAGES := kmod-rt2800-pci
+  SUPPORTED_DEVICES += whr-600d
+endef
+TARGET_DEVICES += buffalo_whr-600d
+
+define Device/buffalo_wmr-300
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WMR-300
+  SUPPORTED_DEVICES += wmr-300
+endef
+TARGET_DEVICES += buffalo_wmr-300
+
+define Device/comfast_cf-wr800n
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Comfast
+  DEVICE_MODEL := CF-WR800N
+  SUPPORTED_DEVICES += cf-wr800n
+endef
+TARGET_DEVICES += comfast_cf-wr800n
+
+define Device/dlink_dch-m225
+  $(Device/seama)
+  SOC := mt7620a
+  BLOCKSIZE := 4k
+  SEAMA_SIGNATURE := wapn22_dlink.2013gui_dap1320b
+  IMAGE_SIZE := 6848k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DCH-M225
+  DEVICE_PACKAGES := kmod-sound-core kmod-sound-mt7620 kmod-i2c-ralink
+  SUPPORTED_DEVICES += dch-m225
+endef
+TARGET_DEVICES += dlink_dch-m225
+
+define Device/dlink_dir-510l
+  $(Device/amit_jboot)
+  SOC := mt7620a
+  IMAGE_SIZE := 14208k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-510L
+  DEVICE_PACKAGES += kmod-mt76x0e
+  DLINK_ROM_ID := DLK6E3805001
+  DLINK_FAMILY_MEMBER := 0x6E38
+  DLINK_FIRMWARE_SIZE := 0xDE0000
+  DLINK_IMAGE_OFFSET := 0x210000
+endef
+TARGET_DEVICES += dlink_dir-510l
+
+define Device/dlink_dir-810l
+  SOC := mt7620a
+  DEVICE_PACKAGES := kmod-mt76x0e
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-810L
+  IMAGE_SIZE := 6720k
+  SUPPORTED_DEVICES += dir-810l
+endef
+TARGET_DEVICES += dlink_dir-810l
+
+define Device/dlink_dwr-116-a1
+  $(Device/amit_jboot)
+  SOC := mt7620n
+  IMAGE_SIZE := 8064k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-116
+  DEVICE_VARIANT := A1/A2
+  DLINK_ROM_ID := DLK6E3803001
+  DLINK_FAMILY_MEMBER := 0x6E38
+  DLINK_FIRMWARE_SIZE := 0x7E0000
+endef
+TARGET_DEVICES += dlink_dwr-116-a1
+
+define Device/dlink_dwr-118-a1
+  $(Device/amit_jboot)
+  SOC := mt7620a
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-118
+  DEVICE_VARIANT := A1
+  DEVICE_PACKAGES += kmod-mt76x0e
+  DLINK_ROM_ID := DLK6E3811001
+  DLINK_FAMILY_MEMBER := 0x6E38
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+endef
+TARGET_DEVICES += dlink_dwr-118-a1
+
+define Device/dlink_dwr-118-a2
+  $(Device/amit_jboot)
+  SOC := mt7620a
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-118
+  DEVICE_VARIANT := A2
+  DEVICE_PACKAGES += kmod-mt76x2
+  DLINK_ROM_ID := DLK6E3814001
+  DLINK_FAMILY_MEMBER := 0x6E38
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+endef
+TARGET_DEVICES += dlink_dwr-118-a2
+
+define Device/dlink_dwr-921-c1
+  $(Device/amit_jboot)
+  SOC := mt7620n
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-921
+  DEVICE_VARIANT := C1
+  DLINK_ROM_ID := DLK6E2414001
+  DLINK_FAMILY_MEMBER := 0x6E24
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+  DEVICE_PACKAGES += kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
+endef
+TARGET_DEVICES += dlink_dwr-921-c1
+
+define Device/dlink_dwr-921-c3
+  $(Device/dlink_dwr-921-c1)
+  DEVICE_DTS := mt7620n_dlink_dwr-921-c1
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-921
+  DEVICE_VARIANT := C3
+  DLINK_ROM_ID := DLK6E2414009
+  SUPPORTED_DEVICES := dlink,dwr-921-c1
+endef
+TARGET_DEVICES += dlink_dwr-921-c3
+
+define Device/dlink_dwr-922-e2
+  $(Device/amit_jboot)
+  SOC := mt7620n
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-922
+  DEVICE_VARIANT := E2
+  DLINK_ROM_ID := DLK6E2414005
+  DLINK_FAMILY_MEMBER := 0x6E24
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+  DEVICE_PACKAGES += kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
+endef
+TARGET_DEVICES += dlink_dwr-922-e2
+
+define Device/dlink_dwr-960
+  $(Device/amit_jboot)
+  SOC := mt7620a
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-960
+  DLINK_ROM_ID := DLK6E2429001
+  DLINK_FAMILY_MEMBER := 0x6E24
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+  DEVICE_PACKAGES += kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi \
+	kmod-mt76x0e
+endef
+TARGET_DEVICES += dlink_dwr-960
+
+define Device/dovado_tiny-ac
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Dovado
+  DEVICE_MODEL := Tiny AC
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += tiny-ac
+endef
+TARGET_DEVICES += dovado_tiny-ac
+
+define Device/edimax_br-6478ac-v2
+  SOC := mt7620a
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := BR-6478AC
+  DEVICE_VARIANT := V2
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7744k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN68 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += edimax_br-6478ac-v2
+
+define Device/edimax_ew-7476rpc
+  SOC := mt7620a
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := EW-7476RPC
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN79 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek
+endef
+TARGET_DEVICES += edimax_ew-7476rpc
+
+define Device/edimax_ew-7478ac
+  SOC := mt7620a
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := EW-7478AC
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN70 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek
+endef
+TARGET_DEVICES += edimax_ew-7478ac
+
+define Device/edimax_ew-7478apc
+  SOC := mt7620a
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := EW-7478APC
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN75 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += edimax_ew-7478apc
+
+define Device/elecom_wrh-300cr
+  SOC := mt7620n
+  IMAGE_SIZE := 14272k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | elecom-header
+  DEVICE_VENDOR := Elecom
+  DEVICE_MODEL := WRH-300CR
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += wrh-300cr
+endef
+TARGET_DEVICES += elecom_wrh-300cr
+
+define Device/engenius_esr600
+  SOC := mt7620a
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 15616k
+  IMAGES += factory.dlf
+  IMAGE/factory.dlf := $$(sysupgrade_bin) | check-size | \
+	senao-header -r 0x101 -p 0x57 -t 2
+  DEVICE_VENDOR := EnGenius
+  DEVICE_MODEL := ESR600
+  DEVICE_PACKAGES += kmod-rt2800-pci kmod-usb-storage kmod-usb-ohci \
+	kmod-usb-ehci
+endef
+TARGET_DEVICES += engenius_esr600
+
+define Device/fon_fon2601
+  SOC := mt7620a
+  IMAGE_SIZE := 15936k
+  DEVICE_VENDOR := Fon
+  DEVICE_MODEL := FON2601
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  KERNEL_INITRAMFS := $$(KERNEL) | uimage-padhdr
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | uimage-padhdr | \
+	pad-rootfs | append-metadata | check-size
+endef
+TARGET_DEVICES += fon_fon2601
+
+define Device/glinet_gl-mt300a
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := GL-MT300A
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += gl-mt300a
+endef
+TARGET_DEVICES += glinet_gl-mt300a
+
+define Device/glinet_gl-mt300n
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := GL-MT300N
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += gl-mt300n
+endef
+TARGET_DEVICES += glinet_gl-mt300n
+
+define Device/glinet_gl-mt750
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := GL-MT750
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += gl-mt750
+endef
+TARGET_DEVICES += glinet_gl-mt750
+
+define Device/head-weblink_hdrm200
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Head Weblink
+  DEVICE_MODEL := HDRM2000
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+	uqmi kmod-usb-serial-option
+endef
+TARGET_DEVICES += head-weblink_hdrm200
+
+define Device/hiwifi_hc5661
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5661
+  DEVICE_PACKAGES := kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += hc5661
+endef
+TARGET_DEVICES += hiwifi_hc5661
+
+define Device/hiwifi_hc5761
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5761
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += hc5761
+endef
+TARGET_DEVICES += hiwifi_hc5761
+
+define Device/hiwifi_hc5861
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5861
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += hc5861
+endef
+TARGET_DEVICES += hiwifi_hc5861
+
+define Device/hnet_c108
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := HNET
+  DEVICE_MODEL := C108
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += c108
+endef
+TARGET_DEVICES += hnet_c108
+
+define Device/sunvalley_filehub_common
+  SOC := mt7620n
+  IMAGE_SIZE := 6144k
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-i2c-ralink
+  LOADER_TYPE := bin
+  LOADER_FLASH_OFFS := 0x200000
+  COMPILE := loader-$(1).bin
+  COMPILE/loader-$(1).bin := loader-okli-compile | pad-to 64k | lzma | \
+	uImage lzma
+  KERNEL := $(KERNEL_DTB) | uImage lzma -M 0x4f4b4c49
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma
+  IMAGES += kernel.bin rootfs.bin
+  IMAGE/kernel.bin := append-loader-okli $(1) | check-size 64k
+  IMAGE/rootfs.bin := $$(sysupgrade_bin) | check-size
+endef
+
+define Device/hootoo_ht-tm05
+  $(Device/sunvalley_filehub_common)
+  DEVICE_VENDOR := HooToo
+  DEVICE_MODEL := HT-TM05
+endef
+TARGET_DEVICES += hootoo_ht-tm05
+
+define Device/iodata_wn-ac1167gr
+  SOC := mt7620a
+  DEVICE_VENDOR := I-O DATA
+  DEVICE_MODEL := WN-AC1167GR
+  IMAGE_SIZE := 6864k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 01040016 8844A2D168B45A2D
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += iodata_wn-ac1167gr
+
+define Device/iodata_wn-ac733gr3
+  SOC := mt7620a
+  DEVICE_VENDOR := I-O DATA
+  DEVICE_MODEL := WN-AC733GR3
+  IMAGE_SIZE := 6992k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 01040006 8844A2D168B45A2D
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-switch-rtl8367b
+endef
+TARGET_DEVICES += iodata_wn-ac733gr3
+
+define Device/iptime_a1004ns
+  SOC := mt7620a
+  IMAGE_SIZE := 16192k
+  UIMAGE_NAME := a1004ns
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A1004ns
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += iptime_a1004ns
+
+define Device/iptime_a104ns
+  SOC := mt7620a
+  IMAGE_SIZE := 8000k
+  UIMAGE_NAME := a104ns
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A104ns
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += iptime_a104ns
+
+define Device/kimax_u25awf-h1
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Kimax
+  DEVICE_MODEL := U25AWF
+  DEVICE_VARIANT := H1
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-storage kmod-scsi-core \
+	kmod-fs-ext4 kmod-fs-vfat block-mount
+  SUPPORTED_DEVICES += u25awf-h1
+endef
+TARGET_DEVICES += kimax_u25awf-h1
+
+define Device/kimax_u35wf
+  SOC := mt7620n
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Kimax
+  DEVICE_MODEL := U35WF
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-storage kmod-scsi-core \
+	kmod-fs-ext4 kmod-fs-vfat block-mount
+endef
+TARGET_DEVICES += kimax_u35wf
+
+define Device/kingston_mlw221
+  SOC := mt7620n
+  IMAGE_SIZE := 15744k
+  DEVICE_VENDOR := Kingston
+  DEVICE_MODEL := MLW221
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += mlw221
+endef
+TARGET_DEVICES += kingston_mlw221
+
+define Device/kingston_mlwg2
+  SOC := mt7620n
+  IMAGE_SIZE := 15744k
+  DEVICE_VENDOR := Kingston
+  DEVICE_MODEL := MLWG2
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += mlwg2
+endef
+TARGET_DEVICES += kingston_mlwg2
+
+define Device/lava_lr-25g001
+  $(Device/amit_jboot)
+  SOC := mt7620a
+  IMAGE_SIZE := 16256k
+  DEVICE_VENDOR := LAVA
+  DEVICE_MODEL := LR-25G001
+  DLINK_ROM_ID := LVA6E3804001
+  DLINK_FAMILY_MEMBER := 0x6E38
+  DLINK_FIRMWARE_SIZE := 0xFE0000
+  DEVICE_PACKAGES += kmod-mt76x0e
+endef
+TARGET_DEVICES += lava_lr-25g001
+
+define Device/lb-link_bl-w1200
+  SOC := mt7620a
+  DEVICE_VENDOR := LB-Link
+  DEVICE_MODEL := BL-W1200
+  IMAGE_SIZE := 7872k
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-mt76x2
+endef
+TARGET_DEVICES += lb-link_bl-w1200
+
+define Device/lenovo_newifi-y1
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Lenovo
+  DEVICE_MODEL := Y1
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += y1
+endef
+TARGET_DEVICES += lenovo_newifi-y1
+
+define Device/lenovo_newifi-y1s
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Lenovo
+  DEVICE_MODEL := Y1S
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += y1s
+endef
+TARGET_DEVICES += lenovo_newifi-y1s
+
+define Device/linksys_e1700
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | umedia-header 0x013326
+  DEVICE_VENDOR := Linksys
+  DEVICE_MODEL := E1700
+  SUPPORTED_DEVICES += e1700
+endef
+TARGET_DEVICES += linksys_e1700
+
+define Device/microduino_microwrt
+  SOC := mt7620a
+  IMAGE_SIZE := 16128k
+  DEVICE_VENDOR := Microduino
+  DEVICE_MODEL := MicroWRT
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += microwrt
+endef
+TARGET_DEVICES += microduino_microwrt
+
+define Device/netgear_ex2700
+  SOC := mt7620a
+  NETGEAR_HW_ID := 29764623+4+0+32+2x2+0
+  NETGEAR_BOARD_ID := EX2700
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  KERNEL := $(KERNEL_DTB) | uImage lzma | pad-offset 64k 64 | \
+	append-uImage-fakehdr filesystem
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | netgear-dni
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := EX2700
+  SUPPORTED_DEVICES += ex2700
+  DEFAULT := n
+endef
+TARGET_DEVICES += netgear_ex2700
+
+define Device/netgear_ex3700
+  SOC := mt7620a
+  NETGEAR_BOARD_ID := U12H319T00_NETGEAR
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGES += factory.chk
+  IMAGE/factory.chk := $$(sysupgrade_bin) | check-size | netgear-chk
+  DEVICE_PACKAGES := kmod-mt76x2
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := EX3700/EX3800
+  SUPPORTED_DEVICES += ex3700
+endef
+TARGET_DEVICES += netgear_ex3700
+
+define Device/netgear_ex6120
+  SOC := mt7620a
+  NETGEAR_BOARD_ID := U12H319T30_NETGEAR
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGES += factory.chk
+  IMAGE/factory.chk := $$(sysupgrade_bin) | check-size | netgear-chk
+  DEVICE_PACKAGES := kmod-mt76x2
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := EX6120
+endef
+TARGET_DEVICES += netgear_ex6120
+
+define Device/netgear_ex6130
+  SOC := mt7620a
+  NETGEAR_BOARD_ID := U12H319T50_NETGEAR
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGES += factory.chk
+  IMAGE/factory.chk := $$(sysupgrade_bin) | check-size | netgear-chk
+  DEVICE_PACKAGES := kmod-mt76x2
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := EX6130
+endef
+TARGET_DEVICES += netgear_ex6130
+
+define Device/netgear_jwnr2010-v5
+  $(Device/netgear_sercomm_nor)
+  SOC := mt7620n
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3840k
+  DEVICE_MODEL := JWNR2010
+  DEVICE_VARIANT := v5
+  SERCOMM_HWNAME := N300
+  SERCOMM_HWID := ASW
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0040
+  SERCOMM_PAD := 128k
+  DEFAULT := n
+endef
+TARGET_DEVICES += netgear_jwnr2010-v5
+
+define Device/netgear_wn3000rp-v3
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  NETGEAR_HW_ID := 29764836+8+0+32+2x2+0
+  NETGEAR_BOARD_ID := WN3000RPv3
+  BLOCKSIZE := 4k
+  IMAGES += factory.bin
+  KERNEL := $(KERNEL_DTB) | uImage lzma | pad-offset 64k 64 | \
+	append-uImage-fakehdr filesystem
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | netgear-dni
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := WN3000RP
+  DEVICE_VARIANT := v3
+  SUPPORTED_DEVICES += wn3000rpv3
+endef
+TARGET_DEVICES += netgear_wn3000rp-v3
+
+define Device/netis_wf2770
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  UIMAGE_NAME := WF2770_0.0.00
+  DEVICE_VENDOR := NETIS
+  DEVICE_MODEL := WF2770
+  DEVICE_PACKAGES := kmod-mt76x0e
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | netis-tail WF2770 | uImage lzma
+endef
+TARGET_DEVICES += netis_wf2770
+
+define Device/nexx_wt3020-4m
+  SOC := mt7620n
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B WT3020 -F 4M
+  DEVICE_VENDOR := Nexx
+  DEVICE_MODEL := WT3020
+  DEVICE_VARIANT := 4M
+  SUPPORTED_DEVICES += wt3020 wt3020-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += nexx_wt3020-4m
+
+define Device/nexx_wt3020-8m
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B WT3020 -F 8M
+  DEVICE_VENDOR := Nexx
+  DEVICE_MODEL := WT3020
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += wt3020 wt3020-8M
+endef
+TARGET_DEVICES += nexx_wt3020-8m
+
+define Device/ohyeah_oy-0001
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Oh Yeah
+  DEVICE_MODEL := OY-0001
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += oy-0001
+endef
+TARGET_DEVICES += ohyeah_oy-0001
+
+define Device/phicomm_k2g
+  SOC := mt7620a
+  IMAGE_SIZE := 7552k
+  DEVICE_VENDOR := Phicomm
+  DEVICE_MODEL := K2G
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += phicomm_k2g
+
+define Device/phicomm_psg1208
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Phicomm
+  DEVICE_MODEL := PSG1208
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += psg1208
+endef
+TARGET_DEVICES += phicomm_psg1208
+
+define Device/phicomm_psg1218a
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Phicomm
+  DEVICE_MODEL := PSG1218
+  DEVICE_VARIANT:= Ax
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += psg1218 psg1218a
+endef
+TARGET_DEVICES += phicomm_psg1218a
+
+define Device/phicomm_psg1218b
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Phicomm
+  DEVICE_MODEL := PSG1218
+  DEVICE_VARIANT := Bx
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += psg1218 psg1218b
+endef
+TARGET_DEVICES += phicomm_psg1218b
+
+define Device/planex_cs-qr10
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := CS-QR10
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sound-core \
+	kmod-sound-mt7620 kmod-i2c-ralink kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += cs-qr10
+endef
+TARGET_DEVICES += planex_cs-qr10
+
+define Device/planex_db-wrt01
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := DB-WRT01
+  SUPPORTED_DEVICES += db-wrt01
+endef
+TARGET_DEVICES += planex_db-wrt01
+
+define Device/planex_mzk-750dhp
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-750DHP
+  DEVICE_PACKAGES := kmod-mt76x0e
+  SUPPORTED_DEVICES += mzk-750dhp
+endef
+TARGET_DEVICES += planex_mzk-750dhp
+
+define Device/planex_mzk-ex300np
+  SOC := mt7620a
+  IMAGE_SIZE := 7360k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-EX300NP
+  SUPPORTED_DEVICES += mzk-ex300np
+endef
+TARGET_DEVICES += planex_mzk-ex300np
+
+define Device/planex_mzk-ex750np
+  SOC := mt7620a
+  IMAGE_SIZE := 7360k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-EX750NP
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += mzk-ex750np
+endef
+TARGET_DEVICES += planex_mzk-ex750np
+
+define Device/ralink_mt7620a-evb
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7620a EVB
+endef
+TARGET_DEVICES += ralink_mt7620a-evb
+
+define Device/ralink_mt7620a-mt7530-evb
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7620a + MT7530 EVB
+  SUPPORTED_DEVICES += mt7620a_mt7530
+endef
+TARGET_DEVICES += ralink_mt7620a-mt7530-evb
+
+define Device/ralink_mt7620a-mt7610e-evb
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7620a + MT7610e EVB
+  DEVICE_PACKAGES := kmod-mt76x0e
+  SUPPORTED_DEVICES += mt7620a_mt7610e
+endef
+TARGET_DEVICES += ralink_mt7620a-mt7610e-evb
+
+define Device/ralink_mt7620a-v22sg-evb
+  SOC := mt7620a
+  IMAGE_SIZE := 130560k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7620a V22SG
+  SUPPORTED_DEVICES += mt7620a_v22sg
+endef
+TARGET_DEVICES += ralink_mt7620a-v22sg-evb
+
+define Device/ravpower_rp-wd03
+  $(Device/sunvalley_filehub_common)
+  DEVICE_VENDOR := RAVPower
+  DEVICE_MODEL := RP-WD03
+  SUPPORTED_DEVICES += ravpower,wd03
+  DEVICE_COMPAT_VERSION := 2.0
+  DEVICE_COMPAT_MESSAGE := Partition design has changed compared to older versions (up to 19.07) due to kernel size restrictions. \
+	Upgrade via sysupgrade mechanism is not possible, so new installation via TFTP is required.
+endef
+TARGET_DEVICES += ravpower_rp-wd03
+
+define Device/sanlinking_d240
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Sanlinking Technologies
+  DEVICE_MODEL := D240
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += d240
+endef
+TARGET_DEVICES += sanlinking_d240
+
+define Device/sercomm_na930
+  SOC := mt7620a
+  IMAGE_SIZE := 20480k
+  DEVICE_VENDOR := Sercomm
+  DEVICE_MODEL := NA930
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += na930
+endef
+TARGET_DEVICES += sercomm_na930
+
+define Device/sitecom_wlr-4100-v1-002
+  SOC := mt7620a
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7744k
+  IMAGES += factory.dlf
+  IMAGE/factory.dlf := $$(sysupgrade_bin) | check-size | \
+	senao-header -r 0x0222 -p 0x104A -t 2
+  DEVICE_VENDOR := Sitecom
+  DEVICE_MODEL := WLR-4100
+  DEVICE_VARIANT := v1 002
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci uboot-envtools
+endef
+TARGET_DEVICES += sitecom_wlr-4100-v1-002
+
+define Device/tplink_archer-c20i
+  $(Device/tplink-v2)
+  SOC := mt7620a
+  IMAGE_SIZE := 7808k
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0xc2000001
+  TPLINK_HWREV := 58
+  DEVICE_MODEL := Archer C20i
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += c20i
+endef
+TARGET_DEVICES += tplink_archer-c20i
+
+define Device/tplink_archer-c20-v1
+  $(Device/tplink-v2)
+  SOC := mt7620a
+  IMAGE_SIZE := 7808k
+  SUPPORTED_DEVICES += tplink,c20-v1
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0xc2000001
+  TPLINK_HWREV := 0x44
+  TPLINK_HWREVADD := 0x1
+  IMAGES := sysupgrade.bin
+  DEVICE_MODEL := Archer C20
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += tplink_archer-c20-v1
+
+define Device/tplink_archer-c2-v1
+  $(Device/tplink-v2)
+  SOC := mt7620a
+  IMAGE_SIZE := 7808k
+  SUPPORTED_DEVICES += tplink,c2-v1
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0xc7500001
+  TPLINK_HWREV := 50
+  IMAGES := sysupgrade.bin
+  DEVICE_MODEL := Archer C2
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+endef
+TARGET_DEVICES += tplink_archer-c2-v1
+
+define Device/tplink_archer-c50-v1
+  $(Device/tplink-v2)
+  SOC := mt7620a
+  IMAGE_SIZE := 7808k
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0xc7500001
+  TPLINK_HWREV := 69
+  IMAGES := sysupgrade.bin factory-us.bin factory-eu.bin
+  IMAGE/factory-us.bin := tplink-v2-image -e -w 0
+  IMAGE/factory-eu.bin := tplink-v2-image -e -w 2
+  DEVICE_MODEL := Archer C50
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += c50
+endef
+TARGET_DEVICES += tplink_archer-c50-v1
+
+define Device/tplink_archer-mr200
+  $(Device/tplink-v2)
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  TPLINK_FLASHLAYOUT := 8MLmtk
+  TPLINK_HWID := 0xd7500001
+  TPLINK_HWREV := 0x4a
+  IMAGES := sysupgrade.bin
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-net-rndis \
+	kmod-usb-serial-option adb-enablemodem
+  DEVICE_MODEL := Archer MR200
+  SUPPORTED_DEVICES += mr200
+endef
+TARGET_DEVICES += tplink_archer-mr200
+
+define Device/tplink_re200-v1
+  $(Device/tplink-v1)
+  SOC := mt7620a
+  DEVICE_MODEL := RE200
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x0e
+  IMAGE_SIZE := 7936k
+  TPLINK_HWID := 0x02000001
+  TPLINK_FLASHLAYOUT := 8Mmtk
+endef
+TARGET_DEVICES += tplink_re200-v1
+
+define Device/tplink_re210-v1
+  $(Device/tplink-v1)
+  SOC := mt7620a
+  DEVICE_MODEL := RE210
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x0e
+  IMAGE_SIZE := 7936k
+  TPLINK_HWID := 0x02100001
+  TPLINK_FLASHLAYOUT := 8Mmtk
+endef
+TARGET_DEVICES += tplink_re210-v1
+
+define Device/trendnet_tew-810dr
+  SOC := mt7620a
+  DEVICE_PACKAGES := kmod-mt76x0e
+  DEVICE_VENDOR := TRENDnet
+  DEVICE_MODEL := TEW-810DR
+  IMAGE_SIZE := 6720k
+endef
+TARGET_DEVICES += trendnet_tew-810dr
+
+define Device/vonets_var11n-300
+  SOC := mt7620n
+  IMAGE_SIZE := 3776k
+  BLOCKSIZE := 4k
+  DEVICE_VENDOR := Vonets
+  DEVICE_MODEL := VAR11N-300
+  DEFAULT := n
+endef
+TARGET_DEVICES += vonets_var11n-300
+
+define Device/wavlink_wl-wn530hg4
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN530HG4
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += wavlink_wl-wn530hg4
+
+define Device/wavlink_wl-wn579x3
+  SOC := mt7620a
+  IMAGE_SIZE := 7744k
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN579X3
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-phy-realtek
+endef
+TARGET_DEVICES += wavlink_wl-wn579x3
+
+define Device/wrtnode_wrtnode
+  SOC := mt7620n
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := WRTNode
+  DEVICE_MODEL := WRTNode
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += wrtnode
+endef
+TARGET_DEVICES += wrtnode_wrtnode
+
+define Device/xiaomi_miwifi-mini
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := MiWiFi Mini
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += miwifi-mini
+endef
+TARGET_DEVICES += xiaomi_miwifi-mini
+
+define Device/youku_yk-l1
+  SOC := mt7620a
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Youku
+  DEVICE_MODEL := YK-L1
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += youku-yk1 youku,yk1
+endef
+TARGET_DEVICES += youku_yk-l1
+
+define Device/youku_yk-l1c
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Youku
+  DEVICE_MODEL := YK-L1c
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += youku_yk-l1c
+
+define Device/yukai_bocco
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := YUKAI Engineering
+  DEVICE_MODEL := BOCCO
+  DEVICE_PACKAGES := kmod-sound-core kmod-sound-mt7620 kmod-i2c-ralink
+  SUPPORTED_DEVICES += bocco
+endef
+TARGET_DEVICES += yukai_bocco
+
+define Device/zbtlink_zbt-ape522ii
+  SOC := mt7620a
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-APE522II
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += zbt-ape522ii
+endef
+TARGET_DEVICES += zbtlink_zbt-ape522ii
+
+define Device/zbtlink_zbt-cpe102
+  SOC := mt7620n
+  IMAGE_SIZE := 7552k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-CPE102
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += zbt-cpe102
+endef
+TARGET_DEVICES += zbtlink_zbt-cpe102
+
+define Device/zbtlink_zbt-wa05
+  SOC := mt7620n
+  IMAGE_SIZE := 7552k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WA05
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += zbt-wa05
+endef
+TARGET_DEVICES += zbtlink_zbt-wa05
+
+define Device/zbtlink_zbt-we1026-5g-16m
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE1026-5G
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += we1026-5g-16m zbtlink,we1026-5g-16m
+endef
+TARGET_DEVICES += zbtlink_zbt-we1026-5g-16m
+
+define Device/zbtlink_zbt-we1026-h-32m
+  SOC := mt7620a
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE1026-H
+  DEVICE_VARIANT := 32M
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+endef
+TARGET_DEVICES += zbtlink_zbt-we1026-h-32m
+
+define Device/zbtlink_zbt-we2026
+  SOC := mt7620n
+  IMAGE_SIZE := 7552k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE2026
+  SUPPORTED_DEVICES += zbt-we2026
+endef
+TARGET_DEVICES += zbtlink_zbt-we2026
+
+define Device/zbtlink_zbt-we826-16m
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE826
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += zbt-we826 zbt-we826-16M
+endef
+TARGET_DEVICES += zbtlink_zbt-we826-16m
+
+define Device/zbtlink_zbt-we826-32m
+  SOC := mt7620a
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE826
+  DEVICE_VARIANT := 32M
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += zbt-we826-32M
+endef
+TARGET_DEVICES += zbtlink_zbt-we826-32m
+
+define Device/zbtlink_zbt-we826-e
+  SOC := mt7620a
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE826-E
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-sdhci-mt7620 uqmi \
+	kmod-usb-serial-option
+endef
+TARGET_DEVICES += zbtlink_zbt-we826-e
+
+define Device/zbtlink_zbt-wr8305rt
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WR8305RT
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += zbt-wr8305rt
+endef
+TARGET_DEVICES += zbtlink_zbt-wr8305rt
+
+define Device/zte_q7
+  SOC := mt7620a
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZTE
+  DEVICE_MODEL := Q7
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += zte-q7
+endef
+TARGET_DEVICES += zte_q7
+
+define Device/zyxel_keenetic-omni
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Omni
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
+	zyimage -d 4882 -v "ZyXEL Keenetic Omni"
+  SUPPORTED_DEVICES += kn_rc
+endef
+TARGET_DEVICES += zyxel_keenetic-omni
+
+define Device/zyxel_keenetic-omni-ii
+  SOC := mt7620n
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Omni II
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
+	zyimage -d 2102034 -v "ZyXEL Keenetic Omni II"
+  SUPPORTED_DEVICES += kn_rf
+endef
+TARGET_DEVICES += zyxel_keenetic-omni-ii
+
+define Device/zyxel_keenetic-viva
+  SOC := mt7620a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Viva
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
+	kmod-switch-rtl8366-smi kmod-switch-rtl8367b
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
+	zyimage -d 8997 -v "ZyXEL Keenetic Viva"
+  SUPPORTED_DEVICES += kng_rc
+endef
+TARGET_DEVICES += zyxel_keenetic-viva
diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
new file mode 100644
index 0000000..36a03e8
--- /dev/null
+++ b/target/linux/ramips/image/mt7621.mk
@@ -0,0 +1,1679 @@
+#
+# MT7621 Profiles
+#
+
+include ./common-tp-link.mk
+
+DEFAULT_SOC := mt7621
+
+KERNEL_DTB += -d21
+DEVICE_VARS += ELECOM_HWNAME LINKSYS_HWNAME
+
+define Build/elecom-wrc-gs-factory
+	$(eval product=$(word 1,$(1)))
+	$(eval version=$(word 2,$(1)))
+	$(eval hash_opt=$(word 3,$(1)))
+	$(STAGING_DIR_HOST)/bin/mkhash md5 $(hash_opt) $@ >> $@
+	( \
+		echo -n "ELECOM $(product) v$(version)" | \
+			dd bs=32 count=1 conv=sync; \
+		dd if=$@; \
+	) > $@.new
+	mv $@.new $@
+endef
+
+define Build/gemtek-trailer
+	printf "%s%08X" ".GEMTEK." "$$(cksum $@ | cut -d ' ' -f1)" >> $@
+endef
+
+define Build/iodata-factory
+	$(eval fw_size=$(word 1,$(1)))
+	$(eval fw_type=$(word 2,$(1)))
+	$(eval product=$(word 3,$(1)))
+	$(eval factory_bin=$(word 4,$(1)))
+	if [ -e $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) -a "$$(stat -c%s $@)" -lt "$(fw_size)" ]; then \
+		$(CP) $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) $(factory_bin); \
+		$(STAGING_DIR_HOST)/bin/mksenaofw \
+			-r 0x30a -p $(product) -t $(fw_type) \
+			-e $(factory_bin) -o $(factory_bin).new; \
+		mv $(factory_bin).new $(factory_bin); \
+		$(CP) $(factory_bin) $(BIN_DIR)/; \
+	else \
+		echo "WARNING: initramfs kernel image too big, cannot generate factory image" >&2; \
+	fi
+endef
+
+define Build/iodata-mstc-header
+	( \
+		data_size_crc="$$(dd if=$@ ibs=64 skip=1 2>/dev/null | gzip -c | \
+			tail -c 8 | od -An -tx8 --endian little | tr -d ' \n')"; \
+		echo -ne "$$(echo $$data_size_crc | sed 's/../\\x&/g')" | \
+			dd of=$@ bs=8 count=1 seek=7 conv=notrunc 2>/dev/null; \
+	)
+	dd if=/dev/zero of=$@ bs=4 count=1 seek=1 conv=notrunc 2>/dev/null
+	( \
+		header_crc="$$(dd if=$@ bs=64 count=1 2>/dev/null | gzip -c | \
+			tail -c 8 | od -An -N4 -tx4 --endian little | tr -d ' \n')"; \
+		echo -ne "$$(echo $$header_crc | sed 's/../\\x&/g')" | \
+			dd of=$@ bs=4 count=1 seek=1 conv=notrunc 2>/dev/null; \
+	)
+endef
+
+define Build/ubnt-erx-factory-image
+	if [ -e $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) -a "$$(stat -c%s $@)" -lt "$(KERNEL_SIZE)" ]; then \
+		echo '21001:7' > $(1).compat; \
+		$(TAR) -cf $(1) --transform='s/^.*/compat/' $(1).compat; \
+		\
+		$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp/' $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE); \
+		mkhash md5 $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) > $(1).md5; \
+		$(TAR) -rf $(1) --transform='s/^.*/vmlinux.tmp.md5/' $(1).md5; \
+		\
+		echo "dummy" > $(1).rootfs; \
+		$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp/' $(1).rootfs; \
+		\
+		mkhash md5 $(1).rootfs > $(1).md5; \
+		$(TAR) -rf $(1) --transform='s/^.*/squashfs.tmp.md5/' $(1).md5; \
+		\
+		echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $(1).version; \
+		$(TAR) -rf $(1) --transform='s/^.*/version.tmp/' $(1).version; \
+		\
+		$(CP) $(1) $(BIN_DIR)/; \
+	else \
+		echo "WARNING: initramfs kernel image too big, cannot generate factory image" >&2; \
+	fi
+endef
+
+define Build/zytrx-header
+	$(eval board=$(word 1,$(1)))
+	$(eval version=$(word 2,$(1)))
+	$(STAGING_DIR_HOST)/bin/zytrx -B '$(board)' -v '$(version)' -i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Device/dsa-migration
+  DEVICE_COMPAT_VERSION := 1.1
+  DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
+endef
+
+define Device/adslr_g7
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ADSLR
+  DEVICE_MODEL := G7
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += adslr_g7
+
+define Device/afoundry_ew1200
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := AFOUNDRY
+  DEVICE_MODEL := EW1200
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-mt76x2 kmod-mt7603 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += ew1200
+endef
+TARGET_DEVICES += afoundry_ew1200
+
+define Device/alfa-network_quad-e4g
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ALFA Network
+  DEVICE_MODEL := Quad-E4G
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 uboot-envtools \
+	-wpad-basic-wolfssl
+  SUPPORTED_DEVICES += quad-e4g
+endef
+TARGET_DEVICES += alfa-network_quad-e4g
+
+define Device/ampedwireless_ally_common
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := Amped Wireless
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware uboot-envtools
+  IMAGE_SIZE := 32768k
+  KERNEL_SIZE := 4096k
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  UBINIZE_OPTS := -E 5
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma -n 'flashable-initramfs' |\
+	edimax-header -s CSYS -m RN68 -f 0x001c0000 -S 0x01100000
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+
+define Device/ampedwireless_ally-r1900k
+  $(Device/ampedwireless_ally_common)
+  DEVICE_MODEL := ALLY-R1900K
+  DEVICE_PACKAGES += kmod-usb3
+endef
+TARGET_DEVICES += ampedwireless_ally-r1900k
+
+define Device/ampedwireless_ally-00x19k
+  $(Device/ampedwireless_ally_common)
+  DEVICE_MODEL := ALLY-00X19K
+endef
+TARGET_DEVICES += ampedwireless_ally-00x19k
+
+define Device/asiarf_ap7621-001
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16000k
+  DEVICE_VENDOR := AsiaRF
+  DEVICE_MODEL := AP7621-001
+  DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += asiarf_ap7621-001
+
+define Device/asiarf_ap7621-nv1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16000k
+  DEVICE_VENDOR := AsiaRF
+  DEVICE_MODEL := AP7621-NV1
+  DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += asiarf_ap7621-nv1
+
+define Device/asus_rt-ac57u
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := ASUS
+  DEVICE_MODEL := RT-AC57U
+  IMAGE_SIZE := 16064k
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += asus_rt-ac57u
+
+define Device/asus_rt-ac65p
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := ASUS
+  DEVICE_MODEL := RT-AC65P
+  IMAGE_SIZE := 51200k
+  UBINIZE_OPTS := -E 5
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt7615e kmod-mt7615-firmware uboot-envtools
+endef
+TARGET_DEVICES += asus_rt-ac65p
+
+define Device/asus_rt-ac85p
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := ASUS
+  DEVICE_MODEL := RT-AC85P
+  IMAGE_SIZE := 51200k
+  UBINIZE_OPTS := -E 5
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt7615e kmod-mt7615-firmware uboot-envtools
+endef
+TARGET_DEVICES += asus_rt-ac85p
+
+define Device/asus_rt-n56u-b1
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := ASUS
+  DEVICE_MODEL := RT-N56U
+  DEVICE_VARIANT := B1
+  IMAGE_SIZE := 16064k
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += asus_rt-n56u-b1
+
+define Device/buffalo_wsr-1166dhp
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE/sysupgrade.bin := trx | pad-rootfs | append-metadata
+  IMAGE_SIZE := 15936k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WSR-1166DHP
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2
+  SUPPORTED_DEVICES += wsr-1166
+endef
+TARGET_DEVICES += buffalo_wsr-1166dhp
+
+define Device/buffalo_wsr-2533dhpl
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 7936k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WSR-2533DHPL
+  DEVICE_ALT0_VENDOR := Buffalo
+  DEVICE_ALT0_MODEL := WSR-2533DHP
+  IMAGE/sysupgrade.bin := trx | pad-rootfs | append-metadata
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += buffalo_wsr-2533dhpl
+
+define Device/buffalo_wsr-600dhp
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WSR-600DHP
+  DEVICE_PACKAGES := kmod-mt7603 kmod-rt2800-pci
+  SUPPORTED_DEVICES += wsr-600
+endef
+TARGET_DEVICES += buffalo_wsr-600dhp
+
+define Device/cudy_wr1300
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := Cudy
+  DEVICE_MODEL := WR1300
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += cudy_wr1300
+
+define Device/cudy_wr2100
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := Cudy
+  DEVICE_MODEL := WR2100
+  IMAGE_SIZE := 15872k
+  UIMAGE_NAME := R11
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += cudy_wr2100
+
+define Device/dlink_dir-8xx-a1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16000k
+  DEVICE_VENDOR := D-Link
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+  KERNEL_INITRAMFS := $$(KERNEL) | uimage-padhdr 96
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | uimage-padhdr 96 |\
+	pad-rootfs | append-metadata | check-size
+  IMAGE/factory.bin := append-kernel | append-rootfs | uimage-padhdr 96 |\
+	check-size
+endef
+
+define Device/dlink_dir-8xx-r1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := D-Link
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+  KERNEL_INITRAMFS := $$(KERNEL)
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs |\
+	pad-rootfs | append-metadata | check-size
+endef
+
+define Device/dlink_dir-xx60-a1
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 40960k
+  UBINIZE_OPTS := -E 5
+  DEVICE_VENDOR := D-Link
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  KERNEL := $$(KERNEL) | uimage-padhdr 96
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+endef
+
+define Device/dlink_dir-1960-a1
+  $(Device/dlink_dir-xx60-a1)
+  DEVICE_MODEL := DIR-1960
+  DEVICE_VARIANT := A1
+endef
+TARGET_DEVICES += dlink_dir-1960-a1
+
+define Device/dlink_dir-2640-a1
+  $(Device/dlink_dir-xx60-a1)
+  DEVICE_MODEL := DIR-2640
+  DEVICE_VARIANT := A1
+endef
+TARGET_DEVICES += dlink_dir-2640-a1
+
+define Device/dlink_dir-2660-a1
+  $(Device/dlink_dir-xx60-a1)
+  DEVICE_MODEL := DIR-2660
+  DEVICE_VARIANT := A1
+endef
+TARGET_DEVICES += dlink_dir-2660-a1
+
+define Device/dlink_dir-860l-b1
+  $(Device/dsa-migration)
+  $(Device/seama)
+  BLOCKSIZE := 64k
+  SEAMA_SIGNATURE := wrgac13_dlink.2013gui_dir860lb
+  LOADER_TYPE := bin
+  KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | relocate-kernel | \
+	lzma -a0 | uImage lzma
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-860L
+  DEVICE_VARIANT := B1
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += dir-860l-b1
+endef
+TARGET_DEVICES += dlink_dir-860l-b1
+
+define Device/dlink_dir-867-a1
+  $(Device/dlink_dir-8xx-a1)
+  DEVICE_MODEL := DIR-867
+  DEVICE_VARIANT := A1
+endef
+TARGET_DEVICES += dlink_dir-867-a1
+
+define Device/dlink_dir-878-a1
+  $(Device/dlink_dir-8xx-a1)
+  DEVICE_MODEL := DIR-878
+  DEVICE_VARIANT := A1
+endef
+TARGET_DEVICES += dlink_dir-878-a1
+
+define Device/dlink_dir-882-a1
+  $(Device/dlink_dir-8xx-a1)
+  DEVICE_MODEL := DIR-882
+  DEVICE_VARIANT := A1
+  DEVICE_PACKAGES += kmod-usb3 kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += dlink_dir-882-a1
+
+define Device/dlink_dir-882-r1
+  $(Device/dlink_dir-8xx-r1)
+  DEVICE_MODEL := DIR-882
+  DEVICE_VARIANT := R1
+  DEVICE_PACKAGES += kmod-usb3 kmod-usb-ledtrig-usbport
+  IMAGE/factory.bin := append-kernel | append-rootfs | check-size | \
+	  sign-dlink-ru 57c5375741c30ca9ebcb36713db4ba51 \
+	  ab0dff19af8842cdb70a86b4b68d23f7
+endef
+TARGET_DEVICES += dlink_dir-882-r1
+
+define Device/d-team_newifi-d2
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Newifi
+  DEVICE_MODEL := D2
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += d-team_newifi-d2
+
+define Device/d-team_pbr-m1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := PandoraBox
+  DEVICE_MODEL := PBR-M1
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-sdhci-mt7620 \
+	kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += pbr-m1
+endef
+TARGET_DEVICES += d-team_pbr-m1
+
+define Device/edimax_ra21s
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := RA21S
+  DEVICE_ALT0_VENDOR := Edimax
+  DEVICE_ALT0_MODEL := Gemini RA21S
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 02020040 8844A2D168B45A2D
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += edimax_ra21s
+
+define Device/edimax_re23s
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 15680k
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := RE23S
+  DEVICE_ALT0_VENDOR := Edimax
+  DEVICE_ALT0_MODEL := Gemini RE23S
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN76 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  IMAGES += factory.bin
+  IMAGE/factory.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN76 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	check-size
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += edimax_re23s
+
+define Device/edimax_rg21s
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := Gemini AC2600 RG21S
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 02020038 8844A2D168B45A2D
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += edimax_rg21s
+
+define Device/elecom_wrc-1167ghbk2-s
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 15488k
+  DEVICE_VENDOR := ELECOM
+  DEVICE_MODEL := WRC-1167GHBK2-S
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elecom-wrc-gs-factory WRC-1167GHBK2-S 0.00
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += elecom_wrc-1167ghbk2-s
+
+define Device/elecom_wrc-gs
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := ELECOM
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elecom-wrc-gs-factory $$$$(ELECOM_HWNAME) 0.00 -N | \
+	append-string MT7621_ELECOM_$$$$(ELECOM_HWNAME)
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+
+define Device/elecom_wrc-1167gs2-b
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 11264k
+  DEVICE_MODEL := WRC-1167GS2-B
+  ELECOM_HWNAME := WRC-1167GS2
+endef
+TARGET_DEVICES += elecom_wrc-1167gs2-b
+
+define Device/elecom_wrc-1167gst2
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 24576k
+  DEVICE_MODEL := WRC-1167GST2
+  ELECOM_HWNAME := WRC-1167GST2
+endef
+TARGET_DEVICES += elecom_wrc-1167gst2
+
+define Device/elecom_wrc-1750gs
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 11264k
+  DEVICE_MODEL := WRC-1750GS
+  ELECOM_HWNAME := WRC-1750GS
+endef
+TARGET_DEVICES += elecom_wrc-1750gs
+
+define Device/elecom_wrc-1750gst2
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 24576k
+  DEVICE_MODEL := WRC-1750GST2
+  ELECOM_HWNAME := WRC-1750GST2
+endef
+TARGET_DEVICES += elecom_wrc-1750gst2
+
+define Device/elecom_wrc-1750gsv
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 11264k
+  DEVICE_MODEL := WRC-1750GSV
+  ELECOM_HWNAME := WRC-1750GSV
+endef
+TARGET_DEVICES += elecom_wrc-1750gsv
+
+define Device/elecom_wrc-1900gst
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 11264k
+  DEVICE_MODEL := WRC-1900GST
+  ELECOM_HWNAME := WRC-1900GST
+endef
+TARGET_DEVICES += elecom_wrc-1900gst
+
+define Device/elecom_wrc-2533ghbk-i
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := ELECOM
+  DEVICE_MODEL := WRC-2533GHBK-I
+  IMAGE_SIZE := 9856k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 0107002d 8844A2D168B45A2D | \
+	elecom-product-header WRC-2533GHBK-I
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += elecom_wrc-2533ghbk-i
+
+define Device/elecom_wrc-2533gst
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 11264k
+  DEVICE_MODEL := WRC-2533GST
+  ELECOM_HWNAME := WRC-2533GST
+endef
+TARGET_DEVICES += elecom_wrc-2533gst
+
+define Device/elecom_wrc-2533gst2
+  $(Device/elecom_wrc-gs)
+  IMAGE_SIZE := 24576k
+  DEVICE_MODEL := WRC-2533GST2
+  ELECOM_HWNAME := WRC-2533GST2
+endef
+TARGET_DEVICES += elecom_wrc-2533gst2
+
+define Device/firefly_firewrt
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Firefly
+  DEVICE_MODEL := FireWRT
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += firewrt
+endef
+TARGET_DEVICES += firefly_firewrt
+
+define Device/gehua_ghl-r-001
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := GeHua
+  DEVICE_MODEL := GHL-R-001
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += gehua_ghl-r-001
+
+define Device/glinet_gl-mt1300
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := GL-MT1300
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3
+endef
+TARGET_DEVICES += glinet_gl-mt1300
+
+define Device/gnubee_gb-pc1
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := GnuBee
+  DEVICE_MODEL := Personal Cloud One
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-sdhci-mt7620 -wpad-basic-wolfssl
+  IMAGE_SIZE := 32448k
+endef
+TARGET_DEVICES += gnubee_gb-pc1
+
+define Device/gnubee_gb-pc2
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := GnuBee
+  DEVICE_MODEL := Personal Cloud Two
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 kmod-sdhci-mt7620 -wpad-basic-wolfssl
+  IMAGE_SIZE := 32448k
+endef
+TARGET_DEVICES += gnubee_gb-pc2
+
+define Device/hiwifi_hc5962
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  UBINIZE_OPTS := -E 5
+  IMAGE_SIZE := 32768k
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5962
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3
+endef
+TARGET_DEVICES += hiwifi_hc5962
+
+define Device/iodata_wn-ax1167gr
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 15552k
+  KERNEL_INITRAMFS := $$(KERNEL) | \
+	iodata-factory 7864320 4 0x1055 $(KDIR)/tmp/$$(KERNEL_INITRAMFS_PREFIX)-factory.bin
+  DEVICE_VENDOR := I-O DATA
+  DEVICE_MODEL := WN-AX1167GR
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2
+endef
+TARGET_DEVICES += iodata_wn-ax1167gr
+
+define Device/iodata_nand
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := I-O DATA
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  UBINIZE_OPTS := -E 5
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 51200k
+  LOADER_TYPE := bin
+  KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | lzma | uImage lzma
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+
+# The OEM webinterface expects an kernel with initramfs which has the uImage
+# header field ih_name.
+# We don't want to set the header name field for the kernel include in the
+# sysupgrade image as well, as this image shouldn't be accepted by the OEM
+# webinterface. It will soft-brick the board.
+
+define Device/iodata_wn-ax1167gr2
+  $(Device/iodata_nand)
+  DEVICE_MODEL := WN-AX1167GR2
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | loader-kernel | lzma | \
+	uImage lzma -M 0x434f4d42 -n '3.10(XBC.1)b10' | iodata-mstc-header
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += iodata_wn-ax1167gr2
+
+define Device/iodata_wn-ax2033gr
+  $(Device/iodata_nand)
+  DEVICE_MODEL := WN-AX2033GR
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | loader-kernel | lzma | \
+	uImage lzma -M 0x434f4d42 -n '3.10(VST.1)C10' | iodata-mstc-header
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += iodata_wn-ax2033gr
+
+define Device/iodata_wn-dx1167r
+  $(Device/iodata_nand)
+  DEVICE_MODEL := WN-DX1167R
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | loader-kernel | lzma | \
+	uImage lzma -M 0x434f4d43 -n '3.10(XIK.1)b10' | iodata-mstc-header
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += iodata_wn-dx1167r
+
+define Device/iodata_wn-dx1200gr
+  $(Device/iodata_nand)
+  DEVICE_MODEL := WN-DX1200GR
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | loader-kernel | lzma | \
+	uImage lzma -M 0x434f4d43 -n '3.10(XIQ.0)b20' | iodata-mstc-header
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap
+endef
+TARGET_DEVICES += iodata_wn-dx1200gr
+
+define Device/iodata_wn-gx300gr
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 7616k
+  DEVICE_VENDOR := I-O DATA
+  DEVICE_MODEL := WN-GX300GR
+  DEVICE_PACKAGES := kmod-mt7603
+endef
+TARGET_DEVICES += iodata_wn-gx300gr
+
+define Device/iodata_wnpr2600g
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := I-O DATA
+  DEVICE_MODEL := WNPR2600G
+  IMAGE_SIZE := 13952k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	elx-header 0104003a 8844A2D168B45A2D
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += iodata_wnpr2600g
+
+define Device/iptime_a6ns-m
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16128k
+  UIMAGE_NAME := a6nm
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A6ns-M
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += iptime_a6ns-m
+
+define Device/iptime_a8004t
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16128k
+  UIMAGE_NAME := a8004t
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A8004T
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3
+endef
+TARGET_DEVICES += iptime_a8004t
+
+define Device/jcg_jhr-ac876m
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 89.1
+  JCG_MAXSIZE := 16064k
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := JHR-AC876M
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += jcg_jhr-ac876m
+
+define Device/jcg_q20
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  UBINIZE_OPTS := -E 5
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 91136k
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := Q20
+  DEVICE_PACKAGES := kmod-mt7915e uboot-envtools
+endef
+TARGET_DEVICES += jcg_q20
+
+define Device/jcg_y2
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 95.1
+  JCG_MAXSIZE := 16064k
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := Y2
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3
+endef
+TARGET_DEVICES += jcg_y2
+
+define Device/lenovo_newifi-d1
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Newifi
+  DEVICE_MODEL := D1
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += newifi-d1
+endef
+TARGET_DEVICES += lenovo_newifi-d1
+
+define Device/linksys_e5600
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 26624k
+  DEVICE_VENDOR := Linksys
+  DEVICE_MODEL := E5600
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap \
+	uboot-envtools
+  UBINIZE_OPTS := -E 5
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | check-size | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | \
+	append-ubi | check-size | gemtek-trailer
+endef
+TARGET_DEVICES += linksys_e5600
+
+define Device/linksys_ea7xxx
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 36864k
+  DEVICE_VENDOR := Linksys
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt7615e kmod-mt7615-firmware \
+	uboot-envtools
+  UBINIZE_OPTS := -E 5
+  IMAGES := sysupgrade.bin factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata | check-size
+  IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | \
+	append-ubi | check-size | linksys-image type=$$$$(LINKSYS_HWNAME)
+endef
+
+define Device/linksys_ea7300-v1
+  $(Device/linksys_ea7xxx)
+  DEVICE_MODEL := EA7300
+  DEVICE_VARIANT := v1
+  LINKSYS_HWNAME := EA7300
+endef
+TARGET_DEVICES += linksys_ea7300-v1
+
+define Device/linksys_ea7300-v2
+  $(Device/linksys_ea7xxx)
+  DEVICE_MODEL := EA7300
+  DEVICE_VARIANT := v2
+  LINKSYS_HWNAME := EA7300v2
+  DEVICE_PACKAGES += kmod-mt7603
+endef
+TARGET_DEVICES += linksys_ea7300-v2
+
+define Device/linksys_ea7500-v2
+  $(Device/linksys_ea7xxx)
+  DEVICE_MODEL := EA7500
+  DEVICE_VARIANT := v2
+  LINKSYS_HWNAME := EA7500v2
+endef
+TARGET_DEVICES += linksys_ea7500-v2
+
+define Device/linksys_ea8100-v1
+  $(Device/linksys_ea7xxx)
+  DEVICE_MODEL := EA8100
+  DEVICE_VARIANT := v1
+  LINKSYS_HWNAME := EA8100
+endef
+TARGET_DEVICES += linksys_ea8100-v1
+
+define Device/linksys_re6500
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Linksys
+  DEVICE_MODEL := RE6500
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += re6500
+endef
+TARGET_DEVICES += linksys_re6500
+
+define Device/mediatek_ap-mt7621a-v60
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Mediatek
+  DEVICE_MODEL := AP-MT7621A-V60 EVB
+  DEVICE_PACKAGES := kmod-usb3 kmod-sdhci-mt7620 kmod-sound-mt7620 -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += mediatek_ap-mt7621a-v60
+
+define Device/mediatek_mt7621-eval-board
+  $(Device/dsa-migration)
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 15104k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7621 EVB
+  DEVICE_PACKAGES := -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += mt7621
+endef
+TARGET_DEVICES += mediatek_mt7621-eval-board
+
+define Device/MikroTik
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := MikroTik
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 16128k
+  DEVICE_PACKAGES := kmod-usb3
+  KERNEL_NAME := vmlinuz
+  KERNEL := kernel-bin | append-dtb-elf
+  IMAGE/sysupgrade.bin := append-kernel | kernel2minor -s 1024 | \
+	pad-to $$$$(BLOCKSIZE) | append-rootfs | pad-rootfs | append-metadata | \
+	check-size
+endef
+
+define Device/mikrotik_routerboard-750gr3
+  $(Device/MikroTik)
+  DEVICE_MODEL := RouterBOARD 750Gr3
+  DEVICE_PACKAGES += -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += mikrotik,rb750gr3
+endef
+TARGET_DEVICES += mikrotik_routerboard-750gr3
+
+define Device/mikrotik_routerboard-760igs
+  $(Device/MikroTik)
+  DEVICE_MODEL := RouterBOARD 760iGS
+  DEVICE_PACKAGES += kmod-sfp -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += mikrotik_routerboard-760igs
+
+define Device/mikrotik_routerboard-m11g
+  $(Device/MikroTik)
+  DEVICE_MODEL := RouterBOARD M11G
+  DEVICE_PACKAGES := -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += mikrotik,rbm11g
+endef
+TARGET_DEVICES += mikrotik_routerboard-m11g
+
+define Device/mikrotik_routerboard-m33g
+  $(Device/MikroTik)
+  DEVICE_MODEL := RouterBOARD M33G
+  DEVICE_PACKAGES := -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += mikrotik,rbm33g
+endef
+TARGET_DEVICES += mikrotik_routerboard-m33g
+
+define Device/mqmaker_witi
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := MQmaker
+  DEVICE_MODEL := WiTi
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-mt76x2 kmod-sdhci-mt7620 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += witi mqmaker,witi-256m mqmaker,witi-512m
+endef
+TARGET_DEVICES += mqmaker_witi
+
+define Device/mtc_wr1201
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16000k
+  DEVICE_VENDOR := MTC
+  DEVICE_MODEL := Wireless Router WR1201
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma -n 'WR1201_8_128'
+  DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += mtc_wr1201
+
+define Device/netgear_ex6150
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := EX6150
+  DEVICE_PACKAGES := kmod-mt76x2
+  NETGEAR_BOARD_ID := U12H318T00_NETGEAR
+  IMAGE_SIZE := 14848k
+  IMAGES += factory.chk
+  IMAGE/factory.chk := $$(sysupgrade_bin) | check-size | netgear-chk
+endef
+TARGET_DEVICES += netgear_ex6150
+
+define Device/netgear_sercomm_nand
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  UBINIZE_OPTS := -E 5
+  IMAGES += factory.img kernel.bin rootfs.bin
+  IMAGE/factory.img := pad-extra 2048k | append-kernel | pad-to 6144k | \
+	append-ubi | pad-to $$$$(BLOCKSIZE) | sercom-footer | pad-to 128 | \
+	zip $$$$(SERCOMM_HWNAME).bin | sercom-seal
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/kernel.bin := append-kernel
+  IMAGE/rootfs.bin := append-ubi | check-size
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_PACKAGES := kmod-mt7603 kmod-usb3 kmod-usb-ledtrig-usbport
+endef
+
+define Device/netgear_r6220
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6220
+  SERCOMM_HWNAME := R6220
+  SERCOMM_HWID := AYA
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0086
+  IMAGE_SIZE := 28672k
+  DEVICE_PACKAGES += kmod-mt76x2
+  SUPPORTED_DEVICES += r6220
+endef
+TARGET_DEVICES += netgear_r6220
+
+
+define Device/netgear_r6260
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6260
+  SERCOMM_HWNAME := R6260
+  SERCOMM_HWID := CHJ
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0052
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_r6260
+
+define Device/netgear_r6350
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6350
+  SERCOMM_HWNAME := R6350
+  SERCOMM_HWID := CHJ
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0052
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_r6350
+
+define Device/netgear_r6700-v2
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6700
+  DEVICE_VARIANT := v2
+  DEVICE_ALT0_VENDOR := NETGEAR
+  DEVICE_ALT0_MODEL := Nighthawk AC2400
+  DEVICE_ALT0_VARIANT := v1
+  DEVICE_ALT1_VENDOR := NETGEAR
+  DEVICE_ALT1_MODEL := R7200
+  DEVICE_ALT1_VARIANT := v1
+  SERCOMM_HWNAME := R6950
+  SERCOMM_HWID := BZV
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x1032
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_r6700-v2
+
+define Device/netgear_r6800
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6800
+  SERCOMM_HWNAME := R6950
+  SERCOMM_HWID := BZV
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0062
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_r6800
+
+define Device/netgear_r6850
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := R6850
+  SERCOMM_HWNAME := R6850
+  SERCOMM_HWID := CHJ
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0052
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_r6850
+
+define Device/netgear_wac104
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := WAC104
+  SERCOMM_HWNAME := WAC104
+  SERCOMM_HWID := CAY
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0006
+  IMAGE_SIZE := 28672k
+  DEVICE_PACKAGES += kmod-mt76x2
+endef
+TARGET_DEVICES += netgear_wac104
+
+define Device/netgear_wac124
+  $(Device/netgear_sercomm_nand)
+  DEVICE_MODEL := WAC124
+  SERCOMM_HWNAME := WAC124
+  SERCOMM_HWID := CTL
+  SERCOMM_HWVER := A003
+  SERCOMM_SWVER := 0x0402
+  IMAGE_SIZE := 40960k
+  DEVICE_PACKAGES += kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += netgear_wac124
+
+define Device/netgear_wndr3700-v5
+  $(Device/dsa-migration)
+  $(Device/netgear_sercomm_nor)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 15232k
+  DEVICE_MODEL := WNDR3700
+  DEVICE_VARIANT := v5
+  SERCOMM_HWNAME := WNDR3700v5
+  SERCOMM_HWID := AYB
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x1054
+  SERCOMM_PAD := 320k
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += wndr3700v5
+endef
+TARGET_DEVICES += netgear_wndr3700-v5
+
+define Device/netis_wf2881
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  FILESYSTEMS := squashfs
+  KERNEL_SIZE := 4096k
+  IMAGE_SIZE := 129280k
+  UBINIZE_OPTS := -E 5
+  UIMAGE_NAME := WF2881_0.0.00
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | netis-tail WF2881 | uImage lzma
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_VENDOR := NETIS
+  DEVICE_MODEL := WF2881
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += netis_wf2881
+
+define Device/phicomm_k2p
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 15744k
+  DEVICE_VENDOR := Phicomm
+  DEVICE_MODEL := K2P
+  DEVICE_ALT0_VENDOR := Phicomm
+  DEVICE_ALT0_MODEL := KE 2P
+  SUPPORTED_DEVICES += k2p
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += phicomm_k2p
+
+define Device/planex_vr500
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 65216k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := VR500
+  DEVICE_PACKAGES := kmod-usb3 -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += vr500
+endef
+TARGET_DEVICES += planex_vr500
+
+define Device/samknows_whitebox-v8
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := SamKnows
+  DEVICE_MODEL := Whitebox 8
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport uboot-envtools
+  SUPPORTED_DEVICES += sk-wb8
+endef
+TARGET_DEVICES += samknows_whitebox-v8
+
+define Device/sercomm_na502
+  $(Device/uimage-lzma-loader)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  IMAGE_SIZE := 20480k
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  UBINIZE_OPTS := -E 5
+  KERNEL_SIZE := 4096k
+  DEVICE_VENDOR := SERCOMM
+  DEVICE_MODEL := NA502
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-mt7603 kmod-usb3
+endef
+TARGET_DEVICES += sercomm_na502
+
+define Device/storylink_sap-g3200u3
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := STORYLiNK
+  DEVICE_MODEL := SAP-G3200U3
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += sap-g3200u3
+endef
+TARGET_DEVICES += storylink_sap-g3200u3
+
+define Device/telco-electronics_x1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Telco Electronics
+  DEVICE_MODEL := X1
+  DEVICE_PACKAGES := kmod-usb3 kmod-mt76
+endef
+TARGET_DEVICES += telco-electronics_x1
+
+define Device/thunder_timecloud
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Thunder
+  DEVICE_MODEL := Timecloud
+  DEVICE_PACKAGES := kmod-usb3 -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += timecloud
+endef
+TARGET_DEVICES += thunder_timecloud
+
+define Device/totolink_a7000r
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  UIMAGE_NAME := C8340R1C-9999
+  DEVICE_VENDOR := TOTOLINK
+  DEVICE_MODEL := A7000R
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += totolink_a7000r
+
+define Device/totolink_x5000r
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  UIMAGE_NAME := C8343R-9999
+  DEVICE_VENDOR := TOTOLINK
+  DEVICE_MODEL := X5000R
+  DEVICE_PACKAGES := kmod-mt7915e
+endef
+TARGET_DEVICES += totolink_x5000r
+
+define Device/tplink_archer-a6-v3
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := Archer A6
+  DEVICE_VARIANT := V3
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e \
+	kmod-mt7663-firmware-ap
+  TPLINK_BOARD_ID := ARCHER-A6-V3
+  KERNEL := $(KERNEL_DTB) | uImage lzma
+  IMAGE_SIZE := 15744k
+endef
+TARGET_DEVICES += tplink_archer-a6-v3
+
+define Device/tplink_archer-c6u-v1
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := Archer C6U
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt7603 \
+	kmod-mt7615e kmod-mt7663-firmware-ap \
+	kmod-usb3 kmod-usb-ledtrig-usbport
+  KERNEL := $(KERNEL_DTB) | uImage lzma
+  TPLINK_BOARD_ID := ARCHER-C6U-V1
+  IMAGE_SIZE := 15744k
+endef
+TARGET_DEVICES += tplink_archer-c6u-v1
+
+define Device/tplink_eap235-wall-v1
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := EAP235-Wall
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7663-firmware-ap
+  TPLINK_BOARD_ID := EAP235-WALL-V1
+  IMAGE_SIZE := 13440k
+  IMAGE/factory.bin := append-rootfs | tplink-safeloader factory | \
+	pad-extra 128
+endef
+TARGET_DEVICES += tplink_eap235-wall-v1
+
+define Device/tplink_re350-v1
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := RE350
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2
+  TPLINK_BOARD_ID := RE350-V1
+  IMAGE_SIZE := 6016k
+  SUPPORTED_DEVICES += re350-v1
+endef
+TARGET_DEVICES += tplink_re350-v1
+
+define Device/tplink_re500-v1
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := RE500
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+  TPLINK_BOARD_ID := RE500-V1
+  IMAGE_SIZE := 14208k
+endef
+TARGET_DEVICES += tplink_re500-v1
+
+define Device/tplink_re650-v1
+  $(Device/dsa-migration)
+  $(Device/tplink-safeloader)
+  DEVICE_MODEL := RE650
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
+  TPLINK_BOARD_ID := RE650-V1
+  IMAGE_SIZE := 14208k
+endef
+TARGET_DEVICES += tplink_re650-v1
+
+define Device/ubnt_edgerouter_common
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := Ubiquiti
+  IMAGE_SIZE := 256768k
+  FILESYSTEMS := squashfs
+  KERNEL_SIZE := 3145728
+  KERNEL_INITRAMFS := $$(KERNEL) | \
+	ubnt-erx-factory-image $(KDIR)/tmp/$$(KERNEL_INITRAMFS_PREFIX)-factory.tar
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  DEVICE_PACKAGES += -wpad-basic-wolfssl
+endef
+
+define Device/ubnt_edgerouter-x
+  $(Device/ubnt_edgerouter_common)
+  DEVICE_MODEL := EdgeRouter X
+  SUPPORTED_DEVICES += ubnt-erx ubiquiti,edgerouterx
+endef
+TARGET_DEVICES += ubnt_edgerouter-x
+
+define Device/ubnt_edgerouter-x-sfp
+  $(Device/ubnt_edgerouter_common)
+  DEVICE_MODEL := EdgeRouter X SFP
+  DEVICE_PACKAGES += kmod-i2c-algo-pca kmod-gpio-pca953x kmod-sfp
+  SUPPORTED_DEVICES += ubnt-erx-sfp ubiquiti,edgerouterx-sfp
+endef
+TARGET_DEVICES += ubnt_edgerouter-x-sfp
+
+define Device/ubnt_unifi-6-lite
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := Ubiquiti
+  DEVICE_MODEL := UniFi 6 Lite
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt7915e
+  KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
+  IMAGE_SIZE := 15424k
+endef
+TARGET_DEVICES += ubnt_unifi-6-lite
+
+define Device/ubnt_unifi-nanohd
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := Ubiquiti
+  DEVICE_MODEL := UniFi nanoHD
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+  IMAGE_SIZE := 15552k
+endef
+TARGET_DEVICES += ubnt_unifi-nanohd
+
+define Device/unielec_u7621-01-16m
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := UniElec
+  DEVICE_MODEL := U7621-01
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3
+endef
+TARGET_DEVICES += unielec_u7621-01-16m
+
+define Device/unielec_u7621-06-16m
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := UniElec
+  DEVICE_MODEL := U7621-06
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += u7621-06-256M-16M unielec,u7621-06-256m-16m
+endef
+TARGET_DEVICES += unielec_u7621-06-16m
+
+define Device/unielec_u7621-06-64m
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 65216k
+  DEVICE_VENDOR := UniElec
+  DEVICE_MODEL := U7621-06
+  DEVICE_VARIANT := 64M
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-usb3 -wpad-basic-wolfssl
+  SUPPORTED_DEVICES += unielec,u7621-06-512m-64m
+endef
+TARGET_DEVICES += unielec_u7621-06-64m
+
+define Device/wavlink_wl-wn531a6
+  $(Device/dsa-migration)
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN531A6
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware kmod-usb3
+  IMAGE_SIZE := 15040k
+endef
+TARGET_DEVICES += wavlink_wl-wn531a6
+
+define Device/wevo_11acnas
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  UIMAGE_NAME := 11AC-NAS-Router(0.0.0)
+  DEVICE_VENDOR := WeVO
+  DEVICE_MODEL := 11AC NAS Router
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += 11acnas
+endef
+TARGET_DEVICES += wevo_11acnas
+
+define Device/wevo_w2914ns-v2
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  UIMAGE_NAME := W2914NS-V2(0.0.0)
+  DEVICE_VENDOR := WeVO
+  DEVICE_MODEL := W2914NS
+  DEVICE_VARIANT := v2
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += w2914nsv2
+endef
+TARGET_DEVICES += wevo_w2914ns-v2
+
+define Device/winstars_ws-wn583a6
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Winstars
+  DEVICE_MODEL := WS-WN583A6
+  DEVICE_ALT0_VENDOR := Gemeita
+  DEVICE_ALT0_MODEL := AC2100
+  KERNEL_INITRAMFS_SUFFIX := -WN583A6$$(KERNEL_SUFFIX)
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += winstars_ws-wn583a6
+
+define Device/xiaomi_nand_separate
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_PACKAGES := uboot-envtools
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  UBINIZE_OPTS := -E 5
+  IMAGES += kernel1.bin rootfs0.bin
+  IMAGE/kernel1.bin := append-kernel
+  IMAGE/rootfs0.bin := append-ubi | check-size
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+
+define Device/xiaomi_mi-router-3g
+  $(Device/xiaomi_nand_separate)
+  DEVICE_MODEL := Mi Router 3G
+  IMAGE_SIZE := 124416k
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += R3G mir3g xiaomi,mir3g
+endef
+TARGET_DEVICES += xiaomi_mi-router-3g
+
+define Device/xiaomi_mi-router-3g-v2
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 14848k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := Mi Router 3G
+  DEVICE_VARIANT := v2
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2
+  SUPPORTED_DEVICES += xiaomi,mir3g-v2
+endef
+TARGET_DEVICES += xiaomi_mi-router-3g-v2
+
+define Device/xiaomi_mi-router-3-pro
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE:= 4096k
+  UBINIZE_OPTS := -E 5
+  IMAGE_SIZE := 255488k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := Mi Router 3 Pro
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+  IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
+	check-size
+  DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3 \
+	kmod-usb-ledtrig-usbport uboot-envtools
+  SUPPORTED_DEVICES += xiaomi,mir3p
+endef
+TARGET_DEVICES += xiaomi_mi-router-3-pro
+
+define Device/xiaomi_mi-router-4
+  $(Device/xiaomi_nand_separate)
+  DEVICE_MODEL := Mi Router 4
+  IMAGE_SIZE := 124416k
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2
+endef
+TARGET_DEVICES += xiaomi_mi-router-4
+
+define Device/xiaomi_mi-router-4a-gigabit
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 14848k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := Mi Router 4A
+  DEVICE_VARIANT := Gigabit Edition
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2
+endef
+TARGET_DEVICES += xiaomi_mi-router-4a-gigabit
+
+define Device/xiaomi_mi-router-ac2100
+  $(Device/xiaomi_nand_separate)
+  DEVICE_MODEL := Mi Router AC2100
+  IMAGE_SIZE := 120320k
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += xiaomi_mi-router-ac2100
+
+define Device/xiaomi_redmi-router-ac2100
+  $(Device/xiaomi_nand_separate)
+  DEVICE_MODEL := Redmi Router AC2100
+  IMAGE_SIZE := 120320k
+  DEVICE_PACKAGES += kmod-mt7603 kmod-mt7615e kmod-mt7615-firmware
+endef
+TARGET_DEVICES += xiaomi_redmi-router-ac2100
+
+define Device/xiaoyu_xy-c5
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := XiaoYu
+  DEVICE_MODEL := XY-C5
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-usb3 -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += xiaoyu_xy-c5
+
+define Device/xzwifi_creativebox-v1
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := CreativeBox
+  DEVICE_MODEL := v1
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-mt7603 kmod-mt76x2 kmod-sdhci-mt7620 \
+	kmod-usb3 -wpad-basic-wolfssl
+endef
+TARGET_DEVICES += xzwifi_creativebox-v1
+
+define Device/youhua_wr1200js
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := YouHua
+  DEVICE_MODEL := WR1200JS
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += youhua_wr1200js
+
+define Device/youku_yk-l2
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Youku
+  DEVICE_MODEL := YK-L2
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += youku_yk-l2
+
+define Device/yuncore_ax820
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 15808k
+  DEVICE_VENDOR := YunCore
+  DEVICE_MODEL := AX820
+  DEVICE_PACKAGES := kmod-mt7915e
+endef
+TARGET_DEVICES += yuncore_ax820
+
+define Device/zbtlink_zbt-we1326
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE1326
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += zbt-we1326
+endef
+TARGET_DEVICES += zbtlink_zbt-we1326
+
+define Device/zbtlink_zbt-we3526
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE3526
+  DEVICE_PACKAGES := kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += zbtlink_zbt-we3526
+
+define Device/zbtlink_zbt-wg2626
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WG2626
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += zbt-wg2626
+endef
+TARGET_DEVICES += zbtlink_zbt-wg2626
+
+define Device/zbtlink_zbt-wg3526-16m
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WG3526
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 \
+	kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += zbt-wg3526 zbt-wg3526-16M
+endef
+TARGET_DEVICES += zbtlink_zbt-wg3526-16m
+
+define Device/zbtlink_zbt-wg3526-32m
+  $(Device/dsa-migration)
+  $(Device/uimage-lzma-loader)
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WG3526
+  DEVICE_VARIANT := 32M
+  DEVICE_PACKAGES := kmod-ata-ahci kmod-sdhci-mt7620 kmod-mt7603 kmod-mt76x2 \
+	kmod-usb3 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += ac1200pro zbt-wg3526-32M
+endef
+TARGET_DEVICES += zbtlink_zbt-wg3526-32m
+
+define Device/zio_freezio
+  $(Device/dsa-migration)
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := ZIO
+  DEVICE_MODEL := FREEZIO
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 \
+	kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += zio_freezio
+
+define Device/zyxel_nr7101
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  UBINIZE_OPTS := -E 5
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := NR7101
+  DEVICE_PACKAGES := kmod-mt7603 kmod-usb3 uboot-envtools kmod-usb-net-qmi-wwan kmod-usb-serial-option uqmi
+  KERNEL := $(KERNEL_DTB) | uImage lzma | zytrx-header $$(DEVICE_MODEL) $$(VERSION_DIST)-$$(REVISION)
+  KERNEL_INITRAMFS := $(KERNEL_DTB) | uImage lzma | zytrx-header $$(DEVICE_MODEL) 9.99(ABUV.9)$$(VERSION_DIST)-recovery
+  KERNEL_INITRAMFS_SUFFIX := -recovery.bin
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+TARGET_DEVICES += zyxel_nr7101
+
+define Device/zyxel_wap6805
+  $(Device/dsa-migration)
+  BLOCKSIZE := 128k
+  PAGESIZE := 2048
+  KERNEL_SIZE := 4096k
+  UBINIZE_OPTS := -E 5
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := WAP6805
+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt7621-qtn-rgmii
+  KERNEL := $(KERNEL_DTB) | uImage lzma | uimage-padhdr 160
+  IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
+endef
+TARGET_DEVICES += zyxel_wap6805
diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
new file mode 100644
index 0000000..1a75bab
--- /dev/null
+++ b/target/linux/ramips/image/mt76x8.mk
@@ -0,0 +1,836 @@
+#
+# MT76x8 Profiles
+#
+
+include ./common-tp-link.mk
+
+DEFAULT_SOC := mt7628an
+
+define Build/elecom-header
+	$(eval model_id=$(1))
+	( \
+		fw_size="$$(printf '%08x' $$(stat -c%s $@))"; \
+		echo -ne "$$(echo "031d6129$${fw_size}06000000$(model_id)" | \
+			sed 's/../\\x&/g')"; \
+		dd if=/dev/zero bs=92 count=1; \
+		data_crc="$$(dd if=$@ | gzip -c | tail -c 8 | \
+			od -An -N4 -tx4 --endian little | tr -d ' \n')"; \
+		echo -ne "$$(echo "$${data_crc}00000000" | sed 's/../\\x&/g')"; \
+		dd if=$@; \
+	) > $@.new
+	mv $@.new $@
+endef
+
+define Build/ravpower-wd009-factory
+	mkimage -A mips -T standalone -C none -a 0x80010000 -e 0x80010000 \
+		-n "OpenWrt Bootloader" -d $(UBOOT_PATH) $@.new
+	cat $@ >> $@.new
+	@mv $@.new $@
+endef
+
+
+define Device/alfa-network_awusfree1
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ALFA Network
+  DEVICE_MODEL := AWUSFREE1
+  DEVICE_PACKAGES := uboot-envtools
+  SUPPORTED_DEVICES += awusfree1
+endef
+TARGET_DEVICES += alfa-network_awusfree1
+
+define Device/asus_rt-n10p-v3
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N10P
+  DEVICE_VARIANT := V3
+endef
+TARGET_DEVICES += asus_rt-n10p-v3
+
+define Device/asus_rt-n11p-b1
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N11P
+  DEVICE_VARIANT := B1
+endef
+TARGET_DEVICES += asus_rt-n11p-b1
+
+define Device/asus_rt-n12-vp-b1
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N12 VP
+  DEVICE_VARIANT := B1
+endef
+TARGET_DEVICES += asus_rt-n12-vp-b1
+
+define Device/buffalo_wcr-1166ds
+  IMAGE_SIZE := 7936k
+  BUFFALO_TAG_PLATFORM := MTK
+  BUFFALO_TAG_VERSION := 9.99
+  BUFFALO_TAG_MINOR := 9.99
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := trx | pad-rootfs | append-metadata
+  IMAGE/factory.bin := trx -M 0x746f435c | pad-rootfs | append-metadata | \
+	buffalo-enc WCR-1166DS $$(BUFFALO_TAG_VERSION) -l | \
+	buffalo-tag-dhp WCR-1166DS JP JP | buffalo-enc-tag -l | buffalo-dhp-image
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WCR-1166DS
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += wcr-1166ds
+endef
+TARGET_DEVICES += buffalo_wcr-1166ds
+
+define Device/cudy_wr1000
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 92.122
+  JCG_MAXSIZE := 7872k
+  DEVICE_VENDOR := Cudy
+  DEVICE_MODEL := WR1000
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += wr1000
+endef
+TARGET_DEVICES += cudy_wr1000
+
+define Device/d-team_pbr-d1
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := PandoraBox
+  DEVICE_MODEL := PBR-D1
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += pbr-d1
+endef
+TARGET_DEVICES += d-team_pbr-d1
+
+define Device/duzun_dm06
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := DuZun
+  DEVICE_MODEL := DM06
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += duzun-dm06
+endef
+TARGET_DEVICES += duzun_dm06
+
+define Device/elecom_wrc-1167fs
+  IMAGE_SIZE := 7360k
+  DEVICE_VENDOR := ELECOM
+  DEVICE_MODEL := WRC-1167FS
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to 64k | check-size | \
+	xor-image -p 29944A25 -x | elecom-header 00228000 | \
+	elecom-product-header WRC-1167FS
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += elecom_wrc-1167fs
+
+define Device/glinet_gl-mt300n-v2
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := GL-MT300N
+  DEVICE_VARIANT := V2
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += gl-mt300n-v2
+endef
+TARGET_DEVICES += glinet_gl-mt300n-v2
+
+define Device/glinet_microuter-n300
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := microuter-N300
+  SUPPORTED_DEVICES += microuter-n300
+endef
+TARGET_DEVICES += glinet_microuter-n300
+
+define Device/glinet_vixmini
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := GL.iNet
+  DEVICE_MODEL := VIXMINI
+  SUPPORTED_DEVICES += vixmini
+endef
+TARGET_DEVICES += glinet_vixmini
+
+define Device/hak5_wifi-pineapple-mk7
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Hak5
+  DEVICE_MODEL := WiFi Pineapple Mark 7
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += wifi-pineapple-mk7
+endef
+TARGET_DEVICES += hak5_wifi-pineapple-mk7
+
+define Device/hilink_hlk-7628n
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := HILINK
+  DEVICE_MODEL := HLK-7628N
+endef
+TARGET_DEVICES += hilink_hlk-7628n
+
+define Device/hilink_hlk-7688a
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Hi-Link
+  DEVICE_MODEL := HLK-7688A
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+endef
+TARGET_DEVICES += hilink_hlk-7688a
+
+define Device/hiwifi_hc5661a
+  IMAGE_SIZE := 15808k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5661A
+  SUPPORTED_DEVICES += hc5661a
+endef
+TARGET_DEVICES += hiwifi_hc5661a
+
+define Device/hiwifi_hc5761a
+  IMAGE_SIZE := 15808k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5761A
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += hiwifi_hc5761a
+
+define Device/hiwifi_hc5861b
+  IMAGE_SIZE := 15808k
+  DEVICE_VENDOR := HiWiFi
+  DEVICE_MODEL := HC5861B
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += hiwifi_hc5861b
+
+define Device/iptime_a3
+  IMAGE_SIZE := 7936k
+  UIMAGE_NAME := a3
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A3
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += iptime_a3
+
+define Device/iptime_a604m
+  IMAGE_SIZE := 7936k
+  UIMAGE_NAME := a604m
+  DEVICE_VENDOR := ipTIME
+  DEVICE_MODEL := A604M
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += iptime_a604m
+
+define Device/jotale_js76x8
+  DEVICE_VENDOR := Jotale
+  DEVICE_MODEL := JS76x8
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+endef
+
+define Device/jotale_js76x8-8m
+  $(Device/jotale_js76x8)
+  IMAGE_SIZE := 7872k
+  DEVICE_VARIANT := 8M
+endef
+TARGET_DEVICES += jotale_js76x8-8m
+
+define Device/jotale_js76x8-16m
+  $(Device/jotale_js76x8)
+  IMAGE_SIZE := 16064k
+  DEVICE_VARIANT := 16M
+endef
+TARGET_DEVICES += jotale_js76x8-16m
+
+define Device/jotale_js76x8-32m
+  $(Device/jotale_js76x8)
+  IMAGE_SIZE := 32448k
+  DEVICE_VARIANT := 32M
+endef
+TARGET_DEVICES += jotale_js76x8-32m
+
+define Device/mediatek_linkit-smart-7688
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := LinkIt Smart 7688
+  DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += linkits7688 linkits7688d
+endef
+TARGET_DEVICES += mediatek_linkit-smart-7688
+
+define Device/mediatek_mt7628an-eval-board
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := MediaTek
+  DEVICE_MODEL := MT7628 EVB
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += mt7628
+endef
+TARGET_DEVICES += mediatek_mt7628an-eval-board
+
+define Device/mercury_mac1200r-v2
+  IMAGE_SIZE := 7936k
+  DEVICE_VENDOR := Mercury
+  DEVICE_MODEL := MAC1200R
+  DEVICE_VARIANT := v2.0
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += mac1200rv2
+endef
+TARGET_DEVICES += mercury_mac1200r-v2
+
+define Device/minew_g1-c
+  IMAGE_SIZE := 15744k
+  DEVICE_VENDOR := Minew
+  DEVICE_MODEL := G1-C
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport kmod-usb-serial-cp210x
+  SUPPORTED_DEVICES += minew-g1c
+endef
+TARGET_DEVICES += minew_g1-c
+
+define Device/netgear_r6020
+  $(Device/netgear_sercomm_nor)
+  IMAGE_SIZE := 7104k
+  DEVICE_MODEL := R6020
+  DEVICE_PACKAGES := kmod-mt76x2
+  SERCOMM_HWNAME := R6020
+  SERCOMM_HWID := CFR
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0040
+  SERCOMM_PAD := 576k
+endef
+TARGET_DEVICES += netgear_r6020
+
+define Device/netgear_r6080
+  $(Device/netgear_sercomm_nor)
+  IMAGE_SIZE := 7552k
+  DEVICE_MODEL := R6080
+  DEVICE_PACKAGES := kmod-mt76x2
+  SERCOMM_HWNAME := R6080
+  SERCOMM_HWID := CFR
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0040
+  SERCOMM_PAD := 576k
+endef
+TARGET_DEVICES += netgear_r6080
+
+define Device/netgear_r6120
+  $(Device/netgear_sercomm_nor)
+  IMAGE_SIZE := 15744k
+  DEVICE_MODEL := R6120
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci
+  SERCOMM_HWNAME := R6120
+  SERCOMM_HWID := CGQ
+  SERCOMM_HWVER := A001
+  SERCOMM_SWVER := 0x0040
+  SERCOMM_PAD := 576k
+endef
+TARGET_DEVICES += netgear_r6120
+
+define Device/onion_omega2
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Onion
+  DEVICE_MODEL := Omega2
+  DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools
+  SUPPORTED_DEVICES += omega2
+endef
+TARGET_DEVICES += onion_omega2
+
+define Device/onion_omega2p
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Onion
+  DEVICE_MODEL := Omega2+
+  DEVICE_PACKAGES:= kmod-usb2 kmod-usb-ohci uboot-envtools kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += omega2p
+endef
+TARGET_DEVICES += onion_omega2p
+
+define Device/rakwireless_rak633
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Rakwireless
+  DEVICE_MODEL := RAK633
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += rakwireless_rak633
+
+define Device/ravpower_rp-wd009
+  IMAGE_SIZE := 14272k
+  DEVICE_VENDOR := RAVPower
+  DEVICE_MODEL := RP-WD009
+  UBOOT_PATH := $(STAGING_DIR_IMAGE)/ravpower_rp-wd009-u-boot.bin
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-sdhci-mt7620 kmod-i2c-mt7628 ravpower-mcu
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | ravpower-wd009-factory
+endef
+TARGET_DEVICES += ravpower_rp-wd009
+
+define Device/skylab_skw92a
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Skylab
+  DEVICE_MODEL := SKW92A
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += skylab_skw92a
+
+define Device/tama_w06
+  IMAGE_SIZE := 15040k
+  DEVICE_VENDOR := Tama
+  DEVICE_MODEL := W06
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += tama_w06
+
+define Device/totolink_a3
+  IMAGE_SIZE := 7936k
+  UIMAGE_NAME := za3
+  DEVICE_VENDOR := TOTOLINK
+  DEVICE_MODEL := A3
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+TARGET_DEVICES += totolink_a3
+
+define Device/totolink_lr1200
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := TOTOLINK
+  DEVICE_MODEL := LR1200
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 uqmi
+endef
+TARGET_DEVICES += totolink_lr1200
+
+define Device/tplink_archer-c20-v4
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := Archer C20
+  DEVICE_VARIANT := v4
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0xc200004
+  TPLINK_HWREVADD := 0x4
+  DEVICE_PACKAGES := kmod-mt76x0e
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+  SUPPORTED_DEVICES += tplink,c20-v4
+endef
+TARGET_DEVICES += tplink_archer-c20-v4
+
+define Device/tplink_archer-c20-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7616k
+  DEVICE_MODEL := Archer C20
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 8MSUmtk
+  TPLINK_HWID := 0xc200005
+  TPLINK_HWREVADD := 0x5
+  DEVICE_PACKAGES := kmod-mt76x0e
+  IMAGES := sysupgrade.bin
+endef
+TARGET_DEVICES += tplink_archer-c20-v5
+
+define Device/tplink_archer-c50-v3
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := Archer C50
+  DEVICE_VARIANT := v3
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x001D9BA4
+  TPLINK_HWREV := 0x79
+  TPLINK_HWREVADD := 0x1
+  DEVICE_PACKAGES := kmod-mt76x2
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+  SUPPORTED_DEVICES += tplink,c50-v3
+endef
+TARGET_DEVICES += tplink_archer-c50-v3
+
+define Device/tplink_archer-c50-v4
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7616k
+  DEVICE_MODEL := Archer C50
+  DEVICE_VARIANT := v4
+  TPLINK_FLASHLAYOUT := 8MSUmtk
+  TPLINK_HWID := 0x001D589B
+  TPLINK_HWREV := 0x93
+  TPLINK_HWREVADD := 0x2
+  DEVICE_PACKAGES := kmod-mt76x2
+  IMAGES := sysupgrade.bin
+  SUPPORTED_DEVICES += tplink,c50-v4
+endef
+TARGET_DEVICES += tplink_archer-c50-v4
+
+define Device/tplink_re200-v2
+  $(Device/tplink-safeloader)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := RE200
+  DEVICE_VARIANT := v2
+  DEVICE_PACKAGES := kmod-mt76x0e
+  TPLINK_BOARD_ID := RE200-V2
+endef
+TARGET_DEVICES += tplink_re200-v2
+
+define Device/tplink_re200-v3
+  $(Device/tplink-safeloader)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := RE200
+  DEVICE_VARIANT := v3
+  DEVICE_PACKAGES := kmod-mt76x0e
+  TPLINK_BOARD_ID := RE200-V3
+endef
+TARGET_DEVICES += tplink_re200-v3
+
+define Device/tplink_re200-v4
+  $(Device/tplink-safeloader)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := RE200
+  DEVICE_VARIANT := v4
+  DEVICE_PACKAGES := kmod-mt76x0e
+  TPLINK_BOARD_ID := RE200-V4
+endef
+TARGET_DEVICES += tplink_re200-v4
+
+define Device/tplink_re220-v2
+  $(Device/tplink-safeloader)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := RE220
+  DEVICE_VARIANT := v2
+  DEVICE_PACKAGES := kmod-mt76x0e
+  TPLINK_BOARD_ID := RE220-V2
+endef
+TARGET_DEVICES += tplink_re220-v2
+
+define Device/tplink_re305-v1
+  $(Device/tplink-safeloader)
+  IMAGE_SIZE := 6016k
+  DEVICE_MODEL := RE305
+  DEVICE_VARIANT := v1
+  DEVICE_PACKAGES := kmod-mt76x2
+  TPLINK_BOARD_ID := RE305-V1
+endef
+TARGET_DEVICES += tplink_re305-v1
+
+define Device/tplink_tl-mr3020-v3
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-MR3020
+  DEVICE_VARIANT := v3
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x30200003
+  TPLINK_HWREV := 0x3
+  TPLINK_HWREVADD := 0x3
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-mr3020-v3
+
+define Device/tplink_tl-mr3420-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-MR3420
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x34200005
+  TPLINK_HWREV := 0x5
+  TPLINK_HWREVADD := 0x5
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-mr3420-v5
+
+define Device/tplink_tl-mr6400-v4
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-MR6400
+  DEVICE_VARIANT := v4
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x64000004
+  TPLINK_HWREV := 0x4
+  TPLINK_HWREVADD := 0x4
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
+	kmod-usb-serial-option kmod-usb-net-qmi-wwan uqmi
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-mr6400-v4
+
+define Device/tplink_tl-mr6400-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-MR6400
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x64000005
+  TPLINK_HWREV := 0x5
+  TPLINK_HWREVADD := 0x5
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
+	kmod-usb-serial-option kmod-usb-net-qmi-wwan uqmi
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-mr6400-v5
+
+define Device/tplink_tl-wa801nd-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WA801ND
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08010005
+  TPLINK_HWREVADD := 0x5
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-wa801nd-v5
+
+define Device/tplink_tl-wr802n-v4
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR802N
+  DEVICE_VARIANT := v4
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08020004
+  TPLINK_HWREVADD := 0x4
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-wr802n-v4
+
+define Device/tplink_tl-wr840n-v4
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR840N
+  DEVICE_VARIANT := v4
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08400004
+  TPLINK_HWREVADD := 0x4
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+  SUPPORTED_DEVICES += tl-wr840n-v4
+endef
+TARGET_DEVICES += tplink_tl-wr840n-v4
+
+define Device/tplink_tl-wr840n-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 3904k
+  DEVICE_MODEL := TL-WR840N
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 4Mmtk
+  TPLINK_HWID := 0x08400005
+  TPLINK_HWREVADD := 0x5
+  IMAGES := sysupgrade.bin
+  SUPPORTED_DEVICES += tl-wr840n-v5
+  DEFAULT := n
+endef
+TARGET_DEVICES += tplink_tl-wr840n-v5
+
+define Device/tplink_tl-wr841n-v13
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR841N
+  DEVICE_VARIANT := v13
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08410013
+  TPLINK_HWREV := 0x268
+  TPLINK_HWREVADD := 0x13
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+  SUPPORTED_DEVICES += tl-wr841n-v13
+endef
+TARGET_DEVICES += tplink_tl-wr841n-v13
+
+define Device/tplink_tl-wr841n-v14
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 3968k
+  DEVICE_MODEL := TL-WR841N
+  DEVICE_VARIANT := v14
+  TPLINK_FLASHLAYOUT := 4MLmtk
+  TPLINK_HWID := 0x08410014
+  TPLINK_HWREVADD := 0x14
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 64k | $$(IMAGE/factory.bin)
+  DEFAULT := n
+endef
+TARGET_DEVICES += tplink_tl-wr841n-v14
+
+define Device/tplink_tl-wr842n-v5
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR842N
+  DEVICE_VARIANT := v5
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08420005
+  TPLINK_HWREV := 0x5
+  TPLINK_HWREVADD := 0x5
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-wr842n-v5
+
+define Device/tplink_tl-wr850n-v2
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR850N
+  DEVICE_VARIANT := v2
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x08500002
+  TPLINK_HWREVADD := 0x2
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-wr850n-v2
+
+define Device/tplink_tl-wr902ac-v3
+  $(Device/tplink-v2)
+  IMAGE_SIZE := 7808k
+  DEVICE_MODEL := TL-WR902AC
+  DEVICE_VARIANT := v3
+  TPLINK_FLASHLAYOUT := 8Mmtk
+  TPLINK_HWID := 0x000dc88f
+  TPLINK_HWREV := 0x89
+  TPLINK_HWREVADD := 0x1
+  DEVICE_PACKAGES := kmod-mt76x0e kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+  IMAGES := sysupgrade.bin tftp-recovery.bin
+  IMAGE/tftp-recovery.bin := pad-extra 128k | $$(IMAGE/factory.bin)
+endef
+TARGET_DEVICES += tplink_tl-wr902ac-v3
+
+define Device/unielec_u7628-01-16m
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := UniElec
+  DEVICE_MODEL := U7628-01
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += u7628-01-128M-16M unielec,u7628-01-128m-16m
+endef
+TARGET_DEVICES += unielec_u7628-01-16m
+
+define Device/vocore_vocore2
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := VoCore
+  DEVICE_MODEL := VoCore2
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
+	kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += vocore2
+endef
+TARGET_DEVICES += vocore_vocore2
+
+define Device/vocore_vocore2-lite
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := VoCore
+  DEVICE_MODEL := VoCore2-Lite
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport \
+	kmod-sdhci-mt7620
+  SUPPORTED_DEVICES += vocore2lite
+endef
+TARGET_DEVICES += vocore_vocore2-lite
+
+define Device/wavlink_wl-wn570ha1
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN570HA1
+  DEVICE_PACKAGES := kmod-mt76x0e
+endef
+TARGET_DEVICES += wavlink_wl-wn570ha1
+
+define Device/wavlink_wl-wn575a3
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN575A3
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += wl-wn575a3
+endef
+TARGET_DEVICES += wavlink_wl-wn575a3
+
+define Device/wavlink_wl-wn577a2
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Wavlink
+  DEVICE_MODEL := WL-WN577A2
+  DEVICE_ALT0_VENDOR := Maginon
+  DEVICE_ALT0_MODEL := WLR-755
+  DEVICE_PACKAGES := kmod-mt76x0e
+endef
+TARGET_DEVICES += wavlink_wl-wn577a2
+
+define Device/widora_neo-16m
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Widora
+  DEVICE_MODEL := Widora-NEO
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += widora-neo
+endef
+TARGET_DEVICES += widora_neo-16m
+
+define Device/widora_neo-32m
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Widora
+  DEVICE_MODEL := Widora-NEO
+  DEVICE_VARIANT := 32M
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+endef
+TARGET_DEVICES += widora_neo-32m
+
+define Device/wiznet_wizfi630s
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := WIZnet
+  DEVICE_MODEL := WizFi630S
+  SUPPORTED_DEVICES += wizfi630s
+endef
+TARGET_DEVICES += wiznet_wizfi630s
+
+define Device/wrtnode_wrtnode2p
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := WRTnode
+  DEVICE_MODEL := WRTnode 2P
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += wrtnode2p
+endef
+TARGET_DEVICES += wrtnode_wrtnode2p
+
+define Device/wrtnode_wrtnode2r
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := WRTnode
+  DEVICE_MODEL := WRTnode 2R
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
+  SUPPORTED_DEVICES += wrtnode2r
+endef
+TARGET_DEVICES += wrtnode_wrtnode2r
+
+define Device/xiaomi_mi-router-4a-100m
+  IMAGE_SIZE := 14976k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := Mi Router 4A
+  DEVICE_VARIANT := 100M Edition
+  DEVICE_PACKAGES := kmod-mt76x2
+  SUPPORTED_DEVICES += xiaomi,mir4a-100m
+endef
+TARGET_DEVICES += xiaomi_mi-router-4a-100m
+
+define Device/xiaomi_mi-router-4c
+  IMAGE_SIZE := 14976k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := Mi Router 4C
+  DEVICE_PACKAGES := uboot-envtools
+endef
+TARGET_DEVICES += xiaomi_mi-router-4c
+
+define Device/xiaomi_miwifi-nano
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Xiaomi
+  DEVICE_MODEL := MiWiFi Nano
+  DEVICE_PACKAGES := uboot-envtools
+  SUPPORTED_DEVICES += miwifi-nano
+endef
+TARGET_DEVICES += xiaomi_miwifi-nano
+
+define Device/zbtlink_zbt-we1226
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Zbtlink
+  DEVICE_MODEL := ZBT-WE1226
+endef
+TARGET_DEVICES += zbtlink_zbt-we1226
+
+define Device/zyxel_keenetic-extra-ii
+  IMAGE_SIZE := 14912k
+  BLOCKSIZE := 64k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Extra II
+  DEVICE_PACKAGES := kmod-mt76x2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to $$$$(BLOCKSIZE) | \
+	check-size | zyimage -d 6162 -v "ZyXEL Keenetic Extra II"
+endef
+TARGET_DEVICES += zyxel_keenetic-extra-ii
diff --git a/target/linux/ramips/image/rt288x.mk b/target/linux/ramips/image/rt288x.mk
new file mode 100644
index 0000000..eff5a22
--- /dev/null
+++ b/target/linux/ramips/image/rt288x.mk
@@ -0,0 +1,108 @@
+#
+# RT288X Profiles
+#
+
+DEFAULT_SOC := rt2880
+
+define Build/gemtek-header
+	if [ -f $@ ]; then \
+		mkheader_gemtek $@ $@.new $(1) && \
+		mv $@.new $@; \
+	fi
+endef
+
+define Device/airlink101_ar670w
+  BLOCKSIZE := 64k
+  DEVICE_VENDOR := Airlink
+  DEVICE_MODEL := AR670W
+  IMAGE_SIZE := 3840k
+  KERNEL := $(KERNEL_DTB) | pad-to $$(BLOCKSIZE)
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	wrg-header wrgn16a_airlink_ar670w
+  SUPPORTED_DEVICES += ar670w
+  DEFAULT := n
+endef
+TARGET_DEVICES += airlink101_ar670w
+
+define Device/airlink101_ar725w
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Airlink
+  DEVICE_MODEL := AR725W
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size 3328k | \
+	gemtek-header ar725w
+  SUPPORTED_DEVICES += ar725w
+  DEFAULT := n
+endef
+TARGET_DEVICES += airlink101_ar725w
+
+define Device/asus_rt-n15
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N15
+  DEVICE_PACKAGES := kmod-switch-rtl8366s
+  SUPPORTED_DEVICES += rt-n15
+  DEFAULT := n
+endef
+TARGET_DEVICES += asus_rt-n15
+
+define Device/belkin_f5d8235-v1
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Belkin
+  DEVICE_MODEL := F5D8235
+  DEVICE_VARIANT := V1
+  DEVICE_PACKAGES := kmod-switch-rtl8366s kmod-usb-ohci kmod-usb-ohci-pci \
+	kmod-usb2 kmod-usb2-pci kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += f5d8235-v1
+endef
+TARGET_DEVICES += belkin_f5d8235-v1
+
+define Device/buffalo_wli-tx4-ag300n
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WLI-TX4-AG300N
+  DEVICE_PACKAGES := kmod-switch-ip17xx
+  SUPPORTED_DEVICES += wli-tx4-ag300n
+  DEFAULT := n
+endef
+TARGET_DEVICES += buffalo_wli-tx4-ag300n
+
+define Device/buffalo_wzr-agl300nh
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WZR-AGL300NH
+  DEVICE_PACKAGES := kmod-switch-rtl8366s
+  SUPPORTED_DEVICES += wzr-agl300nh
+  DEFAULT := n
+endef
+TARGET_DEVICES += buffalo_wzr-agl300nh
+
+define Device/dlink_dap-1522-a1
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3712k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DAP-1522
+  DEVICE_VARIANT := A1
+  DEVICE_PACKAGES := kmod-switch-rtl8366s
+  KERNEL := $(KERNEL_DTB)
+  IMAGES += factory.bin
+  IMAGE/factory.bin := append-kernel | pad-offset $$$$(BLOCKSIZE) 96 | \
+	append-rootfs | pad-rootfs -x 96 | wrg-header wapnd01_dlink_dap1522 | \
+	check-size
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dap-1522-a1
+
+define Device/ralink_v11st-fe
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Ralink
+  DEVICE_MODEL := V11ST-FE
+  SUPPORTED_DEVICES += v11st-fe
+  DEFAULT := n
+endef
+TARGET_DEVICES += ralink_v11st-fe
diff --git a/target/linux/ramips/image/rt305x.mk b/target/linux/ramips/image/rt305x.mk
new file mode 100644
index 0000000..9b498fa
--- /dev/null
+++ b/target/linux/ramips/image/rt305x.mk
@@ -0,0 +1,1248 @@
+#
+# RT305X Profiles
+#
+define Build/buffalo-tftp-header
+	( \
+		echo -n -e "# Airstation FirmWare\nrun u_fw\nreset\n\n" | \
+			dd bs=512 count=1 conv=sync; \
+		dd if=$@; \
+	) > $@.tmp && \
+	$(STAGING_DIR_HOST)/bin/buffalo-tftp -i $@.tmp -o $@.new
+	mv $@.new $@
+endef
+
+define Build/dap-header
+	$(STAGING_DIR_HOST)/bin/mkdapimg $(1) -i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/hilink-header
+	$(STAGING_DIR_HOST)/bin/mkhilinkfw -e -i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Device/7links_px-4885-4m
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := 7Links
+  DEVICE_MODEL := PX-4885
+  DEVICE_VARIANT := 4M
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport kmod-leds-gpio
+  SUPPORTED_DEVICES += px-4885-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += 7links_px-4885-4m
+
+define Device/7links_px-4885-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := 7Links
+  DEVICE_MODEL := PX-4885
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb2 kmod-usb-ohci \
+	kmod-usb-ledtrig-usbport kmod-leds-gpio
+  SUPPORTED_DEVICES += px-4885-8M
+endef
+TARGET_DEVICES += 7links_px-4885-8m
+
+define Device/8devices_carambola
+  SOC := rt3050
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := 8devices
+  DEVICE_MODEL := Carambola
+  DEVICE_PACKAGES :=
+  SUPPORTED_DEVICES += carambola
+endef
+TARGET_DEVICES += 8devices_carambola
+
+define Device/accton_wr6202
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Accton
+  DEVICE_MODEL := WR6202
+  SUPPORTED_DEVICES += wr6202
+endef
+TARGET_DEVICES += accton_wr6202
+
+define Device/airlive_air3gii
+  SOC := rt5350
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := AirLive
+  DEVICE_MODEL := Air3GII
+  SUPPORTED_DEVICES += air3gii
+  DEFAULT := n
+endef
+TARGET_DEVICES += airlive_air3gii
+
+define Device/alfa-network_w502u
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ALFA
+  DEVICE_MODEL := Networks W502U
+  SUPPORTED_DEVICES += w502u
+endef
+TARGET_DEVICES += alfa-network_w502u
+
+define Device/allnet_all0256n-4m
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Allnet
+  DEVICE_MODEL := ALL0256N
+  DEVICE_VARIANT := 4M
+  DEVICE_PACKAGES := rssileds
+  SUPPORTED_DEVICES += all0256n-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += allnet_all0256n-4m
+
+define Device/allnet_all0256n-8m
+  SOC := rt3050
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Allnet
+  DEVICE_MODEL := ALL0256N
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := rssileds
+  SUPPORTED_DEVICES += all0256n-8M
+endef
+TARGET_DEVICES += allnet_all0256n-8m
+
+define Device/allnet_all5002
+  SOC := rt3352
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Allnet
+  DEVICE_MODEL := ALL5002
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport \
+	kmod-i2c-gpio kmod-hwmon-lm92 kmod-gpio-pcf857x
+  SUPPORTED_DEVICES += all5002
+endef
+TARGET_DEVICES += allnet_all5002
+
+define Device/allnet_all5003
+  SOC := rt5350
+  IMAGE_SIZE := 32448k
+  DEVICE_VENDOR := Allnet
+  DEVICE_MODEL := ALL5003
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport \
+	kmod-i2c-gpio kmod-hwmon-lm92 kmod-gpio-pcf857x
+  SUPPORTED_DEVICES += all5003
+endef
+TARGET_DEVICES += allnet_all5003
+
+define Device/alphanetworks_asl26555-16m
+  SOC := rt3050
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := Alpha
+  DEVICE_MODEL := ASL26555
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += asl26555 asl26555-16M
+endef
+TARGET_DEVICES += alphanetworks_asl26555-16m
+
+define Device/alphanetworks_asl26555-8m
+  SOC := rt3050
+  IMAGE_SIZE := 7744k
+  DEVICE_VENDOR := Alpha
+  DEVICE_MODEL := ASL26555
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += asl26555 asl26555-8M
+endef
+TARGET_DEVICES += alphanetworks_asl26555-8m
+
+define Device/arcwireless_freestation5
+  SOC := rt3050
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ARC Wireless
+  DEVICE_MODEL := FreeStation
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-rt2500-usb kmod-rt2800-usb \
+	kmod-rt2x00-usb
+  SUPPORTED_DEVICES += freestation5
+endef
+TARGET_DEVICES += arcwireless_freestation5
+
+define Device/argus_atp-52b
+  SOC := rt3052
+  IMAGE_SIZE := 7808k
+  DEVICE_VENDOR := Argus
+  DEVICE_MODEL := ATP-52B
+  SUPPORTED_DEVICES += atp-52b
+endef
+TARGET_DEVICES += argus_atp-52b
+
+define Device/asiarf_awapn2403
+  SOC := rt3052
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := AsiaRF
+  DEVICE_MODEL := AWAPN2403
+  SUPPORTED_DEVICES += awapn2403
+  DEFAULT := n
+endef
+TARGET_DEVICES += asiarf_awapn2403
+
+define Device/asiarf_awm002-evb-4m
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := AsiaRF
+  DEVICE_MODEL := AWM002-EVB
+  DEVICE_VARIANT := 4M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-gpio
+  SUPPORTED_DEVICES += awm002-evb-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += asiarf_awm002-evb-4m
+
+define Device/asiarf_awm002-evb-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := AsiaRF
+  DEVICE_MODEL := AWM002-EVB/AWM003-EVB
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-gpio
+  SUPPORTED_DEVICES += awm002-evb-8M
+endef
+TARGET_DEVICES += asiarf_awm002-evb-8m
+
+define Device/asus_rt-g32-b1
+  SOC := rt3050
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-G32
+  DEVICE_VARIANT := B1
+  SUPPORTED_DEVICES += rt-g32-b1
+  DEFAULT := n
+endef
+TARGET_DEVICES += asus_rt-g32-b1
+
+define Device/asus_rt-n10-plus
+  SOC := rt3050
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N10+
+  SUPPORTED_DEVICES += rt-n10-plus
+  DEFAULT := n
+endef
+TARGET_DEVICES += asus_rt-n10-plus
+
+define Device/asus_rt-n13u
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N13U
+  DEVICE_PACKAGES := kmod-leds-gpio kmod-rt2800-pci kmod-usb-dwc2
+  SUPPORTED_DEVICES += rt-n13u
+endef
+TARGET_DEVICES += asus_rt-n13u
+
+define Device/asus_wl-330n
+  SOC := rt3050
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := WL-330N
+  SUPPORTED_DEVICES += wl-330n
+  DEFAULT := n
+endef
+TARGET_DEVICES += asus_wl-330n
+
+define Device/asus_wl-330n3g
+  SOC := rt3050
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := WL-330N3G
+  DEVICE_PACKAGES :=
+  SUPPORTED_DEVICES += wl-330n3g
+  DEFAULT := n
+endef
+TARGET_DEVICES += asus_wl-330n3g
+
+define Device/aximcom_mr-102n
+  SOC := rt3052
+  IMAGE_SIZE := 7744k
+  DEVICE_VENDOR := AXIMCom
+  DEVICE_MODEL := MR-102N
+  SUPPORTED_DEVICES += mr-102n
+endef
+TARGET_DEVICES += aximcom_mr-102n
+
+define Device/aztech_hw550-3g
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Aztech
+  DEVICE_MODEL := HW550-3G
+  DEVICE_ALT0_VENDOR := Allnet
+  DEVICE_ALT0_MODEL := ALL0239-3G
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += hw550-3g
+endef
+TARGET_DEVICES += aztech_hw550-3g
+
+define Device/belkin_f5d8235-v2
+  SOC := rt3052
+  IMAGE_SIZE := 7744k
+  DEVICE_VENDOR := Belkin
+  DEVICE_MODEL := F5D8235
+  DEVICE_VARIANT := v2
+  DEVICE_PACKAGES := kmod-switch-rtl8366rb
+  SUPPORTED_DEVICES += f5d8235-v2
+endef
+TARGET_DEVICES += belkin_f5d8235-v2
+
+define Device/belkin_f7c027
+  SOC := rt5350
+  IMAGE_SIZE := 7616k
+  DEVICE_VENDOR := Belkin
+  DEVICE_MODEL := F7C027
+  SUPPORTED_DEVICES += f7c027
+endef
+TARGET_DEVICES += belkin_f7c027
+
+define Device/buffalo_whr-g300n
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3712k
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := WHR-G300N
+  IMAGES += tftp.bin
+  IMAGE/tftp.bin := $$(sysupgrade_bin) | check-size | buffalo-tftp-header
+  SUPPORTED_DEVICES += whr-g300n
+  DEFAULT := n
+endef
+TARGET_DEVICES += buffalo_whr-g300n
+
+define Device/dlink_dap-1350
+  SOC := rt3052
+  IMAGES += factory.bin factory-NA.bin
+  IMAGE_SIZE := 7488k
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	dap-header -s RT3052-AP-DAP1350WW-3
+  IMAGE/factory-NA.bin := $$(sysupgrade_bin) | check-size | \
+	dap-header -s RT3052-AP-DAP1350-3
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DAP-1350
+  SUPPORTED_DEVICES += dap-1350
+endef
+TARGET_DEVICES += dlink_dap-1350
+
+define Device/dlink_dcs-930
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DCS-930
+  DEVICE_PACKAGES := kmod-video-core kmod-video-uvc kmod-sound-core \
+	kmod-usb-audio kmod-usb-dwc2
+  SUPPORTED_DEVICES += dcs-930
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dcs-930
+
+define Device/dlink_dcs-930l-b1
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DCS-930L
+  DEVICE_VARIANT := B1
+  DEVICE_PACKAGES := kmod-video-core kmod-video-uvc kmod-sound-core \
+	kmod-usb-audio kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += dcs-930l-b1
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dcs-930l-b1
+
+define Device/dlink_dir-300-b1
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	wrg-header wrgn23_dlwbr_dir300b
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-300
+  DEVICE_VARIANT := B1
+  SUPPORTED_DEVICES += dir-300-b1
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dir-300-b1
+
+define Device/dlink_dir-300-b7
+  SOC := rt5350
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-300
+  DEVICE_VARIANT := B7
+  SUPPORTED_DEVICES += dir-300-b7
+endef
+TARGET_DEVICES += dlink_dir-300-b7
+
+define Device/dlink_dir-320-b1
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-320
+  DEVICE_VARIANT := B1
+  SUPPORTED_DEVICES += dir-320-b1
+endef
+TARGET_DEVICES += dlink_dir-320-b1
+
+define Device/dlink_dir-600-b1
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	wrg-header wrgn23_dlwbr_dir600b
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-600
+  DEVICE_VARIANT := B1/B2
+  SUPPORTED_DEVICES += dir-600-b1 dir-600-b2
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dir-600-b1
+
+define Device/dlink_dir-610-a1
+  $(Device/seama)
+  SOC := rt5350
+  BLOCKSIZE := 4k
+  SEAMA_SIGNATURE := wrgn59_dlob.hans_dir610
+  KERNEL := $(KERNEL_DTB)
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-610
+  DEVICE_VARIANT := A1
+  SUPPORTED_DEVICES += dir-610-a1
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dir-610-a1
+
+define Device/dlink_dir-615-d
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	wrg-header wrgn23_dlwbr_dir615d
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-615
+  DEVICE_VARIANT := D
+  SUPPORTED_DEVICES += dir-615-d
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dir-615-d
+
+define Device/dlink_dir-615-h1
+  SOC := rt3352
+  BLOCKSIZE := 4k
+  IMAGES += factory.bin
+  IMAGE_SIZE := 3776k
+  IMAGE/factory.bin := $$(sysupgrade_bin) | senao-header -r 0x218 -p 0x30 -t 3
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-615
+  DEVICE_VARIANT := H1
+  SUPPORTED_DEVICES += dir-615-h1
+  DEFAULT := n
+endef
+TARGET_DEVICES += dlink_dir-615-h1
+
+define Device/dlink_dir-620-a1
+  SOC := rt3050
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-620
+  DEVICE_VARIANT := A1
+  SUPPORTED_DEVICES += dir-620-a1
+endef
+TARGET_DEVICES += dlink_dir-620-a1
+
+define Device/dlink_dir-620-d1
+  SOC := rt3352
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-620
+  DEVICE_VARIANT := D1
+  SUPPORTED_DEVICES += dir-620-d1
+endef
+TARGET_DEVICES += dlink_dir-620-d1
+
+define Device/dlink_dwr-512-b
+  SOC := rt5350
+  IMAGE_SIZE := 8064k
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DWR-512
+  DEVICE_VARIANT := B
+  DEVICE_PACKAGES := jboot-tools kmod-usb2 kmod-spi-dev \
+	kmod-usb-serial-option kmod-usb-net-cdc-ether comgt-ncm
+  DLINK_ROM_ID := DLK6E2412001
+  DLINK_FAMILY_MEMBER := 0x6E24
+  DLINK_FIRMWARE_SIZE := 0x7E0000
+  KERNEL := $(KERNEL_DTB)
+  IMAGES += factory.bin
+  IMAGE/sysupgrade.bin := mkdlinkfw | pad-rootfs | append-metadata
+  IMAGE/factory.bin := mkdlinkfw | pad-rootfs | mkdlinkfw-factory
+  SUPPORTED_DEVICES += dwr-512-b
+endef
+TARGET_DEVICES += dlink_dwr-512-b
+
+define Device/easyacc_wizard-8800
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  UIMAGE_NAME:= Linux Kernel Image
+  DEVICE_VENDOR := EasyAcc
+  DEVICE_MODEL := WIZARD 8800
+  SUPPORTED_DEVICES += wizard8800
+endef
+TARGET_DEVICES += easyacc_wizard-8800
+
+define Device/edimax_3g-6200n
+  SOC := rt3050
+  IMAGE_SIZE := 3648k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m 3G62 -f 0x50000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := 3g-6200n
+  SUPPORTED_DEVICES += 3g-6200n
+  DEFAULT := n
+endef
+TARGET_DEVICES += edimax_3g-6200n
+
+define Device/edimax_3g-6200nl
+  SOC := rt3050
+  IMAGE_SIZE := 3648k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m 3G62 -f 0x50000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := 3g-6200nl
+  SUPPORTED_DEVICES += 3g-6200nl
+  DEFAULT := n
+endef
+TARGET_DEVICES += edimax_3g-6200nl
+
+define Device/engenius_esr-9753
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := EnGenius
+  DEVICE_MODEL := ESR-9753
+  SUPPORTED_DEVICES += esr-9753
+  DEFAULT := n
+endef
+TARGET_DEVICES += engenius_esr-9753
+
+define Device/fon_fonera-20n
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | \
+	edimax-header -s RSDK -m NL1T -f 0x50000 -S 0xc0000
+  DEVICE_VENDOR := Fon
+  DEVICE_MODEL := Fonera 2.0N
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += fonera20n
+endef
+TARGET_DEVICES += fon_fonera-20n
+
+define Device/hame_mpr-a1
+  SOC := rt5350
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  UIMAGE_NAME:= Linux Kernel Image
+  DEVICE_VENDOR := HAME
+  DEVICE_MODEL := MPR
+  DEVICE_VARIANT := A1
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += mpr-a1
+  DEFAULT := n
+endef
+TARGET_DEVICES += hame_mpr-a1
+
+define Device/hame_mpr-a2
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  UIMAGE_NAME:= Linux Kernel Image
+  DEVICE_VENDOR := HAME
+  DEVICE_MODEL := MPR
+  DEVICE_VARIANT := A2
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += mpr-a2
+endef
+TARGET_DEVICES += hame_mpr-a2
+
+define Device/hauppauge_broadway
+  SOC := rt3052
+  IMAGE_SIZE := 7744k
+  UIMAGE_NAME:= Broadway Kernel Image
+  DEVICE_VENDOR := Hauppauge
+  DEVICE_MODEL := Broadway
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += broadway
+endef
+TARGET_DEVICES += hauppauge_broadway
+
+define Device/hilink_hlk-rm04
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | hilink-header
+  DEVICE_VENDOR := Hi-Link
+  DEVICE_MODEL := HLK-RM04
+  SUPPORTED_DEVICES += hlk-rm04
+  DEFAULT := n
+endef
+TARGET_DEVICES += hilink_hlk-rm04
+
+define Device/hootoo_ht-tm02
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := HooToo
+  DEVICE_MODEL := HT-TM02
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += ht-tm02
+  DEFAULT := n
+endef
+TARGET_DEVICES += hootoo_ht-tm02
+
+define Device/huawei_d105
+  SOC := rt3050
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Huawei
+  DEVICE_MODEL := D105
+  SUPPORTED_DEVICES += d105
+  DEFAULT := n
+endef
+TARGET_DEVICES += huawei_d105
+
+define Device/huawei_hg255d
+  SOC := rt3052
+  IMAGE_SIZE := 15744k
+  DEVICE_VENDOR := HuaWei
+  DEVICE_MODEL := HG255D
+  SUPPORTED_DEVICES += hg255d
+endef
+TARGET_DEVICES += huawei_hg255d
+
+define Device/intenso_memory2move
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  UIMAGE_NAME:= Linux Kernel Image
+  DEVICE_VENDOR := Intenso
+  DEVICE_MODEL := Memory 2 Move
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-scsi-core kmod-fs-ext4 \
+	kmod-fs-vfat block-mount
+  SUPPORTED_DEVICES += m2m
+endef
+TARGET_DEVICES += intenso_memory2move
+
+define Device/jcg_jhr-n805r
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 29.24
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := JHR-N805R
+  SUPPORTED_DEVICES += jhr-n805r
+  DEFAULT := n
+endef
+TARGET_DEVICES += jcg_jhr-n805r
+
+define Device/jcg_jhr-n825r
+  SOC := rt3052
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 23.24
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := JHR-N825R
+  SUPPORTED_DEVICES += jhr-n825r
+  DEFAULT := n
+endef
+TARGET_DEVICES += jcg_jhr-n825r
+
+define Device/jcg_jhr-n926r
+  SOC := rt3052
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | jcg-header 25.24
+  DEVICE_VENDOR := JCG
+  DEVICE_MODEL := JHR-N926R
+  SUPPORTED_DEVICES += jhr-n926r
+  DEFAULT := n
+endef
+TARGET_DEVICES += jcg_jhr-n926r
+
+define Device/mofinetwork_mofi3500-3gn
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := MoFi Network
+  DEVICE_MODEL := MOFI3500-3GN
+  SUPPORTED_DEVICES += mofi3500-3gn
+endef
+TARGET_DEVICES += mofinetwork_mofi3500-3gn
+
+define Device/netcore_nw718
+  SOC := rt3050
+  IMAGE_SIZE := 3712k
+  UIMAGE_NAME:= ARA1B4NCRNW718;1
+  DEVICE_VENDOR := Netcore
+  DEVICE_MODEL := NW718
+  SUPPORTED_DEVICES += nw718
+  DEFAULT := n
+endef
+TARGET_DEVICES += netcore_nw718
+
+define Device/netgear_wnce2001
+  SOC := rt3052
+  IMAGE_SIZE := 3392k
+  IMAGES += factory.bin factory-NA.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	dap-header -s RT3052-AP-WNCE2001-3 -r WW -v 1.0.0.99
+  IMAGE/factory-NA.bin := $$(sysupgrade_bin) | check-size | \
+	dap-header -s RT3052-AP-WNCE2001-3 -r NA -v 1.0.0.99
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := WNCE2001
+  SUPPORTED_DEVICES += wnce2001
+  DEFAULT := n
+endef
+TARGET_DEVICES += netgear_wnce2001
+
+define Device/nexaira_bc2
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := NexAira
+  DEVICE_MODEL := BC2
+  SUPPORTED_DEVICES += bc2
+endef
+TARGET_DEVICES += nexaira_bc2
+
+define Device/nexx_wt1520-4m
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B WT1520 -F 4M
+  DEVICE_VENDOR := Nexx
+  DEVICE_MODEL := WT1520
+  DEVICE_VARIANT := 4M
+  SUPPORTED_DEVICES += wt1520-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += nexx_wt1520-4m
+
+define Device/nexx_wt1520-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B WT1520 -F 8M
+  DEVICE_VENDOR := Nexx
+  DEVICE_MODEL := WT1520
+  DEVICE_VARIANT := 8M
+  SUPPORTED_DEVICES += wt1520-8M
+endef
+TARGET_DEVICES += nexx_wt1520-8m
+
+define Device/nixcore_x1-16m
+  SOC := rt5350
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Nixcore
+  DEVICE_MODEL := X1
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += nixcore-x1 nixcore-x1-16M
+endef
+TARGET_DEVICES += nixcore_x1-16m
+
+define Device/nixcore_x1-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Nixcore
+  DEVICE_MODEL := X1
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += nixcore-x1 nixcore-x1-8M
+endef
+TARGET_DEVICES += nixcore_x1-8m
+
+define Device/olimex_rt5350f-olinuxino
+  $(Device/uimage-lzma-loader)
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := OLIMEX
+  DEVICE_MODEL := RT5350F-OLinuXino
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += rt5350f-olinuxino
+endef
+TARGET_DEVICES += olimex_rt5350f-olinuxino
+
+define Device/olimex_rt5350f-olinuxino-evb
+  $(Device/uimage-lzma-loader)
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := OLIMEX
+  DEVICE_MODEL := RT5350F-OLinuXino-EVB
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += rt5350f-olinuxino-evb
+endef
+TARGET_DEVICES += olimex_rt5350f-olinuxino-evb
+
+define Device/omnima_miniembplug
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Omnima
+  DEVICE_MODEL := MiniEMBPlug
+  SUPPORTED_DEVICES += miniembplug
+endef
+TARGET_DEVICES += omnima_miniembplug
+
+define Device/omnima_miniembwifi
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Omnima
+  DEVICE_MODEL := MiniEMBWiFi
+  SUPPORTED_DEVICES += miniembwifi
+endef
+TARGET_DEVICES += omnima_miniembwifi
+
+define Device/petatel_psr-680w
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Petatel
+  DEVICE_MODEL := PSR-680W Wireless 3G Router
+  SUPPORTED_DEVICES += psr-680w
+  DEFAULT := n
+endef
+TARGET_DEVICES += petatel_psr-680w
+
+define Device/planex_mzk-dp150n
+  SOC := rt5350
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-DP150N
+  DEVICE_PACKAGES := kmod-spi-dev
+  SUPPORTED_DEVICES += mzk-dp150n
+  DEFAULT := n
+endef
+TARGET_DEVICES += planex_mzk-dp150n
+
+define Device/planex_mzk-w300nh2
+  SOC := rt3052
+  IMAGE_SIZE := 3648k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | \
+	edimax-header -s CSYS -m RN52 -f 0x50000 -S 0xc0000
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-W300NH2
+  SUPPORTED_DEVICES += mzk-w300nh2
+  DEFAULT := n
+endef
+TARGET_DEVICES += planex_mzk-w300nh2
+
+define Device/planex_mzk-wdpr
+  SOC := rt3052
+  IMAGE_SIZE := 6656k
+  DEVICE_VENDOR := Planex
+  DEVICE_MODEL := MZK-WDPR
+  SUPPORTED_DEVICES += mzk-wdpr
+endef
+TARGET_DEVICES += planex_mzk-wdpr
+
+define Device/poray_ip2202
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := IP2202
+  SUPPORTED_DEVICES += ip2202
+endef
+TARGET_DEVICES += poray_ip2202
+
+define Device/poray_m3
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B M3 -F 4M
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := M3
+  DEVICE_PACKAGES := kmod-usb2
+  SUPPORTED_DEVICES += m3
+  DEFAULT := n
+endef
+TARGET_DEVICES += poray_m3
+
+define Device/poray_m4-4m
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B M4 -F 4M
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := M4
+  DEVICE_VARIANT := 4M
+  DEVICE_PACKAGES := kmod-usb2
+  SUPPORTED_DEVICES += m4-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += poray_m4-4m
+
+define Device/poray_m4-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B M4 -F 8M
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := M4
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb2
+  SUPPORTED_DEVICES += m4-8M
+endef
+TARGET_DEVICES += poray_m4-8m
+
+define Device/poray_x5
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B X5 -F 8M
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := X5/X6
+  DEVICE_PACKAGES := kmod-usb2
+  SUPPORTED_DEVICES += x5
+endef
+TARGET_DEVICES += poray_x5
+
+define Device/poray_x8
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B X8 -F 8M
+  DEVICE_VENDOR := Poray
+  DEVICE_MODEL := X8
+  DEVICE_PACKAGES := kmod-usb2
+  SUPPORTED_DEVICES += x8
+endef
+TARGET_DEVICES += poray_x8
+
+define Device/prolink_pwh2004
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Prolink
+  DEVICE_MODEL := PWH2004
+  DEVICE_PACKAGES :=
+  SUPPORTED_DEVICES += pwh2004
+endef
+TARGET_DEVICES += prolink_pwh2004
+
+define Device/ralink_v22rw-2x2
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Ralink
+  DEVICE_MODEL := AP-RT3052-V22RW-2X2
+  SUPPORTED_DEVICES += v22rw-2x2
+  DEFAULT := n
+endef
+TARGET_DEVICES += ralink_v22rw-2x2
+
+define Device/sitecom_wl-351
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Sitecom
+  DEVICE_MODEL := WL-351 v1
+  DEVICE_PACKAGES := kmod-switch-rtl8366rb
+  SUPPORTED_DEVICES += wl-351
+  DEFAULT := n
+endef
+TARGET_DEVICES += sitecom_wl-351
+
+define Device/skyline_sl-r7205
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Skyline
+  DEVICE_MODEL := SL-R7205 Wireless 3G Router
+  SUPPORTED_DEVICES += sl-r7205
+  DEFAULT := n
+endef
+TARGET_DEVICES += skyline_sl-r7205
+
+define Device/sparklan_wcr-150gn
+  SOC := rt3050
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Sparklan
+  DEVICE_MODEL := WCR-150GN
+  SUPPORTED_DEVICES += wcr-150gn
+  DEFAULT := n
+endef
+TARGET_DEVICES += sparklan_wcr-150gn
+
+define Device/teltonika_rut5xx
+  SOC := rt3050
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Teltonika
+  DEVICE_MODEL := RUT5XX
+  DEVICE_PACKAGES := om-watchdog
+  SUPPORTED_DEVICES += rut5xx
+endef
+TARGET_DEVICES += teltonika_rut5xx
+
+define Device/tenda_3g150b
+  SOC := rt5350
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 3776k
+  UIMAGE_NAME:= Linux Kernel Image
+  DEVICE_VENDOR := Tenda
+  DEVICE_MODEL := 3G150B
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += 3g150b
+  DEFAULT := n
+endef
+TARGET_DEVICES += tenda_3g150b
+
+define Device/tenda_3g300m
+  SOC := rt3052
+  IMAGE_SIZE := 3776k
+  UIMAGE_NAME := 3G150M_SPI Kernel Image
+  DEVICE_VENDOR := Tenda
+  DEVICE_MODEL := 3G300M
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += 3g300m
+  DEFAULT := n
+endef
+TARGET_DEVICES += tenda_3g300m
+
+define Device/tenda_w150m
+  SOC := rt3050
+  IMAGE_SIZE := 3776k
+  UIMAGE_NAME:= W150M Kernel Image
+  DEVICE_VENDOR := Tenda
+  DEVICE_MODEL := W150M
+  SUPPORTED_DEVICES += w150m
+  DEFAULT := n
+endef
+TARGET_DEVICES += tenda_w150m
+
+define Device/tenda_w306r-v2
+  SOC := rt3052
+  IMAGE_SIZE := 3776k
+  UIMAGE_NAME:= linkn Kernel Image
+  DEVICE_VENDOR := Tenda
+  DEVICE_MODEL := W306R
+  DEVICE_VARIANT := V2.0
+  SUPPORTED_DEVICES += w306r-v20
+  DEFAULT := n
+endef
+TARGET_DEVICES += tenda_w306r-v2
+
+define Device/trendnet_tew-638apb-v2
+  SOC := rt3050
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  IMAGE/sysupgrade.bin := $$(sysupgrade_bin) | umedia-header 0x026382 | \
+	append-metadata | check-size
+  DEVICE_VENDOR := TRENDnet
+  DEVICE_MODEL := TEW-638APB
+  DEVICE_VARIANT := v2
+  SUPPORTED_DEVICES += tew-638apb-v2
+  DEFAULT := n
+endef
+TARGET_DEVICES += trendnet_tew-638apb-v2
+
+define Device/trendnet_tew-714tru
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := TRENDnet
+  DEVICE_MODEL := TEW-714TRU
+  SUPPORTED_DEVICES += tew-714tru
+endef
+TARGET_DEVICES += trendnet_tew-714tru
+
+define Device/unbranded_a5-v11
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | \
+	poray-header -B A5-V11 -F 4M
+  DEVICE_VENDOR :=
+  DEVICE_MODEL := A5-V11
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += a5-v11
+  DEFAULT := n
+endef
+TARGET_DEVICES += unbranded_a5-v11
+
+define Device/unbranded_wr512-3gn-4m
+  SOC := rt3052
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := Ralink
+  DEVICE_MODEL := WR512-3GN
+  DEVICE_VARIANT := 4M
+  SUPPORTED_DEVICES += wr512-3gn-4M
+  DEFAULT := n
+endef
+TARGET_DEVICES += unbranded_wr512-3gn-4m
+
+define Device/unbranded_wr512-3gn-8m
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Ralink
+  DEVICE_MODEL := WR512-3GN
+  DEVICE_VARIANT := 8M
+  SUPPORTED_DEVICES += wr512-3gn-8M
+endef
+TARGET_DEVICES += unbranded_wr512-3gn-8m
+
+define Device/unbranded_xdx-rn502j
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := XDX
+  DEVICE_MODEL := RN502J
+  SUPPORTED_DEVICES += xdxrn502j
+  DEFAULT := n
+endef
+TARGET_DEVICES += unbranded_xdx-rn502j
+
+define Device/upvel_ur-326n4g
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := UPVEL
+  DEVICE_MODEL := UR-326N4G
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += ur-326n4g
+  DEFAULT := n
+endef
+TARGET_DEVICES += upvel_ur-326n4g
+
+define Device/upvel_ur-336un
+  SOC := rt3052
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := UPVEL
+  DEVICE_MODEL := UR-336UN
+  DEVICE_PACKAGES := kmod-usb-dwc2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += ur-336un
+endef
+TARGET_DEVICES += upvel_ur-336un
+
+define Device/vocore_vocore-16m
+  SOC := rt5350
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := VoCore
+  DEVICE_MODEL := VoCore
+  DEVICE_VARIANT := 16M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += vocore vocore-16M
+endef
+TARGET_DEVICES += vocore_vocore-16m
+
+define Device/vocore_vocore-8m
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := VoCore
+  DEVICE_MODEL := VoCore
+  DEVICE_VARIANT := 8M
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-i2c-ralink kmod-spi-dev
+  SUPPORTED_DEVICES += vocore vocore-8M
+endef
+TARGET_DEVICES += vocore_vocore-8m
+
+define Device/wansview_ncs601w
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Wansview
+  DEVICE_MODEL := NCS601W
+  DEVICE_PACKAGES := kmod-video-core kmod-video-uvc kmod-usb-ohci
+  SUPPORTED_DEVICES += ncs601w
+endef
+TARGET_DEVICES += wansview_ncs601w
+
+define Device/wiznet_wizfi630a
+  SOC := rt5350
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := WIZnet
+  DEVICE_MODEL := WizFi630A
+  SUPPORTED_DEVICES += wizfi630a
+endef
+TARGET_DEVICES += wiznet_wizfi630a
+
+define Device/zorlik_zl5900v2
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Zorlik
+  DEVICE_MODEL := ZL5900V2
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+endef
+TARGET_DEVICES += zorlik_zl5900v2
+
+define Device/zte_mf283plus
+  $(Device/uimage-lzma-loader)
+  SOC := rt3352
+  IMAGE_SIZE := 15872k
+  DEVICE_VENDOR := ZTE
+  DEVICE_MODEL := MF283+
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-net-qmi-wwan uqmi \
+	kmod-usb-serial kmod-usb-serial-option
+endef
+TARGET_DEVICES += zte_mf283plus
+
+define Device/zyxel_keenetic
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic
+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ehci kmod-usb-ledtrig-usbport \
+	kmod-usb-dwc2
+  SUPPORTED_DEVICES += kn
+endef
+TARGET_DEVICES += zyxel_keenetic
+
+define Device/zyxel_keenetic-lite-b
+  $(Device/uimage-lzma-loader)
+  SOC := rt5350
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Lite
+  DEVICE_VARIANT := B
+endef
+TARGET_DEVICES += zyxel_keenetic-lite-b
+
+define Device/zyxel_keenetic-start
+  SOC := rt5350
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := Keenetic Start
+  DEFAULT := n
+endef
+TARGET_DEVICES += zyxel_keenetic-start
+
+define Device/zyxel_nbg-419n
+  SOC := rt3052
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 3776k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := NBG-419N
+  SUPPORTED_DEVICES += nbg-419n
+  DEFAULT := n
+endef
+TARGET_DEVICES += zyxel_nbg-419n
+
+define Device/zyxel_nbg-419n-v2
+  $(Device/uimage-lzma-loader)
+  SOC := rt3352
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := ZyXEL
+  DEVICE_MODEL := NBG-419N
+  DEVICE_VARIANT := v2
+  SUPPORTED_DEVICES += nbg-419n2
+endef
+TARGET_DEVICES += zyxel_nbg-419n-v2
diff --git a/target/linux/ramips/image/rt3883.mk b/target/linux/ramips/image/rt3883.mk
new file mode 100644
index 0000000..4b169f5
--- /dev/null
+++ b/target/linux/ramips/image/rt3883.mk
@@ -0,0 +1,147 @@
+#
+# RT3662/RT3883 Profiles
+#
+define Build/mkrtn56uimg
+	$(STAGING_DIR_HOST)/bin/mkrtn56uimg $(1) $@
+endef
+
+define Device/asus_rt-n56u
+  SOC := rt3662
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  IMAGE/sysupgrade.bin += | mkrtn56uimg -s
+  DEVICE_VENDOR := Asus
+  DEVICE_MODEL := RT-N56U
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += rt-n56u
+endef
+TARGET_DEVICES += asus_rt-n56u
+
+define Device/belkin_f9k1109v1
+  $(Device/uimage-lzma-loader)
+  SOC := rt3883
+  BLOCKSIZE := 64k
+  DEVICE_VENDOR := Belkin
+  DEVICE_MODEL := F9K1109
+  DEVICE_VARIANT := Version 1.0
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport
+  IMAGE_SIZE := 7808k
+  # Stock firmware checks for this uImage image name during upload.
+  UIMAGE_NAME := N750F9K1103VB
+endef
+TARGET_DEVICES += belkin_f9k1109v1
+
+define Device/dlink_dir-645
+  $(Device/seama)
+  $(Device/uimage-lzma-loader)
+  SOC := rt3662
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7872k
+  KERNEL := kernel-bin | append-dtb | lzma -d10
+  SEAMA_SIGNATURE := wrgn39_dlob.hans_dir645
+  DEVICE_VENDOR := D-Link
+  DEVICE_MODEL := DIR-645
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += dir-645
+endef
+TARGET_DEVICES += dlink_dir-645
+
+define Device/edimax_br-6475nd
+  SOC := rt3662
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7744k
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+	edimax-header -s CSYS -m RN54 -f 0x70000 -S 0x01100000 | pad-rootfs | \
+	append-metadata | check-size
+  DEVICE_VENDOR := Edimax
+  DEVICE_MODEL := BR-6475nD
+  SUPPORTED_DEVICES += br-6475nd
+endef
+TARGET_DEVICES += edimax_br-6475nd
+
+define Device/engenius_esr600h
+  $(Device/uimage-lzma-loader)
+  SOC := rt3662
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.dlf
+  IMAGE/factory.dlf := $$(sysupgrade_bin) | check-size | \
+	senao-header -r 0x101 -p 0x44 -t 2
+  DEVICE_VENDOR := EnGenius
+  DEVICE_MODEL := ESR600H
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 uboot-envtools
+endef
+TARGET_DEVICES += engenius_esr600h
+
+define Device/loewe_wmdr-143n
+  SOC := rt3662
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  DEVICE_VENDOR := Loewe
+  DEVICE_MODEL := WMDR-143N
+  SUPPORTED_DEVICES += wmdr-143n
+endef
+TARGET_DEVICES += loewe_wmdr-143n
+
+define Device/omnima_hpm
+  SOC := rt3662
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 16064k
+  DEVICE_VENDOR := Omnima
+  DEVICE_MODEL := HPM
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += hpm
+endef
+TARGET_DEVICES += omnima_hpm
+
+define Device/samsung_cy-swr1100
+  $(Device/seama)
+  SOC := rt3662
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  KERNEL := $(KERNEL_DTB)
+  SEAMA_SIGNATURE := wrgnd10_samsung_ss815
+  DEVICE_VENDOR := Samsung
+  DEVICE_MODEL := CY-SWR1100
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport
+  SUPPORTED_DEVICES += cy-swr1100
+endef
+TARGET_DEVICES += samsung_cy-swr1100
+
+define Device/sitecom_wlr-6000
+  SOC := rt3883
+  BLOCKSIZE := 4k
+  IMAGE_SIZE := 7244k
+  IMAGES += factory.dlf
+  IMAGE/factory.dlf := $$(sysupgrade_bin) | check-size | \
+	senao-header -r 0x0202 -p 0x41 -t 2
+  DEVICE_VENDOR := Sitecom
+  DEVICE_MODEL := WLR-6000
+  DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2
+  SUPPORTED_DEVICES += wlr-6000
+endef
+TARGET_DEVICES += sitecom_wlr-6000
+
+define Device/trendnet_tew-691gr
+  SOC := rt3883
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | umedia-header 0x026910
+  DEVICE_VENDOR := TRENDnet
+  DEVICE_MODEL := TEW-691GR
+  SUPPORTED_DEVICES += tew-691gr
+endef
+TARGET_DEVICES += trendnet_tew-691gr
+
+define Device/trendnet_tew-692gr
+  SOC := rt3883
+  BLOCKSIZE := 64k
+  IMAGE_SIZE := 7872k
+  IMAGES += factory.bin
+  IMAGE/factory.bin := $$(sysupgrade_bin) | check-size | umedia-header 0x026920
+  DEVICE_VENDOR := TRENDnet
+  DEVICE_MODEL := TEW-692GR
+  SUPPORTED_DEVICES += tew-692gr
+endef
+TARGET_DEVICES += trendnet_tew-692gr
diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk
new file mode 100644
index 0000000..6f199c4
--- /dev/null
+++ b/target/linux/ramips/modules.mk
@@ -0,0 +1,135 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2006-2016 OpenWrt.org
+
+OTHER_MENU:=Other modules
+
+define KernelPackage/pwm-mediatek-ramips
+  SUBMENU:=Other modules
+  TITLE:=MT7628 PWM
+  DEPENDS:=@(TARGET_ramips_mt76x8)
+  KCONFIG:= \
+	CONFIG_PWM=y \
+	CONFIG_PWM_MEDIATEK_RAMIPS \
+	CONFIG_PWM_SYSFS=y
+  FILES:= \
+	$(LINUX_DIR)/drivers/pwm/pwm-mediatek-ramips.ko
+  AUTOLOAD:=$(call AutoProbe,pwm-mediatek-ramips)
+endef
+
+define KernelPackage/pwm-mediatek-ramips/description
+  Kernel modules for MediaTek Pulse Width Modulator
+endef
+
+$(eval $(call KernelPackage,pwm-mediatek-ramips))
+
+define KernelPackage/sdhci-mt7620
+  SUBMENU:=Other modules
+  TITLE:=MT7620 SDCI
+  DEPENDS:=@(TARGET_ramips_mt7620||TARGET_ramips_mt76x8||TARGET_ramips_mt7621) +kmod-mmc
+  KCONFIG:= \
+	CONFIG_MTK_MMC \
+	CONFIG_MTK_AEE_KDUMP=n \
+	CONFIG_MTK_MMC_CD_POLL=n
+  FILES:= \
+	$(LINUX_DIR)/drivers/mmc/host/mtk-mmc/mtk_sd.ko
+  AUTOLOAD:=$(call AutoProbe,mtk_sd,1)
+endef
+
+$(eval $(call KernelPackage,sdhci-mt7620))
+
+I2C_RALINK_MODULES:= \
+  CONFIG_I2C_RALINK:drivers/i2c/busses/i2c-ralink
+
+define KernelPackage/i2c-ralink
+  $(call i2c_defaults,$(I2C_RALINK_MODULES),59)
+  TITLE:=Ralink I2C Controller
+  DEPENDS:=+kmod-i2c-core @TARGET_ramips \
+	@!(TARGET_ramips_mt7621||TARGET_ramips_mt76x8)
+endef
+
+define KernelPackage/i2c-ralink/description
+ Kernel modules for enable ralink i2c controller.
+endef
+
+$(eval $(call KernelPackage,i2c-ralink))
+
+
+I2C_MT7621_MODULES:= \
+  CONFIG_I2C_MT7621:drivers/i2c/busses/i2c-mt7621
+
+define KernelPackage/i2c-mt7628
+  $(call i2c_defaults,$(I2C_MT7621_MODULES),59)
+  TITLE:=MT7628/88 I2C Controller
+  DEPENDS:=+kmod-i2c-core \
+	@(TARGET_ramips_mt76x8)
+endef
+
+define KernelPackage/i2c-mt7628/description
+ Kernel modules for enable mt7621 i2c controller.
+endef
+
+$(eval $(call KernelPackage,i2c-mt7628))
+
+define KernelPackage/dma-ralink
+  SUBMENU:=Other modules
+  TITLE:=Ralink GDMA Engine
+  DEPENDS:=@TARGET_ramips
+  KCONFIG:= \
+	CONFIG_DMADEVICES=y \
+	CONFIG_DW_DMAC_PCI=n \
+	CONFIG_DMA_RALINK
+  FILES:= \
+	$(LINUX_DIR)/drivers/dma/virt-dma.ko \
+	$(LINUX_DIR)/drivers/staging/ralink-gdma/ralink-gdma.ko
+  AUTOLOAD:=$(call AutoLoad,52,ralink-gdma)
+endef
+
+define KernelPackage/dma-ralink/description
+ Kernel modules for enable ralink dma engine.
+endef
+
+$(eval $(call KernelPackage,dma-ralink))
+
+define KernelPackage/hsdma-mtk
+  SUBMENU:=Other modules
+  TITLE:=MediaTek HSDMA Engine
+  DEPENDS:=@TARGET_ramips @TARGET_ramips_mt7621
+  KCONFIG:= \
+	CONFIG_DMADEVICES=y \
+	CONFIG_DW_DMAC_PCI=n \
+	CONFIG_MTK_HSDMA
+  FILES:= \
+	$(LINUX_DIR)/drivers/dma/virt-dma.ko \
+	$(LINUX_DIR)/drivers/staging/mt7621-dma/hsdma-mt7621.ko
+  AUTOLOAD:=$(call AutoLoad,53,hsdma-mt7621)
+endef
+
+define KernelPackage/hsdma-mtk/description
+ Kernel modules for enable MediaTek hsdma engine.
+endef
+
+$(eval $(call KernelPackage,hsdma-mtk))
+
+define KernelPackage/sound-mt7620
+  TITLE:=MT7620 PCM/I2S Alsa Driver
+  DEPENDS:=@TARGET_ramips +kmod-sound-soc-core +kmod-regmap-i2c +kmod-dma-ralink @!TARGET_ramips_rt288x
+  KCONFIG:= \
+	CONFIG_SND_RALINK_SOC_I2S \
+	CONFIG_SND_SIMPLE_CARD \
+	CONFIG_SND_SIMPLE_CARD_UTILS \
+	CONFIG_SND_SOC_WM8960
+  FILES:= \
+	$(LINUX_DIR)/sound/soc/ralink/snd-soc-ralink-i2s.ko \
+	$(LINUX_DIR)/sound/soc/generic/snd-soc-simple-card.ko \
+	$(LINUX_DIR)/sound/soc/generic/snd-soc-simple-card-utils.ko \
+	$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8960.ko
+  AUTOLOAD:=$(call AutoLoad,90,snd-soc-wm8960 snd-soc-ralink-i2s snd-soc-simple-card)
+  $(call AddDepends/sound)
+endef
+
+define KernelPackage/sound-mt7620/description
+ Alsa modules for ralink i2s controller.
+endef
+
+$(eval $(call KernelPackage,sound-mt7620))
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..4fe7d2d
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/01_leds
@@ -0,0 +1,226 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+aigale,ai-br100)
+	ucidef_set_led_netdev "wan" "wan" "blue:wan" "eth0.2"
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wlan" "wlan0"
+	;;
+alfa-network,ac1200rm)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan2g" "wlan1"
+	;;
+alfa-network,r36m-e4g)
+	ucidef_set_led_netdev "4g" "4g" "orange:4g" "wwan0"
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x8"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+alfa-network,tube-e4g)
+	ucidef_set_led_netdev "4g" "4g" "green:4g" "wwan0"
+	ucidef_set_led_netdev "lan" "lan" "blue:lan" "eth0"
+	;;
+asus,rp-n53)
+	ucidef_set_led_netdev "eth" "Network" "white:back" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wifi" "wlan0"
+	;;
+asus,rt-n12p)
+	ucidef_set_led_netdev "lan" "lan" "green:lan" eth0.1
+	ucidef_set_led_netdev "wan" "wan" "green:wan" eth0.2
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:air" "wlan0"
+	;;
+asus,rt-n14u)
+	ucidef_set_led_netdev "lan" "lan" "blue:lan" eth0.1
+	ucidef_set_led_netdev "wan" "wan" "blue:wan" eth0.2
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:air" "wlan0"
+	;;
+bdcom,wap2100-sk)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan2g" "wlan0"
+	;;
+comfast,cf-wr800n)
+	ucidef_set_led_netdev "lan" "lan" "white:ethernet" eth0.1
+	ucidef_set_led_netdev "wifi_led" "wifi" "white:wifi" "wlan0"
+	;;
+dlink,dir-810l|\
+trendnet,tew-810dr)
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+dlink,dwr-116-a1|\
+head-weblink,hdrm200|\
+ohyeah,oy-0001|\
+planex,mzk-ex300np|\
+zbtlink,zbt-we826-16m|\
+zbtlink,zbt-we826-32m|\
+zbtlink,zbt-wr8305rt|\
+zyxel,keenetic-omni|\
+zyxel,keenetic-omni-ii|\
+zyxel,keenetic-viva)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+dlink,dwr-118-a1)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1f"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x20"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan2g" "wlan1"
+	;;
+dlink,dwr-118-a2)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan2g" "wlan1"
+	;;
+dlink,dwr-921-c1|\
+dlink,dwr-922-e2)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x0f"
+	ucidef_set_led_netdev "signalstrength" "signalstrength" "green:sigstrength" "wwan0" "link"
+	ucidef_set_led_netdev "4g" "4g" "green:4g" "wwan0" "tx rx"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+dlink,dwr-960)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x2e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	;;
+dovado,tiny-ac)
+	ucidef_set_led_netdev "wifi_led" "wifi" "orange:wifi" "wlan0"
+	;;
+edimax,br-6478ac-v2|\
+edimax,ew-7478apc)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wlan" "wlan0"
+	;;
+edimax,ew-7476rpc|\
+edimax,ew-7478ac)
+	ucidef_set_led_switch "lan" "lan" "green:lan"  "switch0" "0x20"
+	;;
+elecom,wrh-300cr)
+	ucidef_set_led_netdev "lan" "lan" "green:ethernet" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+engenius,esr600)
+	ucidef_set_led_netdev "wlan5g" "5.0GHz" "blue:wlan5g" "wlan0"
+	ucidef_set_led_netdev "wlan2g" "2.4GHz" "blue:wlan2g" "wlan1"
+	;;
+glinet,gl-mt300a|\
+glinet,gl-mt300n|\
+glinet,gl-mt750)
+	ucidef_set_led_netdev "wifi_led" "wifi" "wlan" "wlan0"
+	;;
+hiwifi,hc5661|\
+hiwifi,hc5761)
+	ucidef_set_led_switch "internet" "internet" "blue:internet" "switch0" "0x01"
+	;;
+hiwifi,hc5861)
+	ucidef_set_led_switch "internet" "internet" "blue:internet" "switch0" "0x20"
+	;;
+hnet,c108)
+	ucidef_set_led_netdev "lan" "lan" "green:lan" "eth0"
+	ucidef_set_led_netdev "modem" "modem" "green:modem" "wwan0"
+	;;
+iodata,wn-ac1167gr|\
+iodata,wn-ac733gr3)
+	ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wlan5g" "phy0radio"
+	ucidef_set_led_wlan "wlan2g" "WLAN2G" "green:wlan2g" "phy1radio"
+	;;
+kimax,u25awf-h1)
+	ucidef_set_led_netdev "eth" "eth" "green:lan" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "red:wifi" "wlan0"
+	;;
+kimax,u35wf)
+	ucidef_set_led_netdev "eth" "ETH" "green:eth" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wifi" "wlan0"
+	;;
+kingston,mlw221|\
+kingston,mlwg2|\
+sanlinking,d240)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wifi" "wlan0"
+	;;
+lava,lr-25g001)
+	ucidef_set_led_netdev "wlan2g" "WiFi 2.4GHz" "green:wlan2g" "wlan1"
+	ucidef_set_led_netdev "wlan5g" "WiFi 5GHz" "green:wlan5g" "wlan0"
+	;;
+lenovo,newifi-y1)
+	ucidef_set_led_netdev "wifi" "WIFI" "blue:wifi" "wlan1"
+	ucidef_set_led_netdev "wifi5g" "WIFI5G" "blue:wifi5g" "wlan0"
+	ucidef_set_led_switch "lan" "LAN" "blue:lan" "switch0" "0x03"
+	;;
+lenovo,newifi-y1s)
+	ucidef_set_led_netdev "wifi" "WIFI" "yellow:wifi" "wlan1"
+	ucidef_set_led_netdev "wifi5g" "WIFI5G" "blue:wifi" "wlan0"
+	ucidef_set_led_netdev "wan" "WAN" "blue:internet" "eth0.2" "tx rx"
+	;;
+netgear,ex2700|\
+netgear,wn3000rp-v3)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:router" "wlan0"
+	;;
+netgear,ex3700|\
+netgear,ex6130)
+	ucidef_set_led_netdev "wlan5g" "ROUTER (green)" "green:router" "wlan0"
+	ucidef_set_led_netdev "wlan2g" "DEVICE (green)" "green:device" "wlan1"
+	;;
+netgear,jwnr2010-v5)
+	ucidef_set_led_switch "lan1" "lan1" "green:lan1" "switch0" "0x08"
+	ucidef_set_led_switch "lan2" "lan2" "green:lan2" "switch0" "0x04"
+	ucidef_set_led_switch "lan3" "lan3" "green:lan3" "switch0" "0x02"
+	ucidef_set_led_switch "lan4" "lan4" "green:lan4" "switch0" "0x01"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+phicomm,psg1208)
+	ucidef_set_led_netdev "wifi_led" "wifi" "white:wlan2g" "wlan0"
+	;;
+planex,mzk-ex750np|\
+zbtlink,zbt-we826-e)
+	ucidef_set_led_netdev "wifi_led" "wifi" "red:wifi" "wlan0"
+	;;
+ravpower,rp-wd03)
+	ucidef_set_led_netdev "internet" "internet" "green:wifi" "eth0"
+	;;
+tplink,archer-c2-v1)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch1" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch1" "0x01"
+	;;
+tplink,archer-c20-v1|\
+tplink,archer-c20i)
+	ucidef_set_led_switch "lan" "lan" "blue:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "blue:wan" "switch0" "0x01"
+	;;
+tplink,archer-c50-v1)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	;;
+tplink,archer-mr200)
+	ucidef_set_led_netdev "lan" "lan" "white:lan" "eth0.1"
+	ucidef_set_led_netdev "wan" "wan" "white:wan" "usb0"
+	;;
+tplink,re200-v1)
+	ucidef_set_led_netdev "lan" "lan" "green:lan" "eth0"
+	;;
+wavlink,wl-wn579x3)
+	ucidef_set_led_switch "lan" "lan" "blue:lan" "switch0" "0x20"
+	ucidef_set_led_switch "wan" "wan" "blue:wan" "switch0" "0x10"
+	;;
+zbtlink,zbt-ape522ii)
+	ucidef_set_led_netdev "wlan2g4" "wlan1-link" "green:wlan2g4" "wlan1"
+	ucidef_set_led_netdev "sys1" "wlan1" "green:sys1" "wlan1" "tx rx"
+	ucidef_set_led_netdev "sys2" "wlan0" "green:sys2" "wlan0" "tx rx"
+	;;
+zbtlink,zbt-wa05)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:air" "wlan0"
+	;;
+zbtlink,zbt-we1026-5g-16m)
+	ucidef_set_led_netdev "lan" "LAN" "green:lan" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+zbtlink,zbt-we1026-h-32m)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x8"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+zbtlink,zbt-we2026)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/02_network b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..07b17a9
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/02_network
@@ -0,0 +1,393 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	aigale,ai-br100|\
+	alfa-network,ac1200rm|\
+	asus,rt-n12p|\
+	dlink,dwr-116-a1|\
+	dlink,dwr-921-c1|\
+	dlink,dwr-922-e2|\
+	dovado,tiny-ac|\
+	ohyeah,oy-0001|\
+	phicomm,psg1208|\
+	planex,db-wrt01|\
+	planex,mzk-750dhp|\
+	ralink,mt7620a-evb|\
+	ralink,mt7620a-mt7610e-evb|\
+	ralink,mt7620a-v22sg-evb|\
+	sanlinking,d240|\
+	zbtlink,zbt-ape522ii|\
+	zbtlink,zbt-we826-16m|\
+	zbtlink,zbt-we826-32m|\
+	zbtlink,zbt-we826-e|\
+	zbtlink,zbt-wr8305rt|\
+	zyxel,keenetic-omni)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
+		;;
+	alfa-network,r36m-e4g|\
+	zbtlink,zbt-we1026-h-32m)
+		ucidef_add_switch "switch0" \
+			"3:lan" "4:wan" "6@eth0"
+		;;
+	alfa-network,tube-e4g|\
+	buffalo,wmr-300|\
+	dlink,dch-m225|\
+	edimax,ew-7476rpc|\
+	edimax,ew-7478ac|\
+	elecom,wrh-300cr|\
+	hootoo,ht-tm05|\
+	kimax,u25awf-h1|\
+	kimax,u35wf|\
+	kingston,mlw221|\
+	kingston,mlwg2|\
+	microduino,microwrt|\
+	netgear,ex2700|\
+	netgear,ex3700|\
+	netgear,ex6120|\
+	netgear,ex6130|\
+	netgear,wn3000rp-v3|\
+	planex,cs-qr10|\
+	planex,mzk-ex300np|\
+	planex,mzk-ex750np|\
+	ravpower,rp-wd03|\
+	sercomm,na930|\
+	tplink,re200-v1|\
+	tplink,re210-v1|\
+	yukai,bocco|\
+	zbtlink,zbt-cpe102|\
+	zte,q7)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_set_interface_lan "eth0"
+		;;
+	asus,rp-n53)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "6t@eth0"
+		;;
+	asus,rt-ac51u|\
+	asus,rt-ac54u|\
+	asus,rt-n14u|\
+	bdcom,wap2100-sk|\
+	edimax,ew-7478apc|\
+	glinet,gl-mt300a|\
+	glinet,gl-mt300n|\
+	glinet,gl-mt750|\
+	hiwifi,hc5661|\
+	wrtnode,wrtnode|\
+	zbtlink,zbt-wa05|\
+	zyxel,keenetic-omni-ii)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	buffalo,whr-300hp2|\
+	buffalo,whr-600d)
+		ucidef_add_switch "switch0" \
+			"0:lan:1" "1:lan:2" "2:lan:3" "3:lan:4" "4:wan:5" "6@eth0"
+		;;
+	buffalo,whr-1166d)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "5:wan" "6@eth0"
+		;;
+	comfast,cf-wr800n|\
+	hnet,c108)
+		ucidef_add_switch "switch0" \
+			"4:lan" "6@eth0"
+		;;
+	dlink,dir-510l)
+		ucidef_add_switch "switch0" \
+			"0:lan" "6@eth0"
+		;;
+	dlink,dir-810l|\
+	netgear,jwnr2010-v5|\
+	phicomm,psg1218a|\
+	trendnet,tew-810dr|\
+	zbtlink,zbt-we2026)
+		ucidef_add_switch "switch0" \
+			"0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4:wan" "6@eth0"
+		;;
+	dlink,dwr-118-a1)
+		ucidef_add_switch "switch0" \
+			"1:lan:2" "2:lan:3" "3:lan:1" "4:lan:0" "5:wan" "6@eth0"
+		;;
+	dlink,dwr-118-a2)
+		ucidef_add_switch "switch0" \
+			"1:lan:2" "2:lan:1" "3:lan:3" "4:lan" "0:wan" "6@eth0"
+		;;
+	dlink,dwr-960)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "5:lan" "0:wan" "6@eth0"
+		;;
+	edimax,br-6478ac-v2|\
+	lb-link,bl-w1200|\
+	tplink,archer-c2-v1)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_add_switch "switch1" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	engenius,esr600|\
+	sitecom,wlr-4100-v1-002)
+		ucidef_add_switch "switch0" \
+			"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "5:wan" "0@eth0"
+		ucidef_add_switch "switch1" \
+			"5:lan" "6@eth0"
+		ucidef_add_switch_attr "switch1" "enable" "false"
+		;;
+	fon,fon2601)
+		ucidef_add_switch "switch0" \
+			"0:lan" "4:wan" "6@eth0"
+		;;
+	head-weblink,hdrm200)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "0:wan" "6@eth0"
+		;;
+	hiwifi,hc5761)
+		ucidef_add_switch "switch0" \
+			"1:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	hiwifi,hc5861)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "5:wan" "6@eth0"
+		;;
+	iodata,wn-ac1167gr|\
+	iodata,wn-ac733gr3|\
+	iptime,a1004ns)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_add_switch "switch1" \
+			"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "0:wan" "6@eth0"
+		;;
+	iptime,a104ns)
+		ucidef_add_switch "switch0" \
+			"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "0:wan" "6@eth0"
+		;;
+	lava,lr-25g001)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0"
+		ucidef_add_switch "switch1" \
+			"5:lan" "6@eth0"
+		ucidef_add_switch_attr "switch1" "enable" "false"
+		;;
+	lenovo,newifi-y1|\
+	xiaomi,miwifi-mini)
+		ucidef_add_switch "switch0" \
+			"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
+		;;
+	lenovo,newifi-y1s)
+		ucidef_add_switch "switch0" \
+			"1:lan:4" "2:lan:3" "4:lan:2" "5:lan:1" "0:wan" "6@eth0"
+		;;
+	linksys,e1700|\
+	netis,wf2770|\
+	ralink,mt7620a-mt7530-evb)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_add_switch "switch1" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
+		;;
+	nexx,wt3020-4m|\
+	nexx,wt3020-8m)
+		ucidef_add_switch "switch0" \
+			"4:lan" "0:wan" "6@eth0"
+		;;
+	phicomm,k2g|\
+	wavlink,wl-wn530hg4)
+		ucidef_add_switch "switch0" \
+			"0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "5:wan" "6@eth0"
+		;;
+	phicomm,psg1218b)
+		ucidef_add_switch "switch0" \
+			"0:lan:3" "1:lan:2" "2:lan:1" "3:wan" "6@eth0"
+		;;
+	tplink,archer-c20i|\
+	tplink,archer-c20-v1|\
+	tplink,archer-c50-v1)
+		ucidef_add_switch "switch0" \
+			"1:lan:3" "2:lan:4" "3:lan:1" "4:lan:2" "0:wan" "6@eth0"
+		;;
+	tplink,archer-mr200)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "6t@eth0"
+		ucidef_set_interface_wan "usb0"
+		;;
+	vonets,var11n-300)
+		ucidef_add_switch "switch0" \
+			"0:lan" "4:wan" "6@eth0"
+		;;
+	wavlink,wl-wn579x3)
+		ucidef_add_switch "switch0" \
+			"5:lan" "4:wan" "6@eth0"
+		;;
+	youku,yk-l1|\
+	youku,yk-l1c)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "4:wan" "6@eth0"
+		;;
+	zbtlink,zbt-we1026-5g-16m)
+		ucidef_add_switch "switch0" \
+			"0:lan" "6t@eth0"
+		;;
+	zyxel,keenetic-viva)
+		ucidef_add_switch "switch1" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "7t@eth0"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	aigale,ai-br100|\
+	asus,rt-n12p|\
+	asus,rt-n14u|\
+	bdcom,wap2100-sk|\
+	edimax,ew-7478apc|\
+	fon,fon2601|\
+	head-weblink,hdrm200|\
+	netgear,jwnr2010-v5|\
+	nexx,wt3020-4m|\
+	nexx,wt3020-8m|\
+	phicomm,psg1208|\
+	planex,db-wrt01|\
+	planex,mzk-750dhp|\
+	sanlinking,d240|\
+	vonets,var11n-300|\
+	wrtnode,wrtnode|\
+	zbtlink,zbt-ape522ii|\
+	zbtlink,zbt-wa05|\
+	zbtlink,zbt-we2026|\
+	zbtlink,zbt-we826-16m|\
+	zbtlink,zbt-we826-32m|\
+	zbtlink,zbt-we826-e|\
+	zbtlink,zbt-wr8305rt)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1)
+		;;
+	alfa-network,ac1200rm|\
+	dlink,dir-810l|\
+	trendnet,tew-810dr)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x28)" 1)
+		;;
+	alfa-network,r36m-e4g|\
+	zbtlink,zbt-we1026-h-32m)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	asus,rt-ac51u|\
+	asus,rt-ac54u)
+		lan_mac=$(mtd_get_mac_binary factory 0x22)
+		;;
+	dlink,dch-m225)
+		lan_mac=$(mtd_get_mac_ascii factory lanmac)
+		;;
+	dlink,dir-510l|\
+	dlink,dwr-116-a1|\
+	dlink,dwr-118-a1|\
+	dlink,dwr-118-a2|\
+	dlink,dwr-921-c1|\
+	dlink,dwr-922-e2|\
+	dlink,dwr-960|\
+	lava,lr-25g001)
+		wan_mac=$(jboot_config_read -m -i $(find_mtd_part "config") -o 0xE000)
+		lan_mac=$(macaddr_add "$wan_mac" 1)
+		label_mac=$wan_mac
+		;;
+	dovado,tiny-ac)
+		lan_mac=$(mtd_get_mac_ascii u-boot-env LAN_MAC_ADDR)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env WAN_MAC_ADDR)
+		;;
+	edimax,br-6478ac-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 2)
+		;;
+	engenius,esr600)
+		lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		;;
+	glinet,gl-mt300a|\
+	glinet,gl-mt300n|\
+	glinet,gl-mt750)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4000)" 1)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	hiwifi,hc5661|\
+	hiwifi,hc5761|\
+	hiwifi,hc5861)
+		lan_mac=$(mtd_get_mac_ascii bdinfo "Vfac_mac ")
+		label_mac=$lan_mac
+		[ -n "$lan_mac" ] || lan_mac=$(cat /sys/class/net/eth0/address)
+		wan_mac=$(macaddr_add "$lan_mac" 1)
+		;;
+	iodata,wn-ac1167gr|\
+	iodata,wn-ac733gr3)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		;;
+	iptime,a1004ns)
+		wan_mac=$(mtd_get_mac_binary u-boot 0x1fc40)
+		;;
+	iptime,a104ns)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary u-boot 0x1fc20)" 2)
+		;;
+	lb-link,bl-w1200|\
+	phicomm,k2g|\
+	phicomm,psg1218a|\
+	phicomm,psg1218b)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		label_mac=$wan_mac
+		;;
+	lenovo,newifi-y1|\
+	lenovo,newifi-y1s|\
+	ohyeah,oy-0001|\
+	wavlink,wl-wn530hg4|\
+	youku,yk-l1|\
+	youku,yk-l1c)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		;;
+	linksys,e1700)
+		wan_mac=$(mtd_get_mac_ascii config WAN_MAC_ADDR)
+		;;
+	netis,wf2770)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		label_mac=$wan_mac
+		;;
+	tplink,archer-c2-v1|\
+	tplink,archer-c20-v1|\
+	tplink,archer-c20i|\
+	tplink,archer-c50-v1|\
+	tplink,archer-mr200)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1)
+		;;
+	zbtlink,zbt-we1026-5g-16m)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	zyxel,keenetic-omni|\
+	zyxel,keenetic-omni-ii|\
+	zyxel,keenetic-viva)
+		wan_mac=$(mtd_get_mac_binary factory 0x28)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches
new file mode 100755
index 0000000..9599915
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/board.d/03_gpio_switches
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+board=$(board_name)
+
+case "$board" in
+dlink,dir-510l)
+	ucidef_add_gpio_switch "usb_enable1" "USB 1A enable" "12" "0"
+	ucidef_add_gpio_switch "usb_enable05" "USB 0.5A enable" "13" "1"
+	;;
+dlink,dwr-960)
+	ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "0" "1"
+	;;
+head-weblink,hdrm200)
+	ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "0"
+	ucidef_add_gpio_switch "io1" "I/O 1" "1"
+	ucidef_add_gpio_switch "io2" "I/O 2" "2"
+	ucidef_add_gpio_switch "io3" "I/O 3" "11"
+	ucidef_add_gpio_switch "io4" "I/O 4" "14"
+	ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "21" "1"
+	;;
+lb-link,bl-w1200)
+	ucidef_add_gpio_switch "eth_leds_enable" "ETH LEDs enable" "10" "1"
+	;;
+zbtlink,zbt-we826-e)
+	ucidef_add_gpio_switch "sim_switch" "SIM slot switch" "13"
+	ucidef_add_gpio_switch "power_mpcie" "mPCIe power" "14" "1"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7620/base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom b/target/linux/ramips/mt7620/base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom
new file mode 100644
index 0000000..291f89f
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+[ -e /lib/firmware/$FIRMWARE ] && exit 0
+
+. /lib/functions/caldata.sh
+
+jboot_eeprom_extract() {
+	local part=$1
+	local offset=$2
+	local mtd
+
+	mtd=$(find_mtd_part $part)
+	[ -n "$mtd" ] || \
+		caldata_die "no mtd device found for partition $part"
+
+	jboot_config_read -i $mtd -o $offset -e /lib/firmware/$FIRMWARE  2>/dev/null || \
+		caldata_die "failed to extract from $mtd"
+}
+
+board=$(board_name)
+
+case "$FIRMWARE" in
+"soc_wmac.eeprom")
+	case $board in
+	dlink,dir-510l|\
+	dlink,dwr-116-a1|\
+	dlink,dwr-118-a1|\
+	dlink,dwr-118-a2|\
+	dlink,dwr-921-c1|\
+	dlink,dwr-922-e2|\
+	dlink,dwr-960|\
+	lava,lr-25g001)
+		wan_mac=$(jboot_config_read -m -i $(find_mtd_part "config") -o 0xE000)
+		wifi_mac=$(macaddr_add "$wan_mac" 1)
+		jboot_eeprom_extract "config" 0xE000
+		caldata_patch_mac $wifi_mac 0x4
+		;;
+	dovado,tiny-ac)
+		wifi_mac=$(mtd_get_mac_ascii u-boot-env INIC_MAC_ADDR)
+		caldata_extract "factory" 0x0 0x200
+		caldata_patch_mac $wifi_mac 0x4
+		;;
+	*)
+		caldata_die "Please define mtd-eeprom in $board DTS file!"
+		;;
+	esac
+	;;
+esac
diff --git a/target/linux/ramips/mt7620/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7620/base-files/etc/init.d/bootcount
new file mode 100755
index 0000000..06316e4
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/init.d/bootcount
@@ -0,0 +1,14 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+boot() {
+	case $(board_name) in
+	alfa-network,ac1200rm|\
+	alfa-network,r36m-e4g|\
+	alfa-network,tube-e4g)
+		[ -n "$(fw_printenv bootcount bootchanged 2>/dev/null)" ] &&\
+			echo -e "bootcount\nbootchanged\n" | /usr/sbin/fw_setenv -s -
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt7620/base-files/etc/uci-defaults/05_fix-compat-version b/target/linux/ramips/mt7620/base-files/etc/uci-defaults/05_fix-compat-version
new file mode 100644
index 0000000..9f981df
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/etc/uci-defaults/05_fix-compat-version
@@ -0,0 +1,10 @@
+. /lib/functions.sh
+
+case "$(board_name)" in
+	ravpower,rp-wd03)
+		uci set system.@system[0].compat_version="2.0"
+		uci commit system
+		;;
+esac
+
+exit 0
diff --git a/target/linux/ramips/mt7620/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7620/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..9f71dc9
--- /dev/null
+++ b/target/linux/ramips/mt7620/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+RAMFS_COPY_BIN='fw_printenv fw_setenv'
+RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	alfa-network,ac1200rm|\
+	alfa-network,r36m-e4g|\
+	alfa-network,tube-e4g)
+		[ "$(fw_printenv -n dual_image 2>/dev/null)" = "1" ] &&\
+		[ -n "$(find_mtd_part backup)" ] && {
+			PART_NAME=backup
+			if [ "$(fw_printenv -n bootactive 2>/dev/null)" = "1" ]; then
+				fw_setenv bootactive 2 || exit 1
+			else
+				fw_setenv bootactive 1 || exit 1
+			fi
+		}
+		default_do_upgrade "$1"
+		;;
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt7620/config-5.4 b/target/linux/ramips/mt7620/config-5.4
new file mode 100644
index 0000000..6ee5ce8
--- /dev/null
+++ b/target/linux/ramips/mt7620/config-5.4
@@ -0,0 +1,249 @@
+CONFIG_AR8216_PHY=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_AT803X_PHY=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_CEVT_R4K=y
+CONFIG_CEVT_SYSTICK_QUIRK=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKEVT_RT3352=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DMA_RALINK is not set
+# CONFIG_DTB_MT7620A_EVAL is not set
+# CONFIG_DTB_OMEGA2P is not set
+CONFIG_DTB_RT_NONE=y
+# CONFIG_DTB_VOCORE2 is not set
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_ETHERNET_PACKET_MANGLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_MT7621 is not set
+CONFIG_GPIO_RALINK=y
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PCI=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MT7621_WDT is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
+CONFIG_MTD_SPLIT_JIMAGE_FW=y
+CONFIG_MTD_SPLIT_SEAMA_FW=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_VIRT_CONCAT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK_GSW_MT7620=y
+CONFIG_NET_RALINK_MDIO=y
+CONFIG_NET_RALINK_MDIO_MT7620=y
+CONFIG_NET_RALINK_MT7620=y
+# CONFIG_NET_RALINK_RT3050 is not set
+CONFIG_NET_RALINK_SOC=y
+# CONFIG_NET_VENDOR_MEDIATEK is not set
+CONFIG_NET_VENDOR_RALINK=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+# CONFIG_PCI_MT7621 is not set
+# CONFIG_PCI_MT7621_PHY is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHY_RALINK_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_WDT=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SOC_MT7620=y
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_MT7621 is not set
+CONFIG_SPI_RT2880=y
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWCONFIG_LEDS=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/ramips/mt7620/target.mk b/target/linux/ramips/mt7620/target.mk
new file mode 100644
index 0000000..5fc61e4
--- /dev/null
+++ b/target/linux/ramips/mt7620/target.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+SUBTARGET:=mt7620
+BOARDNAME:=MT7620 based boards
+FEATURES+=usb ramdisk
+CPU_TYPE:=24kc
+
+DEFAULT_PACKAGES += kmod-rt2800-soc wpad-basic-wolfssl swconfig
+
+define Target/Description
+	Build firmware images for Ralink MT7620 based boards.
+endef
+
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..d9df98c
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/01_leds
@@ -0,0 +1,120 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+asus,rt-n56u-b1)
+	ucidef_set_led_netdev "lan" "LAN link" "blue:lan" "br-lan"
+	ucidef_set_led_netdev "wan" "WAN link" "blue:wan" "wan"
+	;;
+cudy,wr2100)
+	ucidef_set_led_netdev "lan1" "lan1" "green:lan1" "lan1"
+	ucidef_set_led_netdev "lan2" "lan2" "green:lan2" "lan2"
+	ucidef_set_led_netdev "lan3" "lan3" "green:lan3" "lan3"
+	ucidef_set_led_netdev "lan4" "lan4" "green:lan4" "lan4"
+	ucidef_set_led_netdev "wan" "wan" "green:wan" "wan"
+	;;
+d-team,newifi-d2)
+	ucidef_set_led_netdev "internet" "internet" "amber:internet" "wan"
+	ucidef_set_led_netdev "wlan2g" "WiFi 2.4GHz" "blue:wlan2g" "wlan0"
+	ucidef_set_led_netdev "wlan5g" "WiFi 5GHz" "blue:wlan5g" "wlan1"
+	;;
+d-team,pbr-m1|\
+gehua,ghl-r-001|\
+jcg,y2|\
+xzwifi,creativebox-v1)
+	ucidef_set_led_netdev "internet" "internet" "blue:internet" "wan"
+	;;
+dlink,dir-1960-a1|\
+dlink,dir-2640-a1|\
+dlink,dir-2660-a1)
+	ucidef_set_led_netdev "wan" "wan" "white:net" "wan"
+	;;
+dlink,dir-860l-b1|\
+dlink,dir-867-a1|\
+dlink,dir-878-a1|\
+dlink,dir-882-a1|\
+dlink,dir-882-r1)
+	ucidef_set_led_netdev "wan" "wan" "green:net" "wan"
+	;;
+gnubee,gb-pc2)
+	ucidef_set_led_netdev "ethyellow" "ethyellow" "orange:ethyellow" "ethyellow" "link tx rx"
+	;;
+linksys,e5600)
+	ucidef_set_led_netdev "wan" "wan link" "blue:wan" "wan" "link"
+	;;
+linksys,ea7300-v1|\
+linksys,ea7300-v2|\
+linksys,ea7500-v2|\
+linksys,ea8100-v1)
+	ucidef_set_led_netdev "lan1" "lan1 link" "green:lan1" "lan1" "link"
+	ucidef_set_led_netdev "lan2" "lan2 link" "green:lan2" "lan2" "link"
+	ucidef_set_led_netdev "lan3" "lan3 link" "green:lan3" "lan3" "link"
+	ucidef_set_led_netdev "lan4" "lan4 link" "green:lan4" "lan4" "link"
+	ucidef_set_led_netdev "wan" "wan link" "green:wan" "wan" "link"
+	;;
+mikrotik,routerboard-760igs)
+	ucidef_set_led_netdev "sfp" "SFP" "blue:sfp" "sfp"
+	;;
+mikrotik,routerboard-m11g)
+	ucidef_set_rssimon "wlan0" "200000" "1"
+	ucidef_set_led_rssi "rssilow" "RSSILOW" "green:rssi0" "wlan0" "1" "100"
+	ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "green:rssi1" "wlan0" "20" "100"
+	ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "green:rssi2" "wlan0" "40" "100"
+	ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "green:rssi3" "wlan0" "60" "100"
+	ucidef_set_led_rssi "rssiveryhigh" "RSSIVERYHIGH" "green:rssi4" "wlan0" "80" "100"
+	;;
+mtc,wr1201)
+	ucidef_set_led_netdev "eth_link" "LAN link" "green:eth_link" "br-lan"
+	;;
+netgear,r6220|\
+netgear,r6260|\
+netgear,r6350|\
+netgear,r6850|\
+netgear,wac124|\
+netgear,wndr3700-v5)
+	ucidef_set_led_netdev "wan" "wan" "green:wan" "wan"
+	;;
+netgear,r6700-v2|\
+netgear,r6800)
+	ucidef_set_led_netdev "wan" "WAN" "white:wan" "wan"
+	ucidef_set_led_netdev "lan1" "LAN1" "white:lan1" "lan1"
+	ucidef_set_led_netdev "lan2" "LAN2" "white:lan2" "lan2"
+	ucidef_set_led_netdev "lan3" "LAN3" "white:lan3" "lan3"
+	ucidef_set_led_netdev "lan4" "LAN4" "white:lan4" "lan4"
+	;;
+tplink,archer-a6-v3|\
+tplink,archer-c6u-v1)
+	ucidef_set_led_netdev "lan" "LAN" "green:lan" "br-lan"
+	ucidef_set_led_netdev "wan" "WAN" "green:wan" "wan"
+	;;
+tplink,re350-v1)
+	ucidef_set_led_netdev "wifi2g" "Wifi 2.4G" "blue:wifi2G" "wlan0"
+	ucidef_set_led_netdev "wifi5g" "Wifi 5G" "blue:wifi5G" "wlan1"
+	ucidef_set_led_netdev "eth_act" "LAN act" "green:eth_act" "lan" "tx rx"
+	ucidef_set_led_netdev "eth_link" "LAN link" "green:eth_link" "lan" "link"
+	;;
+tplink,re500-v1|\
+tplink,re650-v1)
+	ucidef_set_led_netdev "eth_act" "LAN act" "green:eth_act" "lan" "tx rx"
+	ucidef_set_led_netdev "eth_link" "LAN link" "green:eth_link" "lan" "link"
+	;;
+xiaomi,mi-router-ac2100)
+	ucidef_set_led_netdev "wan-blue" "WAN (blue)" "blue:wan" "wan"
+	;;
+xiaomi,redmi-router-ac2100)
+	ucidef_set_led_netdev "wan" "wan" "white:wan" "wan"
+	;;
+youhua,wr1200js)
+	ucidef_set_led_netdev "internet" "INTERNET" "green:wan" "wan"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/02_network b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..9ebe652
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/02_network
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	ampedwireless,ally-00x19k|\
+	edimax,re23s|\
+	mikrotik,routerboard-m11g|\
+	netgear,ex6150|\
+	sercomm,na502|\
+	thunder,timecloud|\
+	tplink,re350-v1|\
+	tplink,re500-v1|\
+	tplink,re650-v1|\
+	ubnt,unifi-6-lite|\
+	ubnt,unifi-nanohd)
+		ucidef_set_interface_lan "lan"
+		;;
+	ampedwireless,ally-r1900k|\
+	gehua,ghl-r-001|\
+	hiwifi,hc5962|\
+	xiaomi,mi-router-3-pro|\
+	xiaomi,mi-router-ac2100|\
+	xiaomi,redmi-router-ac2100)
+		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
+		;;
+	asiarf,ap7621-001|\
+	winstars,ws-wn583a6)
+		ucidef_set_interfaces_lan_wan "lan" "wan"
+		;;
+	asiarf,ap7621-nv1|\
+	glinet,gl-mt1300|\
+	jcg,q20|\
+	lenovo,newifi-d1|\
+	mikrotik,routerboard-m33g|\
+	xiaomi,mi-router-3g|\
+	xiaomi,mi-router-3g-v2|\
+	xiaomi,mi-router-4|\
+	xiaomi,mi-router-4a-gigabit)
+		ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
+		;;
+	gnubee,gb-pc1)
+		ucidef_set_interface_lan "ethblack ethblue"
+		;;
+	gnubee,gb-pc2)
+		ucidef_set_interface_lan "ethblack ethblue ethyellow"
+		;;
+	linksys,re6500|\
+	netgear,wac104)
+		ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
+		;;
+	mikrotik,routerboard-750gr3)
+		ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan"
+		;;
+	mikrotik,routerboard-760igs)
+		ucidef_set_interfaces_lan_wan "lan2 lan3 lan4 lan5" "wan sfp"
+		;;
+	tplink,eap235-wall-v1)
+		ucidef_set_interface_lan "lan0 lan1 lan2 lan3"
+		;;
+	ubnt,edgerouter-x)
+		ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4" "eth0"
+		;;
+	ubnt,edgerouter-x-sfp)
+		ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4 eth5" "eth0"
+		;;
+	yuncore,ax820|\
+	zyxel,nr7101)
+		ucidef_set_interfaces_lan_wan "lan" "wan"
+		;;
+	zyxel,wap6805)
+		ucidef_set_interface_lan "lan1 lan2 lan3 lan4"
+		ucidef_set_interface "qtn" ifname "eth1" protocol "static" ipaddr "1.1.1.1" netmask "255.255.255.0"
+		;;
+	*)
+		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	ampedwireless,ally-00x19k)
+		lan_mac=$(mtd_get_mac_ascii hwconfig HW.LAN.MAC.Address)
+		label_mac=$lan_mac
+		;;
+	ampedwireless,ally-r1900k)
+		lan_mac=$(mtd_get_mac_ascii hwconfig HW.LAN.MAC.Address)
+		wan_mac=$(mtd_get_mac_ascii hwconfig HW.WAN.MAC.Address)
+		label_mac=$lan_mac
+		;;
+	asus,rt-ac65p|\
+	asus,rt-ac85p)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env et1macaddr)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	buffalo,wsr-1166dhp)
+		local index="$(find_mtd_index "board_data")"
+		wan_mac="$(grep -m1 mac= "/dev/mtd${index}" | cut -d= -f2)"
+		lan_mac=$wan_mac
+		;;
+	dlink,dir-860l-b1)
+		lan_mac=$(mtd_get_mac_ascii factory lanmac)
+		wan_mac=$(mtd_get_mac_ascii factory wanmac)
+		;;
+	edimax,ra21s|\
+	edimax,rg21s)
+		lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		;;
+	elecom,wrc-2533ghbk-i)
+		lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		label_mac=$wan_mac
+		;;
+	hiwifi,hc5962)
+		lan_mac=$(mtd_get_mac_ascii bdinfo "Vfac_mac ")
+		label_mac=$lan_mac
+		[ -n "$lan_mac" ] || lan_mac=$(cat /sys/class/net/eth0/address)
+		wan_mac=$(macaddr_add "$lan_mac" 1)
+		;;
+	iodata,wnpr2600g)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		label_mac=$wan_mac
+		;;
+	jcg,y2|\
+	wavlink,wl-wn531a6|\
+	winstars,ws-wn583a6|\
+	zbtlink,zbt-we1326|\
+	zbtlink,zbt-wg3526-16m|\
+	zbtlink,zbt-wg3526-32m)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	linksys,e5600|\
+	linksys,ea7300-v1|\
+	linksys,ea7300-v2|\
+	linksys,ea7500-v2|\
+	linksys,ea8100-v1)
+		lan_mac=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+		wan_mac=$lan_mac
+		label_mac=$lan_mac
+		;;
+	mikrotik,routerboard-750gr3|\
+	mikrotik,routerboard-760igs|\
+	mikrotik,routerboard-m11g|\
+	mikrotik,routerboard-m33g)
+		label_mac=$(cat "/sys/firmware/mikrotik/hard_config/mac_base")
+		wan_mac=$label_mac
+		lan_mac=$(macaddr_add $label_mac 1)
+		;;
+	yuncore,ax820)
+		label_mac=$(mtd_get_mac_binary Factory 0x4)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
new file mode 100755
index 0000000..8ef8156
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/03_gpio_switches
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+board=$(board_name)
+
+case "$board" in
+mikrotik,routerboard-760igs)
+	ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "497"
+	;;
+telco-electronics,x1)
+	ucidef_add_gpio_switch "modem_reset" "Modem Reset" "496"
+	;;
+ubnt,edgerouter-x)
+	ucidef_add_gpio_switch "poe_passthrough" "PoE Passthrough" "480"
+	;;
+ubnt,edgerouter-x-sfp)
+	ucidef_add_gpio_switch "poe_power_port0" "PoE Power Port0" "400"
+	ucidef_add_gpio_switch "poe_power_port1" "PoE Power Port1" "401"
+	ucidef_add_gpio_switch "poe_power_port2" "PoE Power Port2" "402"
+	ucidef_add_gpio_switch "poe_power_port3" "PoE Power Port3" "403"
+	ucidef_add_gpio_switch "poe_power_port4" "PoE Power Port4" "404"
+	;;
+zyxel,nr7101)
+	ucidef_add_gpio_switch "lte_reset" "Reset LTE/5G modem" "483"
+	;;
+zyxel,wap6805)
+	ucidef_add_gpio_switch "qtn_power" "Quantenna Module Power" "496" "1"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version b/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version
new file mode 100755
index 0000000..d79092f
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/board.d/05_compat-version
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Copyright (C) 2020 OpenWrt.org
+#
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+case "$(board_name)" in
+	*)
+		ucidef_set_compat_version "1.1"
+		;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
new file mode 100644
index 0000000..68ee537
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac
@@ -0,0 +1,34 @@
+[ "$ACTION" == "add" ] || exit 0
+
+PHYNBR=${DEVPATH##*/phy}
+
+[ -n $PHYNBR ] || exit 0
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+board=$(board_name)
+
+case "$board" in
+	glinet,gl-mt1300)
+		[ "$PHYNBR" = "1" ] && \
+			macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1 > /sys${DEVPATH}/macaddress
+		;;
+	jcg,q20)
+		[ "$PHYNBR" = "1" ] && \
+			macaddr_setbit_la "$(mtd_get_mac_binary Factory 0x4)" > /sys${DEVPATH}/macaddress
+		;;
+	linksys,e5600|\
+	linksys,ea7300-v1|\
+	linksys,ea7300-v2|\
+	linksys,ea7500-v2|\
+	linksys,ea8100-v1)
+		hw_mac_addr=$(mtd_get_mac_ascii devinfo hw_mac_addr)
+		[ "$PHYNBR" = "0" ] && macaddr_add $hw_mac_addr 1 > /sys${DEVPATH}/macaddress
+		[ "$PHYNBR" = "1" ] && macaddr_add $hw_mac_addr 2 > /sys${DEVPATH}/macaddress
+		;;
+	yuncore,ax820)
+		[ "$PHYNBR" = "1" ] && \
+			macaddr_setbit_la "$(mtd_get_mac_binary Factory 0xe000)" > /sys${DEVPATH}/macaddress
+		;;
+esac
diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
new file mode 100755
index 0000000..d3525ea
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/init.d/bootcount
@@ -0,0 +1,27 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+boot() {
+	case $(board_name) in
+	alfa-network,quad-e4g)
+		[ -n "$(fw_printenv bootcount bootchanged 2>/dev/null)" ] &&\
+			echo -e "bootcount\nbootchanged\n" | /usr/sbin/fw_setenv -s -
+		;;
+	linksys,e5600|\
+	linksys,ea7300-v1|\
+	linksys,ea7300-v2|\
+	linksys,ea7500-v2|\
+	linksys,ea8100-v1)
+		mtd resetbc s_env || true
+		;;
+	samknows,whitebox-v8)
+		fw_setenv bootcount 0
+		;;
+	zyxel,nr7101)
+		[ $(printf %d $(fw_printenv -n DebugFlag)) -gt 0 ] || fw_setenv DebugFlag 0x1
+		[ $(printf %d $(fw_printenv -n Image1Stable)) -gt 0 ] || fw_setenv Image1Stable 1
+		[ $(printf %d $(fw_printenv -n Image1Try)) -gt 0 ] && fw_setenv Image1Try 0
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt7621/base-files/etc/init.d/set-irq-affinity b/target/linux/ramips/mt7621/base-files/etc/init.d/set-irq-affinity
new file mode 100755
index 0000000..c118d92
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/init.d/set-irq-affinity
@@ -0,0 +1,19 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+start() {
+	if grep -q 'processor.*: 2' /proc/cpuinfo; then
+		mask=4
+	elif grep -q 'processor.*: 1' /proc/cpuinfo; then
+		mask=2
+	else
+		return
+	fi
+
+	for irq in $(grep "mt76..e" /proc/interrupts | cut -d: -f1 | sed 's, *,,')
+	do
+		echo "$mask" > "/proc/irq/$irq/smp_affinity"
+		[ $mask = 4 ] && mask=8
+	done
+}
diff --git a/target/linux/ramips/mt7621/base-files/etc/uci-defaults/01_enable_packet_steering b/target/linux/ramips/mt7621/base-files/etc/uci-defaults/01_enable_packet_steering
new file mode 100644
index 0000000..114c7e1
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/etc/uci-defaults/01_enable_packet_steering
@@ -0,0 +1,5 @@
+uci -q get network.globals.packet_steering > /dev/null || {
+	uci set network.globals='globals'
+	uci set network.globals.packet_steering=1
+	uci commit network
+}
diff --git a/target/linux/ramips/mt7621/base-files/lib/preinit/07_mt7621_bringup_dsa_master b/target/linux/ramips/mt7621/base-files/lib/preinit/07_mt7621_bringup_dsa_master
new file mode 100644
index 0000000..0f4660d
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/lib/preinit/07_mt7621_bringup_dsa_master
@@ -0,0 +1,20 @@
+. /lib/functions.sh
+
+mt7621_bringup_dsa_master() {
+    local board=$(board_name)
+    local masterif
+
+    case "$board" in
+    ubnt,edgerouter-x|\
+    ubnt,edgerouter-x-sfp)
+        masterif="dsa"
+        ;;
+    *)
+        masterif="eth0"
+        ;;
+    esac
+
+    ip link set $masterif up
+}
+
+boot_hook_add preinit_main mt7621_bringup_dsa_master
\ No newline at end of file
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/iodata.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/iodata.sh
new file mode 100644
index 0000000..8303ae9
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/iodata.sh
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2019 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+iodata_mstc_prepare_fail() {
+	echo "failed to check and prepare the environment, rebooting..."
+	umount -a
+	reboot -f
+}
+
+# I-O DATA devices manufactured by MSTC (MitraStar Technology Corp.)
+# have two important flags:
+# - bootnum: switch between two os images
+#     use 1st image in OpenWrt
+# - debugflag: enable/disable debug
+#     users can interrupt Z-Loader for recovering the device if enabled
+#
+# parameters:
+# - $1: the offset of "debugflag"
+iodata_mstc_upgrade_prepare() {
+	local persist_mtd="$(find_mtd_part persist)"
+	local factory_mtd="$(find_mtd_part factory)"
+	local dflag_offset="$1"
+
+	if [ -z "$dflag_offset" ]; then
+		echo 'no debugflag offset provided'
+		iodata_mstc_prepare_fail
+	fi
+
+	if [ -z "$persist_mtd" ] || [ -z "$factory_mtd" ]; then
+		echo 'cannot find mtd partition(s), "factory" or "persist"'
+		iodata_mstc_prepare_fail
+	fi
+
+	local bootnum=$(hexdump -s 4 -n 1 -e '"%x"' ${persist_mtd})
+	local debugflag=$(hexdump -s $((dflag_offset)) -n 1 -e '"%x"' ${factory_mtd})
+
+	if [ "$bootnum" != "1" ] && [ "$bootnum" != "2" ]; then
+		echo "failed to get bootnum, please check the value at 0x4 in ${persist_mtd}"
+		iodata_mstc_prepare_fail
+	fi
+	if [ "$debugflag" != "0" ] && [ "$debugflag" != "1" ]; then
+		echo "failed to get debugflag, please check the value at ${dflag_offset} in ${factory_mtd}"
+		iodata_mstc_prepare_fail
+	fi
+	echo "current: bootnum => ${bootnum}, debugflag => ${debugflag}"
+
+	if [ "$bootnum" = "2" ]; then
+		if ! (echo -ne "\x01" | dd bs=1 count=1 seek=4 conv=notrunc of=${persist_mtd} 2>/dev/null); then
+			echo "failed to set bootnum"
+			iodata_mstc_prepare_fail
+		fi
+		echo "### switch to 1st os-image on next boot ###"
+	fi
+	if [ "$debugflag" = "0" ]; then
+		if ! (echo -ne "\x01" | dd bs=1 count=1 seek=$((dflag_offset)) conv=notrunc of=${factory_mtd} 2>/dev/null); then
+			echo "failed to set debugflag"
+			iodata_mstc_prepare_fail
+		fi
+		echo "### enable debug ###"
+	fi
+}
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..c2ad4d3
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,116 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+RAMFS_COPY_BIN='fw_printenv fw_setenv'
+RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	alfa-network,quad-e4g)
+		[ "$(fw_printenv -n dual_image 2>/dev/null)" = "1" ] &&\
+		[ -n "$(find_mtd_part backup)" ] && {
+			PART_NAME=backup
+			if [ "$(fw_printenv -n bootactive 2>/dev/null)" = "1" ]; then
+				fw_setenv bootactive 2 || exit 1
+			else
+				fw_setenv bootactive 1 || exit 1
+			fi
+		}
+		;;
+	ampedwireless,ally-00x19k|\
+	ampedwireless,ally-r1900k)
+		if [ "$(fw_printenv --lock / -n bootImage 2>/dev/null)" != "0" ]; then
+			fw_setenv --lock / bootImage 0 || exit 1
+		fi
+		;;
+	mikrotik,routerboard-750gr3|\
+	mikrotik,routerboard-760igs|\
+	mikrotik,routerboard-m11g|\
+	mikrotik,routerboard-m33g)
+		[ "$(rootfs_type)" = "tmpfs" ] && mtd erase firmware
+		;;
+	asus,rt-ac65p|\
+	asus,rt-ac85p)
+		echo "Backing up firmware"
+		dd if=/dev/mtd4 bs=1024 count=4096  > /tmp/backup_firmware.bin
+		dd if=/dev/mtd5 bs=1024 count=52224 >> /tmp/backup_firmware.bin
+		mtd -e firmware2 write /tmp/backup_firmware.bin firmware2
+		;;
+	esac
+
+	case "$board" in
+	ampedwireless,ally-00x19k|\
+	ampedwireless,ally-r1900k|\
+	asus,rt-ac65p|\
+	asus,rt-ac85p|\
+	dlink,dir-1960-a1|\
+	dlink,dir-2640-a1|\
+	dlink,dir-2660-a1|\
+	hiwifi,hc5962|\
+	jcg,q20|\
+	linksys,e5600|\
+	linksys,ea7300-v1|\
+	linksys,ea7300-v2|\
+	linksys,ea7500-v2|\
+	linksys,ea8100-v1|\
+	netgear,r6220|\
+	netgear,r6260|\
+	netgear,r6350|\
+	netgear,r6700-v2|\
+	netgear,r6800|\
+	netgear,r6850|\
+	netgear,wac104|\
+	netgear,wac124|\
+	netis,wf2881|\
+	sercomm,na502|\
+	xiaomi,mi-router-3g|\
+	xiaomi,mi-router-3-pro|\
+	xiaomi,mi-router-4|\
+	xiaomi,mi-router-ac2100|\
+	xiaomi,redmi-router-ac2100)
+		nand_do_upgrade "$1"
+		;;
+	iodata,wn-ax1167gr2|\
+	iodata,wn-ax2033gr|\
+	iodata,wn-dx1167r)
+		iodata_mstc_upgrade_prepare "0xfe75"
+		nand_do_upgrade "$1"
+		;;
+	iodata,wn-dx1200gr)
+		iodata_mstc_upgrade_prepare "0x1fe75"
+		nand_do_upgrade "$1"
+		;;
+	ubnt,edgerouter-x|\
+	ubnt,edgerouter-x-sfp)
+		platform_upgrade_ubnt_erx "$1"
+		;;
+	zyxel,nr7101)
+		fw_setenv CheckBypass 0
+		fw_setenv Image1Stable 0
+		CI_KERNPART="Kernel"
+		nand_do_upgrade "$1"
+		;;
+	zyxel,wap6805)
+		local kernel2_mtd="$(find_mtd_part Kernel2)"
+		[ "$(hexdump -n 4 -e '"%x"' $kernel2_mtd)" = "56190527" ] &&\
+		[ "$(hexdump -n 4 -s 104 -e '"%x"' $kernel2_mtd)" != "0" ] &&\
+		dd bs=4 count=1 seek=26 conv=notrunc if=/dev/zero of=$kernel2_mtd 2>/dev/null &&\
+		echo "Kernel2 sequence number was reset to 0"
+		CI_KERNPART="Kernel"
+		nand_do_upgrade "$1"
+		;;
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt7621/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/mt7621/base-files/lib/upgrade/ubnt.sh
new file mode 100644
index 0000000..748ec8e
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/lib/upgrade/ubnt.sh
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+
+. /lib/functions.sh
+#Note: this code also uses some functions from nand.sh, but it is expected to be run by nand.sh, so we are not
+#sourcing it explicitly here
+
+UBNT_ERX_KERNEL_INDEX_OFFSET=160
+
+ubnt_get_target_kernel() {
+	local factory_mtd=$1
+	local current_kernel_index=$(hexdump -s $UBNT_ERX_KERNEL_INDEX_OFFSET -n 1 -e '/1 "%X "' ${factory_mtd})
+
+	if [ $current_kernel_index == "0" ]; then
+		echo 'kernel2'
+	elif [ $current_kernel_index == "1" ]; then
+		echo 'kernel1'
+	fi
+}
+
+ubnt_update_target_kernel() {
+	local factory_mtd=$1
+	local kernel_part=$2
+
+	local new_kernel_index
+	if [ $kernel_part == "kernel1" ]; then
+		new_kernel_index="\x00"
+	elif [ $kernel_part == "kernel2" ]; then
+		new_kernel_index="\x01"
+	else
+		echo 'Unknown kernel image index' >&2
+		return 1
+	fi
+
+	if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
+		echo 'Failed to update kernel bootup index' >&2
+		return 1
+	fi
+}
+
+platform_upgrade_ubnt_erx() {
+	local factory_mtd=$(find_mtd_part factory)
+	if [ -z "$factory_mtd" ]; then
+		echo "cannot find factory partition" >&2
+		exit 1
+	fi
+
+	local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
+	if [ -z "$kernel_part" ]; then
+		echo "cannot find factory partition" >&2
+		exit 1
+	fi
+
+	# This is a global defined in nand.sh, sets partition kernel will be flashed into
+	CI_KERNPART=${kernel_part}
+
+	#Remove volume possibly left over from stock firmware
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	if [ -z "$ubidev" ]; then
+		local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+		if [ -z "$mtdnum" ]; then
+			echo "cannot find ubi mtd partition $CI_UBIPART" >&2
+			exit 1
+		fi
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	fi
+	if [ -n "$ubidev" ]; then
+		local troot_ubivol="$( nand_find_volume $ubidev troot )"
+		[ -n "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
+	fi
+
+	ubnt_update_target_kernel ${factory_mtd} ${kernel_part} || exit 1
+
+	nand_do_upgrade "$1"
+}
diff --git a/target/linux/ramips/mt7621/base-files/sbin/fixup-mac-address b/target/linux/ramips/mt7621/base-files/sbin/fixup-mac-address
new file mode 100755
index 0000000..dad15c5
--- /dev/null
+++ b/target/linux/ramips/mt7621/base-files/sbin/fixup-mac-address
@@ -0,0 +1,80 @@
+#!/bin/sh
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+partname=""
+offset=""
+NEW_MAC=
+YES=
+
+board=$(board_name)
+case $board in
+	mqmaker,witi)
+		partname=factory
+		offset=$((0xe000))
+	;;
+	*)
+		echo "Unsupported board"
+		exit 1
+	;;
+esac
+
+while [ -n "$1" ]; do
+	case "$1" in
+		??:??:??:??:??:??) NEW_MAC="$1";;
+		-y) YES=1;;
+		*)
+			cat <<EOF
+Unknown option/argument '$1'
+Usage: $0 [-y] [<macaddr>]
+EOF
+			exit 1
+		;;
+	esac
+	shift
+done
+
+ask_bool() {
+	local message="$1"
+	local default="$((! ${2:-0}))"
+	[ -n "$YES" ] && return 0
+	echo -n "$message "
+	read opt
+	case "$opt" in
+		y|Y) return 0;;
+		n|N) return 1;;
+		*) return $default;;
+	esac
+}
+
+convert_hex() {
+	hexdump -e '/1 "%02x "'
+}
+
+gen_mac() {
+	dd if=/dev/urandom bs=6 count=1 2>/dev/null
+}
+
+mac="$(mtd_get_mac_binary $partname $offset)"
+case "$mac" in
+	00:00:00:00:00:00);;
+	ff:ff:ff:ff:ff:ff);;
+	*)
+		echo "Current MAC address: $mac"
+		ask_bool "Overwrite (y/N)?" 0 || exit
+	;;
+esac
+
+if [ -n "$NEW_MAC" ]; then
+	set -- $(echo "$NEW_MAC" | sed 's,:, ,g')
+else
+	set -- $(gen_mac | convert_hex)
+	set -- $(printf %02x $(( (0x$1 & 0xfe) | 0x02 ))) $2 $3 $4 $5 $6
+fi
+echo "New MAC address: $1:$2:$3:$4:$5:$6"
+ask_bool "Write to EEPROM (y/N)?" || exit
+
+part=$(find_mtd_part "$partname")
+[ -n "$part" ] || exit
+echo -ne "\x$1\x$2\x$3\x$4\x$5\x$6" | dd of=$part conv=notrunc bs=1 count=6 seek=$offset 2>/dev/null
+echo "Done"
diff --git a/target/linux/ramips/mt7621/config-5.4 b/target/linux/ramips/mt7621/config-5.4
new file mode 100644
index 0000000..6ff91a9
--- /dev/null
+++ b/target/linux/ramips/mt7621/config-5.4
@@ -0,0 +1,292 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_AT803X_PHY=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BOARD_SCACHE=y
+CONFIG_BOUNCE=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MIPS_GIC=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMMON_CLK=y
+# CONFIG_COMMON_CLK_BOSTON is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_EI=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_RMAP=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRC16=y
+CONFIG_CRYPTO_ACOMP2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DIMLIB=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DMA_RALINK is not set
+# CONFIG_DTB_GNUBEE1 is not set
+# CONFIG_DTB_GNUBEE2 is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_IPI=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_MT7621=y
+# CONFIG_GPIO_RALINK is not set
+CONFIG_GPIO_WATCHDOG=y
+# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
+CONFIG_GRO_CELLS=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HIGHMEM=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_MT7621=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_DOMAIN_HIERARCHY=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LED_TRIGGER_PHY=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIKROTIK=y
+CONFIG_MIKROTIK_RB_SYSFS=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CBPF_JIT=y
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+CONFIG_MIPS_CM=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+CONFIG_MIPS_CPC=y
+CONFIG_MIPS_CPS=y
+# CONFIG_MIPS_CPS_NS16550_BOOL is not set
+CONFIG_MIPS_CPU_SCACHE=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_GIC=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_MIPS_MT=y
+CONFIG_MIPS_MT_FPAFF=y
+CONFIG_MIPS_MT_SMP=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_NR_CPU_NR_MAP=4
+CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MT7621_WDT=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_NAND_CORE=y
+CONFIG_MTD_NAND_ECC_SW_HAMMING=y
+CONFIG_MTD_NAND_MT7621=y
+# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_ROUTERBOOT_PARTS=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_FIT_FW=y
+CONFIG_MTD_SPLIT_MINOR_FW=y
+CONFIG_MTD_SPLIT_SEAMA_FW=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_TRX_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_VIRT_CONCAT=y
+# CONFIG_MTK_HSDMA is not set
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NET_DEVLINK=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MT7530=y
+CONFIG_NET_DSA_TAG_MTK=y
+CONFIG_NET_FLOW_LIMIT=y
+CONFIG_NET_MEDIATEK_SOC=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_VENDOR_MEDIATEK=y
+# CONFIG_NET_VENDOR_RALINK is not set
+CONFIG_NR_CPUS=4
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PADATA=y
+CONFIG_PCI=y
+CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_DRIVERS_GENERIC=y
+CONFIG_PCI_MT7621=y
+CONFIG_PCI_MT7621_PHY=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+# CONFIG_PHY_RALINK_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PINCTRL_SX150X=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_QUEUED_RWLOCKS=y
+CONFIG_QUEUED_SPINLOCKS=y
+CONFIG_RALINK=y
+# CONFIG_RALINK_WDT is not set
+CONFIG_RATIONAL=y
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RFS_ACCEL=y
+CONFIG_RPS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_BQ32K=y
+# CONFIG_RTC_DRV_JZ4740 is not set
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_MC146818_LIB=y
+CONFIG_SCHED_SMT=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
+CONFIG_SMP=y
+CONFIG_SMP_UP=y
+# CONFIG_SOC_MT7620 is not set
+CONFIG_SOC_MT7621=y
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT7621=y
+# CONFIG_SPI_RT2880 is not set
+CONFIG_SRCU=y
+CONFIG_SWPHY=y
+CONFIG_SYNC_R4K=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HOTPLUG_CPU=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_SYS_SUPPORTS_MIPS_CPS=y
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
+CONFIG_SYS_SUPPORTS_SCHED_SMT=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TREE_RCU=y
+CONFIG_TREE_SRCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_WEAK_REORDERING_BEYOND_LLSC=y
+CONFIG_XPS=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/ramips/mt7621/target.mk b/target/linux/ramips/mt7621/target.mk
new file mode 100644
index 0000000..d1f987b
--- /dev/null
+++ b/target/linux/ramips/mt7621/target.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+SUBTARGET:=mt7621
+BOARDNAME:=MT7621 based boards
+FEATURES+=nand ramdisk rtc usb minor
+CPU_TYPE:=24kc
+KERNELNAME:=vmlinux vmlinuz
+# make Kernel/CopyImage use $LINUX_DIR/vmlinuz
+IMAGES_DIR:=../../..
+
+DEFAULT_PACKAGES += wpad-basic-wolfssl
+
+define Target/Description
+	Build firmware images for Ralink MT7621 based boards.
+endef
+
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..47b73e0
--- /dev/null
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
@@ -0,0 +1,151 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+alfa-network,awusfree1)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wlan" "wlan0"
+	;;
+asus,rt-n10p-v3|\
+asus,rt-n11p-b1|\
+asus,rt-n12-vp-b1|\
+netgear,r6020|\
+netgear,r6080|\
+netgear,r6120)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0xf"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+cudy,wr1000)
+	ucidef_set_led_switch "wan" "wan" "blue:wan" "switch0" "0x10"
+	ucidef_set_led_switch "lan1" "lan1" "blue:lan1" "switch0" "0x08"
+	ucidef_set_led_switch "lan2" "lan2" "blue:lan2" "switch0" "0x04"
+	;;
+elecom,wrc-1167fs)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x8"
+	ucidef_set_led_switch "internet" "internet" "green:internet" "switch0" "0x10"
+	;;
+glinet,gl-mt300n-v2)
+	ucidef_set_led_netdev "wifi_led" "wifi" "red:wlan" "wlan0"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x1"
+	;;
+hilink,hlk-7628n|\
+skylab,skw92a)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+hilink,hlk-7688a)
+	ucidef_set_led_wlan "wlan" "WLAN" "green:wlan" "phy0tpt"
+	;;
+hiwifi,hc5661a|\
+hiwifi,hc5761a)
+	ucidef_set_led_switch "internet" "internet" "blue:internet" "switch0" "0x10"
+	;;
+mediatek,linkit-smart-7688)
+	ucidef_set_led_wlan "wifi" "wifi" "orange:wifi" "phy0tpt"
+	;;
+rakwireless,rak633)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wifi" "wlan0"
+	;;
+tama,w06)
+	ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth0"
+	ucidef_set_led_wlan "wlan" "WLAN" "green:wlan" "phy0tpt"
+	;;
+tplink,archer-c20-v4|\
+tplink,archer-c20-v5|\
+tplink,tl-wr850n-v2)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	;;
+tplink,archer-c50-v3|\
+tplink,archer-c50-v4)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	ucidef_set_led_wlan "wlan2g" "wlan2g" "green:wlan2g" "phy0tpt"
+	ucidef_set_led_wlan "wlan5g" "wlan5g" "green:wlan5g" "phy1tpt"
+	;;
+tplink,re200-v2|\
+tplink,re200-v3|\
+tplink,re200-v4|\
+tplink,re220-v2|\
+tplink,tl-mr3020-v3|\
+tplink,tl-wa801nd-v5)
+	ucidef_set_led_netdev "lan" "lan" "green:lan" "eth0"
+	;;
+tplink,tl-mr3420-v5|\
+tplink,tl-wr840n-v4|\
+tplink,tl-wr842n-v5)
+	ucidef_set_led_wlan "wlan2g" "wlan2g" "green:wlan" "phy0tpt"
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	;;
+tplink,tl-mr6400-v4)
+	ucidef_set_led_switch "lan" "lan" "white:lan" "switch0" "0x0e"
+	ucidef_set_led_switch "wan" "wan" "white:wan" "switch0" "0x10"
+	;;
+tplink,tl-mr6400-v5)
+	ucidef_set_led_switch "lan" "lan" "white:lan" "switch0" "0x07"
+	ucidef_set_led_switch "wan" "wan" "white:wan" "switch0" "0x08"
+	;;
+tplink,tl-wr841n-v13)
+	ucidef_set_led_wlan "wlan2g" "wlan2g" "green:wlan" "phy0tpt"
+	ucidef_set_led_switch "lan1" "lan1" "green:lan1" "switch0" "0x2"
+	ucidef_set_led_switch "lan2" "lan2" "green:lan2" "switch0" "0x4"
+	ucidef_set_led_switch "lan3" "lan3" "green:lan3" "switch0" "0x8"
+	ucidef_set_led_switch "lan4" "lan4" "green:lan4" "switch0" "0x10"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	;;
+tplink,tl-wr841n-v14)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x1e"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	ucidef_set_led_wlan "wifi_led" "wifi" "green:wlan" "phy0tpt"
+	;;
+tplink,tl-wr902ac-v3)
+	ucidef_set_led_wlan "wlan2g" "wlan2g" "green:wlan" "phy0tpt"
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x10"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+unielec,u7628-01-16m)
+	ucidef_set_led_switch "lan1" "lan1" "green:lan1" "switch0" "0x2"
+	ucidef_set_led_switch "lan2" "lan2" "green:lan2" "switch0" "0x4"
+	ucidef_set_led_switch "lan3" "lan3" "green:lan3" "switch0" "0x8"
+	ucidef_set_led_switch "lan4" "lan4" "green:lan4" "switch0" "0x10"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+wavlink,wl-wn570ha1)
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+	ucidef_set_rssimon "wlan0" "200000" "1"
+	ucidef_set_led_rssi "wifi-low" "wifi-low" "green:wifi-low" "wlan0" "1" "49"
+	ucidef_set_led_rssi "wifi-med" "wifi-med" "green:wifi-med" "wlan0" "50" "84"
+	ucidef_set_led_rssi "wifi-high" "wifi-high" "green:wifi-high" "wlan0" "85" "100"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+wavlink,wl-wn575a3)
+	ucidef_set_rssimon "wlan1" "200000" "1"
+	ucidef_set_led_rssi "wifi-low" "wifi-low" "green:wifi-low" "wlan1" "1" "49"
+	ucidef_set_led_rssi "wifi-med" "wifi-med" "green:wifi-med" "wlan1" "50" "84"
+	ucidef_set_led_rssi "wifi-high" "wifi-high" "green:wifi-high" "wlan1" "85" "100"
+	;;
+wavlink,wl-wn577a2)
+	ucidef_set_led_switch "lan" "lan" "green:lan" "switch0" "0x8"
+	ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x10"
+	;;
+zbtlink,zbt-we1226)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	ucidef_set_led_switch "lan1" "LAN1" "green:lan1" "switch0" "0x01"
+	ucidef_set_led_switch "lan2" "LAN2" "green:lan2" "switch0" "0x02"
+	ucidef_set_led_switch "wan" "WAN" "green:wan" "switch0" "0x10"
+	;;
+zyxel,keenetic-extra-ii)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	ucidef_set_led_switch "internet" "internet" "green:internet" "switch0" "0x01"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..7fc69ac
--- /dev/null
+++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
@@ -0,0 +1,266 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	alfa-network,awusfree1|\
+	d-team,pbr-d1|\
+	glinet,microuter-n300|\
+	glinet,vixmini|\
+	hak5,wifi-pineapple-mk7|\
+	mediatek,linkit-smart-7688|\
+	minew,g1-c|\
+	onion,omega2p|\
+	onion,omega2|\
+	ravpower,rp-wd009|\
+	tama,w06|\
+	tplink,re200-v2|\
+	tplink,re200-v3|\
+	tplink,re200-v4|\
+	tplink,re220-v2|\
+	tplink,re305-v1|\
+	tplink,tl-wr802n-v4|\
+	tplink,tl-wa801nd-v5|\
+	widora,neo-16m|\
+	widora,neo-32m)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_set_interface_lan "eth0"
+		;;
+	tplink,tl-mr3020-v3)
+		ucidef_add_switch "switch0" \
+			"0:lan" "6@eth0"
+		;;
+	asus,rt-n10p-v3|\
+	asus,rt-n11p-b1|\
+	asus,rt-n12-vp-b1|\
+	hiwifi,hc5661a|\
+	mediatek,mt7628an-eval-board|\
+	mercury,mac1200r-v2|\
+	totolink,lr1200|\
+	wavlink,wl-wn570ha1|\
+	wavlink,wl-wn575a3)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
+		;;
+	buffalo,wcr-1166ds|\
+	elecom,wrc-1167fs|\
+	wavlink,wl-wn577a2)
+		ucidef_add_switch "switch0" \
+			"3:lan" "4:wan" "6@eth0"
+		;;
+	cudy,wr1000)
+		ucidef_add_switch "switch0" \
+			"2:lan:2" "3:lan:1" "4:wan" "6@eth0"
+		;;
+	duzun,dm06)
+		ucidef_add_switch "switch0" \
+			"1:lan" "0:wan" "6@eth0"
+		;;
+	glinet,gl-mt300n-v2)
+		ucidef_add_switch "switch0" \
+			"1:lan" "0:wan" "6@eth0"
+		;;
+	hilink,hlk-7628n|\
+	hilink,hlk-7688a|\
+	hiwifi,hc5861b|\
+	skylab,skw92a|\
+	tplink,archer-c20-v4|\
+	tplink,archer-c20-v5|\
+	tplink,archer-c50-v3|\
+	tplink,archer-c50-v4|\
+	tplink,tl-mr3420-v5|\
+	tplink,tl-wr840n-v4|\
+	tplink,tl-wr840n-v5|\
+	tplink,tl-wr841n-v13|\
+	tplink,tl-wr841n-v14|\
+	tplink,tl-wr842n-v5|\
+	tplink,tl-wr850n-v2|\
+	unielec,u7628-01-16m|\
+	wrtnode,wrtnode2p|\
+	wrtnode,wrtnode2r|\
+	zyxel,keenetic-extra-ii)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	hiwifi,hc5761a)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "4:wan" "6@eth0"
+		;;
+	iptime,a3|\
+	totolink,a3)
+		ucidef_add_switch "switch0" \
+			"2:lan:2" "3:lan:1" "0:wan" "6@eth0"
+		;;
+	iptime,a604m)
+		ucidef_add_switch "switch0" \
+			"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "0:wan" "6@eth0"
+		;;
+	jotale,js76x8-8m|\
+	jotale,js76x8-16m|\
+	jotale,js76x8-32m)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "6@eth0"
+		;;
+	netgear,r6020|\
+	netgear,r6080|\
+	netgear,r6120)
+		ucidef_add_switch "switch0" \
+			"0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4:wan" "6@eth0"
+		;;
+	rakwireless,rak633)
+		ucidef_add_switch "switch0" \
+			"0:wan" "1:lan" "2:lan" "3:lan" "4:lan" "6t@eth0"
+		;;
+	tplink,tl-mr6400-v4)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
+		;;
+	tplink,tl-mr6400-v5)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:wan" "6@eth0"
+		;;
+	tplink,tl-wr902ac-v3)
+		ucidef_add_switch "switch0" \
+			"4:lan" "6@eth0"
+		;;
+	vocore,vocore2|\
+	vocore,vocore2-lite)
+		ucidef_add_switch "switch0" \
+			"0:lan" "2:lan" "6t@eth0"
+		;;
+	wiznet,wizfi630s)
+		ucidef_add_switch "switch0" \
+			"0:wan" "3:lan" "4:lan" "6@eth0"
+		;;
+	xiaomi,mi-router-4a-100m)
+		ucidef_add_switch "switch0" \
+			"4:lan:1" "2:lan:2" "0:wan" "6@eth0"
+		;;
+	xiaomi,mi-router-4c)
+		ucidef_add_switch "switch0" \
+			"4:lan:1" "2:lan:2" "1:wan" "6@eth0"
+		;;
+	xiaomi,miwifi-nano)
+		ucidef_add_switch "switch0" \
+			"0:lan:2" "2:lan:1" "4:wan" "6@eth0"
+		;;
+	zbtlink,zbt-we1226)
+		ucidef_add_switch "switch0" \
+			"0:lan:2" "1:lan:1" "4:wan" "6@eth0"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	buffalo,wcr-1166ds)
+		local index="$(find_mtd_index "board_data")"
+		wan_mac="$(grep -m1 mac= "/dev/mtd${index}" | cut -d= -f2)"
+		lan_mac=$wan_mac
+		;;
+	cudy,wr1000|\
+	hilink,hlk-7628n|\
+	hilink,hlk-7688a|\
+	wavlink,wl-wn577a2)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	duzun,dm06|\
+	netgear,r6020|\
+	netgear,r6080|\
+	netgear,r6120|\
+	wrtnode,wrtnode2p|\
+	wrtnode,wrtnode2r|\
+	zyxel,keenetic-extra-ii)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1)
+		;;
+	elecom,wrc-1167fs)
+		wan_mac=$(mtd_get_mac_binary factory 0x22)
+		label_mac=$wan_mac
+		;;
+	hiwifi,hc5661a|\
+	hiwifi,hc5761a|\
+	hiwifi,hc5861b)
+		lan_mac=$(mtd_get_mac_ascii bdinfo "Vfac_mac ")
+		label_mac=$lan_mac
+		[ -n "$lan_mac" ] || lan_mac=$(cat /sys/class/net/eth0/address)
+		wan_mac=$(macaddr_add "$lan_mac" 1)
+		;;
+	iptime,a3|\
+	iptime,a604m|\
+	totolink,a3)
+		wan_mac=$(mtd_get_mac_binary u-boot 0x1fc40)
+		;;
+	jotale,js76x8-8m|\
+	jotale,js76x8-16m|\
+	jotale,js76x8-32m|\
+	skylab,skw92a|\
+	totolink,lr1200)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		;;
+	mercury,mac1200r-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory_info 0xd)" 1)
+		;;
+	rakwireless,rak633|\
+	unielec,u7628-01-16m|\
+	wavlink,wl-wn575a3)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x28)" 1)
+		;;
+	tplink,archer-c20-v4|\
+	tplink,archer-c50-v3|\
+	tplink,tl-mr3420-v5|\
+	tplink,tl-wr840n-v4|\
+	tplink,tl-wr840n-v5|\
+	tplink,tl-wr841n-v13|\
+	tplink,tl-wr841n-v14|\
+	tplink,tl-wr842n-v5|\
+	tplink,tl-wr850n-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0xf100)" 1)
+		;;
+	tplink,archer-c20-v5|\
+	tplink,archer-c50-v4)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary rom 0xf100)" 1)
+		;;
+	vocore,vocore2|\
+	vocore,vocore2-lite)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	wavlink,wl-wn570ha1|\
+	zbtlink,zbt-we1226)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x2e)" 1)
+		;;
+	wiznet,wizfi630s)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		wan_mac=$(mtd_get_mac_binary factory 0x28)
+		;;
+	xiaomi,mi-router-4a-100m|\
+	xiaomi,mi-router-4c)
+		wan_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/mt76x8/base-files/etc/init.d/bootcount b/target/linux/ramips/mt76x8/base-files/etc/init.d/bootcount
new file mode 100755
index 0000000..23f1e71
--- /dev/null
+++ b/target/linux/ramips/mt76x8/base-files/etc/init.d/bootcount
@@ -0,0 +1,16 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+boot() {
+	case $(board_name) in
+	alfa-network,awusfree1)
+		[ -n "$(fw_printenv bootcount bootchanged 2>/dev/null)" ] &&\
+			echo -e "bootcount\nbootchanged\n" | /usr/sbin/fw_setenv -s -
+		;;
+	xiaomi,mi-router-4c|\
+	xiaomi,miwifi-nano)
+		fw_setenv flag_boot_success 1
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt76x8/base-files/lib/upgrade/platform.sh b/target/linux/ramips/mt76x8/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..20adfaf
--- /dev/null
+++ b/target/linux/ramips/mt76x8/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+RAMFS_COPY_BIN='fw_printenv fw_setenv'
+RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	alfa-network,awusfree1)
+		[ "$(fw_printenv -n dual_image 2>/dev/null)" = "1" ] &&\
+		[ -n "$(find_mtd_part backup)" ] && {
+			PART_NAME=backup
+			if [ "$(fw_printenv -n bootactive 2>/dev/null)" = "1" ]; then
+				fw_setenv bootactive 2 || exit 1
+			else
+				fw_setenv bootactive 1 || exit 1
+			fi
+		}
+		default_do_upgrade "$1"
+		;;
+	tplink,archer-c20-v5|\
+	tplink,archer-c50-v4)
+		MTD_ARGS="-t romfile"
+		default_do_upgrade "$1"
+		;;
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/mt76x8/config-5.4 b/target/linux/ramips/mt76x8/config-5.4
new file mode 100644
index 0000000..0c53b6f
--- /dev/null
+++ b/target/linux/ramips/mt76x8/config-5.4
@@ -0,0 +1,244 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_AT803X_PHY=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_CEVT_R4K=y
+CONFIG_CEVT_SYSTICK_QUIRK=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKEVT_RT3352=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_MIPSR2_IRQ_VI=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DMA_RALINK is not set
+# CONFIG_DTB_MT7620A_EVAL is not set
+# CONFIG_DTB_OMEGA2P is not set
+CONFIG_DTB_RT_NONE=y
+# CONFIG_DTB_VOCORE2 is not set
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_GPIO_MT7621=y
+# CONFIG_GPIO_RALINK is not set
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PCI=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+CONFIG_MT7621_WDT=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_PARSER_TPLINK_SAFELOADER is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_TPLINK_FW=y
+CONFIG_MTD_SPLIT_TRX_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK_ESW_RT3050=y
+# CONFIG_NET_RALINK_MT7620 is not set
+CONFIG_NET_RALINK_RT3050=y
+CONFIG_NET_RALINK_SOC=y
+# CONFIG_NET_VENDOR_MEDIATEK is not set
+CONFIG_NET_VENDOR_RALINK=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+# CONFIG_PCI_MT7621 is not set
+# CONFIG_PCI_MT7621_PHY is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHY_RALINK_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+# CONFIG_PWM_MEDIATEK is not set
+CONFIG_RALINK=y
+# CONFIG_RALINK_WDT is not set
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SOC_MT7620=y
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+CONFIG_SPI_MT7621=y
+# CONFIG_SPI_RT2880 is not set
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWCONFIG_LEDS=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/ramips/mt76x8/target.mk b/target/linux/ramips/mt76x8/target.mk
new file mode 100644
index 0000000..f939e4c
--- /dev/null
+++ b/target/linux/ramips/mt76x8/target.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+SUBTARGET:=mt76x8
+BOARDNAME:=MT76x8 based boards
+FEATURES+=usb ramdisk
+CPU_TYPE:=24kc
+
+DEFAULT_PACKAGES += kmod-mt7603 wpad-basic-wolfssl swconfig
+
+define Target/Description
+	Build firmware images for Ralink MT76x8 based boards.
+endef
+
diff --git a/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch b/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch
new file mode 100644
index 0000000..eedc749
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0001-MIPS-cmdline-Clean-up-boot_command_line-initializati.patch
@@ -0,0 +1,192 @@
+From: Paul Burton <paul.burton@mips.com>
+Date: Wed, 9 Oct 2019 23:09:45 +0000
+Subject: MIPS: cmdline: Clean up boot_command_line initialization
+
+Our current code to initialize boot_command_line is a mess. Some of this
+is due to the addition of too many options over the years, and some of
+this is due to workarounds for early_init_dt_scan_chosen() performing
+actions specific to options from other architectures that probably
+shouldn't be in generic code.
+
+Clean this up by introducing a new bootcmdline_init() function that
+simplifies the initialization somewhat. The major changes are:
+
+- Because bootcmdline_init() is a function it can return early in the
+  CONFIG_CMDLINE_OVERRIDE case.
+
+- We clear boot_command_line rather than inheriting whatever
+  early_init_dt_scan_chosen() may have left us. This means we no longer
+  need to set boot_command_line to a space character in an attempt to
+  prevent early_init_dt_scan_chosen() from copying CONFIG_CMDLINE into
+  boot_command_line without us knowing about it.
+
+- Indirection via USE_PROM_CMDLINE, USE_DTB_CMDLINE, EXTEND_WITH_PROM &
+  BUILTIN_EXTEND_WITH_PROM macros is removed; they seemingly served only
+  to obfuscate the code.
+
+- The logic is cleaner, clearer & commented.
+
+Two minor drawbacks of this approach are:
+
+1) We call of_scan_flat_dt(), which means we scan through the DT again.
+   The overhead is fairly minimal & shouldn't be noticeable.
+
+2) cmdline_scan_chosen() duplicates a small amount of the logic from
+   early_init_dt_scan_chosen(). Alternatives might be to allow the
+   generic FDT code to keep & expose a copy of the arguments taken from
+   the /chosen node's bootargs property, or to introduce a function like
+   early_init_dt_scan_chosen() that retrieves them without modification
+   to handle CONFIG_CMDLINE. Neither of these sounds particularly
+   cleaner though, and this way we at least keep the extra work in
+   arch/mips.
+
+Origin: upstream, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7784cac697351f0cc0a4bb619594c0c99348c5aa
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Cc: linux-mips@vger.kernel.org
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -538,11 +538,88 @@ static void __init check_kernel_sections
+ 	}
+ }
+ 
+-#define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
+-#define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
+-#define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
+-#define BUILTIN_EXTEND_WITH_PROM	\
+-	IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND)
++static void __init bootcmdline_append(const char *s, size_t max)
++{
++	if (!s[0] || !max)
++		return;
++
++	if (boot_command_line[0])
++		strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
++
++	strlcat(boot_command_line, s, max);
++}
++
++static int __init bootcmdline_scan_chosen(unsigned long node, const char *uname,
++					  int depth, void *data)
++{
++	bool *dt_bootargs = data;
++	const char *p;
++	int l;
++
++	if (depth != 1 || !data ||
++	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
++		return 0;
++
++	p = of_get_flat_dt_prop(node, "bootargs", &l);
++	if (p != NULL && l > 0) {
++		bootcmdline_append(p, min(l, COMMAND_LINE_SIZE));
++		*dt_bootargs = true;
++	}
++
++	return 1;
++}
++
++static void __init bootcmdline_init(char **cmdline_p)
++{
++	bool dt_bootargs = false;
++
++	/*
++	 * If CMDLINE_OVERRIDE is enabled then initializing the command line is
++	 * trivial - we simply use the built-in command line unconditionally &
++	 * unmodified.
++	 */
++	if (IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
++		strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
++		return;
++	}
++
++	/*
++	 * If the user specified a built-in command line &
++	 * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
++	 * prepended to arguments from the bootloader or DT so we'll copy them
++	 * to the start of boot_command_line here. Otherwise, empty
++	 * boot_command_line to undo anything early_init_dt_scan_chosen() did.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
++		strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
++	else
++		boot_command_line[0] = 0;
++
++	/*
++	 * If we're configured to take boot arguments from DT, look for those
++	 * now.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB))
++		of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs);
++
++	/*
++	 * If we didn't get any arguments from DT (regardless of whether that's
++	 * because we weren't configured to look for them, or because we looked
++	 * & found none) then we'll take arguments from the bootloader.
++	 * plat_mem_setup() should have filled arcs_cmdline with arguments from
++	 * the bootloader.
++	 */
++	if (IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND) || !dt_bootargs)
++		bootcmdline_append(arcs_cmdline, COMMAND_LINE_SIZE);
++
++	/*
++	 * If the user specified a built-in command line & we didn't already
++	 * prepend it, we append it to boot_command_line here.
++	 */
++	if (IS_ENABLED(CONFIG_CMDLINE_BOOL) &&
++	    !IS_ENABLED(CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND))
++		bootcmdline_append(builtin_cmdline, COMMAND_LINE_SIZE);
++}
+ 
+ /*
+  * arch_mem_init - initialize memory management subsystem
+@@ -570,48 +647,12 @@ static void __init arch_mem_init(char **
+ {
+ 	extern void plat_mem_setup(void);
+ 
+-	/*
+-	 * Initialize boot_command_line to an innocuous but non-empty string in
+-	 * order to prevent early_init_dt_scan_chosen() from copying
+-	 * CONFIG_CMDLINE into it without our knowledge. We handle
+-	 * CONFIG_CMDLINE ourselves below & don't want to duplicate its
+-	 * content because repeating arguments can be problematic.
+-	 */
+-	strlcpy(boot_command_line, " ", COMMAND_LINE_SIZE);
+-
+ 	/* call board setup routine */
+ 	plat_mem_setup();
+ 	memblock_set_bottom_up(true);
+ 
+-#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
+-	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+-#else
+-	if ((USE_PROM_CMDLINE && arcs_cmdline[0]) ||
+-	    (USE_DTB_CMDLINE && !boot_command_line[0]))
+-		strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-
+-	if (EXTEND_WITH_PROM && arcs_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-	}
+-
+-#if defined(CONFIG_CMDLINE_BOOL)
+-	if (builtin_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+-	}
+-
+-	if (BUILTIN_EXTEND_WITH_PROM && arcs_cmdline[0]) {
+-		if (boot_command_line[0])
+-			strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
+-		strlcat(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+-	}
+-#endif
+-#endif
++	bootcmdline_init(cmdline_p);
+ 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+-
+ 	*cmdline_p = command_line;
+ 
+ 	parse_early_param();
diff --git a/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch b/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch
new file mode 100644
index 0000000..03124d0
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0002-MIPS-Always-define-builtin_cmdline.patch
@@ -0,0 +1,44 @@
+From b7340422cc16c5deff100812f38114bb5ec81203 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@mips.com>
+Date: Sat, 12 Oct 2019 20:43:36 +0000
+Subject: [PATCH] MIPS: Always define builtin_cmdline
+
+Commit 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line
+initialization") made use of builtin_cmdline conditional upon plain C if
+statements rather than preprocessor #ifdef's. This caused build failures
+for configurations with CONFIG_CMDLINE_BOOL=n where builtin_cmdline
+wasn't defined, for example:
+
+   arch/mips/kernel/setup.c: In function 'bootcmdline_init':
+>> arch/mips/kernel/setup.c:582:30: error: 'builtin_cmdline' undeclared
+    (first use in this function); did you mean 'builtin_driver'?
+      strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+                                 ^~~~~~~~~~~~~~~
+                                 builtin_driver
+   arch/mips/kernel/setup.c:582:30: note: each undeclared identifier is
+    reported only once for each function it appears in
+
+Fix this by defining builtin_cmdline as an empty string in the affected
+configurations. All of the paths that use it should be optimized out
+anyway so the data itself gets optimized away too.
+
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Fixes: 7784cac69735 ("MIPS: cmdline: Clean up boot_command_line initialization")
+Reported-by: kbuild test robot <lkp@intel.com>
+Reported-by: Nathan Chancellor <natechancellor@gmail.com>
+Cc: linux-mips@vger.kernel.org
+---
+ arch/mips/kernel/setup.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -68,6 +68,8 @@ char __initdata arcs_cmdline[COMMAND_LIN
+ 
+ #ifdef CONFIG_CMDLINE_BOOL
+ static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
++#else
++static const char builtin_cmdline[] __initconst = "";
+ #endif
+ 
+ /*
diff --git a/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch b/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch
new file mode 100644
index 0000000..63429f4
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0003-MIPS-Fix-memory-reservation-in-bootmem_init-for-cert.patch
@@ -0,0 +1,45 @@
+From: Tobias Wolf <dev-NTEO@vplace.de>
+Subject: [v2] MIPS: Fix memory reservation in bootmem_init for certain non-usermem setups
+
+Commit 67a3ba25aa95 ("MIPS: Fix incorrect mem=X@Y handling") introduced a new
+issue for rt288x where "PHYS_OFFSET" is 0x0 but the calculated "ramstart" is
+not. As the prerequisite of custom memory map has been removed, this results
+in the full memory range of 0x0 - 0x8000000 to be marked as reserved for this
+platform.
+
+v2: Correctly compare that usermem is not null.
+
+This patch adds the originally intended prerequisite again.
+
+Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
+---
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -287,6 +287,8 @@ static unsigned long __init init_initrd(
+  * Initialize the bootmem allocator. It also setup initrd related data
+  * if needed.
+  */
++static int usermem __initdata;
++
+ #if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA))
+ 
+ static void __init bootmem_init(void)
+@@ -325,7 +327,7 @@ static void __init bootmem_init(void)
+ 	/*
+ 	 * Reserve any memory between the start of RAM and PHYS_OFFSET
+ 	 */
+-	if (ramstart > PHYS_OFFSET)
++	if (usermem && ramstart > PHYS_OFFSET)
+ 		memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
+ 
+ 	if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
+@@ -386,8 +388,6 @@ static void __init bootmem_init(void)
+ 
+ #endif	/* CONFIG_SGI_IP27 */
+ 
+-static int usermem __initdata;
+-
+ static int __init early_parse_mem(char *p)
+ {
+ 	phys_addr_t start, size;
diff --git a/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch b/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
new file mode 100644
index 0000000..773c74f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0005-MIPS-use-set_mode-to-enable-disable-the-cevt-r4k-irq.patch
@@ -0,0 +1,82 @@
+From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 14 Jul 2013 23:08:11 +0200
+Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k
+ irq
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/Kconfig |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -1,12 +1,17 @@
+ # SPDX-License-Identifier: GPL-2.0
+ if RALINK
+ 
++config CEVT_SYSTICK_QUIRK
++	bool
++	default n
++
+ config CLKEVT_RT3352
+ 	bool
+ 	depends on SOC_RT305X || SOC_MT7620
+ 	default y
+ 	select TIMER_OF
+ 	select CLKSRC_MMIO
++	select CEVT_SYSTICK_QUIRK
+ 
+ config RALINK_ILL_ACC
+ 	bool
+--- a/arch/mips/kernel/cevt-r4k.c
++++ b/arch/mips/kernel/cevt-r4k.c
+@@ -15,6 +15,26 @@
+ #include <asm/time.h>
+ #include <asm/cevt-r4k.h>
+ 
++static int mips_state_oneshot(struct clock_event_device *evt)
++{
++	if (!cp0_timer_irq_installed) {
++		cp0_timer_irq_installed = 1;
++		setup_irq(evt->irq, &c0_compare_irqaction);
++	}
++
++	return 0;
++}
++
++static int mips_state_shutdown(struct clock_event_device *evt)
++{
++	if (cp0_timer_irq_installed) {
++		cp0_timer_irq_installed = 0;
++		remove_irq(evt->irq, &c0_compare_irqaction);
++	}
++
++	return 0;
++}
++
+ static int mips_next_event(unsigned long delta,
+ 			   struct clock_event_device *evt)
+ {
+@@ -281,17 +301,21 @@ int r4k_clockevent_init(void)
+ 	cd->rating		= 300;
+ 	cd->irq			= irq;
+ 	cd->cpumask		= cpumask_of(cpu);
++	cd->set_state_shutdown	= mips_state_shutdown;
++	cd->set_state_oneshot	= mips_state_oneshot;
+ 	cd->set_next_event	= mips_next_event;
+ 	cd->event_handler	= mips_event_handler;
+ 
+ 	clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff);
+ 
++#ifndef CONFIG_CEVT_SYSTICK_QUIRK
+ 	if (cp0_timer_irq_installed)
+ 		return 0;
+ 
+ 	cp0_timer_irq_installed = 1;
+ 
+ 	setup_irq(irq, &c0_compare_irqaction);
++#endif
+ 
+ 	return 0;
+ }
diff --git a/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch b/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch
new file mode 100644
index 0000000..a3b8e4d
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0006-MIPS-ralink-add-cpu-frequency-scaling.patch
@@ -0,0 +1,200 @@
+From bd30f19a006fb52bac80c6463c49dd2f4159f4ac Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 28 Jul 2013 16:26:41 +0200
+Subject: [PATCH 06/53] MIPS: ralink: add cpu frequency scaling
+
+This feature will break udelay() and cause the delay loop to have longer delays
+when the frequency is scaled causing a performance hit.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/cevt-rt3352.c |   38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+--- a/arch/mips/ralink/cevt-rt3352.c
++++ b/arch/mips/ralink/cevt-rt3352.c
+@@ -29,6 +29,10 @@
+ /* enable the counter */
+ #define CFG_CNT_EN		0x1
+ 
++/* mt7620 frequency scaling defines */
++#define CLK_LUT_CFG	0x40
++#define SLEEP_EN	BIT(31)
++
+ struct systick_device {
+ 	void __iomem *membase;
+ 	struct clock_event_device dev;
+@@ -36,21 +40,53 @@ struct systick_device {
+ 	int freq_scale;
+ };
+ 
++static void (*systick_freq_scaling)(struct systick_device *sdev, int status);
++
+ static int systick_set_oneshot(struct clock_event_device *evt);
+ static int systick_shutdown(struct clock_event_device *evt);
+ 
++static inline void mt7620_freq_scaling(struct systick_device *sdev, int status)
++{
++	if (sdev->freq_scale == status)
++		return;
++
++	sdev->freq_scale = status;
++
++	pr_info("%s: %s autosleep mode\n", sdev->dev.name,
++			(status) ? ("enable") : ("disable"));
++	if (status)
++		rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) | SLEEP_EN, CLK_LUT_CFG);
++	else
++		rt_sysc_w32(rt_sysc_r32(CLK_LUT_CFG) & ~SLEEP_EN, CLK_LUT_CFG);
++}
++
++static inline unsigned int read_count(struct systick_device *sdev)
++{
++	return ioread32(sdev->membase + SYSTICK_COUNT);
++}
++
++static inline unsigned int read_compare(struct systick_device *sdev)
++{
++	return ioread32(sdev->membase + SYSTICK_COMPARE);
++}
++
++static inline void write_compare(struct systick_device *sdev, unsigned int val)
++{
++	iowrite32(val, sdev->membase + SYSTICK_COMPARE);
++}
++
+ static int systick_next_event(unsigned long delta,
+ 				struct clock_event_device *evt)
+ {
+ 	struct systick_device *sdev;
+-	u32 count;
++	int res;
+ 
+ 	sdev = container_of(evt, struct systick_device, dev);
+-	count = ioread32(sdev->membase + SYSTICK_COUNT);
+-	count = (count + delta) % SYSTICK_FREQ;
+-	iowrite32(count, sdev->membase + SYSTICK_COMPARE);
++	delta += read_count(sdev);
++	write_compare(sdev, delta);
++	res = ((int)(read_count(sdev) - delta) >= 0) ? -ETIME : 0;
+ 
+-	return 0;
++	return res;
+ }
+ 
+ static void systick_event_handler(struct clock_event_device *dev)
+@@ -60,20 +96,25 @@ static void systick_event_handler(struct
+ 
+ static irqreturn_t systick_interrupt(int irq, void *dev_id)
+ {
+-	struct clock_event_device *dev = (struct clock_event_device *) dev_id;
++	int ret = 0;
++	struct clock_event_device *cdev;
++	struct systick_device *sdev;
+ 
+-	dev->event_handler(dev);
++	if (read_c0_cause() & STATUSF_IP7) {
++		cdev = (struct clock_event_device *) dev_id;
++		sdev = container_of(cdev, struct systick_device, dev);
++
++		/* Clear Count/Compare Interrupt */
++		write_compare(sdev, read_compare(sdev));
++		cdev->event_handler(cdev);
++		ret = 1;
++	}
+ 
+-	return IRQ_HANDLED;
++	return IRQ_RETVAL(ret);
+ }
+ 
+ static struct systick_device systick = {
+ 	.dev = {
+-		/*
+-		 * cevt-r4k uses 300, make sure systick
+-		 * gets used if available
+-		 */
+-		.rating			= 310,
+ 		.features		= CLOCK_EVT_FEAT_ONESHOT,
+ 		.set_next_event		= systick_next_event,
+ 		.set_state_shutdown	= systick_shutdown,
+@@ -95,9 +136,15 @@ static int systick_shutdown(struct clock
+ 	sdev = container_of(evt, struct systick_device, dev);
+ 
+ 	if (sdev->irq_requested)
+-		free_irq(systick.dev.irq, &systick_irqaction);
++		remove_irq(systick.dev.irq, &systick_irqaction);
+ 	sdev->irq_requested = 0;
+-	iowrite32(0, systick.membase + SYSTICK_CONFIG);
++	iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
++
++	if (systick_freq_scaling)
++		systick_freq_scaling(sdev, 0);
++
++	if (systick_freq_scaling)
++		systick_freq_scaling(sdev, 1);
+ 
+ 	return 0;
+ }
+@@ -117,34 +164,48 @@ static int systick_set_oneshot(struct cl
+ 	return 0;
+ }
+ 
++static const struct of_device_id systick_match[] = {
++	{ .compatible = "ralink,mt7620a-systick", .data = mt7620_freq_scaling},
++	{},
++};
++
+ static int __init ralink_systick_init(struct device_node *np)
+ {
++	const struct of_device_id *match;
++	int rating = 200;
+ 	int ret;
+ 
+ 	systick.membase = of_iomap(np, 0);
+ 	if (!systick.membase)
+ 		return -ENXIO;
+ 
+-	systick_irqaction.name = np->name;
+-	systick.dev.name = np->name;
+-	clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
+-	systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
+-	systick.dev.max_delta_ticks = 0x7fff;
+-	systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
+-	systick.dev.min_delta_ticks = 0x3;
++	match = of_match_node(systick_match, np);
++	if (match) {
++		systick_freq_scaling = match->data;
++		/*
++		 * cevt-r4k uses 300, make sure systick
++		 * gets used if available
++		 */
++		rating = 310;
++	}
++
++	/* enable counter than register clock source */
++	iowrite32(CFG_CNT_EN, systick.membase + SYSTICK_CONFIG);
++	clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
++			SYSTICK_FREQ, rating, 16, clocksource_mmio_readl_up);
++
++	/* register clock event */
+ 	systick.dev.irq = irq_of_parse_and_map(np, 0);
+ 	if (!systick.dev.irq) {
+ 		pr_err("%pOFn: request_irq failed", np);
+ 		return -EINVAL;
+ 	}
+ 
+-	ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
+-				    SYSTICK_FREQ, 301, 16,
+-				    clocksource_mmio_readl_up);
+-	if (ret)
+-		return ret;
+-
+-	clockevents_register_device(&systick.dev);
++	systick_irqaction.name = np->name;
++	systick.dev.name = np->name;
++	systick.dev.rating = rating;
++	systick.dev.cpumask = cpumask_of(0);
++	clockevents_config_and_register(&systick.dev, SYSTICK_FREQ, 0x3, 0x7fff);
+ 
+ 	pr_info("%pOFn: running - mult: %d, shift: %d\n",
+ 			np, systick.dev.mult, systick.dev.shift);
diff --git a/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch b/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch
new file mode 100644
index 0000000..c05ee80
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0007-MIPS-ralink-copy-the-commandline-from-the-devicetree.patch
@@ -0,0 +1,21 @@
+From 67b7bff0fd364c194e653f69baa623ba2141bd4c Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 4 Aug 2014 18:46:02 +0200
+Subject: [PATCH 07/53] MIPS: ralink: copy the commandline from the devicetree
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/of.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -82,6 +82,8 @@ void __init plat_mem_setup(void)
+ 
+ 	__dt_setup_arch(dtb);
+ 
++	strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
++
+ 	of_scan_flat_dt(early_init_dt_find_memory, NULL);
+ 	if (memory_dtb)
+ 		of_scan_flat_dt(early_init_dt_scan_memory, NULL);
diff --git a/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch b/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch
new file mode 100644
index 0000000..c19a0fb
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0010-MIPS-add-bootargs-override-property.patch
@@ -0,0 +1,63 @@
+From f15d27f9c90ede4b16eb37f9ae573ef81c2b6996 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail@david-bauer.net>
+Date: Thu, 31 Dec 2020 18:49:12 +0100
+Subject: [PATCH] MIPS: add bootargs-override property
+
+Add support for the bootargs-override property to the chosen node
+similar to the one used on ipq806x or mpc85xx.
+
+This is necessary, as the U-Boot used on some boards, notably the
+Ubiquiti UniFi 6 Lite, overwrite the bootargs property of the chosen
+node leading to a kernel panic when loading OpenWrt.
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+ arch/mips/kernel/setup.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -571,8 +571,28 @@ static int __init bootcmdline_scan_chose
+ 	return 1;
+ }
+ 
++static int __init bootcmdline_scan_chosen_override(unsigned long node, const char *uname,
++						   int depth, void *data)
++{
++	bool *dt_bootargs = data;
++	const char *p;
++	int l;
++
++	if (depth != 1 || !data || strcmp(uname, "chosen") != 0)
++		return 0;
++
++	p = of_get_flat_dt_prop(node, "bootargs-override", &l);
++	if (p != NULL && l > 0) {
++		strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
++		*dt_bootargs = true;
++	}
++
++	return 1;
++}
++
+ static void __init bootcmdline_init(char **cmdline_p)
+ {
++	bool dt_bootargs_override = false;
+ 	bool dt_bootargs = false;
+ 
+ 	/*
+@@ -586,6 +606,14 @@ static void __init bootcmdline_init(char
+ 	}
+ 
+ 	/*
++	 * If bootargs-override in the chosen node is set, use this as the
++	 * command line
++	 */
++	of_scan_flat_dt(bootcmdline_scan_chosen_override, &dt_bootargs_override);
++	if (dt_bootargs_override)
++		return;
++
++	/*
+ 	 * If the user specified a built-in command line &
+ 	 * MIPS_CMDLINE_BUILTIN_EXTEND, then the built-in command line is
+ 	 * prepended to arguments from the bootloader or DT so we'll copy them
diff --git a/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch b/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch
new file mode 100644
index 0000000..bedea14
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0013-owrt-hack-fix-mt7688-cache-issue.patch
@@ -0,0 +1,29 @@
+From 5ede027f6c4a57ed25da872420508b7f1168b36b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 7 Dec 2015 17:15:32 +0100
+Subject: [PATCH 13/53] owrt: hack: fix mt7688 cache issue
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/kernel/setup.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -723,8 +723,6 @@ static void __init arch_mem_init(char **
+ 		memblock_reserve(crashk_res.start,
+ 				 crashk_res.end - crashk_res.start + 1);
+ #endif
+-	device_tree_init();
+-
+ 	/*
+ 	 * In order to reduce the possibility of kernel panic when failed to
+ 	 * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate
+@@ -841,6 +839,7 @@ void __init setup_arch(char **cmdline_p)
+ 
+ 	cpu_cache_init();
+ 	paging_init();
++	device_tree_init();
+ }
+ 
+ unsigned long kernelsp[NR_CPUS];
diff --git a/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch b/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch
new file mode 100644
index 0000000..1dc54cc
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0015-arch-mips-do-not-select-illegal-access-driver-by-def.patch
@@ -0,0 +1,25 @@
+From 9e6ce539092a1dd605a20bf73c655a9de58d8641 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 7 Dec 2015 17:18:05 +0100
+Subject: [PATCH 15/53] arch: mips: do not select illegal access driver by
+ default
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/Kconfig |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -14,9 +14,9 @@ config CLKEVT_RT3352
+ 	select CEVT_SYSTICK_QUIRK
+ 
+ config RALINK_ILL_ACC
+-	bool
++	bool "illegal access irq"
+ 	depends on SOC_RT305X
+-	default y
++	default n
+ 
+ config IRQ_INTC
+ 	bool
diff --git a/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch b/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch
new file mode 100644
index 0000000..a7f1a48
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0024-GPIO-add-named-gpio-exports.patch
@@ -0,0 +1,165 @@
+From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Tue, 12 Aug 2014 20:49:27 +0200
+Subject: [PATCH 24/53] GPIO: add named gpio exports
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/gpio/gpiolib-of.c     |   68 +++++++++++++++++++++++++++++++++++++++++
+ drivers/gpio/gpiolib-sysfs.c  |   10 +++++-
+ include/asm-generic/gpio.h    |    6 ++++
+ include/linux/gpio/consumer.h |    8 +++++
+ 4 files changed, 91 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -19,6 +19,8 @@
+ #include <linux/pinctrl/pinctrl.h>
+ #include <linux/slab.h>
+ #include <linux/gpio/machine.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
+ 
+ #include "gpiolib.h"
+ #include "gpiolib-of.h"
+@@ -917,3 +919,68 @@ void of_gpiochip_remove(struct gpio_chip
+ {
+ 	of_node_put(chip->of_node);
+ }
++
++static struct of_device_id gpio_export_ids[] = {
++	{ .compatible = "gpio-export" },
++	{ /* sentinel */ }
++};
++
++static int of_gpio_export_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct device_node *cnp;
++	u32 val;
++	int nb = 0;
++
++	for_each_child_of_node(np, cnp) {
++		const char *name = NULL;
++		int gpio;
++		bool dmc;
++		int max_gpio = 1;
++		int i;
++
++		of_property_read_string(cnp, "gpio-export,name", &name);
++
++		if (!name)
++			max_gpio = of_gpio_count(cnp);
++
++		for (i = 0; i < max_gpio; i++) {
++			unsigned flags = 0;
++			enum of_gpio_flags of_flags;
++
++			gpio = of_get_gpio_flags(cnp, i, &of_flags);
++			if (!gpio_is_valid(gpio))
++				return gpio;
++
++			if (of_flags == OF_GPIO_ACTIVE_LOW)
++				flags |= GPIOF_ACTIVE_LOW;
++
++			if (!of_property_read_u32(cnp, "gpio-export,output", &val))
++				flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++			else
++				flags |= GPIOF_IN;
++
++			if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
++				continue;
++
++			dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
++			gpio_export_with_name(gpio, dmc, name);
++			nb++;
++		}
++	}
++
++	dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
++
++	return 0;
++}
++
++static struct platform_driver gpio_export_driver = {
++	.driver		= {
++		.name		= "gpio-export",
++		.owner	= THIS_MODULE,
++		.of_match_table	= of_match_ptr(gpio_export_ids),
++	},
++	.probe		= of_gpio_export_probe,
++};
++
++module_platform_driver(gpio_export_driver);
+--- a/drivers/gpio/gpiolib-sysfs.c
++++ b/drivers/gpio/gpiolib-sysfs.c
+@@ -571,7 +571,7 @@ static struct class gpio_class = {
+  *
+  * Returns zero on success, else an error.
+  */
+-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
++int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
+ {
+ 	struct gpio_chip	*chip;
+ 	struct gpio_device	*gdev;
+@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc,
+ 	offset = gpio_chip_hwgpio(desc);
+ 	if (chip->names && chip->names[offset])
+ 		ioname = chip->names[offset];
++	if (name)
++		ioname = name;
+ 
+ 	dev = device_create_with_groups(&gpio_class, &gdev->dev,
+ 					MKDEV(0, 0), data, gpio_groups,
+@@ -654,6 +656,12 @@ err_unlock:
+ 	gpiod_dbg(desc, "%s: status %d\n", __func__, status);
+ 	return status;
+ }
++EXPORT_SYMBOL_GPL(__gpiod_export);
++
++int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
++{
++	return __gpiod_export(desc, direction_may_change, NULL);
++}
+ EXPORT_SYMBOL_GPL(gpiod_export);
+ 
+ static int match_export(struct device *dev, const void *desc)
+--- a/include/asm-generic/gpio.h
++++ b/include/asm-generic/gpio.h
+@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
+ 	return gpiod_export(gpio_to_desc(gpio), direction_may_change);
+ }
+ 
++int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
++static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
++{
++	return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
++}
++
+ static inline int gpio_export_link(struct device *dev, const char *name,
+ 				   unsigned gpio)
+ {
+--- a/include/linux/gpio/consumer.h
++++ b/include/linux/gpio/consumer.h
+@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
+ 
+ #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
+ 
++int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
+ int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
+ int gpiod_export_link(struct device *dev, const char *name,
+ 		      struct gpio_desc *desc);
+@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
+ 
+ #else  /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
+ 
++static inline int _gpiod_export(struct gpio_desc *desc,
++			       bool direction_may_change,
++			       const char *name)
++{
++	return -ENOSYS;
++}
++
+ static inline int gpiod_export(struct gpio_desc *desc,
+ 			       bool direction_may_change)
+ {
diff --git a/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch b/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch
new file mode 100644
index 0000000..7d5f98f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0026-DT-Add-documentation-for-gpio-ralink.patch
@@ -0,0 +1,59 @@
+From d410e5478c622c01fcf31427533df5f433df9146 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 28 Jul 2013 19:45:30 +0200
+Subject: [PATCH 26/53] DT: Add documentation for gpio-ralink
+
+Describe gpio-ralink binding.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+Cc: devicetree@vger.kernel.org
+Cc: linux-gpio@vger.kernel.org
+---
+ .../devicetree/bindings/gpio/gpio-ralink.txt       |   40 ++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/gpio/gpio-ralink.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
+@@ -0,0 +1,40 @@
++Ralink SoC GPIO controller bindings
++
++Required properties:
++- compatible:
++  - "ralink,rt2880-gpio" for Ralink controllers
++- #gpio-cells : Should be two.
++  - first cell is the pin number
++  - second cell is used to specify optional parameters (unused)
++- gpio-controller : Marks the device node as a GPIO controller
++- reg : Physical base address and length of the controller's registers
++- interrupt-parent: phandle to the INTC device node
++- interrupts : Specify the INTC interrupt number
++- ralink,num-gpios : Specify the number of GPIOs
++- ralink,register-map : The register layout depends on the GPIO bank and actual
++		SoC type. Register offsets need to be in this order.
++		[ INT, EDGE, RENA, FENA, DATA, DIR, POL, SET, RESET, TOGGLE ]
++
++Optional properties:
++- ralink,gpio-base : Specify the GPIO chips base number
++
++Example:
++
++	gpio0: gpio@600 {
++		compatible = "ralink,rt5350-gpio", "ralink,rt2880-gpio";
++
++		#gpio-cells = <2>;
++		gpio-controller;
++
++		reg = <0x600 0x34>;
++
++		interrupt-parent = <&intc>;
++		interrupts = <6>;
++
++		ralink,gpio-base = <0>;
++		ralink,num-gpios = <24>;
++		ralink,register-map = [ 00 04 08 0c
++				20 24 28 2c
++				30 34 ];
++
++	};
diff --git a/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch b/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch
new file mode 100644
index 0000000..eae507b
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0027-GPIO-MIPS-ralink-add-gpio-driver-for-ralink-SoC.patch
@@ -0,0 +1,416 @@
+From 69fdd2c4f937796b934e89c33acde9d082e27bfd Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 4 Aug 2014 20:36:29 +0200
+Subject: [PATCH 27/53] GPIO: MIPS: ralink: add gpio driver for ralink SoC
+
+Add gpio driver for Ralink SoC. This driver makes the gpio core on
+RT2880, RT305x, rt3352, rt3662, rt3883, rt5350 and mt7620 work.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+Cc: linux-mips@linux-mips.org
+Cc: linux-gpio@vger.kernel.org
+---
+ arch/mips/include/asm/mach-ralink/gpio.h |   24 ++
+ drivers/gpio/Kconfig                     |    6 +
+ drivers/gpio/Makefile                    |    1 +
+ drivers/gpio/gpio-ralink.c               |  355 ++++++++++++++++++++++++++++++
+ 4 files changed, 386 insertions(+)
+ create mode 100644 arch/mips/include/asm/mach-ralink/gpio.h
+ create mode 100644 drivers/gpio/gpio-ralink.c
+
+--- /dev/null
++++ b/arch/mips/include/asm/mach-ralink/gpio.h
+@@ -0,0 +1,24 @@
++/*
++ *  Ralink SoC GPIO API support
++ *
++ *  Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
++ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
++ *
++ *  This program is free software; you can redistribute it and/or modify it
++ *  under the terms of the GNU General Public License version 2 as published
++ *  by the Free Software Foundation.
++ *
++ */
++
++#ifndef __ASM_MACH_RALINK_GPIO_H
++#define __ASM_MACH_RALINK_GPIO_H
++
++#define ARCH_NR_GPIOS	128
++#include <asm-generic/gpio.h>
++
++#define gpio_get_value	__gpio_get_value
++#define gpio_set_value	__gpio_set_value
++#define gpio_cansleep	__gpio_cansleep
++#define gpio_to_irq	__gpio_to_irq
++
++#endif /* __ASM_MACH_RALINK_GPIO_H */
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -471,6 +471,12 @@ config GPIO_SNPS_CREG
+ 	  where only several fields in register belong to GPIO lines and
+ 	  each GPIO line owns a field with different length and on/off value.
+ 
++config GPIO_RALINK
++	bool "Ralink GPIO Support"
++	depends on RALINK
++	help
++	  Say yes here to support the Ralink SoC GPIO device
++
+ config GPIO_SPEAR_SPICS
+ 	bool "ST SPEAr13xx SPI Chip Select as GPIO support"
+ 	depends on PLAT_SPEAR
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -112,6 +112,7 @@ obj-$(CONFIG_GPIO_PISOSR)		+= gpio-pisos
+ obj-$(CONFIG_GPIO_PL061)		+= gpio-pl061.o
+ obj-$(CONFIG_GPIO_PMIC_EIC_SPRD)	+= gpio-pmic-eic-sprd.o
+ obj-$(CONFIG_GPIO_PXA)			+= gpio-pxa.o
++obj-$(CONFIG_GPIO_RALINK)		+= gpio-ralink.o
+ obj-$(CONFIG_GPIO_RASPBERRYPI_EXP)	+= gpio-raspberrypi-exp.o
+ obj-$(CONFIG_GPIO_RC5T583)		+= gpio-rc5t583.o
+ obj-$(CONFIG_GPIO_RCAR)			+= gpio-rcar.o
+--- /dev/null
++++ b/drivers/gpio/gpio-ralink.c
+@@ -0,0 +1,341 @@
++/*
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 as published
++ * by the Free Software Foundation.
++ *
++ * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
++ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/gpio.h>
++#include <linux/spinlock.h>
++#include <linux/platform_device.h>
++#include <linux/of_irq.h>
++#include <linux/irqdomain.h>
++#include <linux/interrupt.h>
++
++enum ralink_gpio_reg {
++	GPIO_REG_INT = 0,
++	GPIO_REG_EDGE,
++	GPIO_REG_RENA,
++	GPIO_REG_FENA,
++	GPIO_REG_DATA,
++	GPIO_REG_DIR,
++	GPIO_REG_POL,
++	GPIO_REG_SET,
++	GPIO_REG_RESET,
++	GPIO_REG_TOGGLE,
++	GPIO_REG_MAX
++};
++
++struct ralink_gpio_chip {
++	struct gpio_chip chip;
++	u8 regs[GPIO_REG_MAX];
++
++	spinlock_t lock;
++	void __iomem *membase;
++	struct irq_domain *domain;
++	int irq;
++
++	u32 rising;
++	u32 falling;
++};
++
++#define MAP_MAX	4
++static struct irq_domain *irq_map[MAP_MAX];
++static int irq_map_count;
++static atomic_t irq_refcount = ATOMIC_INIT(0);
++
++static inline struct ralink_gpio_chip *to_ralink_gpio(struct gpio_chip *chip)
++{
++	struct ralink_gpio_chip *rg;
++
++	rg = container_of(chip, struct ralink_gpio_chip, chip);
++
++	return rg;
++}
++
++static inline void rt_gpio_w32(struct ralink_gpio_chip *rg, u8 reg, u32 val)
++{
++	iowrite32(val, rg->membase + rg->regs[reg]);
++}
++
++static inline u32 rt_gpio_r32(struct ralink_gpio_chip *rg, u8 reg)
++{
++	return ioread32(rg->membase + rg->regs[reg]);
++}
++
++static void ralink_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
++{
++	struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
++
++	rt_gpio_w32(rg, (value) ? GPIO_REG_SET : GPIO_REG_RESET, BIT(offset));
++}
++
++static int ralink_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++	struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
++
++	return !!(rt_gpio_r32(rg, GPIO_REG_DATA) & BIT(offset));
++}
++
++static int ralink_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++	struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
++	unsigned long flags;
++	u32 t;
++
++	spin_lock_irqsave(&rg->lock, flags);
++	t = rt_gpio_r32(rg, GPIO_REG_DIR);
++	t &= ~BIT(offset);
++	rt_gpio_w32(rg, GPIO_REG_DIR, t);
++	spin_unlock_irqrestore(&rg->lock, flags);
++
++	return 0;
++}
++
++static int ralink_gpio_direction_output(struct gpio_chip *chip,
++					unsigned offset, int value)
++{
++	struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
++	unsigned long flags;
++	u32 t;
++
++	spin_lock_irqsave(&rg->lock, flags);
++	ralink_gpio_set(chip, offset, value);
++	t = rt_gpio_r32(rg, GPIO_REG_DIR);
++	t |= BIT(offset);
++	rt_gpio_w32(rg, GPIO_REG_DIR, t);
++	spin_unlock_irqrestore(&rg->lock, flags);
++
++	return 0;
++}
++
++static int ralink_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
++{
++	struct ralink_gpio_chip *rg = to_ralink_gpio(chip);
++
++	if (rg->irq < 1)
++		return -1;
++
++	return irq_create_mapping(rg->domain, pin);
++}
++
++static void ralink_gpio_irq_handler(struct irq_desc *desc)
++{
++	int i;
++
++	for (i = 0; i < irq_map_count; i++) {
++		struct irq_domain *domain = irq_map[i];
++		struct ralink_gpio_chip *rg;
++		unsigned long pending;
++		int bit;
++
++		rg = (struct ralink_gpio_chip *) domain->host_data;
++		pending = rt_gpio_r32(rg, GPIO_REG_INT);
++
++		for_each_set_bit(bit, &pending, rg->chip.ngpio) {
++			u32 map = irq_find_mapping(domain, bit);
++			generic_handle_irq(map);
++			rt_gpio_w32(rg, GPIO_REG_INT, BIT(bit));
++		}
++	}
++}
++
++static void ralink_gpio_irq_unmask(struct irq_data *d)
++{
++	struct ralink_gpio_chip *rg;
++	unsigned long flags;
++	u32 rise, fall;
++
++	rg = (struct ralink_gpio_chip *) d->domain->host_data;
++	rise = rt_gpio_r32(rg, GPIO_REG_RENA);
++	fall = rt_gpio_r32(rg, GPIO_REG_FENA);
++
++	spin_lock_irqsave(&rg->lock, flags);
++	rt_gpio_w32(rg, GPIO_REG_RENA, rise | (BIT(d->hwirq) & rg->rising));
++	rt_gpio_w32(rg, GPIO_REG_FENA, fall | (BIT(d->hwirq) & rg->falling));
++	spin_unlock_irqrestore(&rg->lock, flags);
++}
++
++static void ralink_gpio_irq_mask(struct irq_data *d)
++{
++	struct ralink_gpio_chip *rg;
++	unsigned long flags;
++	u32 rise, fall;
++
++	rg = (struct ralink_gpio_chip *) d->domain->host_data;
++	rise = rt_gpio_r32(rg, GPIO_REG_RENA);
++	fall = rt_gpio_r32(rg, GPIO_REG_FENA);
++
++	spin_lock_irqsave(&rg->lock, flags);
++	rt_gpio_w32(rg, GPIO_REG_FENA, fall & ~BIT(d->hwirq));
++	rt_gpio_w32(rg, GPIO_REG_RENA, rise & ~BIT(d->hwirq));
++	spin_unlock_irqrestore(&rg->lock, flags);
++}
++
++static int ralink_gpio_irq_type(struct irq_data *d, unsigned int type)
++{
++	struct ralink_gpio_chip *rg;
++	u32 mask = BIT(d->hwirq);
++
++	rg = (struct ralink_gpio_chip *) d->domain->host_data;
++
++	if (type == IRQ_TYPE_PROBE) {
++		if ((rg->rising | rg->falling) & mask)
++			return 0;
++
++		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
++	}
++
++	if (type & IRQ_TYPE_EDGE_RISING)
++		rg->rising |= mask;
++	else
++		rg->rising &= ~mask;
++
++	if (type & IRQ_TYPE_EDGE_FALLING)
++		rg->falling |= mask;
++	else
++		rg->falling &= ~mask;
++
++	return 0;
++}
++
++static struct irq_chip ralink_gpio_irq_chip = {
++	.name		= "GPIO",
++	.irq_unmask	= ralink_gpio_irq_unmask,
++	.irq_mask	= ralink_gpio_irq_mask,
++	.irq_mask_ack	= ralink_gpio_irq_mask,
++	.irq_set_type	= ralink_gpio_irq_type,
++};
++
++static int gpio_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
++{
++	irq_set_chip_and_handler(irq, &ralink_gpio_irq_chip, handle_level_irq);
++	irq_set_handler_data(irq, d);
++
++	return 0;
++}
++
++static const struct irq_domain_ops irq_domain_ops = {
++	.xlate = irq_domain_xlate_onecell,
++	.map = gpio_map,
++};
++
++static void ralink_gpio_irq_init(struct device_node *np,
++				 struct ralink_gpio_chip *rg)
++{
++	if (irq_map_count >= MAP_MAX)
++		return;
++
++	rg->irq = irq_of_parse_and_map(np, 0);
++	if (!rg->irq)
++		return;
++
++	rg->domain = irq_domain_add_linear(np, rg->chip.ngpio,
++					   &irq_domain_ops, rg);
++	if (!rg->domain) {
++		dev_err(rg->chip.parent, "irq_domain_add_linear failed\n");
++		return;
++	}
++
++	irq_map[irq_map_count++] = rg->domain;
++
++	rt_gpio_w32(rg, GPIO_REG_RENA, 0x0);
++	rt_gpio_w32(rg, GPIO_REG_FENA, 0x0);
++
++	if (!atomic_read(&irq_refcount))
++		irq_set_chained_handler(rg->irq, ralink_gpio_irq_handler);
++	atomic_inc(&irq_refcount);
++
++	dev_info(rg->chip.parent, "registering %d irq handlers\n", rg->chip.ngpio);
++}
++
++static int ralink_gpio_probe(struct platform_device *pdev)
++{
++	struct device_node *np = pdev->dev.of_node;
++	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	struct ralink_gpio_chip *rg;
++	const __be32 *ngpio, *gpiobase;
++
++	if (!res) {
++		dev_err(&pdev->dev, "failed to find resource\n");
++		return -ENOMEM;
++	}
++
++	rg = devm_kzalloc(&pdev->dev,
++			sizeof(struct ralink_gpio_chip), GFP_KERNEL);
++	if (!rg)
++		return -ENOMEM;
++
++	rg->membase = devm_ioremap_resource(&pdev->dev, res);
++	if (!rg->membase) {
++		dev_err(&pdev->dev, "cannot remap I/O memory region\n");
++		return -ENOMEM;
++	}
++
++	if (of_property_read_u8_array(np, "ralink,register-map",
++			rg->regs, GPIO_REG_MAX)) {
++		dev_err(&pdev->dev, "failed to read register definition\n");
++		return -EINVAL;
++	}
++
++	ngpio = of_get_property(np, "ralink,num-gpios", NULL);
++	if (!ngpio) {
++		dev_err(&pdev->dev, "failed to read number of pins\n");
++		return -EINVAL;
++	}
++
++	gpiobase = of_get_property(np, "ralink,gpio-base", NULL);
++	if (gpiobase)
++		rg->chip.base = be32_to_cpu(*gpiobase);
++	else
++		rg->chip.base = -1;
++
++	spin_lock_init(&rg->lock);
++
++	rg->chip.parent = &pdev->dev;
++	rg->chip.label = dev_name(&pdev->dev);
++	rg->chip.of_node = np;
++	rg->chip.ngpio = be32_to_cpu(*ngpio);
++	rg->chip.direction_input = ralink_gpio_direction_input;
++	rg->chip.direction_output = ralink_gpio_direction_output;
++	rg->chip.get = ralink_gpio_get;
++	rg->chip.set = ralink_gpio_set;
++	rg->chip.request = gpiochip_generic_request;
++	rg->chip.to_irq = ralink_gpio_to_irq;
++	rg->chip.free = gpiochip_generic_free;
++
++	/* set polarity to low for all lines */
++	rt_gpio_w32(rg, GPIO_REG_POL, 0);
++
++	dev_info(&pdev->dev, "registering %d gpios\n", rg->chip.ngpio);
++
++	ralink_gpio_irq_init(np, rg);
++
++	return gpiochip_add(&rg->chip);
++}
++
++static const struct of_device_id ralink_gpio_match[] = {
++	{ .compatible = "ralink,rt2880-gpio" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, ralink_gpio_match);
++
++static struct platform_driver ralink_gpio_driver = {
++	.probe = ralink_gpio_probe,
++	.driver = {
++		.name = "rt2880_gpio",
++		.owner = THIS_MODULE,
++		.of_match_table = ralink_gpio_match,
++	},
++};
++
++static int __init ralink_gpio_init(void)
++{
++	return platform_driver_register(&ralink_gpio_driver);
++}
++
++subsys_initcall(ralink_gpio_init);
diff --git a/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch b/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch
new file mode 100644
index 0000000..8520ce3
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0029-gpio-ralink-Add-support-for-GPIO-as-interrupt-contro.patch
@@ -0,0 +1,44 @@
+From 57fa7f2f4ef6f78ce1d30509c0d111aa3791b524 Mon Sep 17 00:00:00 2001
+From: Daniel Santos <daniel.santos@pobox.com>
+Date: Sun, 4 Nov 2018 20:24:32 -0600
+Subject: gpio-ralink: Add support for GPIO as interrupt-controller
+
+Signed-off-by: Daniel Santos <daniel.santos@pobox.com>
+---
+ Documentation/devicetree/bindings/gpio/gpio-ralink.txt | 6 ++++++
+ drivers/gpio/gpio-ralink.c                             | 2 +-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
++++ b/Documentation/devicetree/bindings/gpio/gpio-ralink.txt
+@@ -17,6 +17,9 @@ Required properties:
+ 
+ Optional properties:
+ - ralink,gpio-base : Specify the GPIO chips base number
++- interrupt-controller : marks this as an interrupt controller
++- #interrupt-cells : a standard two-cell interrupt flag, see
++  interrupt-controller/interrupts.txt
+ 
+ Example:
+ 
+@@ -28,6 +31,9 @@ Example:
+ 
+ 		reg = <0x600 0x34>;
+ 
++		interrupt-controller;
++		#interrupt-cells = <2>;
++
+ 		interrupt-parent = <&intc>;
+ 		interrupts = <6>;
+ 
+--- a/drivers/gpio/gpio-ralink.c
++++ b/drivers/gpio/gpio-ralink.c
+@@ -220,7 +220,7 @@ static int gpio_map(struct irq_domain *d
+ }
+ 
+ static const struct irq_domain_ops irq_domain_ops = {
+-	.xlate = irq_domain_xlate_onecell,
++	.xlate = irq_domain_xlate_twocell,
+ 	.map = gpio_map,
+ };
+ 
diff --git a/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch b/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch
new file mode 100644
index 0000000..a7a16e7
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0031-uvc-add-iPassion-iP2970-support.patch
@@ -0,0 +1,244 @@
+From 975e76214cd2516eb6cfff4c3eec581872645e88 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 19 Sep 2013 01:50:59 +0200
+Subject: [PATCH 31/53] uvc: add iPassion iP2970 support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/media/usb/uvc/uvc_driver.c |   12 +++
+ drivers/media/usb/uvc/uvc_status.c |    2 +
+ drivers/media/usb/uvc/uvc_video.c  |  147 ++++++++++++++++++++++++++++++++++++
+ drivers/media/usb/uvc/uvcvideo.h   |    5 +-
+ 4 files changed, 165 insertions(+), 1 deletion(-)
+
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -2919,6 +2919,18 @@ static const struct usb_device_id uvc_id
+ 	  .bInterfaceSubClass	= 1,
+ 	  .bInterfaceProtocol	= 0,
+ 	  .driver_info		= UVC_INFO_META(V4L2_META_FMT_D4XX) },
++	/* iPassion iP2970 */
++	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
++				| USB_DEVICE_ID_MATCH_INT_INFO,
++	 .idVendor		= 0x1B3B,
++	 .idProduct		= 0x2970,
++	 .bInterfaceClass	= USB_CLASS_VIDEO,
++	 .bInterfaceSubClass	= 1,
++	 .bInterfaceProtocol	= 0,
++	 .driver_info		= UVC_QUIRK_PROBE_MINMAX
++				| UVC_QUIRK_STREAM_NO_FID
++				| UVC_QUIRK_MOTION
++				| UVC_QUIRK_SINGLE_ISO },
+ 	/* Generic USB Video Class */
+ 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
+ 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
+--- a/drivers/media/usb/uvc/uvc_status.c
++++ b/drivers/media/usb/uvc/uvc_status.c
+@@ -225,6 +225,7 @@ static void uvc_status_complete(struct u
+ 			if (uvc_event_control(urb, status, len))
+ 				/* The URB will be resubmitted in work context. */
+ 				return;
++			dev->motion = 1;
+ 			break;
+ 		}
+ 
+@@ -273,6 +274,7 @@ int uvc_status_init(struct uvc_device *d
+ 	}
+ 
+ 	pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
++	dev->motion = 0;
+ 
+ 	/* For high-speed interrupt endpoints, the bInterval value is used as
+ 	 * an exponent of two. Some developers forgot about it.
+--- a/drivers/media/usb/uvc/uvc_video.c
++++ b/drivers/media/usb/uvc/uvc_video.c
+@@ -16,6 +16,11 @@
+ #include <linux/wait.h>
+ #include <linux/atomic.h>
+ #include <asm/unaligned.h>
++#include <linux/skbuff.h>
++#include <linux/kobject.h>
++#include <linux/netlink.h>
++#include <linux/kobject.h>
++#include <linux/workqueue.h>
+ 
+ #include <media/v4l2-common.h>
+ 
+@@ -1188,9 +1193,149 @@ static void uvc_video_decode_data(struct
+ 	uvc_urb->async_operations++;
+ }
+ 
++struct bh_priv {
++	unsigned long	seen;
++};
++
++struct bh_event {
++	const char		*name;
++	struct sk_buff		*skb;
++	struct work_struct	work;
++};
++
++#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, "webcam", ##args )
++#define BH_DBG(fmt, args...) do {} while (0)
++#define BH_SKB_SIZE     2048
++
++extern u64 uevent_next_seqnum(void);
++static int seen = 0;
++
++static int bh_event_add_var(struct bh_event *event, int argv,
++		const char *format, ...)
++{
++	static char buf[128];
++	char *s;
++	va_list args;
++	int len;
++
++	if (argv)
++		return 0;
++
++	va_start(args, format);
++	len = vsnprintf(buf, sizeof(buf), format, args);
++	va_end(args);
++
++	if (len >= sizeof(buf)) {
++		BH_ERR("buffer size too small\n");
++		WARN_ON(1);
++		return -ENOMEM;
++	}
++
++	s = skb_put(event->skb, len + 1);
++	strcpy(s, buf);
++
++	BH_DBG("added variable '%s'\n", s);
++
++	return 0;
++}
++
++static int motion_hotplug_fill_event(struct bh_event *event)
++{
++	int s = jiffies;
++	int ret;
++
++	if (!seen)
++		seen = jiffies;
++
++	ret = bh_event_add_var(event, 0, "HOME=%s", "/");
++	if (ret)
++		return ret;
++
++	ret = bh_event_add_var(event, 0, "PATH=%s",
++		"/sbin:/bin:/usr/sbin:/usr/bin");
++	if (ret)
++		return ret;
++
++	ret = bh_event_add_var(event, 0, "SUBSYSTEM=usb");
++	if (ret)
++		return ret;
++
++	ret = bh_event_add_var(event, 0, "ACTION=motion");
++	if (ret)
++		return ret;
++
++	ret = bh_event_add_var(event, 0, "SEEN=%d", s - seen);
++	if (ret)
++		return ret;
++	seen = s;
++
++	ret = bh_event_add_var(event, 0, "SEQNUM=%llu", uevent_next_seqnum());
++
++	return ret;
++}
++
++static void motion_hotplug_work(struct work_struct *work)
++{
++	struct bh_event *event = container_of(work, struct bh_event, work);
++	int ret = 0;
++
++	event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL);
++	if (!event->skb)
++		goto out_free_event;
++
++	ret = bh_event_add_var(event, 0, "%s@", "add");
++	if (ret)
++		goto out_free_skb;
++
++	ret = motion_hotplug_fill_event(event);
++	if (ret)
++		goto out_free_skb;
++
++	NETLINK_CB(event->skb).dst_group = 1;
++	broadcast_uevent(event->skb, 0, 1, GFP_KERNEL);
++
++out_free_skb:
++	if (ret) {
++		BH_ERR("work error %d\n", ret);
++		kfree_skb(event->skb);
++	}
++out_free_event:
++	kfree(event);
++}
++
++static int motion_hotplug_create_event(void)
++{
++	struct bh_event *event;
++
++	event = kzalloc(sizeof(*event), GFP_KERNEL);
++	if (!event)
++		return -ENOMEM;
++
++	event->name = "motion";
++
++	INIT_WORK(&event->work, (void *)(void *)motion_hotplug_work);
++	schedule_work(&event->work);
++
++	return 0;
++}
++
++#define MOTION_FLAG_OFFSET	4
+ static void uvc_video_decode_end(struct uvc_streaming *stream,
+ 		struct uvc_buffer *buf, const u8 *data, int len)
+ {
++	if ((stream->dev->quirks & UVC_QUIRK_MOTION) &&
++			(data[len - 2] == 0xff) && (data[len - 1] == 0xd9)) {
++		u8 *mem;
++		buf->state = UVC_BUF_STATE_READY;
++		mem = (u8 *) (buf->mem + MOTION_FLAG_OFFSET);
++		if ( stream->dev->motion ) {
++			stream->dev->motion = 0;
++			motion_hotplug_create_event();
++		} else {
++			*mem &= 0x7f;
++		}
++	}
++
+ 	/* Mark the buffer as done if the EOF marker is set. */
+ 	if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) {
+ 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n");
+@@ -1749,6 +1894,8 @@ static int uvc_init_video_isoc(struct uv
+ 	if (npackets == 0)
+ 		return -ENOMEM;
+ 
++	if (stream->dev->quirks & UVC_QUIRK_SINGLE_ISO)
++		npackets = 1;
+ 	size = npackets * psize;
+ 
+ 	for_each_uvc_urb(uvc_urb, stream) {
+--- a/drivers/media/usb/uvc/uvcvideo.h
++++ b/drivers/media/usb/uvc/uvcvideo.h
+@@ -200,6 +200,8 @@
+ #define UVC_QUIRK_FORCE_Y8		0x00000800
+ #define UVC_QUIRK_FORCE_BPP		0x00001000
+ #define UVC_QUIRK_WAKE_AUTOSUSPEND	0x00002000
++#define UVC_QUIRK_MOTION		0x00004000
++#define UVC_QUIRK_SINGLE_ISO		0x00008000
+ 
+ /* Format flags */
+ #define UVC_FMT_FLAG_COMPRESSED		0x00000001
+@@ -668,6 +670,7 @@ struct uvc_device {
+ 	u8 *status;
+ 	struct input_dev *input;
+ 	char input_phys[64];
++	int motion;
+ 
+ 	struct uvc_ctrl_work {
+ 		struct work_struct work;
diff --git a/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch b/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch
new file mode 100644
index 0000000..7011bbe
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0037-mtd-cfi-cmdset-0002-force-word-write.patch
@@ -0,0 +1,20 @@
+From ee9081b2726a5ca8cde5497afdc5425e21ff8f8b Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 15 Jul 2013 00:39:21 +0200
+Subject: [PATCH 37/53] mtd: cfi cmdset 0002 force word write
+
+---
+ drivers/mtd/chips/cfi_cmdset_0002.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -40,7 +40,7 @@
+ #include <linux/mtd/xip.h>
+ 
+ #define AMD_BOOTLOC_BUG
+-#define FORCE_WORD_WRITE 0
++#define FORCE_WORD_WRITE 1
+ 
+ #define MAX_RETRIES 3
+ 
diff --git a/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch b/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch
new file mode 100644
index 0000000..e2643e3
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0041-DT-Add-documentation-for-spi-rt2880.patch
@@ -0,0 +1,44 @@
+From da6015e7f19d749f135f7ac55c4ec47b06faa868 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Fri, 9 Aug 2013 20:12:59 +0200
+Subject: [PATCH 41/53] DT: Add documentation for spi-rt2880
+
+Describe the SPI master found on the MIPS based Ralink RT2880 SoC.
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ .../devicetree/bindings/spi/spi-rt2880.txt         |   28 ++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/spi/spi-rt2880.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/spi/spi-rt2880.txt
+@@ -0,0 +1,28 @@
++Ralink SoC RT2880 SPI master controller.
++
++This SPI controller is found on most wireless SoCs made by ralink.
++
++Required properties:
++- compatible : "ralink,rt2880-spi"
++- reg : The register base for the controller.
++- #address-cells : <1>, as required by generic SPI binding.
++- #size-cells : <0>, also as required by generic SPI binding.
++
++Child nodes as per the generic SPI binding.
++
++Example:
++
++	spi@b00 {
++		compatible = "ralink,rt2880-spi";
++		reg = <0xb00 0x100>;
++
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		m25p80@0 {
++			compatible = "m25p80";
++			reg = <0>;
++			spi-max-frequency = <10000000>;
++		};
++	};
++
diff --git a/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch
new file mode 100644
index 0000000..6523716
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0042-SPI-ralink-add-Ralink-SoC-spi-driver.patch
@@ -0,0 +1,574 @@
+From 683af4ebb91a1600df1946ac4769d916b8a1be65 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 11:15:12 +0100
+Subject: [PATCH 42/53] SPI: ralink: add Ralink SoC spi driver
+
+Add the driver needed to make SPI work on Ralink SoC.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+Acked-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/spi/Kconfig      |    6 +
+ drivers/spi/Makefile     |    1 +
+ drivers/spi/spi-rt2880.c |  530 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 537 insertions(+)
+ create mode 100644 drivers/spi/spi-rt2880.c
+
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -605,6 +605,12 @@ config SPI_QCOM_GENI
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called spi-geni-qcom.
+ 
++config SPI_RT2880
++	tristate "Ralink RT288x SPI Controller"
++	depends on RALINK
++	help
++	  This selects a driver for the Ralink RT288x/RT305x SPI Controller.
++
+ config SPI_S3C24XX
+ 	tristate "Samsung S3C24XX series SPI"
+ 	depends on ARCH_S3C24XX
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -87,6 +87,7 @@ obj-$(CONFIG_SPI_QUP)			+= spi-qup.o
+ obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockchip.o
+ obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
+ obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
++obj-$(CONFIG_SPI_RT2880)		+= spi-rt2880.o
+ obj-$(CONFIG_SPI_S3C24XX)		+= spi-s3c24xx-hw.o
+ spi-s3c24xx-hw-y			:= spi-s3c24xx.o
+ spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o
+--- /dev/null
++++ b/drivers/spi/spi-rt2880.c
+@@ -0,0 +1,530 @@
++/*
++ * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver
++ *
++ * Copyright (C) 2011 Sergiy <piratfm@gmail.com>
++ * Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
++ *
++ * Some parts are based on spi-orion.c:
++ *   Author: Shadi Ammouri <shadi@marvell.com>
++ *   Copyright (C) 2007-2008 Marvell Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/reset.h>
++#include <linux/spi/spi.h>
++#include <linux/platform_device.h>
++#include <linux/gpio.h>
++
++#define DRIVER_NAME			"spi-rt2880"
++
++#define RAMIPS_SPI_STAT			0x00
++#define RAMIPS_SPI_CFG			0x10
++#define RAMIPS_SPI_CTL			0x14
++#define RAMIPS_SPI_DATA			0x20
++#define RAMIPS_SPI_ADDR			0x24
++#define RAMIPS_SPI_BS			0x28
++#define RAMIPS_SPI_USER			0x2C
++#define RAMIPS_SPI_TXFIFO		0x30
++#define RAMIPS_SPI_RXFIFO		0x34
++#define RAMIPS_SPI_FIFO_STAT		0x38
++#define RAMIPS_SPI_MODE			0x3C
++#define RAMIPS_SPI_DEV_OFFSET		0x40
++#define RAMIPS_SPI_DMA			0x80
++#define RAMIPS_SPI_DMASTAT		0x84
++#define RAMIPS_SPI_ARBITER		0xF0
++
++/* SPISTAT register bit field */
++#define SPISTAT_BUSY			BIT(0)
++
++/* SPICFG register bit field */
++#define SPICFG_ADDRMODE			BIT(12)
++#define SPICFG_RXENVDIS			BIT(11)
++#define SPICFG_RXCAP			BIT(10)
++#define SPICFG_SPIENMODE		BIT(9)
++#define SPICFG_MSBFIRST			BIT(8)
++#define SPICFG_SPICLKPOL		BIT(6)
++#define SPICFG_RXCLKEDGE_FALLING	BIT(5)
++#define SPICFG_TXCLKEDGE_FALLING	BIT(4)
++#define SPICFG_HIZSPI			BIT(3)
++#define SPICFG_SPICLK_PRESCALE_MASK	0x7
++#define SPICFG_SPICLK_DIV2		0
++#define SPICFG_SPICLK_DIV4		1
++#define SPICFG_SPICLK_DIV8		2
++#define SPICFG_SPICLK_DIV16		3
++#define SPICFG_SPICLK_DIV32		4
++#define SPICFG_SPICLK_DIV64		5
++#define SPICFG_SPICLK_DIV128		6
++#define SPICFG_SPICLK_DISABLE		7
++
++/* SPICTL register bit field */
++#define SPICTL_START			BIT(4)
++#define SPICTL_HIZSDO			BIT(3)
++#define SPICTL_STARTWR			BIT(2)
++#define SPICTL_STARTRD			BIT(1)
++#define SPICTL_SPIENA			BIT(0)
++
++/* SPIUSER register bit field */
++#define SPIUSER_USERMODE		BIT(21)
++#define SPIUSER_INSTR_PHASE		BIT(20)
++#define SPIUSER_ADDR_PHASE_MASK		0x7
++#define SPIUSER_ADDR_PHASE_OFFSET	17
++#define SPIUSER_MODE_PHASE		BIT(16)
++#define SPIUSER_DUMMY_PHASE_MASK	0x3
++#define SPIUSER_DUMMY_PHASE_OFFSET	14
++#define SPIUSER_DATA_PHASE_MASK		0x3
++#define SPIUSER_DATA_PHASE_OFFSET	12
++#define SPIUSER_DATA_READ		(BIT(0) << SPIUSER_DATA_PHASE_OFFSET)
++#define SPIUSER_DATA_WRITE		(BIT(1) << SPIUSER_DATA_PHASE_OFFSET)
++#define SPIUSER_ADDR_TYPE_OFFSET	9
++#define SPIUSER_MODE_TYPE_OFFSET	6
++#define SPIUSER_DUMMY_TYPE_OFFSET	3
++#define SPIUSER_DATA_TYPE_OFFSET	0
++#define SPIUSER_TRANSFER_MASK		0x7
++#define SPIUSER_TRANSFER_SINGLE		BIT(0)
++#define SPIUSER_TRANSFER_DUAL		BIT(1)
++#define SPIUSER_TRANSFER_QUAD		BIT(2)
++
++#define SPIUSER_TRANSFER_TYPE(type) ( \
++	(type << SPIUSER_ADDR_TYPE_OFFSET) | \
++	(type << SPIUSER_MODE_TYPE_OFFSET) | \
++	(type << SPIUSER_DUMMY_TYPE_OFFSET) | \
++	(type << SPIUSER_DATA_TYPE_OFFSET) \
++)
++
++/* SPIFIFOSTAT register bit field */
++#define SPIFIFOSTAT_TXEMPTY		BIT(19)
++#define SPIFIFOSTAT_RXEMPTY		BIT(18)
++#define SPIFIFOSTAT_TXFULL		BIT(17)
++#define SPIFIFOSTAT_RXFULL		BIT(16)
++#define SPIFIFOSTAT_FIFO_MASK		0xff
++#define SPIFIFOSTAT_TX_OFFSET		8
++#define SPIFIFOSTAT_RX_OFFSET		0
++
++#define SPI_FIFO_DEPTH			16
++
++/* SPIMODE register bit field */
++#define SPIMODE_MODE_OFFSET		24
++#define SPIMODE_DUMMY_OFFSET		0
++
++/* SPIARB register bit field */
++#define SPICTL_ARB_EN			BIT(31)
++#define SPICTL_CSCTL1			BIT(16)
++#define SPI1_POR			BIT(1)
++#define SPI0_POR			BIT(0)
++
++#define RT2880_SPI_MODE_BITS	(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \
++		SPI_CS_HIGH)
++
++static atomic_t hw_reset_count = ATOMIC_INIT(0);
++
++struct rt2880_spi {
++	struct spi_master	*master;
++	void __iomem		*base;
++	u32			speed;
++	u16			wait_loops;
++	u16			mode;
++	struct clk		*clk;
++};
++
++static inline struct rt2880_spi *spidev_to_rt2880_spi(struct spi_device *spi)
++{
++	return spi_master_get_devdata(spi->master);
++}
++
++static inline u32 rt2880_spi_read(struct rt2880_spi *rs, u32 reg)
++{
++	return ioread32(rs->base + reg);
++}
++
++static inline void rt2880_spi_write(struct rt2880_spi *rs, u32 reg,
++		const u32 val)
++{
++	iowrite32(val, rs->base + reg);
++}
++
++static inline void rt2880_spi_setbits(struct rt2880_spi *rs, u32 reg, u32 mask)
++{
++	void __iomem *addr = rs->base + reg;
++
++	iowrite32((ioread32(addr) | mask), addr);
++}
++
++static inline void rt2880_spi_clrbits(struct rt2880_spi *rs, u32 reg, u32 mask)
++{
++	void __iomem *addr = rs->base + reg;
++
++	iowrite32((ioread32(addr) & ~mask), addr);
++}
++
++static u32 rt2880_spi_baudrate_get(struct spi_device *spi, unsigned int speed)
++{
++	struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
++	u32 rate;
++	u32 prescale;
++
++	/*
++	 * the supported rates are: 2, 4, 8, ... 128
++	 * round up as we look for equal or less speed
++	 */
++	rate = DIV_ROUND_UP(clk_get_rate(rs->clk), speed);
++	rate = roundup_pow_of_two(rate);
++
++	/* Convert the rate to SPI clock divisor value.	*/
++	prescale = ilog2(rate / 2);
++
++	/* some tolerance. double and add 100 */
++	rs->wait_loops = (8 * HZ * loops_per_jiffy) /
++		(clk_get_rate(rs->clk) / rate);
++	rs->wait_loops = (rs->wait_loops << 1) + 100;
++	rs->speed = speed;
++
++	dev_dbg(&spi->dev, "speed: %lu/%u, rate: %u, prescal: %u, loops: %hu\n",
++			clk_get_rate(rs->clk) / rate, speed, rate, prescale,
++			rs->wait_loops);
++
++	return prescale;
++}
++
++static u32 get_arbiter_offset(struct spi_master *master)
++{
++	u32 offset;
++
++	offset = RAMIPS_SPI_ARBITER;
++	if (master->bus_num == 1)
++		offset -= RAMIPS_SPI_DEV_OFFSET;
++
++	return offset;
++}
++
++static void rt2880_spi_set_cs(struct spi_device *spi, bool enable)
++{
++	struct rt2880_spi *rs = spidev_to_rt2880_spi(spi);
++
++	if (enable)
++		rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
++	else
++		rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA);
++}
++
++static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len)
++{
++	int loop = rs->wait_loops * len;
++
++	while ((rt2880_spi_read(rs, RAMIPS_SPI_STAT) & SPISTAT_BUSY) && --loop)
++		cpu_relax();
++
++	if (loop)
++		return 0;
++
++	return -ETIMEDOUT;
++}
++
++static void rt2880_dump_reg(struct spi_master *master)
++{
++	struct rt2880_spi *rs = spi_master_get_devdata(master);
++
++	dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \
++			"data: %08x, arb: %08x\n",
++			rt2880_spi_read(rs, RAMIPS_SPI_STAT),
++			rt2880_spi_read(rs, RAMIPS_SPI_CFG),
++			rt2880_spi_read(rs, RAMIPS_SPI_CTL),
++			rt2880_spi_read(rs, RAMIPS_SPI_DATA),
++			rt2880_spi_read(rs, get_arbiter_offset(master)));
++}
++
++static int rt2880_spi_transfer_one(struct spi_master *master,
++		struct spi_device *spi, struct spi_transfer *xfer)
++{
++	struct rt2880_spi *rs = spi_master_get_devdata(master);
++	unsigned len;
++	const u8 *tx = xfer->tx_buf;
++	u8 *rx = xfer->rx_buf;
++	int err = 0;
++
++	/* change clock speed  */
++	if (unlikely(rs->speed != xfer->speed_hz)) {
++		u32 reg;
++		reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
++		reg &= ~SPICFG_SPICLK_PRESCALE_MASK;
++		reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz);
++		rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
++	}
++
++	if (tx) {
++		len = xfer->len;
++		while (len-- > 0) {
++			rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++);
++			rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR);
++			err = rt2880_spi_wait_ready(rs, 1);
++			if (err) {
++				dev_err(&spi->dev, "TX failed, err=%d\n", err);
++				goto out;
++			}
++		}
++	}
++
++	if (rx) {
++		len = xfer->len;
++		while (len-- > 0) {
++			rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD);
++			err = rt2880_spi_wait_ready(rs, 1);
++			if (err) {
++				dev_err(&spi->dev, "RX failed, err=%d\n", err);
++				goto out;
++			}
++			*rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA);
++		}
++	}
++
++out:
++	return err;
++}
++
++/* copy from spi.c */
++static void spi_set_cs(struct spi_device *spi, bool enable)
++{
++	if (spi->mode & SPI_CS_HIGH)
++		enable = !enable;
++
++	if (spi->cs_gpio >= 0)
++		gpio_set_value(spi->cs_gpio, !enable);
++	else if (spi->master->set_cs)
++		spi->master->set_cs(spi, !enable);
++}
++
++static int rt2880_spi_setup(struct spi_device *spi)
++{
++	struct spi_master *master = spi->master;
++	struct rt2880_spi *rs = spi_master_get_devdata(master);
++	u32 reg, old_reg, arbit_off;
++
++	if ((spi->max_speed_hz > master->max_speed_hz) ||
++			(spi->max_speed_hz < master->min_speed_hz)) {
++		dev_err(&spi->dev, "invalide requested speed %d Hz\n",
++				spi->max_speed_hz);
++		return -EINVAL;
++	}
++
++	if (!(master->bits_per_word_mask &
++				BIT(spi->bits_per_word - 1))) {
++		dev_err(&spi->dev, "invalide bits_per_word %d\n",
++				spi->bits_per_word);
++		return -EINVAL;
++	}
++
++	/* the hardware seems can't work on mode0 force it to mode3 */
++	if ((spi->mode & (SPI_CPOL | SPI_CPHA)) == SPI_MODE_0) {
++		dev_warn(&spi->dev, "force spi mode3\n");
++		spi->mode |= SPI_MODE_3;
++	}
++
++	/* chip polarity */
++	arbit_off = get_arbiter_offset(master);
++	reg = old_reg = rt2880_spi_read(rs, arbit_off);
++	if (spi->mode & SPI_CS_HIGH) {
++		switch (master->bus_num) {
++		case 1:
++			reg |= SPI1_POR;
++			break;
++		default:
++			reg |= SPI0_POR;
++			break;
++		}
++	} else {
++		switch (master->bus_num) {
++		case 1:
++			reg &= ~SPI1_POR;
++			break;
++		default:
++			reg &= ~SPI0_POR;
++			break;
++		}
++	}
++
++	/* enable spi1 */
++	if (master->bus_num == 1)
++		reg |= SPICTL_ARB_EN;
++
++	if (reg != old_reg)
++		rt2880_spi_write(rs, arbit_off, reg);
++
++	/* deselected the spi device */
++	spi_set_cs(spi, false);
++
++	rt2880_dump_reg(master);
++
++	return 0;
++}
++
++static int rt2880_spi_prepare_message(struct spi_master *master,
++		struct spi_message *msg)
++{
++	struct rt2880_spi *rs = spi_master_get_devdata(master);
++	struct spi_device *spi = msg->spi;
++	u32 reg;
++
++	if ((rs->mode == spi->mode) && (rs->speed == spi->max_speed_hz))
++		return 0;
++
++#if 0
++	/* set spido to tri-state */
++	rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_HIZSDO);
++#endif
++
++	reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG);
++
++	reg &= ~(SPICFG_MSBFIRST | SPICFG_SPICLKPOL |
++			SPICFG_RXCLKEDGE_FALLING |
++			SPICFG_TXCLKEDGE_FALLING |
++			SPICFG_SPICLK_PRESCALE_MASK);
++
++	/* MSB */
++	if (!(spi->mode & SPI_LSB_FIRST))
++		reg |= SPICFG_MSBFIRST;
++
++	/* spi mode */
++	switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
++	case SPI_MODE_0:
++		reg |= SPICFG_TXCLKEDGE_FALLING;
++		break;
++	case SPI_MODE_1:
++		reg |= SPICFG_RXCLKEDGE_FALLING;
++		break;
++	case SPI_MODE_2:
++		reg |= SPICFG_SPICLKPOL | SPICFG_RXCLKEDGE_FALLING;
++		break;
++	case SPI_MODE_3:
++		reg |= SPICFG_SPICLKPOL | SPICFG_TXCLKEDGE_FALLING;
++		break;
++	}
++	rs->mode = spi->mode;
++
++#if 0
++	/* set spiclk and spiena to tri-state */
++	reg |= SPICFG_HIZSPI;
++#endif
++
++	/* clock divide */
++	reg |= rt2880_spi_baudrate_get(spi, spi->max_speed_hz);
++
++	rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg);
++
++	return 0;
++}
++
++static int rt2880_spi_probe(struct platform_device *pdev)
++{
++	struct spi_master *master;
++	struct rt2880_spi *rs;
++	void __iomem *base;
++	struct resource *r;
++	struct clk *clk;
++	int ret;
++
++	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	base = devm_ioremap_resource(&pdev->dev, r);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
++
++	clk = devm_clk_get(&pdev->dev, NULL);
++	if (IS_ERR(clk)) {
++		dev_err(&pdev->dev, "unable to get SYS clock\n");
++		return PTR_ERR(clk);
++	}
++
++	ret = clk_prepare_enable(clk);
++	if (ret)
++		goto err_clk;
++
++	master = spi_alloc_master(&pdev->dev, sizeof(*rs));
++	if (master == NULL) {
++		dev_dbg(&pdev->dev, "master allocation failed\n");
++		ret = -ENOMEM;
++		goto err_clk;
++	}
++
++	master->dev.of_node = pdev->dev.of_node;
++	master->mode_bits = RT2880_SPI_MODE_BITS;
++	master->bits_per_word_mask = SPI_BPW_MASK(8);
++	master->min_speed_hz = clk_get_rate(clk) / 128;
++	master->max_speed_hz = clk_get_rate(clk) / 2;
++	master->flags = SPI_MASTER_HALF_DUPLEX;
++	master->setup = rt2880_spi_setup;
++	master->prepare_message = rt2880_spi_prepare_message;
++	master->set_cs = rt2880_spi_set_cs;
++	master->transfer_one = rt2880_spi_transfer_one,
++
++	dev_set_drvdata(&pdev->dev, master);
++
++	rs = spi_master_get_devdata(master);
++	rs->master = master;
++	rs->base = base;
++	rs->clk = clk;
++
++	if (atomic_inc_return(&hw_reset_count) == 1)
++		device_reset(&pdev->dev);
++
++	ret = devm_spi_register_master(&pdev->dev, master);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "devm_spi_register_master error.\n");
++		goto err_master;
++	}
++
++	return ret;
++
++err_master:
++	spi_master_put(master);
++	kfree(master);
++err_clk:
++	clk_disable_unprepare(clk);
++
++	return ret;
++}
++
++static int rt2880_spi_remove(struct platform_device *pdev)
++{
++	struct spi_master *master;
++	struct rt2880_spi *rs;
++
++	master = dev_get_drvdata(&pdev->dev);
++	rs = spi_master_get_devdata(master);
++
++	clk_disable_unprepare(rs->clk);
++	atomic_dec(&hw_reset_count);
++
++	return 0;
++}
++
++MODULE_ALIAS("platform:" DRIVER_NAME);
++
++static const struct of_device_id rt2880_spi_match[] = {
++	{ .compatible = "ralink,rt2880-spi" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, rt2880_spi_match);
++
++static struct platform_driver rt2880_spi_driver = {
++	.driver = {
++		.name = DRIVER_NAME,
++		.owner = THIS_MODULE,
++		.of_match_table = rt2880_spi_match,
++	},
++	.probe = rt2880_spi_probe,
++	.remove = rt2880_spi_remove,
++};
++
++module_platform_driver(rt2880_spi_driver);
++
++MODULE_DESCRIPTION("Ralink SPI driver");
++MODULE_AUTHOR("Sergiy <piratfm@gmail.com>");
++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch
new file mode 100644
index 0000000..e3bb7f2
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0044-i2c-MIPS-adds-ralink-I2C-driver.patch
@@ -0,0 +1,507 @@
+From 723b8beaabf3c3c4b1ce69480141f1e926f3f3b2 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:52:56 +0100
+Subject: [PATCH 44/53] i2c: MIPS: adds ralink I2C driver
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ .../devicetree/bindings/i2c/i2c-ralink.txt         |   27 ++
+ drivers/i2c/busses/Kconfig                         |    4 +
+ drivers/i2c/busses/Makefile                        |    1 +
+ drivers/i2c/busses/i2c-ralink.c                    |  327 ++++++++++++++++++++
+ 4 files changed, 359 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/i2c/i2c-ralink.txt
+ create mode 100644 drivers/i2c/busses/i2c-ralink.c
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/i2c/i2c-ralink.txt
+@@ -0,0 +1,27 @@
++I2C for Ralink platforms
++
++Required properties :
++- compatible : Must be "link,rt3052-i2c"
++- reg: physical base address of the controller and length of memory mapped
++     region.
++- #address-cells = <1>;
++- #size-cells = <0>;
++
++Optional properties:
++- Child nodes conforming to i2c bus binding
++
++Example :
++
++palmbus@10000000 {
++	i2c@900 {
++		compatible = "link,rt3052-i2c";
++		reg = <0x900 0x100>;
++		#address-cells = <1>;
++		#size-cells = <0>;
++
++		hwmon@4b {
++			compatible = "national,lm92";
++			reg = <0x4b>;
++		};
++	};
++};
+--- a/drivers/i2c/busses/Kconfig
++++ b/drivers/i2c/busses/Kconfig
+@@ -922,6 +922,11 @@ config I2C_RK3X
+ 	  This driver can also be built as a module. If so, the module will
+ 	  be called i2c-rk3x.
+ 
++config I2C_RALINK
++	tristate "Ralink I2C Controller"
++	depends on RALINK && !SOC_MT7621
++	select OF_I2C
++
+ config HAVE_S3C2410_I2C
+ 	bool
+ 	help
+--- a/drivers/i2c/busses/Makefile
++++ b/drivers/i2c/busses/Makefile
+@@ -91,6 +91,7 @@ obj-$(CONFIG_I2C_PNX)		+= i2c-pnx.o
+ obj-$(CONFIG_I2C_PUV3)		+= i2c-puv3.o
+ obj-$(CONFIG_I2C_PXA)		+= i2c-pxa.o
+ obj-$(CONFIG_I2C_PXA_PCI)	+= i2c-pxa-pci.o
++obj-$(CONFIG_I2C_RALINK)	+= i2c-ralink.o
+ obj-$(CONFIG_I2C_QCOM_GENI)	+= i2c-qcom-geni.o
+ obj-$(CONFIG_I2C_QUP)		+= i2c-qup.o
+ obj-$(CONFIG_I2C_RIIC)		+= i2c-riic.o
+--- /dev/null
++++ b/drivers/i2c/busses/i2c-ralink.c
+@@ -0,0 +1,435 @@
++/*
++ * drivers/i2c/busses/i2c-ralink.c
++ *
++ * Copyright (C) 2013 Steven Liu <steven_liu@mediatek.com>
++ * Copyright (C) 2016 Michael Lee <igvtee@gmail.com>
++ *
++ * Improve driver for i2cdetect from i2c-tools to detect i2c devices on the bus.
++ * (C) 2014 Sittisak <sittisaks@hotmail.com>
++ *
++ * 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/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/reset.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/platform_device.h>
++#include <linux/of_platform.h>
++#include <linux/i2c.h>
++#include <linux/io.h>
++#include <linux/err.h>
++#include <linux/clk.h>
++
++#define REG_CONFIG_REG		0x00
++#define REG_CLKDIV_REG		0x04
++#define REG_DEVADDR_REG		0x08
++#define REG_ADDR_REG		0x0C
++#define REG_DATAOUT_REG		0x10
++#define REG_DATAIN_REG		0x14
++#define REG_STATUS_REG		0x18
++#define REG_STARTXFR_REG	0x1C
++#define REG_BYTECNT_REG		0x20
++
++/* REG_CONFIG_REG */
++#define I2C_ADDRLEN_OFFSET	5
++#define I2C_DEVADLEN_OFFSET	2
++#define I2C_ADDRLEN_MASK	0x3
++#define I2C_ADDR_DIS		BIT(1)
++#define I2C_DEVADDR_DIS		BIT(0)
++#define I2C_ADDRLEN_8		(7 << I2C_ADDRLEN_OFFSET)
++#define I2C_DEVADLEN_7		(6 << I2C_DEVADLEN_OFFSET)
++#define I2C_CONF_DEFAULT	(I2C_ADDRLEN_8 | I2C_DEVADLEN_7)
++
++/* REG_CLKDIV_REG */
++#define I2C_CLKDIV_MASK		0xffff
++
++/* REG_DEVADDR_REG */
++#define I2C_DEVADDR_MASK	0x7f
++
++/* REG_ADDR_REG */
++#define I2C_ADDR_MASK		0xff
++
++/* REG_STATUS_REG */
++#define I2C_STARTERR		BIT(4)
++#define I2C_ACKERR		BIT(3)
++#define I2C_DATARDY		BIT(2)
++#define I2C_SDOEMPTY		BIT(1)
++#define I2C_BUSY		BIT(0)
++
++/* REG_STARTXFR_REG */
++#define NOSTOP_CMD		BIT(2)
++#define NODATA_CMD		BIT(1)
++#define READ_CMD		BIT(0)
++
++/* REG_BYTECNT_REG */
++#define BYTECNT_MAX		64
++#define SET_BYTECNT(x)		(x - 1)
++
++/* timeout waiting for I2C devices to respond (clock streching) */
++#define TIMEOUT_MS              1000
++#define DELAY_INTERVAL_US       100
++
++struct rt_i2c {
++	void __iomem *base;
++	struct clk *clk;
++	struct device *dev;
++	struct i2c_adapter adap;
++	u32 cur_clk;
++	u32 clk_div;
++	u32 flags;
++};
++
++static void rt_i2c_w32(struct rt_i2c *i2c, u32 val, unsigned reg)
++{
++	iowrite32(val, i2c->base + reg);
++}
++
++static u32 rt_i2c_r32(struct rt_i2c *i2c, unsigned reg)
++{
++	return ioread32(i2c->base + reg);
++}
++
++static int poll_down_timeout(void __iomem *addr, u32 mask)
++{
++	unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
++
++	do {
++		if (!(readl_relaxed(addr) & mask))
++			return 0;
++
++		usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
++	} while (time_before(jiffies, timeout));
++
++	return (readl_relaxed(addr) & mask) ? -EAGAIN : 0;
++}
++
++static int rt_i2c_wait_idle(struct rt_i2c *i2c)
++{
++	int ret;
++
++	ret = poll_down_timeout(i2c->base + REG_STATUS_REG, I2C_BUSY);
++	if (ret < 0)
++		dev_dbg(i2c->dev, "idle err(%d)\n", ret);
++
++	return ret;
++}
++
++static int poll_up_timeout(void __iomem *addr, u32 mask)
++{
++	unsigned long timeout = jiffies + msecs_to_jiffies(TIMEOUT_MS);
++	u32 status;
++
++	do {
++		status = readl_relaxed(addr);
++
++		/* check error status */
++		if (status & I2C_STARTERR)
++			return -EAGAIN;
++		else if (status & I2C_ACKERR)
++			return -ENXIO;
++		else if (status & mask)
++			return 0;
++
++		usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
++	} while (time_before(jiffies, timeout));
++
++	return -ETIMEDOUT;
++}
++
++static int rt_i2c_wait_rx_done(struct rt_i2c *i2c)
++{
++	int ret;
++
++	ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_DATARDY);
++	if (ret < 0)
++		dev_dbg(i2c->dev, "rx err(%d)\n", ret);
++
++	return ret;
++}
++
++static int rt_i2c_wait_tx_done(struct rt_i2c *i2c)
++{
++	int ret;
++
++	ret = poll_up_timeout(i2c->base + REG_STATUS_REG, I2C_SDOEMPTY);
++	if (ret < 0)
++		dev_dbg(i2c->dev, "tx err(%d)\n", ret);
++
++	return ret;
++}
++
++static void rt_i2c_reset(struct rt_i2c *i2c)
++{
++	device_reset(i2c->adap.dev.parent);
++	barrier();
++	rt_i2c_w32(i2c, i2c->clk_div, REG_CLKDIV_REG);
++}
++
++static void rt_i2c_dump_reg(struct rt_i2c *i2c)
++{
++	dev_dbg(i2c->dev, "conf %08x, clkdiv %08x, devaddr %08x, " \
++			"addr %08x, dataout %08x, datain %08x, " \
++			"status %08x, startxfr %08x, bytecnt %08x\n",
++			rt_i2c_r32(i2c, REG_CONFIG_REG),
++			rt_i2c_r32(i2c, REG_CLKDIV_REG),
++			rt_i2c_r32(i2c, REG_DEVADDR_REG),
++			rt_i2c_r32(i2c, REG_ADDR_REG),
++			rt_i2c_r32(i2c, REG_DATAOUT_REG),
++			rt_i2c_r32(i2c, REG_DATAIN_REG),
++			rt_i2c_r32(i2c, REG_STATUS_REG),
++			rt_i2c_r32(i2c, REG_STARTXFR_REG),
++			rt_i2c_r32(i2c, REG_BYTECNT_REG));
++}
++
++static int rt_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
++		int num)
++{
++	struct rt_i2c *i2c;
++	struct i2c_msg *pmsg;
++	unsigned char addr;
++	int i, j, ret;
++	u32 cmd;
++
++	i2c = i2c_get_adapdata(adap);
++
++	for (i = 0; i < num; i++) {
++		pmsg = &msgs[i];
++		if (i == (num - 1))
++			cmd = 0;
++		else
++			cmd = NOSTOP_CMD;
++
++		dev_dbg(i2c->dev, "addr: 0x%x, len: %d, flags: 0x%x, stop: %d\n",
++				pmsg->addr, pmsg->len, pmsg->flags,
++				(cmd == 0)? 1 : 0);
++
++		/* wait hardware idle */
++		if ((ret = rt_i2c_wait_idle(i2c)))
++			goto err_timeout;
++
++		if (pmsg->flags & I2C_M_TEN) {
++			rt_i2c_w32(i2c, I2C_CONF_DEFAULT, REG_CONFIG_REG);
++			/* 10 bits address */
++			addr = 0x78 | ((pmsg->addr >> 8) & 0x03);
++			rt_i2c_w32(i2c, addr & I2C_DEVADDR_MASK,
++					REG_DEVADDR_REG);
++			rt_i2c_w32(i2c, pmsg->addr & I2C_ADDR_MASK,
++					REG_ADDR_REG);
++		} else {
++			rt_i2c_w32(i2c, I2C_CONF_DEFAULT | I2C_ADDR_DIS,
++					REG_CONFIG_REG);
++			/* 7 bits address */
++			rt_i2c_w32(i2c, pmsg->addr & I2C_DEVADDR_MASK,
++					REG_DEVADDR_REG);
++		}
++
++		/* buffer length */
++		if (pmsg->len == 0)
++			cmd |= NODATA_CMD;
++		else
++			rt_i2c_w32(i2c, SET_BYTECNT(pmsg->len),
++					REG_BYTECNT_REG);
++
++		j = 0;
++		if (pmsg->flags & I2C_M_RD) {
++			cmd |= READ_CMD;
++			/* start transfer */
++			barrier();
++			rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
++			do {
++				/* wait */
++				if ((ret = rt_i2c_wait_rx_done(i2c)))
++					goto err_timeout;
++				/* read data */
++				if (pmsg->len)
++					pmsg->buf[j] = rt_i2c_r32(i2c,
++							REG_DATAIN_REG);
++				j++;
++			} while (j < pmsg->len);
++		} else {
++			do {
++				/* write data */
++				if (pmsg->len)
++					rt_i2c_w32(i2c, pmsg->buf[j],
++							REG_DATAOUT_REG);
++				/* start transfer */
++				if (j == 0) {
++					barrier();
++					rt_i2c_w32(i2c, cmd, REG_STARTXFR_REG);
++				}
++				/* wait */
++				if ((ret = rt_i2c_wait_tx_done(i2c)))
++					goto err_timeout;
++				j++;
++			} while (j < pmsg->len);
++		}
++	}
++	/* the return value is number of executed messages */
++	ret = i;
++
++	return ret;
++
++err_timeout:
++	rt_i2c_dump_reg(i2c);
++	rt_i2c_reset(i2c);
++	return ret;
++}
++
++static u32 rt_i2c_func(struct i2c_adapter *a)
++{
++	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
++}
++
++static const struct i2c_algorithm rt_i2c_algo = {
++	.master_xfer	= rt_i2c_master_xfer,
++	.functionality	= rt_i2c_func,
++};
++
++static const struct of_device_id i2c_rt_dt_ids[] = {
++	{ .compatible = "ralink,rt2880-i2c" },
++	{ /* sentinel */ }
++};
++
++MODULE_DEVICE_TABLE(of, i2c_rt_dt_ids);
++
++static struct i2c_adapter_quirks rt_i2c_quirks = {
++        .max_write_len = BYTECNT_MAX,
++        .max_read_len = BYTECNT_MAX,
++};
++
++static int rt_i2c_init(struct rt_i2c *i2c)
++{
++	u32 reg;
++
++	/* i2c_sclk = periph_clk / ((2 * clk_div) + 5) */
++	i2c->clk_div = (clk_get_rate(i2c->clk) - (5 * i2c->cur_clk)) /
++		(2 * i2c->cur_clk);
++	if (i2c->clk_div < 8)
++		i2c->clk_div = 8;
++	if (i2c->clk_div > I2C_CLKDIV_MASK)
++		i2c->clk_div = I2C_CLKDIV_MASK;
++
++	/* check support combinde/repeated start message */
++	rt_i2c_w32(i2c, NOSTOP_CMD, REG_STARTXFR_REG);
++	reg = rt_i2c_r32(i2c, REG_STARTXFR_REG) & NOSTOP_CMD;
++
++	rt_i2c_reset(i2c);
++
++	return reg;
++}
++
++static int rt_i2c_probe(struct platform_device *pdev)
++{
++	struct resource *res;
++	struct rt_i2c *i2c;
++	struct i2c_adapter *adap;
++	const struct of_device_id *match;
++	int ret, restart;
++
++	match = of_match_device(i2c_rt_dt_ids, &pdev->dev);
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		dev_err(&pdev->dev, "no memory resource found\n");
++		return -ENODEV;
++	}
++
++	i2c = devm_kzalloc(&pdev->dev, sizeof(struct rt_i2c), GFP_KERNEL);
++	if (!i2c) {
++		dev_err(&pdev->dev, "failed to allocate i2c_adapter\n");
++		return -ENOMEM;
++	}
++
++	i2c->base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(i2c->base))
++		return PTR_ERR(i2c->base);
++
++	i2c->clk = devm_clk_get(&pdev->dev, NULL);
++	if (IS_ERR(i2c->clk)) {
++		dev_err(&pdev->dev, "no clock defined\n");
++		return -ENODEV;
++	}
++	clk_prepare_enable(i2c->clk);
++	i2c->dev = &pdev->dev;
++
++	if (of_property_read_u32(pdev->dev.of_node,
++				"clock-frequency", &i2c->cur_clk))
++		i2c->cur_clk = 100000;
++
++	adap = &i2c->adap;
++	adap->owner = THIS_MODULE;
++	adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
++	adap->algo = &rt_i2c_algo;
++	adap->retries = 3;
++	adap->dev.parent = &pdev->dev;
++	i2c_set_adapdata(adap, i2c);
++	adap->dev.of_node = pdev->dev.of_node;
++	strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
++	adap->quirks = &rt_i2c_quirks;
++
++	platform_set_drvdata(pdev, i2c);
++
++	restart = rt_i2c_init(i2c);
++
++	ret = i2c_add_adapter(adap);
++	if (ret < 0) {
++		dev_err(&pdev->dev, "failed to add adapter\n");
++		clk_disable_unprepare(i2c->clk);
++		return ret;
++	}
++
++	dev_info(&pdev->dev, "clock %uKHz, re-start %ssupport\n",
++			i2c->cur_clk/1000, restart ? "" : "not ");
++
++	return ret;
++}
++
++static int rt_i2c_remove(struct platform_device *pdev)
++{
++	struct rt_i2c *i2c = platform_get_drvdata(pdev);
++
++	i2c_del_adapter(&i2c->adap);
++	clk_disable_unprepare(i2c->clk);
++
++	return 0;
++}
++
++static struct platform_driver rt_i2c_driver = {
++	.probe		= rt_i2c_probe,
++	.remove		= rt_i2c_remove,
++	.driver		= {
++		.owner	= THIS_MODULE,
++		.name	= "i2c-ralink",
++		.of_match_table = i2c_rt_dt_ids,
++	},
++};
++
++static int __init i2c_rt_init (void)
++{
++	return platform_driver_register(&rt_i2c_driver);
++}
++subsys_initcall(i2c_rt_init);
++
++static void __exit i2c_rt_exit (void)
++{
++	platform_driver_unregister(&rt_i2c_driver);
++}
++module_exit(i2c_rt_exit);
++
++MODULE_AUTHOR("Steven Liu <steven_liu@mediatek.com>");
++MODULE_DESCRIPTION("Ralink I2c host driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:Ralink-I2C");
diff --git a/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch b/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
new file mode 100644
index 0000000..f3912a1
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0046-mmc-MIPS-ralink-add-sdhci-for-mt7620a-SoC.patch
@@ -0,0 +1,43 @@
+From 23147af14531cbdada194b94120ef8774f46292d Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Thu, 13 Nov 2014 19:08:40 +0100
+Subject: [PATCH 46/53] mmc: MIPS: ralink: add sdhci for mt7620a SoC
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/mmc/host/Kconfig             |    2 +
+ drivers/mmc/host/Makefile            |    1 +
+ drivers/mmc/host/mtk-mmc/Kconfig     |   16 +
+ drivers/mmc/host/mtk-mmc/Makefile    |   42 +
+ drivers/mmc/host/mtk-mmc/board.h     |  137 ++
+ drivers/mmc/host/mtk-mmc/dbg.c       |  347 ++++
+ drivers/mmc/host/mtk-mmc/dbg.h       |  156 ++
+ drivers/mmc/host/mtk-mmc/mt6575_sd.h | 1001 +++++++++++
+ drivers/mmc/host/mtk-mmc/sd.c        | 3060 ++++++++++++++++++++++++++++++++++
+ 9 files changed, 4762 insertions(+)
+ create mode 100644 drivers/mmc/host/mtk-mmc/Kconfig
+ create mode 100644 drivers/mmc/host/mtk-mmc/Makefile
+ create mode 100644 drivers/mmc/host/mtk-mmc/board.h
+ create mode 100644 drivers/mmc/host/mtk-mmc/dbg.c
+ create mode 100644 drivers/mmc/host/mtk-mmc/dbg.h
+ create mode 100644 drivers/mmc/host/mtk-mmc/mt6575_sd.h
+ create mode 100644 drivers/mmc/host/mtk-mmc/sd.c
+
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -1019,3 +1019,5 @@ config MMC_SDHCI_AM654
+ 	  If you have a controller with this interface, say Y or M here.
+ 
+ 	  If unsure, say N.
++
++source "drivers/mmc/host/mtk-mmc/Kconfig"
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -3,6 +3,7 @@
+ # Makefile for MMC/SD host controller drivers
+ #
+ 
++obj-$(CONFIG_MTK_MMC) 		+= mtk-mmc/
+ obj-$(CONFIG_MMC_ARMMMCI) += armmmci.o
+ armmmci-y := mmci.o
+ armmmci-$(CONFIG_MMC_QCOM_DML) += mmci_qcom_dml.o
diff --git a/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch b/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch
new file mode 100644
index 0000000..cffdc4f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0048-asoc-add-mt7620-support.patch
@@ -0,0 +1,1028 @@
+From 7f29222b1731e8182ba94a331531dec18865a1e4 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:31:47 +0100
+Subject: [PATCH 48/53] asoc: add mt7620 support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ arch/mips/ralink/of.c            |    2 +
+ sound/soc/Kconfig                |    1 +
+ sound/soc/Makefile               |    1 +
+ sound/soc/ralink/Kconfig         |   15 ++
+ sound/soc/ralink/Makefile        |   11 +
+ sound/soc/ralink/mt7620-i2s.c    |  436 ++++++++++++++++++++++++++++++++++++++
+ sound/soc/ralink/mt7620-wm8960.c |  233 ++++++++++++++++++++
+ 7 files changed, 699 insertions(+)
+ create mode 100644 sound/soc/ralink/Kconfig
+ create mode 100644 sound/soc/ralink/Makefile
+ create mode 100644 sound/soc/ralink/mt7620-i2s.c
+ create mode 100644 sound/soc/ralink/mt7620-wm8960.c
+
+--- a/sound/soc/Kconfig
++++ b/sound/soc/Kconfig
+@@ -60,6 +60,7 @@ source "sound/soc/mxs/Kconfig"
+ source "sound/soc/pxa/Kconfig"
+ source "sound/soc/qcom/Kconfig"
+ source "sound/soc/rockchip/Kconfig"
++source "sound/soc/ralink/Kconfig"
+ source "sound/soc/samsung/Kconfig"
+ source "sound/soc/sh/Kconfig"
+ source "sound/soc/sirf/Kconfig"
+--- a/sound/soc/Makefile
++++ b/sound/soc/Makefile
+@@ -43,6 +43,7 @@ obj-$(CONFIG_SND_SOC)	+= kirkwood/
+ obj-$(CONFIG_SND_SOC)	+= pxa/
+ obj-$(CONFIG_SND_SOC)	+= qcom/
+ obj-$(CONFIG_SND_SOC)	+= rockchip/
++obj-$(CONFIG_SND_SOC)	+= ralink/
+ obj-$(CONFIG_SND_SOC)	+= samsung/
+ obj-$(CONFIG_SND_SOC)	+= sh/
+ obj-$(CONFIG_SND_SOC)	+= sirf/
+--- /dev/null
++++ b/sound/soc/ralink/Kconfig
+@@ -0,0 +1,8 @@
++config SND_RALINK_SOC_I2S
++	depends on RALINK && SND_SOC && !SOC_RT288X
++	select SND_SOC_GENERIC_DMAENGINE_PCM
++	select REGMAP_MMIO
++	tristate "SoC Audio (I2S protocol) for Ralink SoC"
++	help
++	  Say Y if you want to use I2S protocol and I2S codec on Ralink/MediaTek
++	  based boards.
+--- /dev/null
++++ b/sound/soc/ralink/Makefile
+@@ -0,0 +1,6 @@
++#
++# Ralink/MediaTek Platform Support
++#
++snd-soc-ralink-i2s-objs := ralink-i2s.o
++
++obj-$(CONFIG_SND_RALINK_SOC_I2S) += snd-soc-ralink-i2s.o
+--- /dev/null
++++ b/sound/soc/ralink/ralink-i2s.c
+@@ -0,0 +1,965 @@
++/*
++ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
++ *  Copyright (C) 2016 Michael Lee <igvtee@gmail.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.
++ *
++ *  You should have received a copy of the GNU General Public License along
++ *  with this program; if not, write to the Free Software Foundation, Inc.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/regmap.h>
++#include <linux/reset.h>
++#include <linux/debugfs.h>
++#include <linux/of_device.h>
++#include <sound/pcm_params.h>
++#include <sound/dmaengine_pcm.h>
++
++#include <asm/mach-ralink/ralink_regs.h>
++
++#define DRV_NAME "ralink-i2s"
++
++#define I2S_REG_CFG0		0x00
++#define I2S_REG_INT_STATUS	0x04
++#define I2S_REG_INT_EN		0x08
++#define I2S_REG_FF_STATUS	0x0c
++#define I2S_REG_WREG		0x10
++#define I2S_REG_RREG		0x14
++#define I2S_REG_CFG1		0x18
++#define I2S_REG_DIVCMP		0x20
++#define I2S_REG_DIVINT		0x24
++
++/* I2S_REG_CFG0 */
++#define I2S_REG_CFG0_EN		BIT(31)
++#define I2S_REG_CFG0_DMA_EN	BIT(30)
++#define I2S_REG_CFG0_BYTE_SWAP	BIT(28)
++#define I2S_REG_CFG0_TX_EN	BIT(24)
++#define I2S_REG_CFG0_RX_EN	BIT(20)
++#define I2S_REG_CFG0_SLAVE	BIT(16)
++#define I2S_REG_CFG0_RX_THRES	12
++#define I2S_REG_CFG0_TX_THRES	4
++#define I2S_REG_CFG0_THRES_MASK	(0xf << I2S_REG_CFG0_RX_THRES) | \
++	(4 << I2S_REG_CFG0_TX_THRES)
++#define I2S_REG_CFG0_DFT_THRES	(4 << I2S_REG_CFG0_RX_THRES) | \
++	(4 << I2S_REG_CFG0_TX_THRES)
++/* RT305x */
++#define I2S_REG_CFG0_CLK_DIS	BIT(8)
++#define I2S_REG_CFG0_TXCH_SWAP	BIT(3)
++#define I2S_REG_CFG0_TXCH1_OFF	BIT(2)
++#define I2S_REG_CFG0_TXCH0_OFF	BIT(1)
++#define I2S_REG_CFG0_SLAVE_EN	BIT(0)
++/* RT3883 */
++#define I2S_REG_CFG0_RXCH_SWAP	BIT(11)
++#define I2S_REG_CFG0_RXCH1_OFF	BIT(10)
++#define I2S_REG_CFG0_RXCH0_OFF	BIT(9)
++#define I2S_REG_CFG0_WS_INV	BIT(0)
++/* MT7628 */
++#define I2S_REG_CFG0_FMT_LE	BIT(29)
++#define I2S_REG_CFG0_SYS_BE	BIT(28)
++#define I2S_REG_CFG0_NORM_24	BIT(18)
++#define I2S_REG_CFG0_DATA_24	BIT(17)
++
++/* I2S_REG_INT_STATUS */
++#define I2S_REG_INT_RX_FAULT	BIT(7)
++#define I2S_REG_INT_RX_OVRUN	BIT(6)
++#define I2S_REG_INT_RX_UNRUN	BIT(5)
++#define I2S_REG_INT_RX_THRES	BIT(4)
++#define I2S_REG_INT_TX_FAULT	BIT(3)
++#define I2S_REG_INT_TX_OVRUN	BIT(2)
++#define I2S_REG_INT_TX_UNRUN	BIT(1)
++#define I2S_REG_INT_TX_THRES	BIT(0)
++#define I2S_REG_INT_TX_MASK	0xf
++#define I2S_REG_INT_RX_MASK	0xf0
++
++/* I2S_REG_INT_STATUS */
++#define I2S_RX_AVCNT(x)		((x >> 4) & 0xf)
++#define I2S_TX_AVCNT(x)		(x & 0xf)
++/* MT7628 */
++#define MT7628_I2S_RX_AVCNT(x)	((x >> 8) & 0x1f)
++#define MT7628_I2S_TX_AVCNT(x)	(x & 0x1f)
++
++/* I2S_REG_CFG1 */
++#define I2S_REG_CFG1_LBK	BIT(31)
++#define I2S_REG_CFG1_EXTLBK	BIT(30)
++/* RT3883 */
++#define I2S_REG_CFG1_LEFT_J	BIT(0)
++#define I2S_REG_CFG1_RIGHT_J	BIT(1)
++#define I2S_REG_CFG1_FMT_MASK	0x3
++
++/* I2S_REG_DIVCMP */
++#define I2S_REG_DIVCMP_CLKEN	BIT(31)
++#define I2S_REG_DIVCMP_DIVCOMP_MASK	0x1ff
++
++/* I2S_REG_DIVINT */
++#define I2S_REG_DIVINT_MASK	0x3ff
++
++/* BCLK dividers */
++#define RALINK_I2S_DIVCMP	0
++#define RALINK_I2S_DIVINT	1
++
++/* FIFO */
++#define RALINK_I2S_FIFO_SIZE	32
++
++/* feature flags */
++#define RALINK_FLAGS_TXONLY	BIT(0)
++#define RALINK_FLAGS_LEFT_J	BIT(1)
++#define RALINK_FLAGS_RIGHT_J	BIT(2)
++#define RALINK_FLAGS_ENDIAN	BIT(3)
++#define RALINK_FLAGS_24BIT	BIT(4)
++
++#define RALINK_I2S_INT_EN	0
++
++struct ralink_i2s_stats {
++	u32 dmafault;
++	u32 overrun;
++	u32 underrun;
++	u32 belowthres;
++};
++
++struct ralink_i2s {
++	struct device *dev;
++	void __iomem *regs;
++	struct clk *clk;
++	struct regmap *regmap;
++	u32 flags;
++	unsigned int fmt;
++	u16 txdma_req;
++	u16 rxdma_req;
++
++	struct snd_dmaengine_dai_dma_data playback_dma_data;
++	struct snd_dmaengine_dai_dma_data capture_dma_data;
++
++	struct dentry *dbg_dir;
++        struct dentry *dbg_stats;
++	struct ralink_i2s_stats txstats;
++	struct ralink_i2s_stats rxstats;
++};
++
++static void ralink_i2s_dump_regs(struct ralink_i2s *i2s)
++{
++	u32 buf[10];
++	int ret;
++
++	ret = regmap_bulk_read(i2s->regmap, I2S_REG_CFG0,
++			buf, ARRAY_SIZE(buf));
++
++	dev_dbg(i2s->dev, "CFG0: %08x, INTSTAT: %08x, INTEN: %08x, " \
++			"FFSTAT: %08x, WREG: %08x, RREG: %08x, " \
++			"CFG1: %08x, DIVCMP: %08x, DIVINT: %08x\n",
++			buf[0], buf[1], buf[2], buf[3], buf[4],
++			buf[5], buf[6], buf[8], buf[9]);
++}
++
++static int ralink_i2s_set_sysclk(struct snd_soc_dai *dai,
++                              int clk_id, unsigned int freq, int dir)
++{
++	return 0;
++}
++
++static int ralink_i2s_set_sys_bclk(struct snd_soc_dai *dai, int width, int rate)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++	unsigned long clk = clk_get_rate(i2s->clk);
++	int div;
++	uint32_t data;
++
++	/* disable clock at slave mode */
++	if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
++			SND_SOC_DAIFMT_CBM_CFM) {
++		regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++				I2S_REG_CFG0_CLK_DIS,
++				I2S_REG_CFG0_CLK_DIS);
++		return 0;
++	}
++
++	/* FREQOUT = FREQIN / (I2S_CLK_DIV + 1) */
++	div = (clk / rate ) - 1;
++
++	data = rt_sysc_r32(0x30);
++	data &= (0xff << 8);
++	data |= (0x1 << 15) | (div << 8);
++	rt_sysc_w32(data, 0x30);
++
++	/* enable clock */
++	regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_CLK_DIS, 0);
++
++	dev_dbg(i2s->dev, "clk: %lu, rate: %u, div: %d\n",
++			clk, rate, div);
++
++	return 0;
++}
++
++static int ralink_i2s_set_bclk(struct snd_soc_dai *dai, int width, int rate)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++	unsigned long clk = clk_get_rate(i2s->clk);
++	int divint, divcomp;
++
++	/* disable clock at slave mode */
++	if ((i2s->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
++			SND_SOC_DAIFMT_CBM_CFM) {
++		regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
++				I2S_REG_DIVCMP_CLKEN, 0);
++		return 0;
++	}
++
++	/* FREQOUT = FREQIN * (1/2) * (1/(DIVINT + DIVCOMP/512)) */
++	clk = clk / (2 * 2 * width);
++	divint = clk / rate;
++	divcomp = ((clk % rate) * 512) / rate;
++
++	if ((divint > I2S_REG_DIVINT_MASK) ||
++			(divcomp > I2S_REG_DIVCMP_DIVCOMP_MASK))
++		return -EINVAL;
++
++	regmap_update_bits(i2s->regmap, I2S_REG_DIVINT,
++			I2S_REG_DIVINT_MASK, divint);
++	regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP,
++			I2S_REG_DIVCMP_DIVCOMP_MASK, divcomp);
++
++	/* enable clock */
++	regmap_update_bits(i2s->regmap, I2S_REG_DIVCMP, I2S_REG_DIVCMP_CLKEN,
++			I2S_REG_DIVCMP_CLKEN);
++
++	dev_dbg(i2s->dev, "clk: %lu, rate: %u, int: %d, comp: %d\n",
++			clk_get_rate(i2s->clk), rate, divint, divcomp);
++
++	return 0;
++}
++
++static int ralink_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++	unsigned int cfg0 = 0, cfg1 = 0;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		if (i2s->flags & RALINK_FLAGS_TXONLY)
++			cfg0 |= I2S_REG_CFG0_SLAVE_EN;
++		else
++			cfg0 |= I2S_REG_CFG0_SLAVE;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		if (i2s->flags & RALINK_FLAGS_RIGHT_J) {
++			cfg1 |= I2S_REG_CFG1_RIGHT_J;
++			break;
++		}
++		return -EINVAL;
++	case SND_SOC_DAIFMT_LEFT_J:
++		if (i2s->flags & RALINK_FLAGS_LEFT_J) {
++			cfg1 |= I2S_REG_CFG1_LEFT_J;
++			break;
++		}
++		return -EINVAL;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	if (i2s->flags & RALINK_FLAGS_TXONLY) {
++		regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++				I2S_REG_CFG0_SLAVE_EN, cfg0);
++	} else {
++		regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++				I2S_REG_CFG0_SLAVE, cfg0);
++	}
++	regmap_update_bits(i2s->regmap, I2S_REG_CFG1,
++			I2S_REG_CFG1_FMT_MASK, cfg1);
++	i2s->fmt = fmt;
++
++	return 0;
++}
++
++static int ralink_i2s_startup(struct snd_pcm_substream *substream,
++		struct snd_soc_dai *dai)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++	if (dai->active)
++		return 0;
++
++	/* setup status interrupt */
++#if (RALINK_I2S_INT_EN)
++	regmap_write(i2s->regmap, I2S_REG_INT_EN, 0xff);
++#else
++	regmap_write(i2s->regmap, I2S_REG_INT_EN, 0x0);
++#endif
++
++	/* enable */
++	regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++			I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
++			I2S_REG_CFG0_THRES_MASK,
++			I2S_REG_CFG0_EN | I2S_REG_CFG0_DMA_EN |
++			I2S_REG_CFG0_DFT_THRES);
++
++	return 0;
++}
++
++static void ralink_i2s_shutdown(struct snd_pcm_substream *substream,
++		struct snd_soc_dai *dai)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++	/* If both streams are stopped, disable module and clock */
++	if (dai->active)
++		return;
++
++	/*
++	 * datasheet mention when disable all control regs are cleared
++	 * to initial values. need reinit at startup.
++	 */
++	regmap_update_bits(i2s->regmap, I2S_REG_CFG0, I2S_REG_CFG0_EN, 0);
++}
++
++static int ralink_i2s_hw_params(struct snd_pcm_substream *substream,
++		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++	int width;
++	int ret;
++
++	width = params_width(params);
++	switch (width) {
++	case 16:
++		if (i2s->flags & RALINK_FLAGS_24BIT)
++			regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++					I2S_REG_CFG0_DATA_24, 0);
++		break;
++	case 24:
++		if (i2s->flags & RALINK_FLAGS_24BIT) {
++			regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++					I2S_REG_CFG0_DATA_24,
++					I2S_REG_CFG0_DATA_24);
++			break;
++		}
++		return -EINVAL;
++	default:
++		return -EINVAL;
++	}
++
++	switch (params_channels(params)) {
++	case 2:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	if (i2s->flags & RALINK_FLAGS_ENDIAN) {
++		/* system endian */
++#ifdef SNDRV_LITTLE_ENDIAN
++		regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++				I2S_REG_CFG0_SYS_BE, 0);
++#else
++		regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++				I2S_REG_CFG0_SYS_BE,
++				I2S_REG_CFG0_SYS_BE);
++#endif
++
++		/* data endian */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++		case SNDRV_PCM_FORMAT_S24_LE:
++			regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++					I2S_REG_CFG0_FMT_LE,
++					I2S_REG_CFG0_FMT_LE);
++			break;
++		case SNDRV_PCM_FORMAT_S16_BE:
++		case SNDRV_PCM_FORMAT_S24_BE:
++			regmap_update_bits(i2s->regmap, I2S_REG_CFG0,
++					I2S_REG_CFG0_FMT_LE, 0);
++			break;
++		default:
++			return -EINVAL;
++		}
++	}
++
++	/* setup bclk rate */
++	if (i2s->flags & RALINK_FLAGS_TXONLY)
++		ret = ralink_i2s_set_sys_bclk(dai, width, params_rate(params));
++	else
++		ret = ralink_i2s_set_bclk(dai, width, params_rate(params));
++
++	return ret;
++}
++
++static int ralink_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
++		struct snd_soc_dai *dai)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++	unsigned int mask, val;
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++		mask = I2S_REG_CFG0_TX_EN;
++	else
++		mask = I2S_REG_CFG0_RX_EN;
++
++	switch (cmd) {
++	case SNDRV_PCM_TRIGGER_START:
++	case SNDRV_PCM_TRIGGER_RESUME:
++	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++		val = mask;
++		break;
++	case SNDRV_PCM_TRIGGER_STOP:
++	case SNDRV_PCM_TRIGGER_SUSPEND:
++	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++		val = 0;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	regmap_update_bits(i2s->regmap, I2S_REG_CFG0, mask, val);
++
++	return 0;
++}
++
++static void ralink_i2s_init_dma_data(struct ralink_i2s *i2s,
++		struct resource *res)
++{
++	struct snd_dmaengine_dai_dma_data *dma_data;
++
++	/* Playback */
++	dma_data = &i2s->playback_dma_data;
++	dma_data->addr = res->start + I2S_REG_WREG;
++	dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++	dma_data->maxburst = 1;
++	dma_data->slave_id = i2s->txdma_req;
++
++	if (i2s->flags & RALINK_FLAGS_TXONLY)
++		return;
++
++	/* Capture */
++	dma_data = &i2s->capture_dma_data;
++	dma_data->addr = res->start + I2S_REG_RREG;
++	dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
++	dma_data->maxburst = 1;
++	dma_data->slave_id = i2s->rxdma_req;
++}
++
++static int ralink_i2s_dai_probe(struct snd_soc_dai *dai)
++{
++	struct ralink_i2s *i2s = snd_soc_dai_get_drvdata(dai);
++
++	snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
++			&i2s->capture_dma_data);
++
++	return 0;
++}
++
++static int ralink_i2s_dai_remove(struct snd_soc_dai *dai)
++{
++	return 0;
++}
++
++static const struct snd_soc_dai_ops ralink_i2s_dai_ops = {
++	.set_sysclk = ralink_i2s_set_sysclk,
++	.set_fmt = ralink_i2s_set_fmt,
++	.startup = ralink_i2s_startup,
++	.shutdown = ralink_i2s_shutdown,
++	.hw_params = ralink_i2s_hw_params,
++	.trigger = ralink_i2s_trigger,
++};
++
++static struct snd_soc_dai_driver ralink_i2s_dai = {
++	.name = DRV_NAME,
++	.probe = ralink_i2s_dai_probe,
++	.remove = ralink_i2s_dai_remove,
++	.ops = &ralink_i2s_dai_ops,
++	.capture = {
++		.stream_name = "I2S Capture",
++		.channels_min = 2,
++		.channels_max = 2,
++		.rate_min = 5512,
++		.rate_max = 192000,
++		.rates = SNDRV_PCM_RATE_CONTINUOUS,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,
++	},
++	.playback = {
++		.stream_name = "I2S Playback",
++		.channels_min = 2,
++		.channels_max = 2,
++		.rate_min = 5512,
++		.rate_max = 192000,
++		.rates = SNDRV_PCM_RATE_CONTINUOUS,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,
++	},
++	.symmetric_rates = 1,
++};
++
++static struct snd_pcm_hardware ralink_pcm_hardware = {
++	.info = SNDRV_PCM_INFO_MMAP |
++		SNDRV_PCM_INFO_MMAP_VALID |
++		SNDRV_PCM_INFO_INTERLEAVED |
++		SNDRV_PCM_INFO_BLOCK_TRANSFER,
++	.formats = SNDRV_PCM_FMTBIT_S16_LE,
++	.channels_min		= 2,
++	.channels_max		= 2,
++	.period_bytes_min	= PAGE_SIZE,
++	.period_bytes_max	= PAGE_SIZE * 2,
++	.periods_min		= 2,
++	.periods_max		= 128,
++	.buffer_bytes_max	= 128 * 1024,
++	.fifo_size		= RALINK_I2S_FIFO_SIZE,
++};
++
++static const struct snd_dmaengine_pcm_config ralink_dmaengine_pcm_config = {
++	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
++	.pcm_hardware = &ralink_pcm_hardware,
++	.prealloc_buffer_size = 256 * PAGE_SIZE,
++};
++
++static const struct snd_soc_component_driver ralink_i2s_component = {
++	.name = DRV_NAME,
++};
++
++static bool ralink_i2s_readable_reg(struct device *dev, unsigned int reg)
++{
++	return true;
++}
++
++static bool ralink_i2s_volatile_reg(struct device *dev, unsigned int reg)
++{
++	switch (reg) {
++	case I2S_REG_INT_STATUS:
++	case I2S_REG_FF_STATUS:
++		return true;
++	}
++	return false;
++}
++
++static bool ralink_i2s_writeable_reg(struct device *dev, unsigned int reg)
++{
++	switch (reg) {
++	case I2S_REG_FF_STATUS:
++	case I2S_REG_RREG:
++		return false;
++	}
++	return true;
++}
++
++static const struct regmap_config ralink_i2s_regmap_config = {
++	.reg_bits = 32,
++	.reg_stride = 4,
++	.val_bits = 32,
++	.writeable_reg = ralink_i2s_writeable_reg,
++	.readable_reg = ralink_i2s_readable_reg,
++	.volatile_reg = ralink_i2s_volatile_reg,
++	.max_register = I2S_REG_DIVINT,
++};
++
++#if (RALINK_I2S_INT_EN)
++static irqreturn_t ralink_i2s_irq(int irq, void *devid)
++{
++	struct ralink_i2s *i2s = devid;
++	u32 status;
++
++	regmap_read(i2s->regmap, I2S_REG_INT_STATUS, &status);
++	if (unlikely(!status))
++		return IRQ_NONE;
++
++	/* tx stats */
++	if (status & I2S_REG_INT_TX_MASK) {
++		if (status & I2S_REG_INT_TX_THRES)
++			i2s->txstats.belowthres++;
++		if (status & I2S_REG_INT_TX_UNRUN)
++			i2s->txstats.underrun++;
++		if (status & I2S_REG_INT_TX_OVRUN)
++			i2s->txstats.overrun++;
++		if (status & I2S_REG_INT_TX_FAULT)
++			i2s->txstats.dmafault++;
++	}
++
++	/* rx stats */
++	if (status & I2S_REG_INT_RX_MASK) {
++		if (status & I2S_REG_INT_RX_THRES)
++			i2s->rxstats.belowthres++;
++		if (status & I2S_REG_INT_RX_UNRUN)
++			i2s->rxstats.underrun++;
++		if (status & I2S_REG_INT_RX_OVRUN)
++			i2s->rxstats.overrun++;
++		if (status & I2S_REG_INT_RX_FAULT)
++			i2s->rxstats.dmafault++;
++	}
++
++	/* clean status bits */
++	regmap_write(i2s->regmap, I2S_REG_INT_STATUS, status);
++
++	return IRQ_HANDLED;
++}
++#endif
++
++#if IS_ENABLED(CONFIG_DEBUG_FS)
++static int ralink_i2s_stats_show(struct seq_file *s, void *unused)
++{
++        struct ralink_i2s *i2s = s->private;
++
++	seq_printf(s, "tx stats\n");
++	seq_printf(s, "\tbelow threshold\t%u\n", i2s->txstats.belowthres);
++	seq_printf(s, "\tunder run\t%u\n", i2s->txstats.underrun);
++	seq_printf(s, "\tover run\t%u\n", i2s->txstats.overrun);
++	seq_printf(s, "\tdma fault\t%u\n", i2s->txstats.dmafault);
++
++	seq_printf(s, "rx stats\n");
++	seq_printf(s, "\tbelow threshold\t%u\n", i2s->rxstats.belowthres);
++	seq_printf(s, "\tunder run\t%u\n", i2s->rxstats.underrun);
++	seq_printf(s, "\tover run\t%u\n", i2s->rxstats.overrun);
++	seq_printf(s, "\tdma fault\t%u\n", i2s->rxstats.dmafault);
++
++	ralink_i2s_dump_regs(i2s);
++
++	return 0;
++}
++
++static int ralink_i2s_stats_open(struct inode *inode, struct file *file)
++{
++        return single_open(file, ralink_i2s_stats_show, inode->i_private);
++}
++
++static const struct file_operations ralink_i2s_stats_ops = {
++        .open = ralink_i2s_stats_open,
++        .read = seq_read,
++        .llseek = seq_lseek,
++        .release = single_release,
++};
++
++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
++{
++        i2s->dbg_dir = debugfs_create_dir(dev_name(i2s->dev), NULL);
++        if (!i2s->dbg_dir)
++                return -ENOMEM;
++
++        i2s->dbg_stats = debugfs_create_file("stats", S_IRUGO,
++                        i2s->dbg_dir, i2s, &ralink_i2s_stats_ops);
++        if (!i2s->dbg_stats) {
++                debugfs_remove(i2s->dbg_dir);
++                return -ENOMEM;
++        }
++
++        return 0;
++}
++
++static inline void ralink_i2s_debugfs_remove(struct ralink_i2s *i2s)
++{
++	debugfs_remove(i2s->dbg_stats);
++	debugfs_remove(i2s->dbg_dir);
++}
++#else
++static inline int ralink_i2s_debugfs_create(struct ralink_i2s *i2s)
++{
++	return 0;
++}
++
++static inline void ralink_i2s_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
++{
++}
++#endif
++
++/*
++ * TODO: these refclk setup functions should use
++ * clock framework instead. hardcode it now.
++ */
++static void rt3350_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data |= (0x1 << 8);
++	rt_sysc_w32(data, 0x2c);
++}
++
++static void rt3883_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data &= ~(0x3 << 13);
++	data |= (0x1 << 13);
++	rt_sysc_w32(data, 0x2c);
++}
++
++static void rt3552_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data &= ~(0xf << 8);
++	data |= (0x3 << 8);
++	rt_sysc_w32(data, 0x2c);
++}
++
++static void mt7620_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data &= ~(0x7 << 9);
++	data |= 0x1 << 9;
++	rt_sysc_w32(data, 0x2c);
++}
++
++static void mt7621_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data &= ~(0x1f << 18);
++	data |= (0x19 << 18);
++	data &= ~(0x1f << 12);
++	data |= (0x1 << 12);
++	data &= ~(0x7 << 9);
++	data |= (0x5 << 9);
++	rt_sysc_w32(data, 0x2c);
++}
++
++static void mt7628_refclk_setup(void)
++{
++	uint32_t data;
++
++	/* set i2s and refclk digital pad */
++	data = rt_sysc_r32(0x3c);
++	data |= 0x1f;
++	rt_sysc_w32(data, 0x3c);
++
++	/* Adjust REFCLK0's driving strength */
++	data = rt_sysc_r32(0x1354);
++	data &= ~(0x1 << 5);
++	rt_sysc_w32(data, 0x1354);
++	data = rt_sysc_r32(0x1364);
++	data |= ~(0x1 << 5);
++	rt_sysc_w32(data, 0x1364);
++
++	/* set refclk output 12Mhz clock */
++	data = rt_sysc_r32(0x2c);
++	data &= ~(0x7 << 9);
++	data |= 0x1 << 9;
++	rt_sysc_w32(data, 0x2c);
++}
++
++struct rt_i2s_data {
++	u32 flags;
++	void (*refclk_setup)(void);
++};
++
++struct rt_i2s_data rt3050_i2s_data = { .flags = RALINK_FLAGS_TXONLY };
++struct rt_i2s_data rt3350_i2s_data = { .flags = RALINK_FLAGS_TXONLY,
++	.refclk_setup = rt3350_refclk_setup };
++struct rt_i2s_data rt3883_i2s_data = {
++	.flags = (RALINK_FLAGS_LEFT_J | RALINK_FLAGS_RIGHT_J),
++	.refclk_setup = rt3883_refclk_setup };
++struct rt_i2s_data rt3352_i2s_data = { .refclk_setup = rt3552_refclk_setup};
++struct rt_i2s_data mt7620_i2s_data = { .refclk_setup = mt7620_refclk_setup};
++struct rt_i2s_data mt7621_i2s_data = { .refclk_setup = mt7621_refclk_setup};
++struct rt_i2s_data mt7628_i2s_data = {
++	.flags = (RALINK_FLAGS_ENDIAN | RALINK_FLAGS_24BIT |
++			RALINK_FLAGS_LEFT_J),
++	.refclk_setup = mt7628_refclk_setup};
++
++static const struct of_device_id ralink_i2s_match_table[] = {
++	{ .compatible = "ralink,rt3050-i2s",
++		.data = (void *)&rt3050_i2s_data },
++	{ .compatible = "ralink,rt3350-i2s",
++		.data = (void *)&rt3350_i2s_data },
++	{ .compatible = "ralink,rt3883-i2s",
++		.data = (void *)&rt3883_i2s_data },
++	{ .compatible = "ralink,rt3352-i2s",
++		.data = (void *)&rt3352_i2s_data },
++	{ .compatible = "mediatek,mt7620-i2s",
++		.data = (void *)&mt7620_i2s_data },
++	{ .compatible = "mediatek,mt7621-i2s",
++		.data = (void *)&mt7621_i2s_data },
++	{ .compatible = "mediatek,mt7628-i2s",
++		.data = (void *)&mt7628_i2s_data },
++};
++MODULE_DEVICE_TABLE(of, ralink_i2s_match_table);
++
++static int ralink_i2s_probe(struct platform_device *pdev)
++{
++	const struct of_device_id *match;
++	struct device_node *np = pdev->dev.of_node;
++	struct ralink_i2s *i2s;
++	struct resource *res;
++	int irq, ret;
++	u32 dma_req;
++	struct rt_i2s_data *data;
++
++	i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
++	if (!i2s)
++		return -ENOMEM;
++
++	platform_set_drvdata(pdev, i2s);
++	i2s->dev = &pdev->dev;
++
++	match = of_match_device(ralink_i2s_match_table, &pdev->dev);
++	if (!match)
++		return -EINVAL;
++	data = (struct rt_i2s_data *)match->data;
++	i2s->flags = data->flags;
++	/* setup out 12Mhz refclk to codec as mclk */
++	if (data->refclk_setup)
++		data->refclk_setup();
++
++	if (of_property_read_u32(np, "txdma-req", &dma_req)) {
++		dev_err(&pdev->dev, "no txdma-req define\n");
++		return -EINVAL;
++	}
++	i2s->txdma_req = (u16)dma_req;
++	if (!(i2s->flags & RALINK_FLAGS_TXONLY)) {
++		if (of_property_read_u32(np, "rxdma-req", &dma_req)) {
++			dev_err(&pdev->dev, "no rxdma-req define\n");
++			return -EINVAL;
++		}
++		i2s->rxdma_req = (u16)dma_req;
++	}
++
++	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	i2s->regs = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(i2s->regs))
++		return PTR_ERR(i2s->regs);
++
++	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->regs,
++			&ralink_i2s_regmap_config);
++	if (IS_ERR(i2s->regmap)) {
++		dev_err(&pdev->dev, "regmap init failed\n");
++		return PTR_ERR(i2s->regmap);
++	}
++
++        irq = platform_get_irq(pdev, 0);
++        if (irq < 0) {
++                dev_err(&pdev->dev, "failed to get irq\n");
++                return -EINVAL;
++        }
++
++#if (RALINK_I2S_INT_EN)
++	ret = devm_request_irq(&pdev->dev, irq, ralink_i2s_irq,
++			0, dev_name(&pdev->dev), i2s);
++	if (ret) {
++		dev_err(&pdev->dev, "failed to request irq\n");
++		return ret;
++	}
++#endif
++
++	i2s->clk = devm_clk_get(&pdev->dev, NULL);
++	if (IS_ERR(i2s->clk)) {
++		dev_err(&pdev->dev, "no clock defined\n");
++		return PTR_ERR(i2s->clk);
++	}
++
++	ret = clk_prepare_enable(i2s->clk);
++	if (ret)
++		return ret;
++
++	ralink_i2s_init_dma_data(i2s, res);
++
++	device_reset(&pdev->dev);
++
++	ret = ralink_i2s_debugfs_create(i2s);
++	if (ret) {
++		dev_err(&pdev->dev, "create debugfs failed\n");
++		goto err_clk_disable;
++	}
++
++	/* enable 24bits support */
++	if (i2s->flags & RALINK_FLAGS_24BIT) {
++		ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S24_LE;
++		ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S24_LE;
++	}
++
++	/* enable big endian support */
++	if (i2s->flags & RALINK_FLAGS_ENDIAN) {
++		ralink_i2s_dai.capture.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++		ralink_i2s_dai.playback.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++		ralink_pcm_hardware.formats |= SNDRV_PCM_FMTBIT_S16_BE;
++		if (i2s->flags & RALINK_FLAGS_24BIT) {
++			ralink_i2s_dai.capture.formats |=
++				SNDRV_PCM_FMTBIT_S24_BE;
++			ralink_i2s_dai.playback.formats |=
++				SNDRV_PCM_FMTBIT_S24_BE;
++			ralink_pcm_hardware.formats |=
++				SNDRV_PCM_FMTBIT_S24_BE;
++		}
++	}
++
++	/* disable capture support */
++	if (i2s->flags & RALINK_FLAGS_TXONLY)
++		memset(&ralink_i2s_dai.capture, sizeof(ralink_i2s_dai.capture),
++				0);
++
++	ret = devm_snd_soc_register_component(&pdev->dev, &ralink_i2s_component,
++			&ralink_i2s_dai, 1);
++	if (ret)
++		goto err_debugfs;
++
++	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
++			&ralink_dmaengine_pcm_config,
++			SND_DMAENGINE_PCM_FLAG_COMPAT);
++	if (ret)
++		goto err_debugfs;
++
++	dev_info(i2s->dev, "mclk %luMHz\n", clk_get_rate(i2s->clk) / 1000000);
++
++	return 0;
++
++err_debugfs:
++	ralink_i2s_debugfs_remove(i2s);
++
++err_clk_disable:
++	clk_disable_unprepare(i2s->clk);
++
++	return ret;
++}
++
++static int ralink_i2s_remove(struct platform_device *pdev)
++{
++	struct ralink_i2s *i2s = platform_get_drvdata(pdev);
++
++	ralink_i2s_debugfs_remove(i2s);
++	clk_disable_unprepare(i2s->clk);
++
++	return 0;
++}
++
++static struct platform_driver ralink_i2s_driver = {
++	.probe = ralink_i2s_probe,
++	.remove = ralink_i2s_remove,
++	.driver = {
++		.name = DRV_NAME,
++		.of_match_table = ralink_i2s_match_table,
++	},
++};
++module_platform_driver(ralink_i2s_driver);
++
++MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
++MODULE_DESCRIPTION("Ralink/MediaTek I2S driver");
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch b/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch
new file mode 100644
index 0000000..7192d61
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0051-serial-add-ugly-custom-baud-rate-hack.patch
@@ -0,0 +1,22 @@
+From a7eb46e0ea4a11e4dfb56ab129bf816d1059a6c5 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 7 Dec 2015 17:31:08 +0100
+Subject: [PATCH 51/53] serial: add ugly custom baud rate hack
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/tty/serial/serial_core.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -423,6 +423,9 @@ uart_get_baud_rate(struct uart_port *por
+ 		break;
+ 	}
+ 
++	if (tty_termios_baud_rate(termios) == 2500000)
++		return 250000;
++
+ 	for (try = 0; try < 2; try++) {
+ 		baud = tty_termios_baud_rate(termios);
+ 
diff --git a/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch b/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch
new file mode 100644
index 0000000..d2c5724
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0052-pwm-add-mediatek-support.patch
@@ -0,0 +1,217 @@
+From fc8f96309c21c1bc3276427309cd7d361347d66e Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Mon, 7 Dec 2015 17:16:50 +0100
+Subject: [PATCH 52/53] pwm: add mediatek support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/pwm/Kconfig        |    9 +++
+ drivers/pwm/Makefile       |    1 +
+ drivers/pwm/pwm-mediatek.c |  173 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 183 insertions(+)
+ create mode 100644 drivers/pwm/pwm-mediatek.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -316,6 +316,15 @@ config PWM_MEDIATEK
+ 	  To compile this driver as a module, choose M here: the module
+ 	  will be called pwm-mediatek.
+ 
++config PWM_MEDIATEK_RAMIPS
++	tristate "Mediatek PWM support"
++	depends on RALINK && OF
++	help
++	  Generic PWM framework driver for Mediatek ARM SoC.
++
++	  To compile this driver as a module, choose M here: the module
++	  will be called pwm-mxs.
++
+ config PWM_MXS
+ 	tristate "Freescale MXS PWM support"
+ 	depends on ARCH_MXS && OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-p
+ obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
+ obj-$(CONFIG_PWM_MESON)		+= pwm-meson.o
+ obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o
++obj-$(CONFIG_PWM_MEDIATEK_RAMIPS)	+= pwm-mediatek-ramips.o
+ obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
+ obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
+ obj-$(CONFIG_PWM_OMAP_DMTIMER)	+= pwm-omap-dmtimer.o
+--- /dev/null
++++ b/drivers/pwm/pwm-mediatek-ramips.c
+@@ -0,0 +1,173 @@
++/*
++ * Mediatek Pulse Width Modulator driver
++ *
++ * Copyright (C) 2015 John Crispin <blogic@openwrt.org>
++ *
++ * 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/err.h>
++#include <linux/io.h>
++#include <linux/ioport.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/platform_device.h>
++#include <linux/pwm.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++
++#define NUM_PWM		4
++
++/* PWM registers and bits definitions */
++#define PWMCON			0x00
++#define PWMHDUR			0x04
++#define PWMLDUR			0x08
++#define PWMGDUR			0x0c
++#define PWMWAVENUM		0x28
++#define PWMDWIDTH		0x2c
++#define PWMTHRES		0x30
++
++/**
++ * struct mtk_pwm_chip - struct representing pwm chip
++ *
++ * @mmio_base: base address of pwm chip
++ * @chip: linux pwm chip representation
++ */
++struct mtk_pwm_chip {
++	void __iomem *mmio_base;
++	struct pwm_chip chip;
++};
++
++static inline struct mtk_pwm_chip *to_mtk_pwm_chip(struct pwm_chip *chip)
++{
++	return container_of(chip, struct mtk_pwm_chip, chip);
++}
++
++static inline u32 mtk_pwm_readl(struct mtk_pwm_chip *chip, unsigned int num,
++				  unsigned long offset)
++{
++	return ioread32(chip->mmio_base + 0x10 + (num * 0x40) + offset);
++}
++
++static inline void mtk_pwm_writel(struct mtk_pwm_chip *chip,
++				    unsigned int num, unsigned long offset,
++				    unsigned long val)
++{
++	iowrite32(val, chip->mmio_base + 0x10 + (num * 0x40) + offset);
++}
++
++static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
++			    int duty_ns, int period_ns)
++{
++	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++	u32 resolution = 100 / 4;
++	u32 clkdiv = 0;
++
++	while (period_ns / resolution  > 8191) {
++		clkdiv++;
++		resolution *= 2;
++	}
++
++	if (clkdiv > 7)
++		return -1;
++
++	mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | BIT(3) | clkdiv);
++	mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
++	mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
++	return 0;
++}
++
++static int mtk_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++	u32 val;
++
++	val = ioread32(pc->mmio_base);
++	val |= BIT(pwm->hwpwm);
++	iowrite32(val, pc->mmio_base);
++
++	return 0;
++}
++
++static void mtk_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
++	u32 val;
++
++	val = ioread32(pc->mmio_base);
++	val &= ~BIT(pwm->hwpwm);
++	iowrite32(val, pc->mmio_base);
++}
++
++static const struct pwm_ops mtk_pwm_ops = {
++	.config = mtk_pwm_config,
++	.enable = mtk_pwm_enable,
++	.disable = mtk_pwm_disable,
++	.owner = THIS_MODULE,
++};
++
++static int mtk_pwm_probe(struct platform_device *pdev)
++{
++	struct mtk_pwm_chip *pc;
++	struct resource *r;
++	int ret;
++
++	pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL);
++	if (!pc)
++		return -ENOMEM;
++
++	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	pc->mmio_base = devm_ioremap_resource(&pdev->dev, r);
++	if (IS_ERR(pc->mmio_base))
++		return PTR_ERR(pc->mmio_base);
++
++	platform_set_drvdata(pdev, pc);
++
++	pc->chip.dev = &pdev->dev;
++	pc->chip.ops = &mtk_pwm_ops;
++	pc->chip.base = -1;
++	pc->chip.npwm = NUM_PWM;
++
++	ret = pwmchip_add(&pc->chip);
++	if (ret < 0)
++		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
++
++	return ret;
++}
++
++static int mtk_pwm_remove(struct platform_device *pdev)
++{
++	struct mtk_pwm_chip *pc = platform_get_drvdata(pdev);
++	int i;
++
++	for (i = 0; i < NUM_PWM; i++)
++		pwm_disable(&pc->chip.pwms[i]);
++
++	return pwmchip_remove(&pc->chip);
++}
++
++static const struct of_device_id mtk_pwm_of_match[] = {
++	{ .compatible = "mediatek,mt7628-pwm" },
++	{ }
++};
++
++MODULE_DEVICE_TABLE(of, mtk_pwm_of_match);
++
++static struct platform_driver mtk_pwm_driver = {
++	.driver = {
++		.name = "mtk-pwm",
++		.owner = THIS_MODULE,
++		.of_match_table = mtk_pwm_of_match,
++	},
++	.probe = mtk_pwm_probe,
++	.remove = mtk_pwm_remove,
++};
++
++module_platform_driver(mtk_pwm_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
++MODULE_ALIAS("platform:mtk-pwm");
diff --git a/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch b/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch
new file mode 100644
index 0000000..7110a5b
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0069-awake-rt305x-dwc2-controller.patch
@@ -0,0 +1,15 @@
+--- a/drivers/usb/dwc2/platform.c
++++ b/drivers/usb/dwc2/platform.c
+@@ -431,6 +431,12 @@ static int dwc2_driver_probe(struct plat
+ 	if (retval)
+ 		return retval;
+ 
++	/* Enable USB port before any regs access */
++	if (readl(hsotg->regs + PCGCTL) & 0x0f) {
++		writel(0x00, hsotg->regs + PCGCTL);
++		/* TODO: mdelay(25) here? vendor driver don't use it */
++	}
++
+ 	hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
+ 
+ 	retval = dwc2_get_dr_mode(hsotg);
diff --git a/target/linux/ramips/patches-5.4/0070-weak_reordering.patch b/target/linux/ramips/patches-5.4/0070-weak_reordering.patch
new file mode 100644
index 0000000..fe3fdec
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0070-weak_reordering.patch
@@ -0,0 +1,10 @@
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -57,6 +57,7 @@ choice
+ 		select COMMON_CLK
+ 		select CLKSRC_MIPS_GIC
+ 		select HAVE_PCI if PCI_MT7621
++		select WEAK_REORDERING_BEYOND_LLSC
+ endchoice
+ 
+ choice
diff --git a/target/linux/ramips/patches-5.4/0098-disable_cm.patch b/target/linux/ramips/patches-5.4/0098-disable_cm.patch
new file mode 100644
index 0000000..1f33675
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0098-disable_cm.patch
@@ -0,0 +1,19 @@
+--- a/arch/mips/kernel/mips-cm.c
++++ b/arch/mips/kernel/mips-cm.c
+@@ -232,6 +232,7 @@ int mips_cm_probe(void)
+ 
+ 	/* disable CM regions */
+ 	write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR);
++	/*
+ 	write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK);
+ 	write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR);
+ 	write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK);
+@@ -239,7 +240,7 @@ int mips_cm_probe(void)
+ 	write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK);
+ 	write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR);
+ 	write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK);
+-
++*/
+ 	/* probe for an L2-only sync region */
+ 	mips_cm_probe_l2sync();
+ 
diff --git a/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch b/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch
new file mode 100644
index 0000000..b9bcd63
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0100-staging-mt7621-pci-simplify-mt7621_pcie_init_virtual.patch
@@ -0,0 +1,133 @@
+From b327cd58c3fec1c6382128e929eab9bc0d68e912 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 8 Mar 2020 10:19:27 +0100
+Subject: [PATCH] staging: mt7621-pci: simplify
+ 'mt7621_pcie_init_virtual_bridges' function
+
+Function 'mt7621_pcie_init_virtual_bridges' is a bit mess and can be
+refactorized properly in a cleaner way. Introduce new 'pcie_rmw' inline
+function helper to do clear and set the correct bits this function needs
+to work.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200308091928.17177-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 85 +++++++++++++--------------------
+ 1 file changed, 33 insertions(+), 52 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -57,13 +57,13 @@
+ #define RALINK_PCI_IOBASE		0x002C
+ 
+ /* PCICFG virtual bridges */
+-#define MT7621_BR0_MASK			GENMASK(19, 16)
+-#define MT7621_BR1_MASK			GENMASK(23, 20)
+-#define MT7621_BR2_MASK			GENMASK(27, 24)
+-#define MT7621_BR_ALL_MASK		GENMASK(27, 16)
+-#define MT7621_BR0_SHIFT		16
+-#define MT7621_BR1_SHIFT		20
+-#define MT7621_BR2_SHIFT		24
++#define PCIE_P2P_MAX			3
++#define PCIE_P2P_BR_DEVNUM_SHIFT(p)	(16 + (p) * 4)
++#define PCIE_P2P_BR_DEVNUM0_SHIFT	PCIE_P2P_BR_DEVNUM_SHIFT(0)
++#define PCIE_P2P_BR_DEVNUM1_SHIFT	PCIE_P2P_BR_DEVNUM_SHIFT(1)
++#define PCIE_P2P_BR_DEVNUM2_SHIFT	PCIE_P2P_BR_DEVNUM_SHIFT(2)
++#define PCIE_P2P_BR_DEVNUM_MASK		0xf
++#define PCIE_P2P_BR_DEVNUM_MASK_FULL	(0xfff << PCIE_P2P_BR_DEVNUM0_SHIFT)
+ 
+ /* PCIe RC control registers */
+ #define MT7621_PCIE_OFFSET		0x2000
+@@ -154,6 +154,15 @@ static inline void pcie_write(struct mt7
+ 	writel(val, pcie->base + reg);
+ }
+ 
++static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set)
++{
++	u32 val = readl(pcie->base + reg);
++
++	val &= ~clr;
++	val |= set;
++	writel(val, pcie->base + reg);
++}
++
+ static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg)
+ {
+ 	return readl(port->base + reg);
+@@ -554,7 +563,9 @@ static void mt7621_pcie_enable_ports(str
+ static int mt7621_pcie_init_virtual_bridges(struct mt7621_pcie *pcie)
+ {
+ 	u32 pcie_link_status = 0;
+-	u32 val = 0;
++	u32 n;
++	int i;
++	u32 p2p_br_devnum[PCIE_P2P_MAX];
+ 	struct mt7621_pcie_port *port;
+ 
+ 	list_for_each_entry(port, &pcie->ports, list) {
+@@ -567,50 +578,20 @@ static int mt7621_pcie_init_virtual_brid
+ 	if (pcie_link_status == 0)
+ 		return -1;
+ 
+-	/*
+-	 * pcie(2/1/0) link status	pcie2_num	pcie1_num	pcie0_num
+-	 * 3'b000			x		x		x
+-	 * 3'b001			x		x		0
+-	 * 3'b010			x		0		x
+-	 * 3'b011			x		1		0
+-	 * 3'b100			0		x		x
+-	 * 3'b101			1		x		0
+-	 * 3'b110			1		0		x
+-	 * 3'b111			2		1		0
+-	 */
+-	switch (pcie_link_status) {
+-	case 2:
+-		val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-		val &= ~(MT7621_BR0_MASK | MT7621_BR1_MASK);
+-		val |= 0x1 << MT7621_BR0_SHIFT;
+-		val |= 0x0 << MT7621_BR1_SHIFT;
+-		pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-		break;
+-	case 4:
+-		val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-		val &= ~MT7621_BR_ALL_MASK;
+-		val |= 0x1 << MT7621_BR0_SHIFT;
+-		val |= 0x2 << MT7621_BR1_SHIFT;
+-		val |= 0x0 << MT7621_BR2_SHIFT;
+-		pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-		break;
+-	case 5:
+-		val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-		val &= ~MT7621_BR_ALL_MASK;
+-		val |= 0x0 << MT7621_BR0_SHIFT;
+-		val |= 0x2 << MT7621_BR1_SHIFT;
+-		val |= 0x1 << MT7621_BR2_SHIFT;
+-		pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-		break;
+-	case 6:
+-		val = pcie_read(pcie, RALINK_PCI_PCICFG_ADDR);
+-		val &= ~MT7621_BR_ALL_MASK;
+-		val |= 0x2 << MT7621_BR0_SHIFT;
+-		val |= 0x0 << MT7621_BR1_SHIFT;
+-		val |= 0x1 << MT7621_BR2_SHIFT;
+-		pcie_write(pcie, val, RALINK_PCI_PCICFG_ADDR);
+-		break;
+-	}
++	n = 0;
++	for (i = 0; i < PCIE_P2P_MAX; i++)
++		if (pcie_link_status & BIT(i))
++			p2p_br_devnum[i] = n++;
++
++	for (i = 0; i < PCIE_P2P_MAX; i++)
++		if ((pcie_link_status & BIT(i)) == 0)
++			p2p_br_devnum[i] = n++;
++
++	pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
++		 PCIE_P2P_BR_DEVNUM_MASK_FULL,
++		 (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
++		 (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
++		 (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
+ 
+ 	return 0;
+ }
diff --git a/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch b/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch
new file mode 100644
index 0000000..3939280
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0101-staging-mt7621-pci-enable-clock-bit-for-each-port.patch
@@ -0,0 +1,74 @@
+From 550fabd71d7fcdfe099bbf41e00e28719737161e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Tue, 10 Mar 2020 12:34:59 +0100
+Subject: [PATCH] staging: mt7621-pci: enable clock bit for each port
+
+The clock related code concerns me from the very beginning because
+there are some set ups got from legacy driver that are not documented
+anywhere. According to the programming guide 0x7c is 'CPE_ROSC_SEL1'
+register and 0x80 is 'CPU_CPE_CN'. I do think this set up is not needed
+at all and the proper thing to do is just enable the clock bit for each
+pcie port. Hence remove useless code and do the right thing which is
+setting up the clock bit for each port enabled.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200310113459.30539-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 17 ++++++-----------
+ 1 file changed, 6 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -45,8 +45,6 @@
+ 
+ /* rt_sysc_membase relative registers */
+ #define RALINK_CLKCFG1			0x30
+-#define RALINK_PCIE_CLK_GEN		0x7c
+-#define RALINK_PCIE_CLK_GEN1		0x80
+ 
+ /* Host-PCI bridge registers */
+ #define RALINK_PCI_PCICFG_ADDR		0x0000
+@@ -85,10 +83,6 @@
+ #define PCIE_PORT_CLK_EN(x)		BIT(24 + (x))
+ #define PCIE_PORT_LINKUP		BIT(0)
+ 
+-#define PCIE_CLK_GEN_EN			BIT(31)
+-#define PCIE_CLK_GEN_DIS		0
+-#define PCIE_CLK_GEN1_DIS		GENMASK(30, 24)
+-#define PCIE_CLK_GEN1_EN		(BIT(27) | BIT(25))
+ #define MEMORY_BASE			0x0
+ #define PERST_MODE_MASK			GENMASK(11, 10)
+ #define PERST_MODE_GPIO			BIT(10)
+@@ -233,6 +227,11 @@ static inline bool mt7621_pcie_port_is_l
+ 	return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0;
+ }
+ 
++static inline void mt7621_pcie_port_clk_enable(struct mt7621_pcie_port *port)
++{
++	rt_sysc_m32(0, PCIE_PORT_CLK_EN(port->slot), RALINK_CLKCFG1);
++}
++
+ static inline void mt7621_pcie_port_clk_disable(struct mt7621_pcie_port *port)
+ {
+ 	rt_sysc_m32(PCIE_PORT_CLK_EN(port->slot), 0, RALINK_CLKCFG1);
+@@ -501,11 +500,6 @@ static void mt7621_pcie_init_ports(struc
+ 		}
+ 	}
+ 
+-	rt_sysc_m32(0x30, 2 << 4, SYSC_REG_SYSTEM_CONFIG1);
+-	rt_sysc_m32(PCIE_CLK_GEN_EN, PCIE_CLK_GEN_DIS, RALINK_PCIE_CLK_GEN);
+-	rt_sysc_m32(PCIE_CLK_GEN1_DIS, PCIE_CLK_GEN1_EN, RALINK_PCIE_CLK_GEN1);
+-	rt_sysc_m32(PCIE_CLK_GEN_DIS, PCIE_CLK_GEN_EN, RALINK_PCIE_CLK_GEN);
+-	msleep(50);
+ 	reset_control_deassert(pcie->rst);
+ }
+ 
+@@ -542,6 +536,7 @@ static void mt7621_pcie_enable_ports(str
+ 
+ 	list_for_each_entry(port, &pcie->ports, list) {
+ 		if (port->enabled) {
++			mt7621_pcie_port_clk_enable(port);
+ 			mt7621_pcie_enable_port(port);
+ 			dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
+ 			num_slots_enabled++;
diff --git a/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch b/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch
new file mode 100644
index 0000000..1b7828f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0102-staging-mt7621-pci-use-gpios-for-properly-reset.patch
@@ -0,0 +1,222 @@
+From 227a8bf421ff8b085444e51e471ef06a87228cfd Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:08 +0100
+Subject: [PATCH] staging: mt7621-pci: use gpios for properly reset
+
+Original driver code was using three gpio's for reset
+asserts and deasserts the pcis. Instead of using that
+a general reset control with a perst gpio was introduced
+and it seems it is partially working but sometimes there
+are some unexpected hangs on boot. This commit make use of
+the three original gpios using 'reset-gpios' property of
+the device tree and removes the reset line and perst gpio.
+According to the mediatek aplication note v0.1 there are
+three gpios used for pcie ports reset control: gpio#19,
+gpio#8 and gpio#7 for slots 0, 1 and 2 respectively.
+This schema can be used separately for mt7621A but in some
+boards due to pin share issue, if the PCM and I2S function
+are enable at the same time, there are no enough GPIO to
+control per-port PCIe reset. In those cases gpio#19 is enought
+for reset the three ports together. Because of this we just
+try to get the three gpios but if some of them fail we are not
+failing in boot process, just prints a kernel notice and take
+after into account if the descriptor is or not valid in order
+to use it. All of them are set as GPIO output low configuration.
+The gpio descriptor's API takes device tree property into account
+and invert value if the pin is configured as active low.
+So we also have to properly request pins from device tree
+and set values correct in assert and deassert functions.
+After this changes the order to make all assert and
+deassert in the 'probe' process makes more sense:
+* Parse device tree.
+* make assert of the RC's and EP's before doing anything else.
+* make deassert of the RC's before initializing the phy.
+* Init the phy.
+* make deassert of the EP's before initialize pci ports.
+* Normal PCI initialization.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-2-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 84 ++++++++++++++++++++-------------
+ 1 file changed, 51 insertions(+), 33 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -95,6 +95,7 @@
+  * @pcie: pointer to PCIe host info
+  * @phy: pointer to PHY control block
+  * @pcie_rst: pointer to port reset control
++ * @gpio_rst: gpio reset
+  * @slot: port slot
+  * @enabled: indicates if port is enabled
+  */
+@@ -104,6 +105,7 @@ struct mt7621_pcie_port {
+ 	struct mt7621_pcie *pcie;
+ 	struct phy *phy;
+ 	struct reset_control *pcie_rst;
++	struct gpio_desc *gpio_rst;
+ 	u32 slot;
+ 	bool enabled;
+ };
+@@ -117,8 +119,6 @@ struct mt7621_pcie_port {
+  * @offset: IO / Memory offset
+  * @dev: Pointer to PCIe device
+  * @ports: pointer to PCIe port information
+- * @perst: gpio reset
+- * @rst: pointer to pcie reset
+  * @resets_inverted: depends on chip revision
+  * reset lines are inverted.
+  */
+@@ -133,8 +133,6 @@ struct mt7621_pcie {
+ 		resource_size_t io;
+ 	} offset;
+ 	struct list_head ports;
+-	struct gpio_desc *perst;
+-	struct reset_control *rst;
+ 	bool resets_inverted;
+ };
+ 
+@@ -210,16 +208,16 @@ static void write_config(struct mt7621_p
+ 	pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA);
+ }
+ 
+-static inline void mt7621_perst_gpio_pcie_assert(struct mt7621_pcie *pcie)
++static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port)
+ {
+-	gpiod_set_value(pcie->perst, 0);
+-	mdelay(PERST_DELAY_US);
++	if (port->gpio_rst)
++		gpiod_set_value(port->gpio_rst, 1);
+ }
+ 
+-static inline void mt7621_perst_gpio_pcie_deassert(struct mt7621_pcie *pcie)
++static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port)
+ {
+-	gpiod_set_value(pcie->perst, 1);
+-	mdelay(PERST_DELAY_US);
++	if (port->gpio_rst)
++		gpiod_set_value(port->gpio_rst, 0);
+ }
+ 
+ static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port)
+@@ -367,6 +365,13 @@ static int mt7621_pcie_parse_port(struct
+ 	if (IS_ERR(port->phy))
+ 		return PTR_ERR(port->phy);
+ 
++	port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
++						       GPIOD_OUT_LOW);
++	if (IS_ERR(port->gpio_rst)) {
++		dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
++		return PTR_ERR(port->gpio_rst);
++	}
++
+ 	port->slot = slot;
+ 	port->pcie = pcie;
+ 
+@@ -383,12 +388,6 @@ static int mt7621_pcie_parse_dt(struct m
+ 	struct resource regs;
+ 	int err;
+ 
+-	pcie->perst = devm_gpiod_get(dev, "perst", GPIOD_OUT_HIGH);
+-	if (IS_ERR(pcie->perst)) {
+-		dev_err(dev, "failed to get gpio perst\n");
+-		return PTR_ERR(pcie->perst);
+-	}
+-
+ 	err = of_address_to_resource(node, 0, &regs);
+ 	if (err) {
+ 		dev_err(dev, "missing \"reg\" property\n");
+@@ -399,12 +398,6 @@ static int mt7621_pcie_parse_dt(struct m
+ 	if (IS_ERR(pcie->base))
+ 		return PTR_ERR(pcie->base);
+ 
+-	pcie->rst = devm_reset_control_get_exclusive(dev, "pcie");
+-	if (PTR_ERR(pcie->rst) == -EPROBE_DEFER) {
+-		dev_err(dev, "failed to get pcie reset control\n");
+-		return PTR_ERR(pcie->rst);
+-	}
+-
+ 	for_each_available_child_of_node(node, child) {
+ 		int slot;
+ 
+@@ -458,16 +451,49 @@ static int mt7621_pcie_init_port(struct
+ 	return 0;
+ }
+ 
++static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie)
++{
++	struct mt7621_pcie_port *port;
++
++	list_for_each_entry(port, &pcie->ports, list) {
++		/* PCIe RC reset assert */
++		mt7621_control_assert(port);
++
++		/* PCIe EP reset assert */
++		mt7621_rst_gpio_pcie_assert(port);
++	}
++
++	mdelay(PERST_DELAY_US);
++}
++
++static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
++{
++	struct mt7621_pcie_port *port;
++
++	list_for_each_entry(port, &pcie->ports, list)
++		mt7621_control_deassert(port);
++}
++
++static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie)
++{
++	struct mt7621_pcie_port *port;
++
++	list_for_each_entry(port, &pcie->ports, list)
++		mt7621_rst_gpio_pcie_deassert(port);
++
++	mdelay(PERST_DELAY_US);
++}
++
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+ 	struct device *dev = pcie->dev;
+ 	struct mt7621_pcie_port *port, *tmp;
+-	u32 val = 0;
+ 	int err;
+ 
+ 	rt_sysc_m32(PERST_MODE_MASK, PERST_MODE_GPIO, MT7621_GPIO_MODE);
+ 
+-	mt7621_perst_gpio_pcie_assert(pcie);
++	mt7621_pcie_reset_assert(pcie);
++	mt7621_pcie_reset_rc_deassert(pcie);
+ 
+ 	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ 		u32 slot = port->slot;
+@@ -476,16 +502,10 @@ static void mt7621_pcie_init_ports(struc
+ 		if (err) {
+ 			dev_err(dev, "Initiating port %d failed\n", slot);
+ 			list_del(&port->list);
+-		} else {
+-			val = read_config(pcie, slot, PCIE_FTS_NUM);
+-			dev_info(dev, "Port %d N_FTS = %x\n", slot,
+-				 (unsigned int)val);
+ 		}
+ 	}
+ 
+-	reset_control_assert(pcie->rst);
+-
+-	mt7621_perst_gpio_pcie_deassert(pcie);
++	mt7621_pcie_reset_ep_deassert(pcie);
+ 
+ 	list_for_each_entry(port, &pcie->ports, list) {
+ 		u32 slot = port->slot;
+@@ -499,8 +519,6 @@ static void mt7621_pcie_init_ports(struc
+ 			port->enabled = false;
+ 		}
+ 	}
+-
+-	reset_control_deassert(pcie->rst);
+ }
+ 
+ static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port)
diff --git a/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch b/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch
new file mode 100644
index 0000000..3d86355
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0103-staging-mt7621-pci-change-value-for-PERST_DELAY_MS.patch
@@ -0,0 +1,45 @@
+From e462e7d3211479df42357a620fa788a2257556b7 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:09 +0100
+Subject: [PATCH] staging: mt7621-pci: change value for 'PERST_DELAY_MS'
+
+Value of 'PERST_DELAY_MS' is too high and it is ok just
+to set up to 100 ms. Update also define name from
+'PERST_DELAY_US' into 'PERST_DELAY_MS'
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -86,7 +86,7 @@
+ #define MEMORY_BASE			0x0
+ #define PERST_MODE_MASK			GENMASK(11, 10)
+ #define PERST_MODE_GPIO			BIT(10)
+-#define PERST_DELAY_US			1000
++#define PERST_DELAY_MS			100
+ 
+ /**
+  * struct mt7621_pcie_port - PCIe port information
+@@ -463,7 +463,7 @@ static void mt7621_pcie_reset_assert(str
+ 		mt7621_rst_gpio_pcie_assert(port);
+ 	}
+ 
+-	mdelay(PERST_DELAY_US);
++	mdelay(PERST_DELAY_MS);
+ }
+ 
+ static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie)
+@@ -481,7 +481,7 @@ static void mt7621_pcie_reset_ep_deasser
+ 	list_for_each_entry(port, &pcie->ports, list)
+ 		mt7621_rst_gpio_pcie_deassert(port);
+ 
+-	mdelay(PERST_DELAY_US);
++	mdelay(PERST_DELAY_MS);
+ }
+ 
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
diff --git a/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch b/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch
new file mode 100644
index 0000000..f24bf83
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0104-staging-mt7621-pci-release-gpios-after-pci-initializ.patch
@@ -0,0 +1,76 @@
+From 4d6a758f2cd2122a7d895f913854c13da62ba6df Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:12 +0100
+Subject: [PATCH] staging: mt7621-pci: release gpios after pci initialization
+
+R3G's LEDs fail to initialize because one of them uses GPIO8
+Hence, release the GPIO resources after PCIe initialization
+and properly release also in driver error path.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-6-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 23 ++++++++++++++++++-----
+ 1 file changed, 18 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -484,6 +484,15 @@ static void mt7621_pcie_reset_ep_deasser
+ 	mdelay(PERST_DELAY_MS);
+ }
+ 
++static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
++{
++	struct mt7621_pcie_port *port;
++
++	list_for_each_entry(port, &pcie->ports, list)
++		if (port->gpio_rst)
++			gpiod_put(port->gpio_rst);
++}
++
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+ 	struct device *dev = pcie->dev;
+@@ -683,7 +692,8 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pcie_init_virtual_bridges(pcie);
+ 	if (err) {
+ 		dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
+-		return 0;
++		err = 0;
++		goto out_release_gpios;
+ 	}
+ 
+ 	mt7621_pcie_enable_ports(pcie);
+@@ -691,7 +701,7 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+ 	if (err) {
+ 		dev_err(dev, "Error requesting pci resources from ranges");
+-		return err;
++		goto out_release_gpios;
+ 	}
+ 
+ 	setup_cm_memory_region(pcie);
+@@ -699,16 +709,19 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pcie_request_resources(pcie, &res);
+ 	if (err) {
+ 		dev_err(dev, "Error requesting resources\n");
+-		return err;
++		goto out_release_gpios;
+ 	}
+ 
+ 	err = mt7621_pcie_register_host(bridge, &res);
+ 	if (err) {
+ 		dev_err(dev, "Error registering host\n");
+-		return err;
++		goto out_release_gpios;
+ 	}
+ 
+-	return 0;
++out_release_gpios:
++	mt7621_pcie_release_gpios(pcie);
++
++	return err;
+ }
+ 
+ static const struct of_device_id mt7621_pci_ids[] = {
diff --git a/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch b/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch
new file mode 100644
index 0000000..fc509e9
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0105-staging-mt7621-pci-delete-no-more-needed-mt7621_rese.patch
@@ -0,0 +1,46 @@
+From 4be54c3a495f08c05a8e485566e5b88cd3537f16 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 13 Mar 2020 21:09:13 +0100
+Subject: [PATCH] staging: mt7621-pci: delete no more needed
+ 'mt7621_reset_port'
+
+After review all the resets at the beggining the function
+'mt7621_reset_port' is not needed anymore. Hence delete it
+and its uses.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200313200913.24321-7-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -255,13 +255,6 @@ static inline void mt7621_control_deasse
+ 		reset_control_assert(port->pcie_rst);
+ }
+ 
+-static void mt7621_reset_port(struct mt7621_pcie_port *port)
+-{
+-	mt7621_control_assert(port);
+-	msleep(100);
+-	mt7621_control_deassert(port);
+-}
+-
+ static void setup_cm_memory_region(struct mt7621_pcie *pcie)
+ {
+ 	struct resource *mem_resource = &pcie->mem;
+@@ -427,12 +420,6 @@ static int mt7621_pcie_init_port(struct
+ 	u32 slot = port->slot;
+ 	int err;
+ 
+-	/*
+-	 * Any MT7621 Ralink pcie controller that doesn't have 0x0101 at
+-	 * the end of the chip_id has inverted PCI resets.
+-	 */
+-	mt7621_reset_port(port);
+-
+ 	err = phy_init(port->phy);
+ 	if (err) {
+ 		dev_err(dev, "failed to initialize port%d phy\n", slot);
diff --git a/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch b/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch
new file mode 100644
index 0000000..234af32
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0106-staging-mt7621-pci-phy-add-mt7621_phy_rmw-to-simplif.patch
@@ -0,0 +1,234 @@
+From bf0c6782e5b9a6deee4e223655325dc004fae8dd Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 15 Mar 2020 17:01:54 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: add 'mt7621_phy_rmw' to simplify
+ code
+
+In order to simplify driver code and decrease a bit LOC add new
+function 'mt7621_phy_rmw' where clear and set bits are passed as
+arguments.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200315160154.10292-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 158 +++++++++++-------------
+ 1 file changed, 71 insertions(+), 87 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -120,17 +120,25 @@ static inline void phy_write(struct mt76
+ 	regmap_write(phy->regmap, reg, val);
+ }
+ 
++static inline void mt7621_phy_rmw(struct mt7621_pci_phy *phy,
++				  u32 reg, u32 clr, u32 set)
++{
++	u32 val = phy_read(phy, reg);
++
++	val &= ~clr;
++	val |= set;
++	phy_write(phy, val, reg);
++}
++
+ static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
+ 				   struct mt7621_pci_phy_instance *instance)
+ {
+ 	u32 offset = (instance->index != 1) ?
+ 		RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
+-	u32 reg;
+ 
+-	reg = phy_read(phy, offset);
+-	reg &= ~(RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+-	reg |= (RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+-	phy_write(phy, reg, offset);
++	mt7621_phy_rmw(phy, offset,
++		       RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
++		       RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
+ }
+ 
+ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
+@@ -139,97 +147,77 @@ static void mt7621_set_phy_for_ssc(struc
+ 	struct device *dev = phy->dev;
+ 	u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+ 	u32 offset;
+-	u32 val;
+ 
+ 	reg = (reg >> 6) & 0x7;
+ 	/* Set PCIe Port PHY to disable SSC */
+ 	/* Debug Xtal Type */
+-	val = phy_read(phy, RG_PE1_FRC_H_XTAL_REG);
+-	val &= ~(RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE);
+-	val |= RG_PE1_FRC_H_XTAL_TYPE;
+-	val |= RG_PE1_H_XTAL_TYPE_VAL(0x00);
+-	phy_write(phy, val, RG_PE1_FRC_H_XTAL_REG);
++	mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
++		       RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE,
++		       RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
+ 
+ 	/* disable port */
+ 	offset = (instance->index != 1) ?
+ 		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-	val = phy_read(phy, offset);
+-	val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-	val |= RG_PE1_FRC_PHY_EN;
+-	phy_write(phy, val, offset);
+-
+-	/* Set Pre-divider ratio (for host mode) */
+-	val = phy_read(phy, RG_PE1_H_PLL_REG);
+-	val &= ~(RG_PE1_H_PLL_PREDIV);
++	mt7621_phy_rmw(phy, offset,
++		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
+ 
+ 	if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+-		val |= RG_PE1_H_PLL_PREDIV_VAL(0x01);
+-		phy_write(phy, val, RG_PE1_H_PLL_REG);
++		/* Set Pre-divider ratio (for host mode) */
++		mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++			       RG_PE1_H_PLL_PREDIV,
++			       RG_PE1_H_PLL_PREDIV_VAL(0x01));
+ 		dev_info(dev, "Xtal is 40MHz\n");
+-	} else { /* 25MHz | 20MHz Xtal */
+-		val |= RG_PE1_H_PLL_PREDIV_VAL(0x00);
+-		phy_write(phy, val, RG_PE1_H_PLL_REG);
+-		if (reg >= 6) {
+-			dev_info(dev, "Xtal is 25MHz\n");
+-
+-			/* Select feedback clock */
+-			val = phy_read(phy, RG_PE1_H_PLL_FBKSEL_REG);
+-			val &= ~(RG_PE1_H_PLL_FBKSEL);
+-			val |= RG_PE1_H_PLL_FBKSEL_VAL(0x01);
+-			phy_write(phy, val, RG_PE1_H_PLL_FBKSEL_REG);
+-
+-			/* DDS NCPO PCW (for host mode) */
+-			val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-			val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
+-			val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000);
+-			phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-
+-			/* DDS SSC dither period control */
+-			val = phy_read(phy, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-			val &= ~(RG_PE1_H_LCDDS_SSC_PRD);
+-			val |= RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d);
+-			phy_write(phy, val, RG_PE1_H_LCDDS_SSC_PRD_REG);
+-
+-			/* DDS SSC dither amplitude control */
+-			val = phy_read(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG);
+-			val &= ~(RG_PE1_H_LCDDS_SSC_DELTA |
+-				 RG_PE1_H_LCDDS_SSC_DELTA1);
+-			val |= RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a);
+-			val |= RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a);
+-			phy_write(phy, val, RG_PE1_H_LCDDS_SSC_DELTA_REG);
+-		} else {
+-			dev_info(dev, "Xtal is 20MHz\n");
+-		}
++	} else if (reg >= 6) { /* 25MHz Xal */
++		mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++			       RG_PE1_H_PLL_PREDIV,
++			       RG_PE1_H_PLL_PREDIV_VAL(0x00));
++		/* Select feedback clock */
++		mt7621_phy_rmw(phy, RG_PE1_H_PLL_FBKSEL_REG,
++			       RG_PE1_H_PLL_FBKSEL,
++			       RG_PE1_H_PLL_FBKSEL_VAL(0x01));
++		/* DDS NCPO PCW (for host mode) */
++		mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
++			       RG_PE1_H_LCDDS_SSC_PRD,
++			       RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18000000));
++		/* DDS SSC dither period control */
++		mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_PRD_REG,
++			       RG_PE1_H_LCDDS_SSC_PRD,
++			       RG_PE1_H_LCDDS_SSC_PRD_VAL(0x18d));
++		/* DDS SSC dither amplitude control */
++		mt7621_phy_rmw(phy, RG_PE1_H_LCDDS_SSC_DELTA_REG,
++			       RG_PE1_H_LCDDS_SSC_DELTA |
++			       RG_PE1_H_LCDDS_SSC_DELTA1,
++			       RG_PE1_H_LCDDS_SSC_DELTA_VAL(0x4a) |
++			       RG_PE1_H_LCDDS_SSC_DELTA1_VAL(0x4a));
++		dev_info(dev, "Xtal is 25MHz\n");
++	} else { /* 20MHz Xtal */
++		mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++			       RG_PE1_H_PLL_PREDIV,
++			       RG_PE1_H_PLL_PREDIV_VAL(0x00));
++
++		dev_info(dev, "Xtal is 20MHz\n");
+ 	}
+ 
+ 	/* DDS clock inversion */
+-	val = phy_read(phy, RG_PE1_LCDDS_CLK_PH_INV_REG);
+-	val &= ~(RG_PE1_LCDDS_CLK_PH_INV);
+-	val |= RG_PE1_LCDDS_CLK_PH_INV;
+-	phy_write(phy, val, RG_PE1_LCDDS_CLK_PH_INV_REG);
++	mt7621_phy_rmw(phy, RG_PE1_LCDDS_CLK_PH_INV_REG,
++		       RG_PE1_LCDDS_CLK_PH_INV, RG_PE1_LCDDS_CLK_PH_INV);
+ 
+ 	/* Set PLL bits */
+-	val = phy_read(phy, RG_PE1_H_PLL_REG);
+-	val &= ~(RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
+-		 RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN);
+-	val |= RG_PE1_H_PLL_BC_VAL(0x02);
+-	val |= RG_PE1_H_PLL_BP_VAL(0x06);
+-	val |= RG_PE1_H_PLL_IR_VAL(0x02);
+-	val |= RG_PE1_H_PLL_IC_VAL(0x01);
+-	val |= RG_PE1_PLL_DIVEN_VAL(0x02);
+-	phy_write(phy, val, RG_PE1_H_PLL_REG);
+-
+-	val = phy_read(phy, RG_PE1_H_PLL_BR_REG);
+-	val &= ~(RG_PE1_H_PLL_BR);
+-	val |= RG_PE1_H_PLL_BR_VAL(0x00);
+-	phy_write(phy, val, RG_PE1_H_PLL_BR_REG);
++	mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
++		       RG_PE1_H_PLL_BC | RG_PE1_H_PLL_BP | RG_PE1_H_PLL_IR |
++		       RG_PE1_H_PLL_IC | RG_PE1_PLL_DIVEN,
++		       RG_PE1_H_PLL_BC_VAL(0x02) | RG_PE1_H_PLL_BP_VAL(0x06) |
++		       RG_PE1_H_PLL_IR_VAL(0x02) | RG_PE1_H_PLL_IC_VAL(0x01) |
++		       RG_PE1_PLL_DIVEN_VAL(0x02));
++
++	mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
++		       RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
+ 
+ 	if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+ 		/* set force mode enable of da_pe1_mstckdiv */
+-		val = phy_read(phy, RG_PE1_MSTCKDIV_REG);
+-		val &= ~(RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV);
+-		val |= (RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
+-		phy_write(phy, val, RG_PE1_MSTCKDIV_REG);
++		mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
++			       RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
++			       RG_PE1_MSTCKDIV_VAL(0x01) | RG_PE1_FRC_MSTCKDIV);
+ 	}
+ }
+ 
+@@ -252,13 +240,11 @@ static int mt7621_pci_phy_power_on(struc
+ 	struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+ 	u32 offset = (instance->index != 1) ?
+ 		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-	u32 val;
+ 
+ 	/* Enable PHY and disable force mode */
+-	val = phy_read(mphy, offset);
+-	val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-	val |= (RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-	phy_write(mphy, val, offset);
++	mt7621_phy_rmw(mphy, offset,
++		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
++		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+ 
+ 	return 0;
+ }
+@@ -269,13 +255,11 @@ static int mt7621_pci_phy_power_off(stru
+ 	struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+ 	u32 offset = (instance->index != 1) ?
+ 		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-	u32 val;
+ 
+ 	/* Disable PHY */
+-	val = phy_read(mphy, offset);
+-	val &= ~(RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
+-	val |= RG_PE1_FRC_PHY_EN;
+-	phy_write(mphy, val, offset);
++	mt7621_phy_rmw(mphy, offset,
++		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
++		       RG_PE1_FRC_PHY_EN);
+ 
+ 	return 0;
+ }
diff --git a/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch b/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch
new file mode 100644
index 0000000..393fd4d
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0107-staging-mt7621-pci-fix-io-space-and-properly-set-res.patch
@@ -0,0 +1,131 @@
+From 3faf4e1c537de86058fc22a851cd979489b9185e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Wed, 18 Mar 2020 10:44:45 +0100
+Subject: [PATCH] staging: mt7621-pci: fix io space and properly set resource
+ limits
+
+Function 'mt7621_pci_parse_request_of_pci_ranges' is using
+'of_pci_range_to_resource' to get both mem and io resources.
+Internally this function calls to 'pci_address_to_pio' which
+returns -1 if io space address is an address > IO_SPACE_LIMIT
+which is 0xFFFF for mips. This mt7621 soc has io space in physical
+address 0x1e160000. In order to fix this, overwrite invalid io
+0xffffffff  with properly values from the device tree and set
+mapped address of this resource as io port base memory address
+calling 'set_io_port_base' function. There is also need to properly
+setup resource limits and io and memory windows with properly
+parsed values instead of set them as 'no limit' which it is wrong.
+For any reason I don't really know legacy driver sets up mem window
+as 0xFFFFFFFF and any other value seems to does not work as expected,
+so set up also here with same values.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200318094445.19669-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 43 +++++++++++++++++++--------------
+ 1 file changed, 25 insertions(+), 18 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -118,6 +118,7 @@ struct mt7621_pcie_port {
+  * @busn: bus range
+  * @offset: IO / Memory offset
+  * @dev: Pointer to PCIe device
++ * @io_map_base: virtual memory base address for io
+  * @ports: pointer to PCIe port information
+  * @resets_inverted: depends on chip revision
+  * reset lines are inverted.
+@@ -132,6 +133,7 @@ struct mt7621_pcie {
+ 		resource_size_t mem;
+ 		resource_size_t io;
+ 	} offset;
++	unsigned long io_map_base;
+ 	struct list_head ports;
+ 	bool resets_inverted;
+ };
+@@ -291,22 +293,21 @@ static int mt7621_pci_parse_request_of_p
+ 	}
+ 
+ 	for_each_of_pci_range(&parser, &range) {
+-		struct resource *res = NULL;
+-
+ 		switch (range.flags & IORESOURCE_TYPE_BITS) {
+ 		case IORESOURCE_IO:
+-			ioremap(range.cpu_addr, range.size);
+-			res = &pcie->io;
++			pcie->io_map_base =
++				(unsigned long)ioremap(range.cpu_addr,
++						       range.size);
++			of_pci_range_to_resource(&range, node, &pcie->io);
++			pcie->io.start = range.cpu_addr;
++			pcie->io.end = range.cpu_addr + range.size - 1;
+ 			pcie->offset.io = 0x00000000UL;
+ 			break;
+ 		case IORESOURCE_MEM:
+-			res = &pcie->mem;
++			of_pci_range_to_resource(&range, node, &pcie->mem);
+ 			pcie->offset.mem = 0x00000000UL;
+ 			break;
+ 		}
+-
+-		if (res)
+-			of_pci_range_to_resource(&range, node, res);
+ 	}
+ 
+ 	err = of_pci_parse_bus_range(node, &pcie->busn);
+@@ -318,6 +319,8 @@ static int mt7621_pci_parse_request_of_p
+ 		pcie->busn.flags = IORESOURCE_BUS;
+ 	}
+ 
++	set_io_port_base(pcie->io_map_base);
++
+ 	return 0;
+ }
+ 
+@@ -548,6 +551,10 @@ static void mt7621_pcie_enable_ports(str
+ 	u32 slot;
+ 	u32 val;
+ 
++	/* Setup MEMWIN and IOWIN */
++	pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE);
++	pcie_write(pcie, pcie->io.start, RALINK_PCI_IOBASE);
++
+ 	list_for_each_entry(port, &pcie->ports, list) {
+ 		if (port->enabled) {
+ 			mt7621_pcie_port_clk_enable(port);
+@@ -668,11 +675,17 @@ static int mt7621_pci_probe(struct platf
+ 		return err;
+ 	}
+ 
++	err = mt7621_pci_parse_request_of_pci_ranges(pcie);
++	if (err) {
++		dev_err(dev, "Error requesting pci resources from ranges");
++		goto out_release_gpios;
++	}
++
+ 	/* set resources limits */
+-	iomem_resource.start = 0;
+-	iomem_resource.end = ~0UL; /* no limit */
+-	ioport_resource.start = 0;
+-	ioport_resource.end = ~0UL; /* no limit */
++	iomem_resource.start = pcie->mem.start;
++	iomem_resource.end = pcie->mem.end;
++	ioport_resource.start = pcie->io.start;
++	ioport_resource.end = pcie->io.end;
+ 
+ 	mt7621_pcie_init_ports(pcie);
+ 
+@@ -685,12 +698,6 @@ static int mt7621_pci_probe(struct platf
+ 
+ 	mt7621_pcie_enable_ports(pcie);
+ 
+-	err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+-	if (err) {
+-		dev_err(dev, "Error requesting pci resources from ranges");
+-		goto out_release_gpios;
+-	}
+-
+ 	setup_cm_memory_region(pcie);
+ 
+ 	err = mt7621_pcie_request_resources(pcie, &res);
diff --git a/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch b/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch
new file mode 100644
index 0000000..5b4c461
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0108-staging-mt7621-pci-fix-register-to-set-up-virtual-br.patch
@@ -0,0 +1,28 @@
+From 0a3085ae142d8f5cf905b104bc66db3721a2fa33 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 19 Mar 2020 10:57:33 +0100
+Subject: [PATCH] staging: mt7621-pci: fix register to set up virtual bridges
+
+Instead of being using PCI Configuration and Status Register to
+set up virtual bridges we are using CONFIG_ADDR Register which is
+wrong. Hence, set the correct value.
+
+Fixes: 9a5e71a68d20 ("staging: mt7621-pci: simplify 'mt7621_pcie_init_virtual_bridges' function")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200319095733.1557-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -603,7 +603,7 @@ static int mt7621_pcie_init_virtual_brid
+ 		if ((pcie_link_status & BIT(i)) == 0)
+ 			p2p_br_devnum[i] = n++;
+ 
+-	pcie_rmw(pcie, RALINK_PCI_CONFIG_ADDR,
++	pcie_rmw(pcie, RALINK_PCI_PCICFG_ADDR,
+ 		 PCIE_P2P_BR_DEVNUM_MASK_FULL,
+ 		 (p2p_br_devnum[0] << PCIE_P2P_BR_DEVNUM0_SHIFT) |
+ 		 (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
diff --git a/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch b/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch
new file mode 100644
index 0000000..55abb89
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0109-staging-mt7621-pci-don-t-return-if-get-gpio-fails.patch
@@ -0,0 +1,34 @@
+From 23a788c23ed10e0d79092fcb693dcf0e357e1f7e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 19 Mar 2020 17:14:16 +0100
+Subject: [PATCH] staging: mt7621-pci: don't return if get gpio fails
+
+In some platforms gpio's are not used for reset but
+for other purposes. Because of that when we try to
+get them are valid gpio's but are already assigned
+to do other function. To avoid those kind of problems
+in those platforms just notice the fail in the kernel
+but continue doing normal boot.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200319161416.19033-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -363,10 +363,8 @@ static int mt7621_pcie_parse_port(struct
+ 
+ 	port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+ 						       GPIOD_OUT_LOW);
+-	if (IS_ERR(port->gpio_rst)) {
+-		dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
+-		return PTR_ERR(port->gpio_rst);
+-	}
++	if (IS_ERR(port->gpio_rst))
++		dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
+ 
+ 	port->slot = slot;
+ 	port->pcie = pcie;
diff --git a/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch b/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch
new file mode 100644
index 0000000..6d84bfd
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0110-staging-mt7621-pci-phy-avoid-to-create-to-different-.patch
@@ -0,0 +1,272 @@
+From 91eb47531421f0e8c9bc4594b4a7caa0e59dc83e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:19 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: avoid to create to different phys
+ for a dual port one
+
+This soc has two phy's for the pcie one of them using just a different
+register for settig it up but sharing all the rest of the config. Until
+now we was presenting this schema as three different phy's in the device
+tree using the 'phy-cells' node property to discriminate an index and
+setting up a complete phy for the dual port index. This sometimes worked
+properly but reconfiguring the same registers twice presents sometimes
+some unstable pcie links and the ports was not properly being detected.
+The problems only appears on hard resets and soft resets was properly
+working. Instead of having this schema just set two phy's in the device
+ree and use the 'phy-cells' property to say if the port has or not a dual
+port. Doing this configuration and set up becomes easier, LOC is decreased
+and the behaviour also gets deterministic with properly and stable pcie
+links in both hard and soft resets.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-2-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 144 ++++++++++--------------
+ 1 file changed, 59 insertions(+), 85 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -78,31 +78,21 @@
+ #define MAX_PHYS	2
+ 
+ /**
+- * struct mt7621_pci_phy_instance - Mt7621 Pcie PHY device
+- * @phy: pointer to the kernel PHY device
+- * @port_base: base register
+- * @index: internal ID to identify the Mt7621 PCIe PHY
+- */
+-struct mt7621_pci_phy_instance {
+-	struct phy *phy;
+-	void __iomem *port_base;
+-	u32 index;
+-};
+-
+-/**
+  * struct mt7621_pci_phy - Mt7621 Pcie PHY core
+  * @dev: pointer to device
+  * @regmap: kernel regmap pointer
+- * @phys: pointer to Mt7621 PHY device
+- * @nphys: number of PHY devices for this core
++ * @phy: pointer to the kernel PHY device
++ * @port_base: base register
++ * @has_dual_port: if the phy has dual ports.
+  * @bypass_pipe_rst: mark if 'mt7621_bypass_pipe_rst'
+  * needs to be executed. Depends on chip revision.
+  */
+ struct mt7621_pci_phy {
+ 	struct device *dev;
+ 	struct regmap *regmap;
+-	struct mt7621_pci_phy_instance **phys;
+-	int nphys;
++	struct phy *phy;
++	void __iomem *port_base;
++	bool has_dual_port;
+ 	bool bypass_pipe_rst;
+ };
+ 
+@@ -130,23 +120,23 @@ static inline void mt7621_phy_rmw(struct
+ 	phy_write(phy, val, reg);
+ }
+ 
+-static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy,
+-				   struct mt7621_pci_phy_instance *instance)
++static void mt7621_bypass_pipe_rst(struct mt7621_pci_phy *phy)
+ {
+-	u32 offset = (instance->index != 1) ?
+-		RG_PE1_PIPE_REG : RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH;
++	mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_RST);
++	mt7621_phy_rmw(phy, RG_PE1_PIPE_REG, 0, RG_PE1_PIPE_CMD_FRC);
+ 
+-	mt7621_phy_rmw(phy, offset,
+-		       RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC,
+-		       RG_PE1_PIPE_RST | RG_PE1_PIPE_CMD_FRC);
++	if (phy->has_dual_port) {
++		mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
++			       0, RG_PE1_PIPE_RST);
++		mt7621_phy_rmw(phy, RG_PE1_PIPE_REG + RG_P0_TO_P1_WIDTH,
++			       0, RG_PE1_PIPE_CMD_FRC);
++	}
+ }
+ 
+-static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy,
+-				   struct mt7621_pci_phy_instance *instance)
++static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
+ {
+ 	struct device *dev = phy->dev;
+ 	u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+-	u32 offset;
+ 
+ 	reg = (reg >> 6) & 0x7;
+ 	/* Set PCIe Port PHY to disable SSC */
+@@ -156,10 +146,13 @@ static void mt7621_set_phy_for_ssc(struc
+ 		       RG_PE1_FRC_H_XTAL_TYPE | RG_PE1_H_XTAL_TYPE_VAL(0x00));
+ 
+ 	/* disable port */
+-	offset = (instance->index != 1) ?
+-		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
+-	mt7621_phy_rmw(phy, offset,
+-		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++	mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG,
++		       RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++
++	if (phy->has_dual_port) {
++		mt7621_phy_rmw(phy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++			       RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++	}
+ 
+ 	if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
+ 		/* Set Pre-divider ratio (for host mode) */
+@@ -223,43 +216,44 @@ static void mt7621_set_phy_for_ssc(struc
+ 
+ static int mt7621_pci_phy_init(struct phy *phy)
+ {
+-	struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-	struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
++	struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+ 
+ 	if (mphy->bypass_pipe_rst)
+-		mt7621_bypass_pipe_rst(mphy, instance);
++		mt7621_bypass_pipe_rst(mphy);
+ 
+-	mt7621_set_phy_for_ssc(mphy, instance);
++	mt7621_set_phy_for_ssc(mphy);
+ 
+ 	return 0;
+ }
+ 
+ static int mt7621_pci_phy_power_on(struct phy *phy)
+ {
+-	struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-	struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+-	u32 offset = (instance->index != 1) ?
+-		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
++	struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+ 
+ 	/* Enable PHY and disable force mode */
+-	mt7621_phy_rmw(mphy, offset,
+-		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
+-		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN);
++	mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
++		       RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
++
++	if (mphy->has_dual_port) {
++		mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++			       RG_PE1_FRC_PHY_EN, RG_PE1_PHY_EN);
++	}
+ 
+ 	return 0;
+ }
+ 
+ static int mt7621_pci_phy_power_off(struct phy *phy)
+ {
+-	struct mt7621_pci_phy_instance *instance = phy_get_drvdata(phy);
+-	struct mt7621_pci_phy *mphy = dev_get_drvdata(phy->dev.parent);
+-	u32 offset = (instance->index != 1) ?
+-		RG_PE1_FRC_PHY_REG : RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH;
++	struct mt7621_pci_phy *mphy = phy_get_drvdata(phy);
+ 
+ 	/* Disable PHY */
+-	mt7621_phy_rmw(mphy, offset,
+-		       RG_PE1_FRC_PHY_EN | RG_PE1_PHY_EN,
+-		       RG_PE1_FRC_PHY_EN);
++	mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG,
++		       RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++
++	if (mphy->has_dual_port) {
++		mt7621_phy_rmw(mphy, RG_PE1_FRC_PHY_REG + RG_P0_TO_P1_WIDTH,
++			       RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
++	}
+ 
+ 	return 0;
+ }
+@@ -282,13 +276,15 @@ static struct phy *mt7621_pcie_phy_of_xl
+ {
+ 	struct mt7621_pci_phy *mt7621_phy = dev_get_drvdata(dev);
+ 
+-	if (args->args_count == 0)
+-		return mt7621_phy->phys[0]->phy;
+-
+ 	if (WARN_ON(args->args[0] >= MAX_PHYS))
+ 		return ERR_PTR(-ENODEV);
+ 
+-	return mt7621_phy->phys[args->args[0]]->phy;
++	mt7621_phy->has_dual_port = args->args[0];
++
++	dev_info(dev, "PHY for 0x%08x (dual port = %d)\n",
++		 (unsigned int)mt7621_phy->port_base, mt7621_phy->has_dual_port);
++
++	return mt7621_phy->phy;
+ }
+ 
+ static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
+@@ -309,19 +305,11 @@ static int mt7621_pci_phy_probe(struct p
+ 	struct phy_provider *provider;
+ 	struct mt7621_pci_phy *phy;
+ 	struct resource *res;
+-	int port;
+-	void __iomem *port_base;
+ 
+ 	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+ 	if (!phy)
+ 		return -ENOMEM;
+ 
+-	phy->nphys = MAX_PHYS;
+-	phy->phys = devm_kcalloc(dev, phy->nphys,
+-				 sizeof(*phy->phys), GFP_KERNEL);
+-	if (!phy->phys)
+-		return -ENOMEM;
+-
+ 	attr = soc_device_match(mt7621_pci_quirks_match);
+ 	if (attr)
+ 		phy->bypass_pipe_rst = true;
+@@ -335,39 +323,25 @@ static int mt7621_pci_phy_probe(struct p
+ 		return -ENXIO;
+ 	}
+ 
+-	port_base = devm_ioremap_resource(dev, res);
+-	if (IS_ERR(port_base)) {
++	phy->port_base = devm_ioremap_resource(dev, res);
++	if (IS_ERR(phy->port_base)) {
+ 		dev_err(dev, "failed to remap phy regs\n");
+-		return PTR_ERR(port_base);
++		return PTR_ERR(phy->port_base);
+ 	}
+ 
+-	phy->regmap = devm_regmap_init_mmio(phy->dev, port_base,
++	phy->regmap = devm_regmap_init_mmio(phy->dev, phy->port_base,
+ 					    &mt7621_pci_phy_regmap_config);
+ 	if (IS_ERR(phy->regmap))
+ 		return PTR_ERR(phy->regmap);
+ 
+-	for (port = 0; port < MAX_PHYS; port++) {
+-		struct mt7621_pci_phy_instance *instance;
+-		struct phy *pphy;
+-
+-		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+-		if (!instance)
+-			return -ENOMEM;
+-
+-		phy->phys[port] = instance;
+-
+-		pphy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
+-		if (IS_ERR(phy)) {
+-			dev_err(dev, "failed to create phy\n");
+-			return PTR_ERR(phy);
+-		}
+-
+-		instance->port_base = port_base;
+-		instance->phy = pphy;
+-		instance->index = port;
+-		phy_set_drvdata(pphy, instance);
++	phy->phy = devm_phy_create(dev, dev->of_node, &mt7621_pci_phy_ops);
++	if (IS_ERR(phy)) {
++		dev_err(dev, "failed to create phy\n");
++		return PTR_ERR(phy);
+ 	}
+ 
++	phy_set_drvdata(phy->phy, phy);
++
+ 	provider = devm_of_phy_provider_register(dev, mt7621_pcie_phy_of_xlate);
+ 
+ 	return PTR_ERR_OR_ZERO(provider);
diff --git a/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch b/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch
new file mode 100644
index 0000000..61aa80e
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0111-staging-mt7621-pci-use-only-two-phys-from-device-tre.patch
@@ -0,0 +1,42 @@
+From c752b54bda4d772426c5eeb56978d2e41bd525b4 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:21 +0100
+Subject: [PATCH] staging: mt7621-pci: use only two phys from device tree
+
+In order to align work with the mt7621-pci-phy part of
+the driver and device tree which is now using only two
+real phys one of them dual ported properly parse the
+device tree and don't call phy initialization for the
+slot 1 because is being taking into account when the
+phy for the slot 0 is instantiated.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-4-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -358,7 +358,7 @@ static int mt7621_pcie_parse_port(struct
+ 
+ 	snprintf(name, sizeof(name), "pcie-phy%d", slot);
+ 	port->phy = devm_phy_get(dev, name);
+-	if (IS_ERR(port->phy))
++	if (IS_ERR(port->phy) && slot != 1)
+ 		return PTR_ERR(port->phy);
+ 
+ 	port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+@@ -495,6 +495,11 @@ static void mt7621_pcie_init_ports(struc
+ 	list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ 		u32 slot = port->slot;
+ 
++		if (slot == 1) {
++			port->enabled = true;
++			continue;
++		}
++
+ 		err = mt7621_pcie_init_port(port);
+ 		if (err) {
+ 			dev_err(dev, "Initiating port %d failed\n", slot);
diff --git a/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch b/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch
new file mode 100644
index 0000000..383c896
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0112-staging-mt7621-pci-change-variable-to-print-for-slot.patch
@@ -0,0 +1,26 @@
+From b59343b7de448c30e5b098484a7c7c5cb300df2f Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:22 +0100
+Subject: [PATCH] staging: mt7621-pci: change variable to print for slot
+
+We are using the counter to print the slot which has been
+enabled. Use the correct associated slot for the port instead.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-5-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -562,7 +562,7 @@ static void mt7621_pcie_enable_ports(str
+ 		if (port->enabled) {
+ 			mt7621_pcie_port_clk_enable(port);
+ 			mt7621_pcie_enable_port(port);
+-			dev_info(dev, "PCIE%d enabled\n", num_slots_enabled);
++			dev_info(dev, "PCIE%d enabled\n", port->slot);
+ 			num_slots_enabled++;
+ 		}
+ 	}
diff --git a/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch b/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch
new file mode 100644
index 0000000..bf6fdf1
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0113-staging-mt7621-pci-be-sure-gpio-descriptor-is-null-o.patch
@@ -0,0 +1,33 @@
+From 87068309300c707d659ce79232eae827604804a4 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 12:01:23 +0100
+Subject: [PATCH] staging: mt7621-pci: be sure gpio descriptor is null on fails
+
+Function 'devm_gpiod_get_index_optional' returns NULL if the
+descriptor is invalid and the error associated for the error
+pointer is ENOENT. Sometimes if the pin is just assigned the
+error associated for the pointer might not be ENOENT but other.
+In order to avoid weirds behaviours if this happen set descriptor
+to NULL in the driver port structure.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320110123.9907-6-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -363,8 +363,10 @@ static int mt7621_pcie_parse_port(struct
+ 
+ 	port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+ 						       GPIOD_OUT_LOW);
+-	if (IS_ERR(port->gpio_rst))
++	if (IS_ERR(port->gpio_rst)) {
+ 		dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
++		port->gpio_rst = NULL;
++	}
+ 
+ 	port->slot = slot;
+ 	port->pcie = pcie;
diff --git a/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch b/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch
new file mode 100644
index 0000000..d733e58
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0114-staging-mt7621-pci-avoid-to-poweroff-the-phy-for-slo.patch
@@ -0,0 +1,79 @@
+From d81fe3c13aa6f4ab1ec318212d2007175e6d05aa Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Fri, 20 Mar 2020 16:38:37 +0100
+Subject: [PATCH] staging: mt7621-pci: avoid to poweroff the phy for slot one
+
+Phy for slot 0 and 1 is shared and handled properly in slot 0.
+If there is only one port in use,(slot 0) we shall not call the
+'phy_power_off' function with an invalid slot because kernel
+will crash with an unaligned access fault like the following:
+
+mt7621-pci 1e140000.pcie: Error applying setting, reverse things back
+mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1)
+mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0)
+mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
+mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
+mt7621-pci 1e140000.pcie: pcie1 no card, disable it (RST & CLK)
+Unhandled kernel unaligned access[#1]:
+CPU: 3 PID: 111 Comm: kworker/3:2 Not tainted 5.6.0-rc3-00347-g825c6f470c62-dirty #9
+Workqueue: events deferred_probe_work_func
+$ 0   : 00000000 00000001 5f60d043 8fe1ba80
+$ 4   : 0000010d 01eb9000 00000000 00000000
+$ 8   : 294b4c00 80940000 00000008 000000ce
+$12   : 2e303030 00000000 00000000 65696370
+$16   : ffffffed 0000010d 8e373cd0 8214c1e0
+$20   : 00000000 82144c80 82144680 8214c250
+$24   : 00000018 803ef8f4
+$28   : 8e372000 8e373c60 8214c080 803940e8
+Hi    : 00000125
+Lo    : 122f2000
+epc   : 807b3328 mutex_lock+0x8/0x44
+ra    : 803940e8 phy_power_off+0x28/0xb0
+Status: 1100fc03        KERNEL EXL IE
+Cause : 00800010 (ExcCode 04)
+BadVA : 0000010d
+PrId  : 0001992f (MIPS 1004Kc)
+Modules linked in:
+Process kworker/3:2 (pid: 111, threadinfo=(ptrval), task=(ptrval), tls=00000000)
+Stack : 8e373cd0 803fe4f4 8e372000 8e373c90 8214c080 804fde1c 8e373c98 808d62f4
+         8e373c78 00000000 8214c254 804fe648 1e160000 804f27b8 00000001 808d62f4
+         00000000 00000001 8214c228 808d62f4 80930000 809a0000 8fd47e10 808d63d4
+         808d62d4 8fd47e10 808d0000 808d0000 8e373cd0 8e373cd0 809e2a74 809db510
+         809db510 00000006 00000001 00000000 00000000 00000000 01000000 1e1440ff
+         ...
+Call Trace:
+[<807b3328>] mutex_lock+0x8/0x44
+[<803940e8>] phy_power_off+0x28/0xb0
+[<804fe648>] mt7621_pci_probe+0xc20/0xd18
+[<80402ab8>] platform_drv_probe+0x40/0x94
+[<80400a74>] really_probe+0x104/0x364
+[<803feb74>] bus_for_each_drv+0x84/0xdc
+[<80400924>] __device_attach+0xdc/0x120
+[<803ffb5c>] bus_probe_device+0xa0/0xbc
+[<80400124>] deferred_probe_work_func+0x7c/0xbc
+[<800420e8>] process_one_work+0x230/0x450
+[<80042638>] worker_thread+0x330/0x5fc
+[<80048eb0>] kthread+0x12c/0x134
+[<80007438>] ret_from_kernel_thread+0x14/0x1c
+Code: 24050002  27bdfff8  8f830000 <c0850000> 14a00005  00000000  00600825  e0810000  1020fffa
+
+Fixes: bf516f413f4e ("staging: mt7621-pci: use only two phys from device tree")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200320153837.20415-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -517,7 +517,8 @@ static void mt7621_pcie_init_ports(struc
+ 		if (!mt7621_pcie_port_is_linkup(port)) {
+ 			dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
+ 				slot);
+-			phy_power_off(port->phy);
++			if (slot != 1)
++				phy_power_off(port->phy);
+ 			mt7621_control_assert(port);
+ 			mt7621_pcie_port_clk_disable(port);
+ 			port->enabled = false;
diff --git a/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch b/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch
new file mode 100644
index 0000000..5bfd205
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0115-staging-mt7621-pci-delete-release-gpios-related-code.patch
@@ -0,0 +1,91 @@
+From 9d789a7728c37e8730b6a9cca60cf155f18537ea Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 08:26:50 +0100
+Subject: [PATCH] staging: mt7621-pci: delete release gpios related code
+
+Making gpio8 and gpio9 vendor specific and putting them
+into the specific dts file makes not needed to release
+gpios anymore because we are not occupying those pins
+in the first place if it is not necessary. When the
+device tree is parsed we can also check and return for
+the error because we rely in the fact that the related
+device for the board is correct.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321072650.7784-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 27 +++++++--------------------
+ 1 file changed, 7 insertions(+), 20 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -364,8 +364,8 @@ static int mt7621_pcie_parse_port(struct
+ 	port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot,
+ 						       GPIOD_OUT_LOW);
+ 	if (IS_ERR(port->gpio_rst)) {
+-		dev_notice(dev, "Failed to get GPIO for PCIe%d\n", slot);
+-		port->gpio_rst = NULL;
++		dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot);
++		return PTR_ERR(port->gpio_rst);
+ 	}
+ 
+ 	port->slot = slot;
+@@ -474,15 +474,6 @@ static void mt7621_pcie_reset_ep_deasser
+ 	mdelay(PERST_DELAY_MS);
+ }
+ 
+-static void mt7621_pcie_release_gpios(struct mt7621_pcie *pcie)
+-{
+-	struct mt7621_pcie_port *port;
+-
+-	list_for_each_entry(port, &pcie->ports, list)
+-		if (port->gpio_rst)
+-			gpiod_put(port->gpio_rst);
+-}
+-
+ static void mt7621_pcie_init_ports(struct mt7621_pcie *pcie)
+ {
+ 	struct device *dev = pcie->dev;
+@@ -684,7 +675,7 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pci_parse_request_of_pci_ranges(pcie);
+ 	if (err) {
+ 		dev_err(dev, "Error requesting pci resources from ranges");
+-		goto out_release_gpios;
++		return err;
+ 	}
+ 
+ 	/* set resources limits */
+@@ -698,8 +689,7 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pcie_init_virtual_bridges(pcie);
+ 	if (err) {
+ 		dev_err(dev, "Nothing is connected in virtual bridges. Exiting...");
+-		err = 0;
+-		goto out_release_gpios;
++		return 0;
+ 	}
+ 
+ 	mt7621_pcie_enable_ports(pcie);
+@@ -709,19 +699,16 @@ static int mt7621_pci_probe(struct platf
+ 	err = mt7621_pcie_request_resources(pcie, &res);
+ 	if (err) {
+ 		dev_err(dev, "Error requesting resources\n");
+-		goto out_release_gpios;
++		return err;
+ 	}
+ 
+ 	err = mt7621_pcie_register_host(bridge, &res);
+ 	if (err) {
+ 		dev_err(dev, "Error registering host\n");
+-		goto out_release_gpios;
++		return err;
+ 	}
+ 
+-out_release_gpios:
+-	mt7621_pcie_release_gpios(pcie);
+-
+-	return err;
++	return 0;
+ }
+ 
+ static const struct of_device_id mt7621_pci_ids[] = {
diff --git a/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch
new file mode 100644
index 0000000..b333bb3
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0116-staging-mt7621-pci-use-builtin_platform_driver.patch
@@ -0,0 +1,29 @@
+From 60a15339ceab9fc2a6cdc85fd54b66b2c947ab4e Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:21 +0100
+Subject: [PATCH] staging: mt7621-pci: use builtin_platform_driver()
+
+Macro builtin_platform_driver can be used for builtin drivers
+that don't do anything in driver init. So, use the macro
+builtin_platform_driver and remove some boilerplate code.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -725,9 +725,4 @@ static struct platform_driver mt7621_pci
+ 	},
+ };
+ 
+-static int __init mt7621_pci_init(void)
+-{
+-	return platform_driver_register(&mt7621_pci_driver);
+-}
+-
+-module_init(mt7621_pci_init);
++builtin_platform_driver(mt7621_pci_driver);
diff --git a/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch b/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch
new file mode 100644
index 0000000..e55def4
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0117-staging-mt7621-pci-phy-use-builtin_platform_driver.patch
@@ -0,0 +1,32 @@
+From ffe3dee4081055b4f58bc50dd3f5c97de42cf126 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:23 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: use builtin_platform_driver()
+
+Macro builtin_platform_driver can be used for builtin drivers
+that don't do anything in driver init. So, use the macro
+builtin_platform_driver and remove some boilerplate code.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-3-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -361,12 +361,7 @@ static struct platform_driver mt7621_pci
+ 	},
+ };
+ 
+-static int __init mt7621_pci_phy_drv_init(void)
+-{
+-	return platform_driver_register(&mt7621_pci_phy_driver);
+-}
+-
+-module_init(mt7621_pci_phy_drv_init);
++builtin_platform_driver(mt7621_pci_phy_driver);
+ 
+ MODULE_AUTHOR("Sergio Paracuellos <sergio.paracuellos@gmail.com>");
+ MODULE_DESCRIPTION("MediaTek MT7621 PCIe PHY driver");
diff --git a/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch b/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch
new file mode 100644
index 0000000..9eb8345
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0118-staging-mt7621-pci-phy-re-do-xtal_mode-detection.patch
@@ -0,0 +1,68 @@
+From ff83e3023cb8fc3b5dfc12e0c91bf1eb9dc4c4c6 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sat, 21 Mar 2020 14:36:24 +0100
+Subject: [PATCH] staging: mt7621-pci-phy: re-do 'xtal_mode' detection
+
+Detection of the Xtal mode is using magic numbers that
+can be avoided using properly some definitions and a more
+accurate variable name from 'reg' into 'xtal_mode'. This
+increase readability.
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200321133624.31388-4-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
++++ b/drivers/staging/mt7621-pci-phy/pci-mt7621-phy.c
+@@ -75,6 +75,9 @@
+ 
+ #define RG_PE1_FRC_MSTCKDIV			BIT(5)
+ 
++#define XTAL_MODE_SEL_SHIFT			6
++#define XTAL_MODE_SEL_MASK			0x7
++
+ #define MAX_PHYS	2
+ 
+ /**
+@@ -136,9 +139,11 @@ static void mt7621_bypass_pipe_rst(struc
+ static void mt7621_set_phy_for_ssc(struct mt7621_pci_phy *phy)
+ {
+ 	struct device *dev = phy->dev;
+-	u32 reg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
++	u32 xtal_mode;
++
++	xtal_mode = (rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0)
++		     >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
+ 
+-	reg = (reg >> 6) & 0x7;
+ 	/* Set PCIe Port PHY to disable SSC */
+ 	/* Debug Xtal Type */
+ 	mt7621_phy_rmw(phy, RG_PE1_FRC_H_XTAL_REG,
+@@ -154,13 +159,13 @@ static void mt7621_set_phy_for_ssc(struc
+ 			       RG_PE1_PHY_EN, RG_PE1_FRC_PHY_EN);
+ 	}
+ 
+-	if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
++	if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
+ 		/* Set Pre-divider ratio (for host mode) */
+ 		mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
+ 			       RG_PE1_H_PLL_PREDIV,
+ 			       RG_PE1_H_PLL_PREDIV_VAL(0x01));
+ 		dev_info(dev, "Xtal is 40MHz\n");
+-	} else if (reg >= 6) { /* 25MHz Xal */
++	} else if (xtal_mode >= 6) { /* 25MHz Xal */
+ 		mt7621_phy_rmw(phy, RG_PE1_H_PLL_REG,
+ 			       RG_PE1_H_PLL_PREDIV,
+ 			       RG_PE1_H_PLL_PREDIV_VAL(0x00));
+@@ -206,7 +211,7 @@ static void mt7621_set_phy_for_ssc(struc
+ 	mt7621_phy_rmw(phy, RG_PE1_H_PLL_BR_REG,
+ 		       RG_PE1_H_PLL_BR, RG_PE1_H_PLL_BR_VAL(0x00));
+ 
+-	if (reg <= 5 && reg >= 3) { /* 40MHz Xtal */
++	if (xtal_mode <= 5 && xtal_mode >= 3) { /* 40MHz Xtal */
+ 		/* set force mode enable of da_pe1_mstckdiv */
+ 		mt7621_phy_rmw(phy, RG_PE1_MSTCKDIV_REG,
+ 			       RG_PE1_MSTCKDIV | RG_PE1_FRC_MSTCKDIV,
diff --git a/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch b/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch
new file mode 100644
index 0000000..9af46f4
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0119-staging-mt7621-pci-avoid-to-set-iomem_resource-addre.patch
@@ -0,0 +1,35 @@
+From 4f0f36b67564311a4ce4441510ef94848febbab2 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Sun, 22 Mar 2020 08:21:28 +0100
+Subject: [PATCH] staging: mt7621-pci: avoid to set 'iomem_resource' addresses
+
+Setting up kernel resource 'iomem_resource' for PCI with
+addresses parsed from device tree gots into a conflict within
+the usb xhci driver:
+
+xhci-mtk 1e1c0000.xhci: can't request region for resource [mem 0x1e1c0000-0x1e1c0fff]
+xhci-mtk: probe of 1e1c0000.xhci failed with error -16
+
+Don't assign it and maintain the default addresses for this
+resource seems to fix the problem. Checking legacy driver it
+is being only  setting the 'ioport_resource'.
+
+Fixes: 09dd629eeabb ("staging: mt7621-pci: fix io space and properly set resource limits")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200322072128.4454-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -679,8 +679,6 @@ static int mt7621_pci_probe(struct platf
+ 	}
+ 
+ 	/* set resources limits */
+-	iomem_resource.start = pcie->mem.start;
+-	iomem_resource.end = pcie->mem.end;
+ 	ioport_resource.start = pcie->io.start;
+ 	ioport_resource.end = pcie->io.end;
+ 
diff --git a/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch b/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch
new file mode 100644
index 0000000..9efcb80
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0120-staging-mt7621-pci-properly-power-off-dual-ported-pc.patch
@@ -0,0 +1,65 @@
+From 5fcded5e857cf66c9592e4be28c4dab4520c9177 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 9 Apr 2020 13:16:52 +0200
+Subject: [PATCH] staging: mt7621-pci: properly power off dual-ported pcie phy
+
+Pcie phy for pcie0 and pcie1 is shared using a dual ported
+one. Current code was assuming that if nothing is connected
+in pcie0 it won't be also nothing connected in pcie1. This
+assumtion is wrong for some devices such us 'Mikrotik rbm33g'
+and 'ZyXEL LTE3301-PLUS' where only connecting a card to the
+second bus on the phy is possible. For such devices kernel
+hangs in the same point because of the wrong poweroff of the
+phy getting the following trace:
+
+mt7621-pci-phy 1e149000.pcie-phy: PHY for 0xbe149000 (dual port = 1)
+mt7621-pci-phy 1e14a000.pcie-phy: PHY for 0xbe14a000 (dual port = 0)
+mt7621-pci-phy 1e149000.pcie-phy: Xtal is 40MHz
+mt7621-pci-phy 1e14a000.pcie-phy: Xtal is 40MHz
+mt7621-pci 1e140000.pcie: pcie0 no card, disable it (RST & CLK)
+[hangs]
+
+The wrong assumption is located in the 'mt7621_pcie_init_ports'
+function where we are just making a power off of the phy for
+slots 0 and 2 if nothing is connected in them. Hence, only
+poweroff the phy if nothing is connected in both slot 0 and
+slot 1 avoiding the kernel to hang.
+
+Fixes: 5737cfe87a9c ("staging: mt7621-pci: avoid to poweroff the phy for slot one")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200409111652.30964-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-pci/pci-mt7621.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -502,17 +502,25 @@ static void mt7621_pcie_init_ports(struc
+ 
+ 	mt7621_pcie_reset_ep_deassert(pcie);
+ 
++	tmp = NULL;
+ 	list_for_each_entry(port, &pcie->ports, list) {
+ 		u32 slot = port->slot;
+ 
+ 		if (!mt7621_pcie_port_is_linkup(port)) {
+ 			dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n",
+ 				slot);
+-			if (slot != 1)
+-				phy_power_off(port->phy);
+ 			mt7621_control_assert(port);
+ 			mt7621_pcie_port_clk_disable(port);
+ 			port->enabled = false;
++
++			if (slot == 0) {
++				tmp = port;
++				continue;
++			}
++
++			if (slot == 1 && tmp && !tmp->enabled)
++				phy_power_off(tmp->phy);
++
+ 		}
+ 	}
+ }
diff --git a/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch b/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch
new file mode 100644
index 0000000..68de6df
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0121-staging-mt7621-pci-fix-PCIe-interrupt-mapping.patch
@@ -0,0 +1,157 @@
+From fab6710e4c51f4eb622f95a08322ab5fdbe3f295 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Mon, 13 Apr 2020 07:59:42 +0200
+Subject: [PATCH] staging: mt7621-pci: fix PCIe interrupt mapping
+
+MT7621 has three assigned interrupts for the pcie. This
+interrupts should properly being mapped taking into account
+which devices are finally connected in which bus according
+to link status. So the irq mappings should be as follows
+according to link status (three bits indicating which devices
+are link up):
+
+* For PCIe Bus 1 slot 0:
+  - status = 0x2 || status = 0x6 => IRQ = pcie1_irq (24).
+  - status = 0x4 => IRQ = pcie2_irq (25).
+  - default => IRQ = pcie0_irq (23).
+* For PCIe Bus 2 slot 0:
+  - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
+  - default => IRQ = pcie1_irq (24).
+* For PCIe Bus 2 slot 1:
+  - status = 0x5 || status = 0x6 => IRQ = pcie2_irq (25).
+  - default => IRQ = pcie1_irq (24).
+* For PCIe Bus 3 any slot:
+  - default => IRQ = pcie2_irq (25).
+
+Because of this, the function 'of_irq_parse_and_map_pci' cannot
+be used and we need to change device tree information from using
+the 'interrupt-map' and 'interrupt-map-mask' properties into an
+'interrupts' property to be able to get irq information from the
+ports using the 'platform_get_irq' and storing an 'irq-map' into
+the pcie driver data node to properly map correct irq using a
+new 'mt7621_map_irq' function where this map will be read and the
+correct irq returned.
+
+Fixes: 46d093124df4 ("staging: mt7621-pci: improve interrupt mapping")
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Link: https://lore.kernel.org/r/20200413055942.2714-1-sergio.paracuellos@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/mt7621-dts/mt7621.dtsi  |  9 +++----
+ drivers/staging/mt7621-pci/pci-mt7621.c | 36 +++++++++++++++++++++++--
+ 2 files changed, 38 insertions(+), 7 deletions(-)
+
+--- a/drivers/staging/mt7621-pci/pci-mt7621.c
++++ b/drivers/staging/mt7621-pci/pci-mt7621.c
+@@ -97,6 +97,7 @@
+  * @pcie_rst: pointer to port reset control
+  * @gpio_rst: gpio reset
+  * @slot: port slot
++ * @irq: GIC irq
+  * @enabled: indicates if port is enabled
+  */
+ struct mt7621_pcie_port {
+@@ -107,6 +108,7 @@ struct mt7621_pcie_port {
+ 	struct reset_control *pcie_rst;
+ 	struct gpio_desc *gpio_rst;
+ 	u32 slot;
++	int irq;
+ 	bool enabled;
+ };
+ 
+@@ -120,6 +122,7 @@ struct mt7621_pcie_port {
+  * @dev: Pointer to PCIe device
+  * @io_map_base: virtual memory base address for io
+  * @ports: pointer to PCIe port information
++ * @irq_map: irq mapping info according pcie link status
+  * @resets_inverted: depends on chip revision
+  * reset lines are inverted.
+  */
+@@ -135,6 +138,7 @@ struct mt7621_pcie {
+ 	} offset;
+ 	unsigned long io_map_base;
+ 	struct list_head ports;
++	int irq_map[PCIE_P2P_MAX];
+ 	bool resets_inverted;
+ };
+ 
+@@ -279,6 +283,16 @@ static void setup_cm_memory_region(struc
+ 	}
+ }
+ 
++static int mt7621_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
++{
++	struct mt7621_pcie *pcie = pdev->bus->sysdata;
++	struct device *dev = pcie->dev;
++	int irq = pcie->irq_map[slot];
++
++	dev_info(dev, "bus=%d slot=%d irq=%d\n", pdev->bus->number, slot, irq);
++	return irq;
++}
++
+ static int mt7621_pci_parse_request_of_pci_ranges(struct mt7621_pcie *pcie)
+ {
+ 	struct device *dev = pcie->dev;
+@@ -330,6 +344,7 @@ static int mt7621_pcie_parse_port(struct
+ {
+ 	struct mt7621_pcie_port *port;
+ 	struct device *dev = pcie->dev;
++	struct platform_device *pdev = to_platform_device(dev);
+ 	struct device_node *pnode = dev->of_node;
+ 	struct resource regs;
+ 	char name[10];
+@@ -371,6 +386,12 @@ static int mt7621_pcie_parse_port(struct
+ 	port->slot = slot;
+ 	port->pcie = pcie;
+ 
++	port->irq = platform_get_irq(pdev, slot);
++	if (port->irq < 0) {
++		dev_err(dev, "Failed to get IRQ for PCIe%d\n", slot);
++		return -ENXIO;
++	}
++
+ 	INIT_LIST_HEAD(&port->list);
+ 	list_add_tail(&port->list, &pcie->ports);
+ 
+@@ -585,13 +606,15 @@ static int mt7621_pcie_init_virtual_brid
+ {
+ 	u32 pcie_link_status = 0;
+ 	u32 n;
+-	int i;
++	int i = 0;
+ 	u32 p2p_br_devnum[PCIE_P2P_MAX];
++	int irqs[PCIE_P2P_MAX];
+ 	struct mt7621_pcie_port *port;
+ 
+ 	list_for_each_entry(port, &pcie->ports, list) {
+ 		u32 slot = port->slot;
+ 
++		irqs[i++] = port->irq;
+ 		if (port->enabled)
+ 			pcie_link_status |= BIT(slot);
+ 	}
+@@ -614,6 +637,15 @@ static int mt7621_pcie_init_virtual_brid
+ 		 (p2p_br_devnum[1] << PCIE_P2P_BR_DEVNUM1_SHIFT) |
+ 		 (p2p_br_devnum[2] << PCIE_P2P_BR_DEVNUM2_SHIFT));
+ 
++	/* Assign IRQs */
++	n = 0;
++	for (i = 0; i < PCIE_P2P_MAX; i++)
++		if (pcie_link_status & BIT(i))
++			pcie->irq_map[n++] = irqs[i];
++
++	for (i = n; i < PCIE_P2P_MAX; i++)
++		pcie->irq_map[i] = -1;
++
+ 	return 0;
+ }
+ 
+@@ -638,7 +670,7 @@ static int mt7621_pcie_register_host(str
+ 	host->busnr = pcie->busn.start;
+ 	host->dev.parent = pcie->dev;
+ 	host->ops = &mt7621_pci_ops;
+-	host->map_irq = of_irq_parse_and_map_pci;
++	host->map_irq = mt7621_map_irq;
+ 	host->swizzle_irq = pci_common_swizzle;
+ 	host->sysdata = pcie;
+ 
diff --git a/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch b/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch
new file mode 100644
index 0000000..86600e8
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0122-mips-ralink-enable-zboot-support.patch
@@ -0,0 +1,26 @@
+From 1f0400d0e2c410b04f246aefb2e9b5155eb4b0bf Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Tue, 13 Oct 2020 10:05:47 +0800
+Subject: mips: ralink: enable zboot support
+
+Some of these ralink devices come with an ancient u-boot which can't
+extract LZMA properly when image gets too big.
+Enable zboot support to get a self-extracting kernel instead of relying
+on broken u-boot support.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+---
+ arch/mips/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -629,6 +629,7 @@ config RALINK
+ 	select SYS_SUPPORTS_32BIT_KERNEL
+ 	select SYS_SUPPORTS_LITTLE_ENDIAN
+ 	select SYS_SUPPORTS_MIPS16
++	select SYS_SUPPORTS_ZBOOT
+ 	select SYS_HAS_EARLY_PRINTK
+ 	select CLKDEV_LOOKUP
+ 	select ARCH_HAS_RESET_CONTROLLER
diff --git a/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch b/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch
new file mode 100644
index 0000000..bdf98f2
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0123-mips-ralink-manage-low-reset-lines.patch
@@ -0,0 +1,45 @@
+From 3f9ef7785a9cd69cb75f5e2ea4ca79a24752e496 Mon Sep 17 00:00:00 2001
+From: Sander Vanheule <sander@svanheule.net>
+Date: Wed, 3 Feb 2021 10:21:41 +0100
+Subject: MIPS: ralink: manage low reset lines
+
+Reset lines with indices smaller than 8 are currently considered invalid
+by the rt2880-reset reset controller.
+
+The MT7621 SoC uses a number of these low reset lines. The DTS defines
+reset lines "hsdma", "fe", and "mcm" with respective values 5, 6, and 2.
+As a result of the above restriction, these resets cannot be asserted or
+de-asserted by the reset controller. In cases where the bootloader does
+not de-assert these lines, this results in e.g. the MT7621's internal
+switch staying in reset.
+
+Change the reset controller to only ignore the system reset, so all
+reset lines with index greater than 0 are considered valid.
+
+Signed-off-by: Sander Vanheule <sander@svanheule.net>
+Acked-by: John Crispin <john@phrozen.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+---
+ arch/mips/ralink/reset.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/ralink/reset.c
++++ b/arch/mips/ralink/reset.c
+@@ -27,7 +27,7 @@ static int ralink_assert_device(struct r
+ {
+ 	u32 val;
+ 
+-	if (id < 8)
++	if (id == 0)
+ 		return -1;
+ 
+ 	val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
+@@ -42,7 +42,7 @@ static int ralink_deassert_device(struct
+ {
+ 	u32 val;
+ 
+-	if (id < 8)
++	if (id == 0)
+ 		return -1;
+ 
+ 	val = rt_sysc_r32(SYSC_REG_RESET_CTRL);
diff --git a/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch b/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch
new file mode 100644
index 0000000..9142faa
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0200-linkit_bootstrap.patch
@@ -0,0 +1,97 @@
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -52,6 +52,7 @@ obj-$(CONFIG_ECHO)		+= echo/
+ obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
+ obj-$(CONFIG_CXL_BASE)		+= cxl/
+ obj-$(CONFIG_PCI_ENDPOINT_TEST)	+= pci_endpoint_test.o
++obj-$(CONFIG_SOC_MT7620)	+= linkit.o
+ obj-$(CONFIG_OCXL)		+= ocxl/
+ obj-y				+= cardreader/
+ obj-$(CONFIG_PVPANIC)   	+= pvpanic.o
+--- /dev/null
++++ b/drivers/misc/linkit.c
+@@ -0,0 +1,84 @@
++/*
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License version 2 as
++ *  publishhed by the Free Software Foundation.
++ *
++ *  Copyright (C) 2015 John Crispin <blogic@openwrt.org>
++ */
++
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/of.h>
++#include <linux/mtd/mtd.h>
++#include <linux/gpio.h>
++
++#define LINKIT_LATCH_GPIO	11
++
++struct linkit_hw_data {
++	char board[16];
++	char rev[16];
++};
++
++static void sanify_string(char *s)
++{
++	int i;
++
++	for (i = 0; i < 15; i++)
++		if (s[i] <= 0x20)
++			s[i] = '\0';
++	s[15] = '\0';
++}
++
++static int linkit_probe(struct platform_device *pdev)
++{
++	struct linkit_hw_data hw;
++	struct mtd_info *mtd;
++	size_t retlen;
++	int ret;
++
++	mtd = get_mtd_device_nm("factory");
++	if (IS_ERR(mtd))
++		return PTR_ERR(mtd);
++
++	ret = mtd_read(mtd, 0x400, sizeof(hw), &retlen, (u_char *) &hw);
++	put_mtd_device(mtd);
++
++	sanify_string(hw.board);
++	sanify_string(hw.rev);
++
++	dev_info(&pdev->dev, "Version  : %s\n", hw.board);
++	dev_info(&pdev->dev, "Revision : %s\n", hw.rev);
++
++	if (!strcmp(hw.board, "LINKITS7688")) {
++		dev_info(&pdev->dev, "setting up bootstrap latch\n");
++
++		if (devm_gpio_request(&pdev->dev, LINKIT_LATCH_GPIO, "bootstrap")) {
++			dev_err(&pdev->dev, "failed to setup bootstrap gpio\n");
++			return -1;
++		}
++		gpio_direction_output(LINKIT_LATCH_GPIO, 0);
++	}
++
++	return 0;
++}
++
++static const struct of_device_id linkit_match[] = {
++	{ .compatible = "mediatek,linkit" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, linkit_match);
++
++static struct platform_driver linkit_driver = {
++	.probe = linkit_probe,
++	.driver = {
++		.name = "mtk-linkit",
++		.owner = THIS_MODULE,
++		.of_match_table = linkit_match,
++	},
++};
++
++int __init linkit_init(void)
++{
++	return platform_driver_register(&linkit_driver);
++}
++late_initcall_sync(linkit_init);
diff --git a/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch b/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
new file mode 100644
index 0000000..cca09cd
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0300-mtd-rawnand-add-driver-support-for-MT7621-nand-flash.patch
@@ -0,0 +1,1400 @@
+From e84e2430ee0e483842b4ff013ae8a6e7e2fa2734 Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao@mediatek.com>
+Date: Wed, 1 Apr 2020 02:07:58 +0800
+Subject: [PATCH 1/2] mtd: rawnand: add driver support for MT7621 nand
+ flash controller
+
+This patch adds NAND flash controller driver for MediaTek MT7621 SoC.
+
+The NAND flash controller is similar with controllers described in
+mtk_nand.c, except that the controller from MT7621 doesn't support DMA
+transmission, and some registers' offset and fields are different.
+
+Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+---
+ drivers/mtd/nand/raw/Kconfig       |    8 +
+ drivers/mtd/nand/raw/Makefile      |    1 +
+ drivers/mtd/nand/raw/mt7621_nand.c | 1348 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1357 insertions(+)
+ create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
+
+--- a/drivers/mtd/nand/raw/Kconfig
++++ b/drivers/mtd/nand/raw/Kconfig
+@@ -391,6 +391,14 @@ config MTD_NAND_QCOM
+ 	  Enables support for NAND flash chips on SoCs containing the EBI2 NAND
+ 	  controller. This controller is found on IPQ806x SoC.
+ 
++config MTD_NAND_MT7621
++	tristate "MT7621 NAND controller"
++	depends on SOC_MT7621 || COMPILE_TEST
++	depends on HAS_IOMEM
++	help
++	  Enables support for NAND controller on MT7621 SoC.
++	  This driver uses PIO mode for data transmission instead of DMA mode.
++
+ config MTD_NAND_MTK
+ 	tristate "MTK NAND controller"
+ 	depends on ARCH_MEDIATEK || COMPILE_TEST
+--- a/drivers/mtd/nand/raw/Makefile
++++ b/drivers/mtd/nand/raw/Makefile
+@@ -52,6 +52,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_n
+ obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
+ obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
+ obj-$(CONFIG_MTD_NAND_QCOM)		+= qcom_nandc.o
++obj-$(CONFIG_MTD_NAND_MT7621)		+= mt7621_nand.o
+ obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
+ obj-$(CONFIG_MTD_NAND_MXIC)		+= mxic_nand.o
+ obj-$(CONFIG_MTD_NAND_TEGRA)		+= tegra_nand.o
+--- /dev/null
++++ b/drivers/mtd/nand/raw/mt7621_nand.c
+@@ -0,0 +1,1350 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * MediaTek MT7621 NAND Flash Controller driver
++ *
++ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
++ *
++ * Author: Weijie Gao <weijie.gao@mediatek.com>
++ */
++
++#include <linux/io.h>
++#include <linux/clk.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/sizes.h>
++#include <linux/iopoll.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/rawnand.h>
++#include <linux/mtd/partitions.h>
++#include <linux/platform_device.h>
++#include <asm/addrspace.h>
++
++/* NFI core registers */
++#define NFI_CNFG			0x000
++#define   CNFG_OP_MODE_S		12
++#define   CNFG_OP_MODE_M		GENMASK(14, 12)
++#define     CNFG_OP_CUSTOM		6
++#define   CNFG_AUTO_FMT_EN		BIT(9)
++#define   CNFG_HW_ECC_EN		BIT(8)
++#define   CNFG_BYTE_RW			BIT(6)
++#define   CNFG_READ_MODE		BIT(1)
++
++#define NFI_PAGEFMT			0x004
++#define   PAGEFMT_FDM_ECC_S		12
++#define   PAGEFMT_FDM_ECC_M		GENMASK(15, 12)
++#define   PAGEFMT_FDM_S			8
++#define   PAGEFMT_FDM_M			GENMASK(11, 8)
++#define   PAGEFMT_SPARE_S		4
++#define   PAGEFMT_SPARE_M		GENMASK(5, 4)
++#define   PAGEFMT_PAGE_S		0
++#define   PAGEFMT_PAGE_M		GENMASK(1, 0)
++
++#define NFI_CON				0x008
++#define   CON_NFI_SEC_S			12
++#define   CON_NFI_SEC_M			GENMASK(15, 12)
++#define   CON_NFI_BWR			BIT(9)
++#define   CON_NFI_BRD			BIT(8)
++#define   CON_NFI_RST			BIT(1)
++#define   CON_FIFO_FLUSH		BIT(0)
++
++#define NFI_ACCCON			0x00c
++#define   ACCCON_POECS_S		28
++#define   ACCCON_POECS_MAX		0x0f
++#define   ACCCON_POECS_DEF		3
++#define   ACCCON_PRECS_S		22
++#define   ACCCON_PRECS_MAX		0x3f
++#define   ACCCON_PRECS_DEF		3
++#define   ACCCON_C2R_S			16
++#define   ACCCON_C2R_MAX		0x3f
++#define   ACCCON_C2R_DEF		7
++#define   ACCCON_W2R_S			12
++#define   ACCCON_W2R_MAX		0x0f
++#define   ACCCON_W2R_DEF		7
++#define   ACCCON_WH_S			8
++#define   ACCCON_WH_MAX			0x0f
++#define   ACCCON_WH_DEF			15
++#define   ACCCON_WST_S			4
++#define   ACCCON_WST_MAX		0x0f
++#define   ACCCON_WST_DEF		15
++#define   ACCCON_WST_MIN		3
++#define   ACCCON_RLT_S			0
++#define   ACCCON_RLT_MAX		0x0f
++#define   ACCCON_RLT_DEF		15
++#define   ACCCON_RLT_MIN		3
++
++#define NFI_CMD				0x020
++
++#define NFI_ADDRNOB			0x030
++#define   ADDR_ROW_NOB_S		4
++#define   ADDR_ROW_NOB_M		GENMASK(6, 4)
++#define   ADDR_COL_NOB_S		0
++#define   ADDR_COL_NOB_M		GENMASK(2, 0)
++
++#define NFI_COLADDR			0x034
++#define NFI_ROWADDR			0x038
++
++#define NFI_STRDATA			0x040
++#define   STR_DATA			BIT(0)
++
++#define NFI_CNRNB			0x044
++#define   CB2R_TIME_S			4
++#define   CB2R_TIME_M			GENMASK(7, 4)
++#define   STR_CNRNB			BIT(0)
++
++#define NFI_DATAW			0x050
++#define NFI_DATAR			0x054
++
++#define NFI_PIO_DIRDY			0x058
++#define   PIO_DIRDY			BIT(0)
++
++#define NFI_STA				0x060
++#define   STA_NFI_FSM_S			16
++#define   STA_NFI_FSM_M			GENMASK(19, 16)
++#define     STA_FSM_CUSTOM_DATA		14
++#define   STA_BUSY			BIT(8)
++#define   STA_ADDR			BIT(1)
++#define   STA_CMD			BIT(0)
++
++#define NFI_ADDRCNTR			0x070
++#define   SEC_CNTR_S			12
++#define   SEC_CNTR_M			GENMASK(15, 12)
++#define   SEC_ADDR_S			0
++#define   SEC_ADDR_M			GENMASK(9, 0)
++
++#define NFI_CSEL			0x090
++#define   CSEL_S			0
++#define   CSEL_M			GENMASK(1, 0)
++
++#define NFI_FDM0L			0x0a0
++#define NFI_FDML(n)			(0x0a0 + ((n) << 3))
++
++#define NFI_FDM0M			0x0a4
++#define NFI_FDMM(n)			(0x0a4 + ((n) << 3))
++
++#define NFI_MASTER_STA			0x210
++#define   MAS_ADDR			GENMASK(11, 9)
++#define   MAS_RD			GENMASK(8, 6)
++#define   MAS_WR			GENMASK(5, 3)
++#define   MAS_RDDLY			GENMASK(2, 0)
++
++/* ECC engine registers */
++#define ECC_ENCCON			0x000
++#define   ENC_EN			BIT(0)
++
++#define ECC_ENCCNFG			0x004
++#define   ENC_CNFG_MSG_S		16
++#define   ENC_CNFG_MSG_M		GENMASK(28, 16)
++#define   ENC_MODE_S			4
++#define   ENC_MODE_M			GENMASK(5, 4)
++#define     ENC_MODE_NFI		1
++#define   ENC_TNUM_S			0
++#define   ENC_TNUM_M			GENMASK(2, 0)
++
++#define ECC_ENCIDLE			0x00c
++#define   ENC_IDLE			BIT(0)
++
++#define ECC_DECCON			0x100
++#define   DEC_EN			BIT(0)
++
++#define ECC_DECCNFG			0x104
++#define   DEC_EMPTY_EN			BIT(31)
++#define   DEC_CS_S			16
++#define   DEC_CS_M			GENMASK(28, 16)
++#define   DEC_CON_S			12
++#define   DEC_CON_M			GENMASK(13, 12)
++#define     DEC_CON_EL			2
++#define   DEC_MODE_S			4
++#define   DEC_MODE_M			GENMASK(5, 4)
++#define     DEC_MODE_NFI		1
++#define   DEC_TNUM_S			0
++#define   DEC_TNUM_M			GENMASK(2, 0)
++
++#define ECC_DECIDLE			0x10c
++#define   DEC_IDLE			BIT(1)
++
++#define ECC_DECENUM			0x114
++#define   ERRNUM_S			2
++#define   ERRNUM_M			GENMASK(3, 0)
++
++#define ECC_DECDONE			0x118
++#define   DEC_DONE7			BIT(7)
++#define   DEC_DONE6			BIT(6)
++#define   DEC_DONE5			BIT(5)
++#define   DEC_DONE4			BIT(4)
++#define   DEC_DONE3			BIT(3)
++#define   DEC_DONE2			BIT(2)
++#define   DEC_DONE1			BIT(1)
++#define   DEC_DONE0			BIT(0)
++
++#define ECC_DECEL(n)			(0x11c + (n) * 4)
++#define   DEC_EL_ODD_S			16
++#define   DEC_EL_EVEN_S			0
++#define   DEC_EL_M			0x1fff
++#define   DEC_EL_BYTE_POS_S		3
++#define   DEC_EL_BIT_POS_M		GENMASK(2, 0)
++
++#define ECC_FDMADDR			0x13c
++
++/* ENCIDLE and DECIDLE */
++#define   ECC_IDLE			BIT(0)
++
++#define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \
++	((tpoecs) << ACCCON_POECS_S | (tprecs) << ACCCON_PRECS_S | \
++	(tc2r) << ACCCON_C2R_S | (tw2r) << ACCCON_W2R_S | \
++	(twh) << ACCCON_WH_S | (twst) << ACCCON_WST_S | (trlt))
++
++#define MASTER_STA_MASK			(MAS_ADDR | MAS_RD | MAS_WR | \
++					 MAS_RDDLY)
++#define NFI_RESET_TIMEOUT		1000000
++#define NFI_CORE_TIMEOUT		500000
++#define ECC_ENGINE_TIMEOUT		500000
++
++#define ECC_SECTOR_SIZE			512
++#define ECC_PARITY_BITS			13
++
++#define NFI_FDM_SIZE		8
++
++#define MT7621_NFC_NAME			"mt7621-nand"
++
++struct mt7621_nfc {
++	struct nand_controller controller;
++	struct nand_chip nand;
++	struct clk *nfi_clk;
++	struct device *dev;
++
++	void __iomem *nfi_regs;
++	void __iomem *ecc_regs;
++
++	u32 spare_per_sector;
++};
++
++static const u16 mt7621_nfi_page_size[] = { SZ_512, SZ_2K, SZ_4K };
++static const u8 mt7621_nfi_spare_size[] = { 16, 26, 27, 28 };
++static const u8 mt7621_ecc_strength[] = { 4, 6, 8, 10, 12 };
++
++static inline u32 nfi_read32(struct mt7621_nfc *nfc, u32 reg)
++{
++	return readl(nfc->nfi_regs + reg);
++}
++
++static inline void nfi_write32(struct mt7621_nfc *nfc, u32 reg, u32 val)
++{
++	writel(val, nfc->nfi_regs + reg);
++}
++
++static inline u16 nfi_read16(struct mt7621_nfc *nfc, u32 reg)
++{
++	return readw(nfc->nfi_regs + reg);
++}
++
++static inline void nfi_write16(struct mt7621_nfc *nfc, u32 reg, u16 val)
++{
++	writew(val, nfc->nfi_regs + reg);
++}
++
++static inline void ecc_write16(struct mt7621_nfc *nfc, u32 reg, u16 val)
++{
++	writew(val, nfc->ecc_regs + reg);
++}
++
++static inline u32 ecc_read32(struct mt7621_nfc *nfc, u32 reg)
++{
++	return readl(nfc->ecc_regs + reg);
++}
++
++static inline void ecc_write32(struct mt7621_nfc *nfc, u32 reg, u32 val)
++{
++	return writel(val, nfc->ecc_regs + reg);
++}
++
++static inline u8 *oob_fdm_ptr(struct nand_chip *nand, int sect)
++{
++	return nand->oob_poi + sect * NFI_FDM_SIZE;
++}
++
++static inline u8 *oob_ecc_ptr(struct mt7621_nfc *nfc, int sect)
++{
++	struct nand_chip *nand = &nfc->nand;
++
++	return nand->oob_poi + nand->ecc.steps * NFI_FDM_SIZE +
++		sect * (nfc->spare_per_sector - NFI_FDM_SIZE);
++}
++
++static inline u8 *page_data_ptr(struct nand_chip *nand, const u8 *buf,
++				int sect)
++{
++	return (u8 *)buf + sect * nand->ecc.size;
++}
++
++static int mt7621_ecc_wait_idle(struct mt7621_nfc *nfc, u32 reg)
++{
++	struct device *dev = nfc->dev;
++	u32 val;
++	int ret;
++
++	ret = readw_poll_timeout_atomic(nfc->ecc_regs + reg, val,
++					val & ECC_IDLE, 10,
++					ECC_ENGINE_TIMEOUT);
++	if (ret) {
++		dev_warn(dev, "ECC engine timed out entering idle mode\n");
++		return -EIO;
++	}
++
++	return 0;
++}
++
++static int mt7621_ecc_decoder_wait_done(struct mt7621_nfc *nfc, u32 sect)
++{
++	struct device *dev = nfc->dev;
++	u32 val;
++	int ret;
++
++	ret = readw_poll_timeout_atomic(nfc->ecc_regs + ECC_DECDONE, val,
++					val & (1 << sect), 10,
++					ECC_ENGINE_TIMEOUT);
++
++	if (ret) {
++		dev_warn(dev, "ECC decoder for sector %d timed out\n",
++			 sect);
++		return -ETIMEDOUT;
++	}
++
++	return 0;
++}
++
++static void mt7621_ecc_encoder_op(struct mt7621_nfc *nfc, bool enable)
++{
++	mt7621_ecc_wait_idle(nfc, ECC_ENCIDLE);
++	ecc_write16(nfc, ECC_ENCCON, enable ? ENC_EN : 0);
++}
++
++static void mt7621_ecc_decoder_op(struct mt7621_nfc *nfc, bool enable)
++{
++	mt7621_ecc_wait_idle(nfc, ECC_DECIDLE);
++	ecc_write16(nfc, ECC_DECCON, enable ? DEC_EN : 0);
++}
++
++static int mt7621_ecc_correct_check(struct mt7621_nfc *nfc, u8 *sector_buf,
++				   u8 *fdm_buf, u32 sect)
++{
++	struct nand_chip *nand = &nfc->nand;
++	u32 decnum, num_error_bits, fdm_end_bits;
++	u32 error_locations, error_bit_loc;
++	u32 error_byte_pos, error_bit_pos;
++	int bitflips = 0;
++	u32 i;
++
++	decnum = ecc_read32(nfc, ECC_DECENUM);
++	num_error_bits = (decnum >> (sect << ERRNUM_S)) & ERRNUM_M;
++	fdm_end_bits = (nand->ecc.size + NFI_FDM_SIZE) << 3;
++
++	if (!num_error_bits)
++		return 0;
++
++	if (num_error_bits == ERRNUM_M)
++		return -1;
++
++	for (i = 0; i < num_error_bits; i++) {
++		error_locations = ecc_read32(nfc, ECC_DECEL(i / 2));
++		error_bit_loc = (error_locations >> ((i % 2) * DEC_EL_ODD_S)) &
++				DEC_EL_M;
++		error_byte_pos = error_bit_loc >> DEC_EL_BYTE_POS_S;
++		error_bit_pos = error_bit_loc & DEC_EL_BIT_POS_M;
++
++		if (error_bit_loc < (nand->ecc.size << 3)) {
++			if (sector_buf) {
++				sector_buf[error_byte_pos] ^=
++					(1 << error_bit_pos);
++			}
++		} else if (error_bit_loc < fdm_end_bits) {
++			if (fdm_buf) {
++				fdm_buf[error_byte_pos - nand->ecc.size] ^=
++					(1 << error_bit_pos);
++			}
++		}
++
++		bitflips++;
++	}
++
++	return bitflips;
++}
++
++static int mt7621_nfc_wait_write_completion(struct mt7621_nfc *nfc,
++					    struct nand_chip *nand)
++{
++	struct device *dev = nfc->dev;
++	u16 val;
++	int ret;
++
++	ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_ADDRCNTR, val,
++		((val & SEC_CNTR_M) >> SEC_CNTR_S) >= nand->ecc.steps, 10,
++		NFI_CORE_TIMEOUT);
++
++	if (ret) {
++		dev_warn(dev, "NFI core write operation timed out\n");
++		return -ETIMEDOUT;
++	}
++
++	return ret;
++}
++
++static void mt7621_nfc_hw_reset(struct mt7621_nfc *nfc)
++{
++	u32 val;
++	int ret;
++
++	/* reset all registers and force the NFI master to terminate */
++	nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST);
++
++	/* wait for the master to finish the last transaction */
++	ret = readw_poll_timeout(nfc->nfi_regs + NFI_MASTER_STA, val,
++				 !(val & MASTER_STA_MASK), 50,
++				 NFI_RESET_TIMEOUT);
++	if (ret) {
++		dev_warn(nfc->dev, "Failed to reset NFI master in %dms\n",
++			 NFI_RESET_TIMEOUT);
++	}
++
++	/* ensure any status register affected by the NFI master is reset */
++	nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST);
++	nfi_write16(nfc, NFI_STRDATA, 0);
++}
++
++static inline void mt7621_nfc_hw_init(struct mt7621_nfc *nfc)
++{
++	u32 acccon;
++
++	/*
++	 * CNRNB: nand ready/busy register
++	 * -------------------------------
++	 * 7:4: timeout register for polling the NAND busy/ready signal
++	 * 0  : poll the status of the busy/ready signal after [7:4]*16 cycles.
++	 */
++	nfi_write16(nfc, NFI_CNRNB, CB2R_TIME_M | STR_CNRNB);
++
++	mt7621_nfc_hw_reset(nfc);
++
++	/* Apply default access timing */
++	acccon = ACCTIMING(ACCCON_POECS_DEF, ACCCON_PRECS_DEF, ACCCON_C2R_DEF,
++			   ACCCON_W2R_DEF, ACCCON_WH_DEF, ACCCON_WST_DEF,
++			   ACCCON_RLT_DEF);
++
++	nfi_write32(nfc, NFI_ACCCON, acccon);
++}
++
++static int mt7621_nfc_send_command(struct mt7621_nfc *nfc, u8 command)
++{
++	struct device *dev = nfc->dev;
++	u32 val;
++	int ret;
++
++	nfi_write32(nfc, NFI_CMD, command);
++
++	ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
++					!(val & STA_CMD), 10,
++					NFI_CORE_TIMEOUT);
++	if (ret) {
++		dev_warn(dev, "NFI core timed out entering command mode\n");
++		return -EIO;
++	}
++
++	return 0;
++}
++
++static int mt7621_nfc_send_address_byte(struct mt7621_nfc *nfc, int addr)
++{
++	struct device *dev = nfc->dev;
++	u32 val;
++	int ret;
++
++	nfi_write32(nfc, NFI_COLADDR, addr);
++	nfi_write32(nfc, NFI_ROWADDR, 0);
++	nfi_write16(nfc, NFI_ADDRNOB, 1);
++
++	ret = readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
++					!(val & STA_ADDR), 10,
++					NFI_CORE_TIMEOUT);
++	if (ret) {
++		dev_warn(dev, "NFI core timed out entering address mode\n");
++		return -EIO;
++	}
++
++	return 0;
++}
++
++static int mt7621_nfc_send_address(struct mt7621_nfc *nfc, const u8 *addr,
++				   unsigned int naddrs)
++{
++	int ret;
++
++	while (naddrs) {
++		ret = mt7621_nfc_send_address_byte(nfc, *addr);
++		if (ret)
++			return ret;
++
++		addr++;
++		naddrs--;
++	}
++
++	return 0;
++}
++
++static void mt7621_nfc_wait_pio_ready(struct mt7621_nfc *nfc)
++{
++	struct device *dev = nfc->dev;
++	int ret;
++	u16 val;
++
++	ret = readw_poll_timeout_atomic(nfc->nfi_regs + NFI_PIO_DIRDY, val,
++					val & PIO_DIRDY, 10,
++					NFI_CORE_TIMEOUT);
++	if (ret < 0)
++		dev_err(dev, "NFI core PIO mode not ready\n");
++}
++
++static u32 mt7621_nfc_pio_read(struct mt7621_nfc *nfc, bool br)
++{
++	u32 reg;
++
++	/* after each byte read, the NFI_STA reg is reset by the hardware */
++	reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S;
++	if (reg != STA_FSM_CUSTOM_DATA) {
++		reg = nfi_read16(nfc, NFI_CNFG);
++		reg |= CNFG_READ_MODE | CNFG_BYTE_RW;
++		if (!br)
++			reg &= ~CNFG_BYTE_RW;
++		nfi_write16(nfc, NFI_CNFG, reg);
++
++		/*
++		 * set to max sector to allow the HW to continue reading over
++		 * unaligned accesses
++		 */
++		nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BRD);
++
++		/* trigger to fetch data */
++		nfi_write16(nfc, NFI_STRDATA, STR_DATA);
++	}
++
++	mt7621_nfc_wait_pio_ready(nfc);
++
++	return nfi_read32(nfc, NFI_DATAR);
++}
++
++static void mt7621_nfc_read_data(struct mt7621_nfc *nfc, u8 *buf, u32 len)
++{
++	while (((uintptr_t)buf & 3) && len) {
++		*buf = mt7621_nfc_pio_read(nfc, true);
++		buf++;
++		len--;
++	}
++
++	while (len >= 4) {
++		*(u32 *)buf = mt7621_nfc_pio_read(nfc, false);
++		buf += 4;
++		len -= 4;
++	}
++
++	while (len) {
++		*buf = mt7621_nfc_pio_read(nfc, true);
++		buf++;
++		len--;
++	}
++}
++
++static void mt7621_nfc_read_data_discard(struct mt7621_nfc *nfc, u32 len)
++{
++	while (len >= 4) {
++		mt7621_nfc_pio_read(nfc, false);
++		len -= 4;
++	}
++
++	while (len) {
++		mt7621_nfc_pio_read(nfc, true);
++		len--;
++	}
++}
++
++static void mt7621_nfc_pio_write(struct mt7621_nfc *nfc, u32 val, bool bw)
++{
++	u32 reg;
++
++	reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S;
++	if (reg != STA_FSM_CUSTOM_DATA) {
++		reg = nfi_read16(nfc, NFI_CNFG);
++		reg &= ~(CNFG_READ_MODE | CNFG_BYTE_RW);
++		if (bw)
++			reg |= CNFG_BYTE_RW;
++		nfi_write16(nfc, NFI_CNFG, reg);
++
++		nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BWR);
++		nfi_write16(nfc, NFI_STRDATA, STR_DATA);
++	}
++
++	mt7621_nfc_wait_pio_ready(nfc);
++	nfi_write32(nfc, NFI_DATAW, val);
++}
++
++static void mt7621_nfc_write_data(struct mt7621_nfc *nfc, const u8 *buf,
++				  u32 len)
++{
++	while (((uintptr_t)buf & 3) && len) {
++		mt7621_nfc_pio_write(nfc, *buf, true);
++		buf++;
++		len--;
++	}
++
++	while (len >= 4) {
++		mt7621_nfc_pio_write(nfc, *(const u32 *)buf, false);
++		buf += 4;
++		len -= 4;
++	}
++
++	while (len) {
++		mt7621_nfc_pio_write(nfc, *buf, true);
++		buf++;
++		len--;
++	}
++}
++
++static void mt7621_nfc_write_data_empty(struct mt7621_nfc *nfc, u32 len)
++{
++	while (len >= 4) {
++		mt7621_nfc_pio_write(nfc, 0xffffffff, false);
++		len -= 4;
++	}
++
++	while (len) {
++		mt7621_nfc_pio_write(nfc, 0xff, true);
++		len--;
++	}
++}
++
++static int mt7621_nfc_dev_ready(struct mt7621_nfc *nfc,
++				unsigned int timeout_ms)
++{
++	u32 val;
++
++	return readl_poll_timeout_atomic(nfc->nfi_regs + NFI_STA, val,
++					 !(val & STA_BUSY), 10,
++					 timeout_ms * 1000);
++}
++
++static int mt7621_nfc_exec_instr(struct nand_chip *nand,
++				 const struct nand_op_instr *instr)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++
++	switch (instr->type) {
++	case NAND_OP_CMD_INSTR:
++		mt7621_nfc_hw_reset(nfc);
++		nfi_write16(nfc, NFI_CNFG, CNFG_OP_CUSTOM << CNFG_OP_MODE_S);
++		return mt7621_nfc_send_command(nfc, instr->ctx.cmd.opcode);
++	case NAND_OP_ADDR_INSTR:
++		return mt7621_nfc_send_address(nfc, instr->ctx.addr.addrs,
++					       instr->ctx.addr.naddrs);
++	case NAND_OP_DATA_IN_INSTR:
++		mt7621_nfc_read_data(nfc, instr->ctx.data.buf.in,
++				     instr->ctx.data.len);
++		return 0;
++	case NAND_OP_DATA_OUT_INSTR:
++		mt7621_nfc_write_data(nfc, instr->ctx.data.buf.out,
++				      instr->ctx.data.len);
++		return 0;
++	case NAND_OP_WAITRDY_INSTR:
++		return mt7621_nfc_dev_ready(nfc,
++					    instr->ctx.waitrdy.timeout_ms);
++	default:
++		WARN_ONCE(1, "unsupported NAND instruction type: %d\n",
++			  instr->type);
++
++		return -EINVAL;
++	}
++}
++
++static int mt7621_nfc_exec_op(struct nand_chip *nand,
++			      const struct nand_operation *op, bool check_only)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	int i, ret;
++
++	if (check_only)
++		return 0;
++
++	/* Only CS0 available */
++	nfi_write16(nfc, NFI_CSEL, 0);
++
++	for (i = 0; i < op->ninstrs; i++) {
++		ret = mt7621_nfc_exec_instr(nand, &op->instrs[i]);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++static int mt7621_nfc_setup_data_interface(struct nand_chip *nand, int csline,
++					   const struct nand_data_interface *conf)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	const struct nand_sdr_timings *timings;
++	u32 acccon, temp, rate, tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt;
++
++	if (!nfc->nfi_clk)
++		return -ENOTSUPP;
++
++	timings = nand_get_sdr_timings(conf);
++	if (IS_ERR(timings))
++		return -ENOTSUPP;
++
++	rate = clk_get_rate(nfc->nfi_clk);
++
++	/* turn clock rate into KHZ */
++	rate /= 1000;
++
++	tpoecs = max(timings->tALH_min, timings->tCLH_min) / 1000;
++	tpoecs = DIV_ROUND_UP(tpoecs * rate, 1000000);
++	tpoecs = min_t(u32, tpoecs, ACCCON_POECS_MAX);
++
++	tprecs = max(timings->tCLS_min, timings->tALS_min) / 1000;
++	tprecs = DIV_ROUND_UP(tprecs * rate, 1000000);
++	tprecs = min_t(u32, tprecs, ACCCON_PRECS_MAX);
++
++	/* sdr interface has no tCR which means CE# low to RE# low */
++	tc2r = 0;
++
++	tw2r = timings->tWHR_min / 1000;
++	tw2r = DIV_ROUND_UP(tw2r * rate, 1000000);
++	tw2r = DIV_ROUND_UP(tw2r - 1, 2);
++	tw2r = min_t(u32, tw2r, ACCCON_W2R_MAX);
++
++	twh = max(timings->tREH_min, timings->tWH_min) / 1000;
++	twh = DIV_ROUND_UP(twh * rate, 1000000) - 1;
++	twh = min_t(u32, twh, ACCCON_WH_MAX);
++
++	/* Calculate real WE#/RE# hold time in nanosecond */
++	temp = (twh + 1) * 1000000 / rate;
++	/* nanosecond to picosecond */
++	temp *= 1000;
++
++	/*
++	 * WE# low level time should be expaned to meet WE# pulse time
++	 * and WE# cycle time at the same time.
++	 */
++	if (temp < timings->tWC_min)
++		twst = timings->tWC_min - temp;
++	else
++		twst = 0;
++	twst = max(timings->tWP_min, twst) / 1000;
++	twst = DIV_ROUND_UP(twst * rate, 1000000) - 1;
++	twst = min_t(u32, twst, ACCCON_WST_MAX);
++
++	/*
++	 * RE# low level time should be expaned to meet RE# pulse time
++	 * and RE# cycle time at the same time.
++	 */
++	if (temp < timings->tRC_min)
++		trlt = timings->tRC_min - temp;
++	else
++		trlt = 0;
++	trlt = max(trlt, timings->tRP_min) / 1000;
++	trlt = DIV_ROUND_UP(trlt * rate, 1000000) - 1;
++	trlt = min_t(u32, trlt, ACCCON_RLT_MAX);
++
++	if (csline == NAND_DATA_IFACE_CHECK_ONLY) {
++		if (twst < ACCCON_WST_MIN || trlt < ACCCON_RLT_MIN)
++			return -ENOTSUPP;
++	}
++
++	acccon = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
++
++	dev_info(nfc->dev, "Using programmed access timing: %08x\n", acccon);
++
++	nfi_write32(nfc, NFI_ACCCON, acccon);
++
++	return 0;
++}
++
++static int mt7621_nfc_calc_ecc_strength(struct mt7621_nfc *nfc,
++					u32 avail_ecc_bytes)
++{
++	struct nand_chip *nand = &nfc->nand;
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	u32 strength;
++	int i;
++
++	strength = avail_ecc_bytes * 8 / ECC_PARITY_BITS;
++
++	/* Find the closest supported ecc strength */
++	for (i = ARRAY_SIZE(mt7621_ecc_strength) - 1; i >= 0; i--) {
++		if (mt7621_ecc_strength[i] <= strength)
++			break;
++	}
++
++	if (unlikely(i < 0)) {
++		dev_err(nfc->dev, "OOB size (%u) is not supported\n",
++			mtd->oobsize);
++		return -EINVAL;
++	}
++
++	nand->ecc.strength = mt7621_ecc_strength[i];
++	nand->ecc.bytes =
++		DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8);
++
++	dev_info(nfc->dev, "ECC strength adjusted to %u bits\n",
++		 nand->ecc.strength);
++
++	return i;
++}
++
++static int mt7621_nfc_set_spare_per_sector(struct mt7621_nfc *nfc)
++{
++	struct nand_chip *nand = &nfc->nand;
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	u32 size;
++	int i;
++
++	size = nand->ecc.bytes + NFI_FDM_SIZE;
++
++	/* Find the closest supported spare size */
++	for (i = 0; i < ARRAY_SIZE(mt7621_nfi_spare_size); i++) {
++		if (mt7621_nfi_spare_size[i] >= size)
++			break;
++	}
++
++	if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_spare_size))) {
++		dev_err(nfc->dev, "OOB size (%u) is not supported\n",
++			mtd->oobsize);
++		return -EINVAL;
++	}
++
++	nfc->spare_per_sector = mt7621_nfi_spare_size[i];
++
++	return i;
++}
++
++static int mt7621_nfc_ecc_init(struct mt7621_nfc *nfc)
++{
++	struct nand_chip *nand = &nfc->nand;
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	u32 spare_per_sector, encode_block_size, decode_block_size;
++	u32 ecc_enccfg, ecc_deccfg;
++	int ecc_cap;
++
++	/* Only hardware ECC mode is supported */
++	if (nand->ecc.mode != NAND_ECC_HW_SYNDROME) {
++		dev_err(nfc->dev, "Only hardware ECC mode is supported\n");
++		return -EINVAL;
++	}
++
++	nand->ecc.size = ECC_SECTOR_SIZE;
++	nand->ecc.steps = mtd->writesize / nand->ecc.size;
++
++	spare_per_sector = mtd->oobsize / nand->ecc.steps;
++
++	ecc_cap = mt7621_nfc_calc_ecc_strength(nfc,
++		spare_per_sector - NFI_FDM_SIZE);
++	if (ecc_cap < 0)
++		return ecc_cap;
++
++	/* Sector + FDM */
++	encode_block_size = (nand->ecc.size + NFI_FDM_SIZE) * 8;
++	ecc_enccfg = ecc_cap | (ENC_MODE_NFI << ENC_MODE_S) |
++		     (encode_block_size << ENC_CNFG_MSG_S);
++
++	/* Sector + FDM + ECC parity bits */
++	decode_block_size = ((nand->ecc.size + NFI_FDM_SIZE) * 8) +
++			    nand->ecc.strength * ECC_PARITY_BITS;
++	ecc_deccfg = ecc_cap | (DEC_MODE_NFI << DEC_MODE_S) |
++		     (decode_block_size << DEC_CS_S) |
++		     (DEC_CON_EL << DEC_CON_S) | DEC_EMPTY_EN;
++
++	mt7621_ecc_encoder_op(nfc, false);
++	ecc_write32(nfc, ECC_ENCCNFG, ecc_enccfg);
++
++	mt7621_ecc_decoder_op(nfc, false);
++	ecc_write32(nfc, ECC_DECCNFG, ecc_deccfg);
++
++	return 0;
++}
++
++static int mt7621_nfc_set_page_format(struct mt7621_nfc *nfc)
++{
++	struct nand_chip *nand = &nfc->nand;
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	int i, spare_size;
++	u32 pagefmt;
++
++	spare_size = mt7621_nfc_set_spare_per_sector(nfc);
++	if (spare_size < 0)
++		return spare_size;
++
++	for (i = 0; i < ARRAY_SIZE(mt7621_nfi_page_size); i++) {
++		if (mt7621_nfi_page_size[i] == mtd->writesize)
++			break;
++	}
++
++	if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_page_size))) {
++		dev_err(nfc->dev, "Page size (%u) is not supported\n",
++			mtd->writesize);
++		return -EINVAL;
++	}
++
++	pagefmt = i | (spare_size << PAGEFMT_SPARE_S) |
++		  (NFI_FDM_SIZE << PAGEFMT_FDM_S) |
++		  (NFI_FDM_SIZE << PAGEFMT_FDM_ECC_S);
++
++	nfi_write16(nfc, NFI_PAGEFMT, pagefmt);
++
++	return 0;
++}
++
++static int mt7621_nfc_attach_chip(struct nand_chip *nand)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	int ret;
++
++	if (nand->options & NAND_BUSWIDTH_16) {
++		dev_err(nfc->dev, "16-bit buswidth is not supported");
++		return -EINVAL;
++	}
++
++	ret = mt7621_nfc_ecc_init(nfc);
++	if (ret)
++		return ret;
++
++	return mt7621_nfc_set_page_format(nfc);
++}
++
++static const struct nand_controller_ops mt7621_nfc_controller_ops = {
++	.attach_chip = mt7621_nfc_attach_chip,
++	.exec_op = mt7621_nfc_exec_op,
++	.setup_data_interface = mt7621_nfc_setup_data_interface,
++};
++
++static int mt7621_nfc_ooblayout_free(struct mtd_info *mtd, int section,
++				     struct mtd_oob_region *oob_region)
++{
++	struct nand_chip *nand = mtd_to_nand(mtd);
++
++	if (section >= nand->ecc.steps)
++		return -ERANGE;
++
++	oob_region->length = NFI_FDM_SIZE - 1;
++	oob_region->offset = section * NFI_FDM_SIZE + 1;
++
++	return 0;
++}
++
++static int mt7621_nfc_ooblayout_ecc(struct mtd_info *mtd, int section,
++				    struct mtd_oob_region *oob_region)
++{
++	struct nand_chip *nand = mtd_to_nand(mtd);
++
++	if (section)
++		return -ERANGE;
++
++	oob_region->offset = NFI_FDM_SIZE * nand->ecc.steps;
++	oob_region->length = mtd->oobsize - oob_region->offset;
++
++	return 0;
++}
++
++static const struct mtd_ooblayout_ops mt7621_nfc_ooblayout_ops = {
++	.free = mt7621_nfc_ooblayout_free,
++	.ecc = mt7621_nfc_ooblayout_ecc,
++};
++
++static void mt7621_nfc_write_fdm(struct mt7621_nfc *nfc)
++{
++	struct nand_chip *nand = &nfc->nand;
++	u32 vall, valm;
++	u8 *oobptr;
++	int i, j;
++
++	for (i = 0; i < nand->ecc.steps; i++) {
++		vall = 0;
++		valm = 0;
++		oobptr = oob_fdm_ptr(nand, i);
++
++		for (j = 0; j < 4; j++)
++			vall |= (u32)oobptr[j] << (j * 8);
++
++		for (j = 0; j < 4; j++)
++			valm |= (u32)oobptr[j + 4] << ((j - 4) * 8);
++
++		nfi_write32(nfc, NFI_FDML(i), vall);
++		nfi_write32(nfc, NFI_FDMM(i), valm);
++	}
++}
++
++static void mt7621_nfc_read_sector_fdm(struct mt7621_nfc *nfc, u32 sect)
++{
++	struct nand_chip *nand = &nfc->nand;
++	u32 vall, valm;
++	u8 *oobptr;
++	int i;
++
++	vall = nfi_read32(nfc, NFI_FDML(sect));
++	valm = nfi_read32(nfc, NFI_FDMM(sect));
++	oobptr = oob_fdm_ptr(nand, sect);
++
++	for (i = 0; i < 4; i++)
++		oobptr[i] = (vall >> (i * 8)) & 0xff;
++
++	for (i = 0; i < 4; i++)
++		oobptr[i + 4] = (valm >> (i * 8)) & 0xff;
++}
++
++static int mt7621_nfc_read_page_hwecc(struct nand_chip *nand, uint8_t *buf,
++				      int oob_required, int page)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	int bitflips = 0;
++	int rc, i;
++
++	nand_read_page_op(nand, page, 0, NULL, 0);
++
++	nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
++		    CNFG_READ_MODE | CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
++
++	mt7621_ecc_decoder_op(nfc, true);
++
++	nfi_write16(nfc, NFI_CON,
++		    CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S));
++
++	for (i = 0; i < nand->ecc.steps; i++) {
++		if (buf)
++			mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i),
++					     nand->ecc.size);
++		else
++			mt7621_nfc_read_data_discard(nfc, nand->ecc.size);
++
++		rc = mt7621_ecc_decoder_wait_done(nfc, i);
++
++		mt7621_nfc_read_sector_fdm(nfc, i);
++
++		if (rc < 0) {
++			bitflips = -EIO;
++			continue;
++		}
++
++		rc = mt7621_ecc_correct_check(nfc,
++			buf ? page_data_ptr(nand, buf, i) : NULL,
++			oob_fdm_ptr(nand, i), i);
++
++		if (rc < 0) {
++			dev_warn(nfc->dev,
++				 "Uncorrectable ECC error at page %d.%d\n",
++				 page, i);
++			bitflips = -EBADMSG;
++			mtd->ecc_stats.failed++;
++		} else if (bitflips >= 0) {
++			bitflips += rc;
++			mtd->ecc_stats.corrected += rc;
++		}
++	}
++
++	mt7621_ecc_decoder_op(nfc, false);
++
++	nfi_write16(nfc, NFI_CON, 0);
++
++	return bitflips;
++}
++
++static int mt7621_nfc_read_page_raw(struct nand_chip *nand, uint8_t *buf,
++				    int oob_required, int page)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	int i;
++
++	nand_read_page_op(nand, page, 0, NULL, 0);
++
++	nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
++		    CNFG_READ_MODE);
++
++	nfi_write16(nfc, NFI_CON,
++		    CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S));
++
++	for (i = 0; i < nand->ecc.steps; i++) {
++		/* Read data */
++		if (buf)
++			mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i),
++					     nand->ecc.size);
++		else
++			mt7621_nfc_read_data_discard(nfc, nand->ecc.size);
++
++		/* Read FDM */
++		mt7621_nfc_read_data(nfc, oob_fdm_ptr(nand, i), NFI_FDM_SIZE);
++
++		/* Read ECC parity data */
++		mt7621_nfc_read_data(nfc, oob_ecc_ptr(nfc, i),
++				     nfc->spare_per_sector - NFI_FDM_SIZE);
++	}
++
++	nfi_write16(nfc, NFI_CON, 0);
++
++	return 0;
++}
++
++static int mt7621_nfc_read_oob_hwecc(struct nand_chip *nand, int page)
++{
++	return mt7621_nfc_read_page_hwecc(nand, NULL, 1, page);
++}
++
++static int mt7621_nfc_read_oob_raw(struct nand_chip *nand, int page)
++{
++	return mt7621_nfc_read_page_raw(nand, NULL, 1, page);
++}
++
++static int mt7621_nfc_check_empty_page(struct nand_chip *nand, const u8 *buf)
++{
++	struct mtd_info *mtd = nand_to_mtd(nand);
++	uint32_t i, j;
++	u8 *oobptr;
++
++	if (buf) {
++		for (i = 0; i < mtd->writesize; i++)
++			if (buf[i] != 0xff)
++				return 0;
++	}
++
++	for (i = 0; i < nand->ecc.steps; i++) {
++		oobptr = oob_fdm_ptr(nand, i);
++		for (j = 0; j < NFI_FDM_SIZE; j++)
++			if (oobptr[j] != 0xff)
++				return 0;
++	}
++
++	return 1;
++}
++
++static int mt7621_nfc_write_page_hwecc(struct nand_chip *nand,
++				       const uint8_t *buf, int oob_required,
++				       int page)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	struct mtd_info *mtd = nand_to_mtd(nand);
++
++	if (mt7621_nfc_check_empty_page(nand, buf)) {
++		/*
++		 * MT7621 ECC engine always generates parity code for input
++		 * pages, even for empty pages. Doing so will write back ECC
++		 * parity code to the oob region, which means such pages will
++		 * no longer be empty pages.
++		 *
++		 * To avoid this, stop write operation if current page is an
++		 * empty page.
++		 */
++		return 0;
++	}
++
++	nand_prog_page_begin_op(nand, page, 0, NULL, 0);
++
++	nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) |
++		   CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN);
++
++	mt7621_ecc_encoder_op(nfc, true);
++
++	mt7621_nfc_write_fdm(nfc);
++
++	nfi_write16(nfc, NFI_CON,
++		    CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S));
++
++	if (buf)
++		mt7621_nfc_write_data(nfc, buf, mtd->writesize);
++	else
++		mt7621_nfc_write_data_empty(nfc, mtd->writesize);
++
++	mt7621_nfc_wait_write_completion(nfc, nand);
++
++	mt7621_ecc_encoder_op(nfc, false);
++
++	nfi_write16(nfc, NFI_CON, 0);
++
++	return nand_prog_page_end_op(nand);
++}
++
++static int mt7621_nfc_write_page_raw(struct nand_chip *nand,
++				     const uint8_t *buf, int oob_required,
++				     int page)
++{
++	struct mt7621_nfc *nfc = nand_get_controller_data(nand);
++	int i;
++
++	nand_prog_page_begin_op(nand, page, 0, NULL, 0);
++
++	nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S));
++
++	nfi_write16(nfc, NFI_CON,
++		    CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S));
++
++	for (i = 0; i < nand->ecc.steps; i++) {
++		/* Write data */
++		if (buf)
++			mt7621_nfc_write_data(nfc, page_data_ptr(nand, buf, i),
++					      nand->ecc.size);
++		else
++			mt7621_nfc_write_data_empty(nfc, nand->ecc.size);
++
++		/* Write FDM */
++		mt7621_nfc_write_data(nfc, oob_fdm_ptr(nand, i),
++				      NFI_FDM_SIZE);
++
++		/* Write dummy ECC parity data */
++		mt7621_nfc_write_data_empty(nfc, nfc->spare_per_sector -
++					    NFI_FDM_SIZE);
++	}
++
++	mt7621_nfc_wait_write_completion(nfc, nand);
++
++	nfi_write16(nfc, NFI_CON, 0);
++
++	return nand_prog_page_end_op(nand);
++}
++
++static int mt7621_nfc_write_oob_hwecc(struct nand_chip *nand, int page)
++{
++	return mt7621_nfc_write_page_hwecc(nand, NULL, 1, page);
++}
++
++static int mt7621_nfc_write_oob_raw(struct nand_chip *nand, int page)
++{
++	return mt7621_nfc_write_page_raw(nand, NULL, 1, page);
++}
++
++static int mt7621_nfc_init_chip(struct mt7621_nfc *nfc)
++{
++	struct nand_chip *nand = &nfc->nand;
++	struct mtd_info *mtd;
++	int ret;
++
++	nand->controller = &nfc->controller;
++	nand_set_controller_data(nand, (void *)nfc);
++	nand_set_flash_node(nand, nfc->dev->of_node);
++
++	nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_NO_SUBPAGE_WRITE;
++	if (!nfc->nfi_clk)
++		nand->options |= NAND_KEEP_TIMINGS;
++
++	nand->ecc.mode = NAND_ECC_HW_SYNDROME;
++	nand->ecc.read_page = mt7621_nfc_read_page_hwecc;
++	nand->ecc.read_page_raw = mt7621_nfc_read_page_raw;
++	nand->ecc.write_page = mt7621_nfc_write_page_hwecc;
++	nand->ecc.write_page_raw = mt7621_nfc_write_page_raw;
++	nand->ecc.read_oob = mt7621_nfc_read_oob_hwecc;
++	nand->ecc.read_oob_raw = mt7621_nfc_read_oob_raw;
++	nand->ecc.write_oob = mt7621_nfc_write_oob_hwecc;
++	nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw;
++
++	mtd = nand_to_mtd(nand);
++	mtd->owner = THIS_MODULE;
++	mtd->dev.parent = nfc->dev;
++	mtd->name = MT7621_NFC_NAME;
++	mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops);
++
++	mt7621_nfc_hw_init(nfc);
++
++	ret = nand_scan(nand, 1);
++	if (ret)
++		return ret;
++
++	ret = mtd_device_register(mtd, NULL, 0);
++	if (ret) {
++		dev_err(nfc->dev, "Failed to register MTD: %d\n", ret);
++		nand_release(nand);
++		return ret;
++	}
++
++	return 0;
++}
++
++static int mt7621_nfc_probe(struct platform_device *pdev)
++{
++	struct device *dev = &pdev->dev;
++	struct mt7621_nfc *nfc;
++	struct resource *res;
++	int ret;
++
++	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
++	if (!nfc)
++		return -ENOMEM;
++
++	nand_controller_init(&nfc->controller);
++	nfc->controller.ops = &mt7621_nfc_controller_ops;
++	nfc->dev = dev;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nfi");
++	nfc->nfi_regs = devm_ioremap_resource(dev, res);
++	if (IS_ERR(nfc->nfi_regs)) {
++		ret = PTR_ERR(nfc->nfi_regs);
++		return ret;
++	}
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ecc");
++	nfc->ecc_regs = devm_ioremap_resource(dev, res);
++	if (IS_ERR(nfc->ecc_regs)) {
++		ret = PTR_ERR(nfc->ecc_regs);
++		return ret;
++	}
++
++	nfc->nfi_clk = devm_clk_get(dev, "nfi_clk");
++	if (IS_ERR(nfc->nfi_clk)) {
++		dev_warn(dev, "nfi clk not provided\n");
++		nfc->nfi_clk = NULL;
++	} else {
++		ret = clk_prepare_enable(nfc->nfi_clk);
++		if (ret) {
++			dev_err(dev, "Failed to enable nfi core clock\n");
++			return ret;
++		}
++	}
++
++	platform_set_drvdata(pdev, nfc);
++
++	ret = mt7621_nfc_init_chip(nfc);
++	if (ret) {
++		dev_err(dev, "Failed to initialize nand chip\n");
++		goto clk_disable;
++	}
++
++	return 0;
++
++clk_disable:
++	clk_disable_unprepare(nfc->nfi_clk);
++
++	return ret;
++}
++
++static int mt7621_nfc_remove(struct platform_device *pdev)
++{
++	struct mt7621_nfc *nfc = platform_get_drvdata(pdev);
++
++	nand_release(&nfc->nand);
++	clk_disable_unprepare(nfc->nfi_clk);
++
++	return 0;
++}
++
++static const struct of_device_id mt7621_nfc_id_table[] = {
++	{ .compatible = "mediatek,mt7621-nfc" },
++	{ },
++};
++MODULE_DEVICE_TABLE(of, match);
++
++static struct platform_driver mt7621_nfc_driver = {
++	.probe = mt7621_nfc_probe,
++	.remove = mt7621_nfc_remove,
++	.driver = {
++		.name = MT7621_NFC_NAME,
++		.owner = THIS_MODULE,
++		.of_match_table = mt7621_nfc_id_table,
++	},
++};
++module_platform_driver(mt7621_nfc_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Weijie Gao <weijie.gao@mediatek.com>");
++MODULE_DESCRIPTION("MediaTek MT7621 NAND Flash Controller driver");
diff --git a/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch b/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch
new file mode 100644
index 0000000..3d122c1
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/0301-dt-bindings-add-documentation-for-mt7621-nand-driver.patch
@@ -0,0 +1,85 @@
+From 3d5f4da8296b23eb3abf8b13122b0d06a215e79c Mon Sep 17 00:00:00 2001
+From: Weijie Gao <weijie.gao@mediatek.com>
+Date: Wed, 1 Apr 2020 02:07:59 +0800
+Subject: [PATCH 2/2] dt-bindings: add documentation for mt7621-nand driver
+
+This patch adds documentation for MediaTek MT7621 NAND flash controller
+driver.
+
+Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+---
+ .../bindings/mtd/mediatek,mt7621-nfc.yaml          | 68 ++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/mtd/mediatek,mt7621-nfc.yaml
+@@ -0,0 +1,68 @@
++# SPDX-License-Identifier: GPL-2.0
++%YAML 1.2
++---
++$id: http://devicetree.org/schemas/mtd/mediatek,mt7621-nfc.yaml#
++$schema: http://devicetree.org/meta-schemas/core.yaml#
++
++title: MediaTek MT7621 SoC NAND Flash Controller (NFC) DT binding
++
++maintainers:
++  - Weijie Gao <weijie.gao@mediatek.com>
++
++description: |
++  This driver uses a single node to describe both NAND Flash controller
++  interface (NFI) and ECC engine for MT7621 SoC.
++  MT7621 supports only one chip select.
++
++properties:
++  "#address-cells": false
++  "#size-cells": false
++
++  compatible:
++    enum:
++      - mediatek,mt7621-nfc
++
++  reg:
++    items:
++      - description: Register base of NFI core
++      - description: Register base of ECC engine
++
++  reg-names:
++    items:
++      - const: nfi
++      - const: ecc
++
++  clocks:
++    items:
++      - description: Source clock for NFI core, fixed 125MHz
++
++  clock-names:
++    items:
++      - const: nfi_clk
++
++required:
++  - compatible
++  - reg
++  - reg-names
++  - clocks
++  - clock-names
++
++examples:
++  - |
++    nficlock: nficlock {
++    	#clock-cells = <0>;
++    	compatible = "fixed-clock";
++
++    	clock-frequency = <125000000>;
++    };
++
++    nand@1e003000 {
++    	compatible = "mediatek,mt7621-nfc";
++
++    	reg = <0x1e003000 0x800
++    	       0x1e003800 0x800>;
++    	reg-names = "nfi", "ecc";
++
++    	clocks = <&nficlock>;
++    	clock-names = "nfi_clk";
++    };
diff --git a/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch b/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch
new file mode 100644
index 0000000..1c8b61f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/100-mt7621-core-detect-hack.patch
@@ -0,0 +1,61 @@
+There is a variant of MT7621 which contains only one CPU core instead of 2.
+This is not reflected in the config register, so the kernel detects more
+physical cores, which leads to a hang on SMP bringup.
+Add a hack to detect missing cores.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+
+--- a/arch/mips/kernel/smp-cps.c
++++ b/arch/mips/kernel/smp-cps.c
+@@ -43,6 +43,11 @@ static unsigned core_vpe_count(unsigned
+ 	return mips_cps_numvps(cluster, core);
+ }
+ 
++bool __weak plat_cpu_core_present(int core)
++{
++	return true;
++}
++
+ static void __init cps_smp_setup(void)
+ {
+ 	unsigned int nclusters, ncores, nvpes, core_vpes;
+@@ -60,6 +65,8 @@ static void __init cps_smp_setup(void)
+ 
+ 		ncores = mips_cps_numcores(cl);
+ 		for (c = 0; c < ncores; c++) {
++			if (!plat_cpu_core_present(c))
++				continue;
+ 			core_vpes = core_vpe_count(cl, c);
+ 
+ 			if (c > 0)
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -13,6 +13,7 @@
+ #include <asm/mips-cps.h>
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/mt7621.h>
++#include <asm/mips-boards/launch.h>
+ 
+ #include <pinmux.h>
+ 
+@@ -160,6 +161,20 @@ void __init ralink_of_remap(void)
+ 		panic("Failed to remap core resources");
+ }
+ 
++bool plat_cpu_core_present(int core)
++{
++	struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
++
++	if (!core)
++		return true;
++	launch += core * 2; /* 2 VPEs per core */
++	if (!(launch->flags & LAUNCH_FREADY))
++		return false;
++	if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE))
++		return false;
++	return true;
++}
++
+ void prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+ 	void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
diff --git a/target/linux/ramips/patches-5.4/101-mt7621-timer.patch b/target/linux/ramips/patches-5.4/101-mt7621-timer.patch
new file mode 100644
index 0000000..8528b71
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/101-mt7621-timer.patch
@@ -0,0 +1,87 @@
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -7,6 +7,7 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/jiffies.h>
+ 
+ #include <asm/mipsregs.h>
+ #include <asm/smp-ops.h>
+@@ -14,6 +15,7 @@
+ #include <asm/mach-ralink/ralink_regs.h>
+ #include <asm/mach-ralink/mt7621.h>
+ #include <asm/mips-boards/launch.h>
++#include <asm/delay.h>
+ 
+ #include <pinmux.h>
+ 
+@@ -175,6 +177,58 @@ bool plat_cpu_core_present(int core)
+ 	return true;
+ }
+ 
++#define LPS_PREC 8
++/*
++*  Re-calibration lpj(loop-per-jiffy).
++*  (derived from kernel/calibrate.c)
++*/
++static int udelay_recal(void)
++{
++	unsigned int i, lpj = 0;
++	unsigned long ticks, loopbit;
++	int lps_precision = LPS_PREC;
++
++	lpj = (1<<12);
++
++	while ((lpj <<= 1) != 0) {
++		/* wait for "start of" clock tick */
++		ticks = jiffies;
++		while (ticks == jiffies)
++			/* nothing */;
++
++		/* Go .. */
++		ticks = jiffies;
++		__delay(lpj);
++		ticks = jiffies - ticks;
++		if (ticks)
++			break;
++	}
++
++	/*
++	 * Do a binary approximation to get lpj set to
++	 * equal one clock (up to lps_precision bits)
++	 */
++	lpj >>= 1;
++	loopbit = lpj;
++	while (lps_precision-- && (loopbit >>= 1)) {
++		lpj |= loopbit;
++		ticks = jiffies;
++		while (ticks == jiffies)
++			/* nothing */;
++		ticks = jiffies;
++		__delay(lpj);
++		if (jiffies != ticks)   /* longer than 1 tick */
++			lpj &= ~loopbit;
++	}
++	printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj);
++
++	for(i=0; i< NR_CPUS; i++)
++		cpu_data[i].udelay_val = lpj;
++
++	return 0;
++}
++device_initcall(udelay_recal);
++
+ void prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+ 	void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+--- a/arch/mips/ralink/Kconfig
++++ b/arch/mips/ralink/Kconfig
+@@ -58,6 +58,7 @@ choice
+ 		select CLKSRC_MIPS_GIC
+ 		select HAVE_PCI if PCI_MT7621
+ 		select WEAK_REORDERING_BEYOND_LLSC
++		select GENERIC_CLOCKEVENTS_BROADCAST
+ endchoice
+ 
+ choice
diff --git a/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch b/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch
new file mode 100644
index 0000000..0c997a3
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/102-mt7621-fix-cpu-clk-add-clkdev.patch
@@ -0,0 +1,224 @@
+--- a/arch/mips/include/asm/mach-ralink/mt7621.h
++++ b/arch/mips/include/asm/mach-ralink/mt7621.h
+@@ -17,6 +17,10 @@
+ #define SYSC_REG_CHIP_REV		0x0c
+ #define SYSC_REG_SYSTEM_CONFIG0		0x10
+ #define SYSC_REG_SYSTEM_CONFIG1		0x14
++#define SYSC_REG_CLKCFG0		0x2c
++#define SYSC_REG_CUR_CLK_STS		0x44
++
++#define MEMC_REG_CPU_PLL		0x648
+ 
+ #define CHIP_REV_PKG_MASK		0x1
+ #define CHIP_REV_PKG_SHIFT		16
+@@ -24,6 +28,22 @@
+ #define CHIP_REV_VER_SHIFT		8
+ #define CHIP_REV_ECO_MASK		0xf
+ 
++#define XTAL_MODE_SEL_MASK		0x7
++#define XTAL_MODE_SEL_SHIFT		6
++
++#define CPU_CLK_SEL_MASK		0x3
++#define CPU_CLK_SEL_SHIFT		30
++
++#define CUR_CPU_FDIV_MASK		0x1f
++#define CUR_CPU_FDIV_SHIFT		8
++#define CUR_CPU_FFRAC_MASK		0x1f
++#define CUR_CPU_FFRAC_SHIFT		0
++
++#define CPU_PLL_PREDIV_MASK		0x3
++#define CPU_PLL_PREDIV_SHIFT		12
++#define CPU_PLL_FBDIV_MASK		0x7f
++#define CPU_PLL_FBDIV_SHIFT		4
++
+ #define MT7621_DRAM_BASE                0x0
+ #define MT7621_DDR2_SIZE_MIN		32
+ #define MT7621_DDR2_SIZE_MAX		256
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -8,6 +8,10 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/jiffies.h>
++#include <linux/clk.h>
++#include <linux/clkdev.h>
++#include <linux/clk-provider.h>
++#include <dt-bindings/clock/mt7621-clk.h>
+ 
+ #include <asm/mipsregs.h>
+ #include <asm/smp-ops.h>
+@@ -16,16 +20,12 @@
+ #include <asm/mach-ralink/mt7621.h>
+ #include <asm/mips-boards/launch.h>
+ #include <asm/delay.h>
++#include <asm/time.h>
+ 
+ #include <pinmux.h>
+ 
+ #include "common.h"
+ 
+-#define SYSC_REG_SYSCFG		0x10
+-#define SYSC_REG_CPLL_CLKCFG0	0x2c
+-#define SYSC_REG_CUR_CLK_STS	0x44
+-#define CPU_CLK_SEL		(BIT(30) | BIT(31))
+-
+ #define MT7621_GPIO_MODE_UART1		1
+ #define MT7621_GPIO_MODE_I2C		2
+ #define MT7621_GPIO_MODE_UART3_MASK	0x3
+@@ -111,49 +111,89 @@ static struct rt2880_pmx_group mt7621_pi
+ 	{ 0 }
+ };
+ 
++static struct clk *clks[MT7621_CLK_MAX];
++static struct clk_onecell_data clk_data = {
++	.clks = clks,
++	.clk_num = ARRAY_SIZE(clks),
++};
++
+ phys_addr_t mips_cpc_default_phys_base(void)
+ {
+ 	panic("Cannot detect cpc address");
+ }
+ 
+-void __init ralink_clk_init(void)
++static struct clk *__init mt7621_add_sys_clkdev(
++	const char *id, unsigned long rate)
+ {
+-	int cpu_fdiv = 0;
+-	int cpu_ffrac = 0;
+-	int fbdiv = 0;
+-	u32 clk_sts, syscfg;
+-	u8 clk_sel = 0, xtal_mode;
+-	u32 cpu_clk;
++	struct clk *clk;
++	int err;
++
++	clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
++	if (IS_ERR(clk))
++		panic("failed to allocate %s clock structure", id);
++
++	err = clk_register_clkdev(clk, id, NULL);
++	if (err)
++		panic("unable to register %s clock device", id);
+ 
+-	if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
+-		clk_sel = 1;
++	return clk;
++}
++
++void __init ralink_clk_init(void)
++{
++	u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
++	u32 pll, prediv, fbdiv;
++	u32 xtal_clk, cpu_clk, bus_clk;
++	const static u32 prediv_tbl[] = {0, 1, 2, 2};
++
++	syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
++	xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
++
++	clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
++	clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
++
++	curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
++	ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
++	ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
++
++	if (xtal_sel <= 2)
++		xtal_clk = 20 * 1000 * 1000;
++	else if (xtal_sel <= 5)
++		xtal_clk = 40 * 1000 * 1000;
++	else
++		xtal_clk = 25 * 1000 * 1000;
+ 
+ 	switch (clk_sel) {
+ 	case 0:
+-		clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+-		cpu_fdiv = ((clk_sts >> 8) & 0x1F);
+-		cpu_ffrac = (clk_sts & 0x1F);
+-		cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
++		cpu_clk = 500 * 1000 * 1000;
+ 		break;
+-
+ 	case 1:
+-		fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
+-		syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
+-		xtal_mode = (syscfg >> 6) & 0x7;
+-		if (xtal_mode >= 6) {
+-			/* 25Mhz Xtal */
+-			cpu_clk = 25 * fbdiv * 1000 * 1000;
+-		} else if (xtal_mode >= 3) {
+-			/* 40Mhz Xtal */
+-			cpu_clk = 40 * fbdiv * 1000 * 1000;
+-		} else {
+-			/* 20Mhz Xtal */
+-			cpu_clk = 20 * fbdiv * 1000 * 1000;
+-		}
++		pll = rt_memc_r32(MEMC_REG_CPU_PLL);
++		fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK;
++		prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK;
++		cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
+ 		break;
++	default:
++		cpu_clk = xtal_clk;
+ 	}
++
++	cpu_clk = cpu_clk / ffiv * ffrac;
++	bus_clk = cpu_clk / 4;
++
++	clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk);
++	clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk);
++
++	pr_info("CPU Clock: %dMHz\n", cpu_clk / 1000000);
++	mips_hpt_frequency = cpu_clk / 2;
+ }
+ 
++static void __init mt7621_clocks_init_dt(struct device_node *np)
++{
++	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
++}
++
++CLK_OF_DECLARE(ar7100, "mediatek,mt7621-pll", mt7621_clocks_init_dt);
++
+ void __init ralink_of_remap(void)
+ {
+ 	rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
+--- a/arch/mips/ralink/timer-gic.c
++++ b/arch/mips/ralink/timer-gic.c
+@@ -9,14 +9,14 @@
+ 
+ #include <linux/of.h>
+ #include <linux/clk-provider.h>
+-#include <linux/clocksource.h>
++#include <asm/time.h>
+ 
+ #include "common.h"
+ 
+ void __init plat_time_init(void)
+ {
+ 	ralink_of_remap();
+-
++	ralink_clk_init();
+ 	of_clk_init(NULL);
+ 	timer_probe();
+ }
+--- /dev/null
++++ b/include/dt-bindings/clock/mt7621-clk.h
+@@ -0,0 +1,18 @@
++/*
++ * Copyright (C) 2018 Weijie Gao <hackpascal@gmail.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#ifndef __DT_BINDINGS_MT7621_CLK_H
++#define __DT_BINDINGS_MT7621_CLK_H
++
++#define MT7621_CLK_CPU		0
++#define MT7621_CLK_BUS		1
++
++#define MT7621_CLK_MAX		2
++
++#endif /* __DT_BINDINGS_MT7621_CLK_H */
diff --git a/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch b/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch
new file mode 100644
index 0000000..277d2aa
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/105-mt7621-memory-detect.patch
@@ -0,0 +1,125 @@
+From b5a52351a66f3c2a7a207548aa87d78ff2d336c0 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Wed, 10 Jul 2019 00:24:48 +0800
+Subject: [PATCH] MIPS: ralink: mt7621: add memory detection support
+
+mt7621 has the following memory map:
+0x0-0x1c000000: lower 448m memory
+0x1c000000-0x2000000: peripheral registers
+0x20000000-0x2400000: higher 64m memory
+
+detect_memory_region in arch/mips/kernel/setup.c only add the first
+memory region and isn't suitable for 512m memory detection because
+it may accidentally read the memory area for peripheral registers.
+
+This commit adds memory detection capability for mt7621:
+1. add the highmem area when 512m is detected.
+2. guard memcmp from accessing peripheral registers:
+     This only happens when some weird user decided to change
+     kernel load address to 256m or higher address. Since this
+     is a quite unusual case, we just skip 512m testing and return
+     256m as memory size.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+---
+ arch/mips/include/asm/mach-ralink/mt7621.h |  7 ++---
+ arch/mips/ralink/mt7621.c                  | 30 +++++++++++++++++++---
+ 2 files changed, 30 insertions(+), 7 deletions(-)
+
+--- a/arch/mips/include/asm/mach-ralink/mt7621.h
++++ b/arch/mips/include/asm/mach-ralink/mt7621.h
+@@ -44,9 +44,10 @@
+ #define CPU_PLL_FBDIV_MASK		0x7f
+ #define CPU_PLL_FBDIV_SHIFT		4
+ 
+-#define MT7621_DRAM_BASE                0x0
+-#define MT7621_DDR2_SIZE_MIN		32
+-#define MT7621_DDR2_SIZE_MAX		256
++#define MT7621_LOWMEM_BASE		0x0
++#define MT7621_LOWMEM_MAX_SIZE		0x1C000000
++#define MT7621_HIGHMEM_BASE		0x20000000
++#define MT7621_HIGHMEM_SIZE		0x4000000
+ 
+ #define MT7621_CHIP_NAME0		0x3637544D
+ #define MT7621_CHIP_NAME1		0x20203132
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -13,6 +13,7 @@
+ #include <linux/clk-provider.h>
+ #include <dt-bindings/clock/mt7621-clk.h>
+ 
++#include <asm/bootinfo.h>
+ #include <asm/mipsregs.h>
+ #include <asm/smp-ops.h>
+ #include <asm/mips-cps.h>
+@@ -55,6 +56,8 @@
+ #define MT7621_GPIO_MODE_SDHCI_SHIFT	18
+ #define MT7621_GPIO_MODE_SDHCI_GPIO	1
+ 
++static void *detect_magic __initdata = detect_memory_region;
++
+ static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
+ static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
+ static struct rt2880_pmx_func uart3_grp[] = {
+@@ -139,6 +142,28 @@ static struct clk *__init mt7621_add_sys
+ 	return clk;
+ }
+ 
++void __init mt7621_memory_detect(void)
++{
++	void *dm = &detect_magic;
++	phys_addr_t size;
++
++	for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
++		if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
++			break;
++	}
++
++	if ((size == 256 * SZ_1M) &&
++	    (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
++	    __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
++		add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
++				  BOOT_MEM_RAM);
++		add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
++				  BOOT_MEM_RAM);
++	} else {
++		add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
++	}
++}
++
+ void __init ralink_clk_init(void)
+ {
+ 	u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+@@ -317,10 +342,7 @@ void prom_soc_init(struct ralink_soc_inf
+ 		(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+ 		(rev & CHIP_REV_ECO_MASK));
+ 
+-	soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
+-	soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
+-	soc_info->mem_base = MT7621_DRAM_BASE;
+-
++	soc_info->mem_detect = mt7621_memory_detect;
+ 	rt2880_pinmux_data = mt7621_pinmux_data;
+ 
+ 
+--- a/arch/mips/ralink/common.h
++++ b/arch/mips/ralink/common.h
+@@ -17,6 +17,7 @@ struct ralink_soc_info {
+ 	unsigned long mem_size;
+ 	unsigned long mem_size_min;
+ 	unsigned long mem_size_max;
++	void (*mem_detect)(void);
+ };
+ extern struct ralink_soc_info soc_info;
+ 
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -87,6 +87,8 @@ void __init plat_mem_setup(void)
+ 	of_scan_flat_dt(early_init_dt_find_memory, NULL);
+ 	if (memory_dtb)
+ 		of_scan_flat_dt(early_init_dt_scan_memory, NULL);
++	else if (soc_info.mem_detect)
++		soc_info.mem_detect();
+ 	else if (soc_info.mem_size)
+ 		add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
+ 				  BOOT_MEM_RAM);
diff --git a/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch b/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch
new file mode 100644
index 0000000..dfeac7e
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/110-mt7621-perfctr-fix.patch
@@ -0,0 +1,15 @@
+--- a/arch/mips/ralink/irq-gic.c
++++ b/arch/mips/ralink/irq-gic.c
+@@ -13,6 +13,12 @@
+ 
+ int get_c0_perfcount_int(void)
+ {
++	/*
++	 * Performance counter events are routed through GIC.
++	 * Prevent them from firing on CPU IRQ7 as well
++	 */
++	clear_c0_status(IE_SW0 << 7);
++
+ 	return gic_get_c0_perfcount_int();
+ }
+ EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
diff --git a/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch b/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch
new file mode 100644
index 0000000..fdb89d0
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/111-gpio-mmio-introduce-BGPIOF_NO_SET_ON_INPUT.patch
@@ -0,0 +1,85 @@
+From 5d7b644aad721ecca20bd8976b38fb243fdc84f9 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Sun, 15 Mar 2020 20:13:37 +0800
+Subject: [PATCH] gpio: mmio: introduce BGPIOF_NO_SET_ON_INPUT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some gpio controllers ignores pin value writing when that pin is
+configured as input mode. As a result, bgpio_dir_out should set
+pin to output before configuring pin values or gpio pin values
+can't be set up properly.
+Introduce two variants of bgpio_dir_out: bgpio_dir_out_val_first
+and bgpio_dir_out_dir_first, and assign direction_output according
+to a new flag: BGPIOF_NO_SET_ON_INPUT.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+Tested-by: René van Dorst <opensource@vdorst.com>
+Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+---
+ drivers/gpio/gpio-mmio.c    | 23 +++++++++++++++++++----
+ include/linux/gpio/driver.h |  1 +
+ 2 files changed, 20 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpio/gpio-mmio.c
++++ b/drivers/gpio/gpio-mmio.c
+@@ -381,12 +381,10 @@ static int bgpio_get_dir(struct gpio_chi
+ 	return 1;
+ }
+ 
+-static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
++static void bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+ {
+ 	unsigned long flags;
+ 
+-	gc->set(gc, gpio, val);
+-
+ 	spin_lock_irqsave(&gc->bgpio_lock, flags);
+ 
+ 	gc->bgpio_dir |= bgpio_line2mask(gc, gpio);
+@@ -397,7 +395,21 @@ static int bgpio_dir_out(struct gpio_chi
+ 		gc->write_reg(gc->reg_dir_out, gc->bgpio_dir);
+ 
+ 	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
++}
+ 
++static int bgpio_dir_out_dir_first(struct gpio_chip *gc, unsigned int gpio,
++				   int val)
++{
++	bgpio_dir_out(gc, gpio, val);
++	gc->set(gc, gpio, val);
++	return 0;
++}
++
++static int bgpio_dir_out_val_first(struct gpio_chip *gc, unsigned int gpio,
++				   int val)
++{
++	gc->set(gc, gpio, val);
++	bgpio_dir_out(gc, gpio, val);
+ 	return 0;
+ }
+ 
+@@ -530,7 +542,10 @@ static int bgpio_setup_direction(struct
+ 	if (dirout || dirin) {
+ 		gc->reg_dir_out = dirout;
+ 		gc->reg_dir_in = dirin;
+-		gc->direction_output = bgpio_dir_out;
++		if (flags & BGPIOF_NO_SET_ON_INPUT)
++			gc->direction_output = bgpio_dir_out_dir_first;
++		else
++			gc->direction_output = bgpio_dir_out_val_first;
+ 		gc->direction_input = bgpio_dir_in;
+ 		gc->get_direction = bgpio_get_dir;
+ 	} else {
+--- a/include/linux/gpio/driver.h
++++ b/include/linux/gpio/driver.h
+@@ -567,6 +567,7 @@ int bgpio_init(struct gpio_chip *gc, str
+ #define BGPIOF_BIG_ENDIAN_BYTE_ORDER	BIT(3)
+ #define BGPIOF_READ_OUTPUT_REG_SET	BIT(4) /* reg_set stores output value */
+ #define BGPIOF_NO_OUTPUT		BIT(5) /* only input */
++#define BGPIOF_NO_SET_ON_INPUT		BIT(6)
+ 
+ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
+ 		     irq_hw_number_t hwirq);
diff --git a/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch b/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch
new file mode 100644
index 0000000..862f9ad
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/112-gpio-mt7621-add-BGPIOF_NO_SET_ON_INPUT-flag.patch
@@ -0,0 +1,33 @@
+From ad65f02fd73e9a700f1693a4513ae923ca07beb0 Mon Sep 17 00:00:00 2001
+From: Chuanhong Guo <gch981213@gmail.com>
+Date: Sun, 15 Mar 2020 20:13:38 +0800
+Subject: [PATCH] gpio: mt7621: add BGPIOF_NO_SET_ON_INPUT flag
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+DSET/DCLR registers only works on output pins. Add corresponding
+BGPIOF_NO_SET_ON_INPUT flag to bgpio_init call to fix direction_out
+behavior.
+
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+Tested-by: René van Dorst <opensource@vdorst.com>
+Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
+---
+ drivers/gpio/gpio-mt7621.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpio/gpio-mt7621.c
++++ b/drivers/gpio/gpio-mt7621.c
+@@ -227,8 +227,8 @@ mediatek_gpio_bank_probe(struct device *
+ 	ctrl = mtk->base + GPIO_REG_DCLR + (rg->bank * GPIO_BANK_STRIDE);
+ 	diro = mtk->base + GPIO_REG_CTRL + (rg->bank * GPIO_BANK_STRIDE);
+ 
+-	ret = bgpio_init(&rg->chip, dev, 4,
+-			 dat, set, ctrl, diro, NULL, 0);
++	ret = bgpio_init(&rg->chip, dev, 4, dat, set, ctrl, diro, NULL,
++			 BGPIOF_NO_SET_ON_INPUT);
+ 	if (ret) {
+ 		dev_err(dev, "bgpio_init() failed\n");
+ 		return ret;
diff --git a/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch b/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch
new file mode 100644
index 0000000..79e7c23
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/200-add-ralink-eth.patch
@@ -0,0 +1,20 @@
+--- a/drivers/net/ethernet/Kconfig
++++ b/drivers/net/ethernet/Kconfig
+@@ -160,6 +160,7 @@ source "drivers/net/ethernet/pasemi/Kcon
+ source "drivers/net/ethernet/pensando/Kconfig"
+ source "drivers/net/ethernet/qlogic/Kconfig"
+ source "drivers/net/ethernet/qualcomm/Kconfig"
++source "drivers/net/ethernet/ralink/Kconfig"
+ source "drivers/net/ethernet/rdc/Kconfig"
+ source "drivers/net/ethernet/realtek/Kconfig"
+ source "drivers/net/ethernet/renesas/Kconfig"
+--- a/drivers/net/ethernet/Makefile
++++ b/drivers/net/ethernet/Makefile
+@@ -72,6 +72,7 @@ obj-$(CONFIG_NET_VENDOR_PACKET_ENGINES)
+ obj-$(CONFIG_NET_VENDOR_PASEMI) += pasemi/
+ obj-$(CONFIG_NET_VENDOR_QLOGIC) += qlogic/
+ obj-$(CONFIG_NET_VENDOR_QUALCOMM) += qualcomm/
++obj-$(CONFIG_NET_VENDOR_RALINK) += ralink/
+ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
+ obj-$(CONFIG_NET_VENDOR_RENESAS) += renesas/
+ obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
diff --git a/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch b/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch
new file mode 100644
index 0000000..8b4335e
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/300-mt7620-export-chip-version-and-pkg.patch
@@ -0,0 +1,19 @@
+--- a/arch/mips/include/asm/mach-ralink/mt7620.h
++++ b/arch/mips/include/asm/mach-ralink/mt7620.h
+@@ -135,4 +135,16 @@ static inline int mt7620_get_eco(void)
+ 	return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
+ }
+ 
++static inline int mt7620_get_chipver(void)
++{
++	return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_VER_SHIFT) &
++		CHIP_REV_VER_MASK;
++}
++
++static inline int mt7620_get_pkg(void)
++{
++	return (rt_sysc_r32(SYSC_REG_CHIP_REV) >> CHIP_REV_PKG_SHIFT) &
++		CHIP_REV_PKG_MASK;
++}
++
+ #endif
diff --git a/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch b/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch
new file mode 100644
index 0000000..dc3dd0d
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/301-MIPS-ralink-mt7621-introduce-soc_device-initializati.patch
@@ -0,0 +1,89 @@
+From f798b7588bd7397bbab958281ca6c88d08714941 Mon Sep 17 00:00:00 2001
+From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Date: Thu, 12 Mar 2020 12:29:15 +0100
+Subject: [PATCH] MIPS: ralink: mt7621: introduce 'soc_device' initialization
+
+mt7621 SoC has its own 'ralink_soc_info' structure with some
+information about the soc itself. Pcie controller and pcie phy
+drivers for this soc which are still in staging git tree make uses
+of 'soc_device_attribute' looking for revision 'E2' in order to
+know if reset lines are or not inverted. This way of doing things
+seems to be necessary in order to make things clean and properly.
+Hence, introduce this 'soc_device' to be able to properly use those
+attributes in drivers. Also set 'data' pointer points to the struct
+'ralink_soc_info' to be able to export also current soc information
+using this mechanism.
+
+Cc: Paul Burton <paul.burton@mips.com>
+Cc: ralf@linux-mips.org
+Cc: jhogan@kernel.org
+Cc: john@phrozen.org
+Cc: NeilBrown <neil@brown.name>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: linux-mips@vger.kernel.org
+
+Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+---
+ arch/mips/ralink/mt7621.c | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -7,6 +7,8 @@
+ 
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/sys_soc.h>
+ #include <linux/jiffies.h>
+ #include <linux/clk.h>
+ #include <linux/clkdev.h>
+@@ -294,6 +296,33 @@ static int udelay_recal(void)
+ }
+ device_initcall(udelay_recal);
+ 
++static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
++{
++	struct soc_device *soc_dev;
++	struct soc_device_attribute *soc_dev_attr;
++
++	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
++	if (!soc_dev_attr)
++		return;
++
++	soc_dev_attr->soc_id = "mt7621";
++	soc_dev_attr->family = "Ralink";
++
++	if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
++	    (rev & CHIP_REV_ECO_MASK) == 1)
++		soc_dev_attr->revision = "E2";
++	else
++		soc_dev_attr->revision = "E1";
++
++	soc_dev_attr->data = soc_info;
++
++	soc_dev = soc_device_register(soc_dev_attr);
++	if (IS_ERR(soc_dev)) {
++		kfree(soc_dev_attr);
++		return;
++	}
++}
++
+ void prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+ 	void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+@@ -345,11 +374,12 @@ void prom_soc_init(struct ralink_soc_inf
+ 	soc_info->mem_detect = mt7621_memory_detect;
+ 	rt2880_pinmux_data = mt7621_pinmux_data;
+ 
+-
+ 	if (!register_cps_smp_ops())
+ 		return;
+ 	if (!register_cmp_smp_ops())
+ 		return;
+ 	if (!register_vsmp_smp_ops())
+ 		return;
++
++	soc_dev_init(soc_info, rev);
+ }
diff --git a/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch b/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch
new file mode 100644
index 0000000..9311462
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/302-spi-nor-add-gd25q512.patch
@@ -0,0 +1,14 @@
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -2308,6 +2308,11 @@ static const struct flash_info spi_nor_i
+ 			SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ 			.fixups = &gd25q256_fixups,
+ 	},
++	{
++		"gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024,
++			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
++			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES)
++	},
+ 
+ 	/* Intel/Numonyx -- xxxs33b */
+ 	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
diff --git a/target/linux/ramips/patches-5.4/325-mt7621-fix-memory-detect.patch b/target/linux/ramips/patches-5.4/325-mt7621-fix-memory-detect.patch
new file mode 100644
index 0000000..f8616c3
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/325-mt7621-fix-memory-detect.patch
@@ -0,0 +1,62 @@
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -58,7 +58,9 @@
+ #define MT7621_GPIO_MODE_SDHCI_SHIFT	18
+ #define MT7621_GPIO_MODE_SDHCI_GPIO	1
+ 
+-static void *detect_magic __initdata = detect_memory_region;
++#define MT7621_MEM_TEST_PATTERN         0xaa5555aa
++
++static u32 detect_magic __initdata;
+ 
+ static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
+ static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
+@@ -144,26 +146,34 @@ static struct clk *__init mt7621_add_sys
+ 	return clk;
+ }
+ 
++static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
++{
++	void *dm = (void *)KSEG1ADDR(&detect_magic);
++	if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
++		return true;
++	__raw_writel(MT7621_MEM_TEST_PATTERN, dm);
++	if (__raw_readl(dm) != __raw_readl(dm + size))
++		return false;
++	__raw_writel(!MT7621_MEM_TEST_PATTERN, dm);
++	return __raw_readl(dm) == __raw_readl(dm + size);
++}
++
+ void __init mt7621_memory_detect(void)
+ {
+-	void *dm = &detect_magic;
+ 	phys_addr_t size;
+ 
+-	for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
+-		if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
+-			break;
++	for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
++		if (mt7621_addr_wraparound_test(size)) {
++			add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
++			return;
++		}
+ 	}
+ 
+-	if ((size == 256 * SZ_1M) &&
+-	    (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
+-	    __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
+-		add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
+-				  BOOT_MEM_RAM);
+-		add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
+-				  BOOT_MEM_RAM);
+-	} else {
+-		add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
+-	}
++	/* addr doesn't wrap around at dm + 256M, assume 512M memory. */
++	add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
++			  BOOT_MEM_RAM);
++	add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
++			  BOOT_MEM_RAM);
+ }
+ 
+ void __init ralink_clk_init(void)
diff --git a/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch b/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch
new file mode 100644
index 0000000..9073777
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/401-net-ethernet-mediatek-support-net-labels.patch
@@ -0,0 +1,34 @@
+From bd0f89de5476ca25e73fae829ba3e1dafae1d90d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
+Date: Fri, 21 Jun 2019 10:04:05 +0200
+Subject: [PATCH] net: ethernet: mediatek: support net-labels
+
+With this patch, device name can be set within dts file in the same way as dsa
+port can.
+Add: label = "wan"; to GMAC node.
+
+Signed-off-by: René van Dorst <opensource@vdorst.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2963,6 +2963,7 @@ static const struct net_device_ops mtk_n
+ 
+ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
+ {
++	const char *name = of_get_property(np, "label", NULL);
+ 	const __be32 *_id = of_get_property(np, "reg", NULL);
+ 	struct phylink *phylink;
+ 	int phy_mode, id, err;
+@@ -3055,6 +3056,9 @@ static int mtk_add_mac(struct mtk_eth *e
+ 
+ 	eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN;
+ 
++	if (name)
++		strlcpy(eth->netdev[id]->name, name, IFNAMSIZ);
++
+ 	return 0;
+ 
+ free_netdev:
diff --git a/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch b/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch
new file mode 100644
index 0000000..19e3cbc
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/990-NET-no-auto-carrier-off-support.patch
@@ -0,0 +1,47 @@
+From 0b6eb1e68290243d439ee330ea8d0b239a5aec69 Mon Sep 17 00:00:00 2001
+From: John Crispin <blogic@openwrt.org>
+Date: Sun, 27 Jul 2014 09:38:50 +0100
+Subject: [PATCH 34/53] NET: multi phy support
+
+Signed-off-by: John Crispin <blogic@openwrt.org>
+---
+ drivers/net/phy/phy.c |    9 ++++++---
+ include/linux/phy.h   |    1 +
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -554,7 +554,10 @@ static int phy_check_link_status(struct
+ 		phy_link_up(phydev);
+ 	} else if (!phydev->link && phydev->state != PHY_NOLINK) {
+ 		phydev->state = PHY_NOLINK;
+-		phy_link_down(phydev, true);
++		if (!phydev->no_auto_carrier_off)
++			phy_link_down(phydev, true);
++		else
++			phy_link_down(phydev, false);
+ 	}
+ 
+ 	return 0;
+@@ -982,7 +985,10 @@ void phy_state_machine(struct work_struc
+ 	case PHY_HALTED:
+ 		if (phydev->link) {
+ 			phydev->link = 0;
+-			phy_link_down(phydev, true);
++			if (!phydev->no_auto_carrier_off)
++				phy_link_down(phydev, true);
++			else
++				phy_link_down(phydev, false);
+ 		}
+ 		do_suspend = true;
+ 		break;
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -380,6 +380,7 @@ struct phy_device {
+ 	unsigned suspended_by_mdio_bus:1;
+ 	unsigned sysfs_links:1;
+ 	unsigned loopback_enabled:1;
++	unsigned no_auto_carrier_off:1;
+ 
+ 	unsigned autoneg:1;
+ 	/* The most recently read link state */
diff --git a/target/linux/ramips/patches-5.4/991-at803x.patch b/target/linux/ramips/patches-5.4/991-at803x.patch
new file mode 100644
index 0000000..af0132f
--- /dev/null
+++ b/target/linux/ramips/patches-5.4/991-at803x.patch
@@ -0,0 +1,156 @@
+From 924453aa9d2324e5611f8e2b71df746d8f0c79f1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
+Date: Fri, 13 Nov 2020 16:11:32 +0100
+Subject: [PATCH] net: phy: at803x: add support for SFP module in
+ RGMII-to-x-base mode
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: René van Dorst <opensource@vdorst.com>
+---
+ drivers/net/phy/at803x.c | 91 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 91 insertions(+)
+
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -14,6 +14,8 @@
+ #include <linux/etherdevice.h>
+ #include <linux/of_gpio.h>
+ #include <linux/gpio/consumer.h>
++#include <linux/sfp.h>
++#include <linux/phylink.h>
+ 
+ #define AT803X_SPECIFIC_STATUS			0x11
+ #define AT803X_SS_SPEED_MASK			(3 << 14)
+@@ -53,9 +55,18 @@
+ 
+ #define AT803X_MODE_CFG_MASK			0x0F
+ #define AT803X_MODE_CFG_SGMII			0x01
++#define AT803X_MODE_CFG_BX1000_RGMII_50		0x02
++#define AT803X_MODE_CFG_BX1000_RGMII_75		0x03
++#define AT803X_MODE_FIBER			0x01
++#define AT803X_MODE_COPPER			0x00
+ 
+ #define AT803X_PSSR			0x11	/*PHY-Specific Status Register*/
+ #define AT803X_PSSR_MR_AN_COMPLETE	0x0200
++#define	 PSSR_LINK			BIT(10)
++#define	 PSSR_SYNC_STATUS		BIT(8)
++#define	 PSSR_DUPLEX			BIT(13)
++#define	 PSSR_SPEED_1000		BIT(15)
++#define	 PSSR_SPEED_100			BIT(14)
+ 
+ #define AT803X_DEBUG_REG_0			0x00
+ #define AT803X_DEBUG_RX_CLK_DLY_EN		BIT(15)
+@@ -243,10 +254,72 @@ static int at803x_resume(struct phy_devi
+ 	return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
+ }
+ 
++static int at803x_mode(struct phy_device *phydev)
++{
++	int mode;
++
++	mode = phy_read(phydev, AT803X_REG_CHIP_CONFIG) & AT803X_MODE_CFG_MASK;
++
++	if (mode == AT803X_MODE_CFG_BX1000_RGMII_50 ||
++	    mode == AT803X_MODE_CFG_BX1000_RGMII_75)
++		return AT803X_MODE_FIBER;
++	return AT803X_MODE_COPPER;
++}
++
++static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
++{
++	__ETHTOOL_DECLARE_LINK_MODE_MASK(at803x_support) = { 0, };
++	__ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
++	struct phy_device *phydev = upstream;
++	phy_interface_t iface;
++
++	phylink_set(at803x_support, 1000baseX_Full);
++	/* AT803x only support 1000baseX but SGMII works fine when module runs
++	 * at 1Gbit.
++	 */
++	phylink_set(at803x_support, 1000baseT_Full);
++
++	sfp_parse_support(phydev->sfp_bus, id, support);
++
++	// Limit to interfaces that both sides support
++	linkmode_and(support, support, at803x_support);
++
++	if (linkmode_empty(support))
++		goto unsupported_mode;
++
++	iface = sfp_select_interface(phydev->sfp_bus, support);
++
++	if (iface != PHY_INTERFACE_MODE_SGMII &&
++	    iface != PHY_INTERFACE_MODE_1000BASEX)
++		goto unsupported_mode;
++
++	dev_info(&phydev->mdio.dev, "SFP interface %s", phy_modes(iface));
++
++	return 0;
++
++unsupported_mode:
++	dev_info(&phydev->mdio.dev, "incompatible SFP module inserted;"
++		 "Only SGMII at 1Gbit/1000BASEX are supported!\n");
++	return -EINVAL;
++}
++
++static const struct sfp_upstream_ops at803x_sfp_ops = {
++	.attach = phy_sfp_attach,
++	.detach = phy_sfp_detach,
++	.module_insert = at803x_sfp_insert,
++};
++
+ static int at803x_probe(struct phy_device *phydev)
+ {
+ 	struct device *dev = &phydev->mdio.dev;
+ 	struct at803x_priv *priv;
++	int ret;
++
++	if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
++		ret = phy_sfp_probe(phydev, &at803x_sfp_ops);
++		if (ret < 0)
++			return ret;
++	}
+ 
+ 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ 	if (!priv)
+@@ -394,6 +467,10 @@ static int at803x_read_status(struct phy
+ {
+ 	int ss, err, old_link = phydev->link;
+ 
++	/* Handle (Fiber) SGMII to RGMII mode */
++	if (at803x_mode(phydev) == AT803X_MODE_FIBER)
++		return genphy_c37_read_status(phydev);
++
+ 	/* Update the link, but return if there was an error */
+ 	err = genphy_update_link(phydev);
+ 	if (err)
+@@ -448,6 +525,19 @@ static int at803x_read_status(struct phy
+ 	return 0;
+ }
+ 
++static int at803x_config_aneg(struct phy_device *phydev)
++{
++	/* Handle (Fiber) SerDes to RGMII mode */
++	if (at803x_mode(phydev) == AT803X_MODE_FIBER) {
++		pr_warn("%s: fiber\n", __func__);
++		return genphy_c37_config_aneg(phydev);
++	}
++
++	pr_warn("%s: enter\n", __func__);
++
++	return genphy_config_aneg(phydev);
++}
++
+ static struct phy_driver at803x_driver[] = {
+ {
+ 	/* ATHEROS 8035 */
+@@ -491,6 +581,7 @@ static struct phy_driver at803x_driver[]
+ 	.suspend		= at803x_suspend,
+ 	.resume			= at803x_resume,
+ 	/* PHY_GBIT_FEATURES */
++	.config_aneg		= at803x_config_aneg,
+ 	.read_status		= at803x_read_status,
+ 	.aneg_done		= at803x_aneg_done,
+ 	.ack_interrupt		= &at803x_ack_interrupt,
diff --git a/target/linux/ramips/rt288x/base-files/etc/board.d/01_leds b/target/linux/ramips/rt288x/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..b62ad76
--- /dev/null
+++ b/target/linux/ramips/rt288x/base-files/etc/board.d/01_leds
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+airlink101,ar670w|\
+airlink101,ar725w)
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800soc-phy0::radio" "wlan0"
+	;;
+belkin,f5d8235-v1)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wireless" "wlan0"
+	;;
+ralink,v11st-fe)
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800pci-phy0::radio" "wlan0"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt288x/base-files/etc/board.d/02_network b/target/linux/ramips/rt288x/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..134ac87
--- /dev/null
+++ b/target/linux/ramips/rt288x/base-files/etc/board.d/02_network
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	airlink101,ar670w|\
+	airlink101,ar725w)
+		ucidef_add_switch "switch0" \
+			"0:wan" "1:lan" "2:lan" "3:lan" "4:lan" "6t@eth0"
+		;;
+	asus,rt-n15)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "5@eth0"
+		;;
+	belkin,f5d8235-v1|\
+	buffalo,wzr-agl300nh|\
+	ralink,v11st-fe)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "5@eth0"
+		;;
+	buffalo,wli-tx4-ag300n|\
+	dlink,dap-1522-a1)
+		ucidef_set_interface_lan "eth0"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	airlink101,ar670w)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x2004)" 1)
+		;;
+	airlink101,ar725w|\
+	asus,rt-n15|\
+	belkin,f5d8235-v1|\
+	buffalo,wzr-agl300nh)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt288x/base-files/lib/upgrade/platform.sh b/target/linux/ramips/rt288x/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..786d57f
--- /dev/null
+++ b/target/linux/ramips/rt288x/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/rt288x/config-5.4 b/target/linux/ramips/rt288x/config-5.4
new file mode 100644
index 0000000..6c0725a
--- /dev/null
+++ b/target/linux/ramips/rt288x/config-5.4
@@ -0,0 +1,227 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DTB_RT2880_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_RALINK=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PCI=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IP17XX_PHY=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=4
+CONFIG_MIPS_L1_CACHE_SHIFT_4=y
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPLIT_LZMA_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_MTD_SPLIT_WRGG_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK_MDIO=y
+CONFIG_NET_RALINK_MDIO_RT2880=y
+CONFIG_NET_RALINK_RT2880=y
+CONFIG_NET_RALINK_SOC=y
+CONFIG_NET_VENDOR_RALINK=y
+CONFIG_NLS=m
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+# CONFIG_PCI_MT7621 is not set
+# CONFIG_PCI_MT7621_PHY is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+# CONFIG_PHY_RALINK_USB is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_WDT=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SOC_MT7620 is not set
+# CONFIG_SOC_MT7621 is not set
+CONFIG_SOC_RT288X=y
+# CONFIG_SOC_RT305X is not set
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_MT7621 is not set
+CONFIG_SPI_RT2880=y
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB=m
+CONFIG_USB_COMMON=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_HCD_PLATFORM=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_HCD_PLATFORM=m
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/ramips/rt288x/target.mk b/target/linux/ramips/rt288x/target.mk
new file mode 100644
index 0000000..814ac97
--- /dev/null
+++ b/target/linux/ramips/rt288x/target.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+SUBTARGET:=rt288x
+BOARDNAME:=RT288x based boards
+FEATURES+=small_flash
+CPU_TYPE:=24kc
+
+DEFAULT_PACKAGES += kmod-rt2800-soc wpad-basic-wolfssl swconfig
+
+define Target/Description
+	Build firmware images for Ralink RT288x based boards.
+endef
+
diff --git a/target/linux/ramips/rt305x/base-files/etc/board.d/01_leds b/target/linux/ramips/rt305x/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..d29328e
--- /dev/null
+++ b/target/linux/ramips/rt305x/base-files/etc/board.d/01_leds
@@ -0,0 +1,105 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+7links,px-4885-4m|\
+7links,px-4885-8m|\
+fon,fonera-20n)
+	ucidef_set_led_netdev "wifi_led" "wifi" "orange:wifi" "wlan0"
+	;;
+airlive,air3gii|\
+aximcom,mr-102n|\
+edimax,3g-6200nl|\
+netgear,wnce2001)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+alfa-network,w502u|\
+dlink,dir-300-b1|\
+dlink,dir-300-b7|\
+dlink,dir-320-b1|\
+dlink,dir-600-b1|\
+dlink,dir-610-a1|\
+dlink,dir-615-h1|\
+dlink,dir-620-a1|\
+engenius,esr-9753|\
+hilink,hlk-rm04|\
+nexx,wt1520-4m|\
+nexx,wt1520-8m|\
+skyline,sl-r7205|\
+tenda,w306r-v2|\
+zyxel,keenetic-start|\
+zyxel,keenetic|\
+zyxel,nbg-419n-v2)
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800pci-phy0::radio" "wlan0"
+	;;
+allnet,all0256n-4m|\
+allnet,all0256n-8m)
+	ucidef_set_rssimon "wlan0" "200000" "1"
+	ucidef_set_led_rssi "rssilow" "RSSILOW" "green:rssilow" "wlan0" "1" "40" "0" "6"
+	ucidef_set_led_rssi "rssimedium" "RSSIMEDIUM" "green:rssimed" "wlan0" "30" "80" "-29" "5"
+	ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "green:rssihigh" "wlan0" "70" "100" "-69" "8"
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800pci-phy0::radio" "wlan0"
+	;;
+alphanetworks,asl26555-8m|\
+alphanetworks,asl26555-16m)
+	ucidef_set_led_netdev "eth" "ETH" "green:eth" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	;;
+asiarf,awapn2403)
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800soc-phy0::radio" "wlan0"
+	;;
+dlink,dcs-930l-b1)
+	ucidef_set_led_netdev "wifi" "WiFi" "blue:wps"
+	;;
+dlink,dir-615-d)
+	ucidef_set_led_netdev "wan" "WAN (green)" "green:wan" "eth0.2"
+	ucidef_set_led_netdev "wifi_led" "wifi" "rt2800soc-phy0::radio" "wlan0"
+	;;
+dlink,dir-620-d1|\
+trendnet,tew-714tru)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+edimax,3g-6200n|\
+planex,mzk-w300nh2)
+	ucidef_set_led_netdev "wifi_led" "wifi" "amber:wlan" "wlan0"
+	;;
+hauppauge,broadway)
+	ucidef_set_led_netdev "wifi_led" "wifi" "red:wps_active" "wlan0"
+	;;
+hootoo,ht-tm02)
+	ucidef_set_led_netdev "eth" "Ethernet" "green:lan" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wlan" "wlan0"
+	;;
+huawei,hg255d)
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wlan" "wlan0"
+	ucidef_set_led_netdev "internet" "internet" "green:internet" "eth0.2"
+	;;
+intenso,memory2move)
+	ucidef_set_led_netdev "wifi_led" "wifi" "blue:wifi" "wlan0"
+	ucidef_set_led_netdev "eth" "Ethernet" "green:wan" "eth0"
+	;;
+omnima,miniembplug)
+	ucidef_set_led_netdev "wifi_led" "wifi" "red:wlan" "wlan0"
+	;;
+vocore,vocore-8m|\
+vocore,vocore-16m)
+	ucidef_set_led_netdev "eth" "ETH" "orange:eth" "eth0"
+	;;
+zorlik,zl5900v2)
+	ucidef_set_led_netdev "lan" "lan" "green:lan" "eth0"
+	;;
+zte,mf283plus)
+	ucidef_set_led_wlan "wifi" "wifi" "rt2800soc-phy0::radio" "phy0tpt"
+	ucidef_set_led_netdev "wwan" "wwan" "blue:wwan" "wwan0"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt305x/base-files/etc/board.d/02_network b/target/linux/ramips/rt305x/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..c3e39e7
--- /dev/null
+++ b/target/linux/ramips/rt305x/base-files/etc/board.d/02_network
@@ -0,0 +1,308 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	7links,px-4885-4m|\
+	7links,px-4885-8m|\
+	allnet,all0256n-4m|\
+	allnet,all0256n-8m|\
+	allnet,all5002|\
+	allnet,all5003|\
+	belkin,f7c027|\
+	dlink,dcs-930l-b1|\
+	dlink,dcs-930|\
+	edimax,3g-6200nl|\
+	hame,mpr-a1|\
+	hame,mpr-a2|\
+	hauppauge,broadway|\
+	hootoo,ht-tm02|\
+	huawei,d105|\
+	intenso,memory2move|\
+	netgear,wnce2001|\
+	tenda,3g150b|\
+	tenda,3g300m|\
+	tenda,w150m|\
+	trendnet,tew-714tru|\
+	unbranded,a5-v11|\
+	wansview,ncs601w|\
+	zorlik,zl5900v2)
+		ucidef_add_switch "switch0"
+		ucidef_add_switch_attr "switch0" "enable" "false"
+		ucidef_set_interface_lan "eth0"
+		;;
+	8devices,carambola)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "6@eth0"
+		;;
+	accton,wr6202|\
+	alfa-network,w502u|\
+	argus,atp-52b|\
+	asiarf,awm002-evb-4m|\
+	asiarf,awm002-evb-8m|\
+	asus,rt-n10-plus|\
+	asus,wl-330n|\
+	asus,wl-330n3g|\
+	aztech,hw550-3g|\
+	engenius,esr-9753|\
+	jcg,jhr-n805r|\
+	jcg,jhr-n825r|\
+	jcg,jhr-n926r|\
+	petatel,psr-680w|\
+	planex,mzk-wdpr|\
+	skyline,sl-r7205|\
+	teltonika,rut5xx|\
+	tenda,w306r-v2|\
+	unbranded,xdx-rn502j|\
+	upvel,ur-326n4g)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	airlive,air3gii|\
+	asus,rt-g32-b1|\
+	asus,rt-n13u|\
+	aximcom,mr-102n|\
+	buffalo,whr-g300n|\
+	dlink,dap-1350|\
+	dlink,dir-300-b1|\
+	dlink,dir-300-b7|\
+	dlink,dir-320-b1|\
+	dlink,dir-600-b1|\
+	dlink,dir-610-a1|\
+	dlink,dir-615-d|\
+	dlink,dir-620-a1|\
+	dlink,dir-620-d1|\
+	dlink,dwr-512-b|\
+	easyacc,wizard-8800|\
+	edimax,3g-6200n|\
+	fon,fonera-20n|\
+	hilink,hlk-rm04|\
+	mofinetwork,mofi3500-3gn|\
+	netcore,nw718|\
+	nexaira,bc2|\
+	nixcore,x1-16m|\
+	nixcore,x1-8m|\
+	olimex,rt5350f-olinuxino|\
+	olimex,rt5350f-olinuxino-evb|\
+	omnima,miniembplug|\
+	omnima,miniembwifi|\
+	planex,mzk-w300nh2|\
+	poray,ip2202|\
+	poray,m3|\
+	poray,m4-4m|\
+	poray,m4-8m|\
+	poray,x5|\
+	poray,x8|\
+	prolink,pwh2004|\
+	ralink,v22rw-2x2|\
+	unbranded,wr512-3gn-4m|\
+	unbranded,wr512-3gn-8m|\
+	upvel,ur-336un|\
+	zyxel,keenetic|\
+	zyxel,nbg-419n|\
+	zyxel,nbg-419n-v2)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "6@eth0"
+		;;
+	alphanetworks,asl26555-8m|\
+	alphanetworks,asl26555-16m)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "6t@eth0"
+		;;
+	arcwireless,freestation5)
+		# FIXME: Which is the actual wan port?
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:wan" "2:wan" "3:wan" "4:wan" "6@eth0"
+		;;
+	asiarf,awapn2403)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:wan" "6@eth0"
+		;;
+	aximcom,mr-102n|\
+	trendnet,tew-638apb-v2)
+		ucidef_add_switch "switch0" \
+			"4:lan" "6@eth0"
+		;;
+	belkin,f5d8235-v2)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "5@eth0"
+		;;
+	dlink,dir-615-h1)
+		ucidef_add_switch "switch0" \
+			"0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4:wan:5" "6@eth0"
+		;;
+	huawei,hg255d)
+		ucidef_add_switch "switch0" \
+			"1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1" "0:wan" "6@eth0"
+		;;
+	nexx,wt1520-4m|\
+	nexx,wt1520-8m)
+		ucidef_add_switch "switch0" \
+			"0:lan" "4:wan" "6@eth0"
+		;;
+	planex,mzk-dp150n|\
+	vocore,vocore-8m|\
+	vocore,vocore-16m)
+		ucidef_add_switch "switch0" \
+			"0:lan" "4:lan" "6t@eth0"
+		;;
+	sitecom,wl-351)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "5@eth0"
+		;;
+	sparklan,wcr-150gn)
+		ucidef_add_switch "switch0" \
+			"0:lan" "6t@eth0"
+		;;
+	wiznet,wizfi630a)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:wan" "6@eth0"
+		;;
+	zte,mf283plus)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "6@eth0"
+		;;
+	zyxel,keenetic-lite-b|\
+	zyxel,keenetic-start)
+		ucidef_add_switch "switch0" \
+			"0:lan:3" "1:lan:2" "2:lan:1" "3:lan:0" "4:wan" "6@eth0"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	7links,px-4885-4m|\
+	7links,px-4885-8m)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary devconf 0x28)" 1)
+		;;
+	8devices,carambola|\
+	alfa-network,w502u|\
+	arcwireless,freestation5|\
+	netgear,wnce2001)
+		wan_mac=$(mtd_get_mac_binary factory 0x2e)
+		;;
+	accton,wr6202|\
+	asiarf,awm002-evb-4m|\
+	asiarf,awm002-evb-8m|\
+	asus,rt-n13u|\
+	aztech,hw550-3g|\
+	fon,fonera-20n|\
+	huawei,hg255d|\
+	omnima,miniembwifi|\
+	planex,mzk-wdpr|\
+	poray,ip2202|\
+	teltonika,rut5xx|\
+	unbranded,xdx-rn502j|\
+	zyxel,keenetic|\
+	zyxel,nbg-419n|\
+	zyxel,nbg-419n-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x28)" 1)
+		;;
+	airlive,air3gii|\
+	argus,atp-52b|\
+	asus,wl-330n3g|\
+	dlink,dir-620-d1|\
+	edimax,3g-6200n|\
+	edimax,3g-6200nl|\
+	netcore,nw718|\
+	nexx,wt1520-4m|\
+	nexx,wt1520-8m|\
+	nixcore,x1-16m|\
+	nixcore,x1-8m|\
+	omnima,miniembplug|\
+	planex,mzk-w300nh2|\
+	sitecom,wl-351|\
+	trendnet,tew-714tru)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1)
+		;;
+	asus,rt-g32-b1|\
+	asus,rt-n10-plus)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary devconf 0x4)" 1)
+		;;
+	belkin,f5d8235-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary uboot 0x40004)" 1)
+		;;
+	dlink,dir-300-b7|\
+	dlink,dir-320-b1|\
+	dlink,dir-620-a1|\
+	engenius,esr-9753|\
+	hame,mpr-a1|\
+	hauppauge,broadway|\
+	huawei,d105|\
+	hilink,hlk-rm04|\
+	nexaira,bc2|\
+	olimex,rt5350f-olinuxino|\
+	olimex,rt5350f-olinuxino-evb|\
+	petatel,psr-680w|\
+	skyline,sl-r7205)
+		lan_mac=$(macaddr_setbit_la "$(cat /sys/class/net/eth0/address)")
+		wan_mac=$(macaddr_add "$lan_mac" 1)
+		;;
+	dlink,dap-1350)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary devdata 0x2e)" 1)
+		;;
+	dlink,dir-300-b1|\
+	dlink,dir-600-b1|\
+	dlink,dir-610-a1)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary devdata 0x4004)" 1)
+		;;
+	dlink,dir-615-d)
+		label_mac=$(mtd_get_mac_binary devdata 0x4004)
+		;;
+	dlink,dir-615-h1)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x28)" 1)
+		label_mac=$(mtd_get_mac_binary factory 0x4)
+		;;
+	dlink,dwr-512-b)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary config 0xe07e)" 1)
+		;;
+	jcg,jhr-n805r|\
+	jcg,jhr-n825r|\
+	jcg,jhr-n926r)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x2e)" 1)
+		;;
+	poray,m3|\
+	poray,m4-4m|\
+	poray,m4-8m|\
+	poray,x5|\
+	poray,x8)
+		lan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" -2)
+		;;
+	sparklan,wcr-150gn|\
+	wiznet,wizfi630a)
+		wan_mac=$(mtd_get_mac_binary factory 0x28)
+		;;
+	tenda,w306r-v2)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x28)" 5)
+		;;
+	upvel,ur-326n4g|\
+	upvel,ur-336un)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4004)" 1)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt305x/base-files/lib/preinit/04_handle_checksumming b/target/linux/ramips/rt305x/base-files/lib/preinit/04_handle_checksumming
new file mode 100644
index 0000000..e2e0893
--- /dev/null
+++ b/target/linux/ramips/rt305x/base-files/lib/preinit/04_handle_checksumming
@@ -0,0 +1,41 @@
+# Netgear WNCE2001 has does a checksum check on boot and goes into recovery
+# tftp mode when the check fails.  Initializing the JFFS2 partition triggers
+# this, so we make sure to zero checksum and size to be checksummed before
+# that happens, so this needs to run very early during boot.
+
+do_checksumming_disable() {
+	. /lib/functions.sh
+
+	local board=$(board_name)
+
+	case "$board" in
+	netgear,wnce2001)
+		echo "Board is WNCE2001, updating checksum partition..."
+		local zeroes=/dev/zero
+		local tmpfile=/tmp/wnce2001_checksum
+		local partname=checksum
+		local mtd=$(find_mtd_part $partname)
+		dd if=$mtd of=$tmpfile bs=80 count=1 2>/dev/null
+		signature=$(dd if=$tmpfile bs=1 skip=24 count=20 2>/dev/null)
+		checksum=$(dd if=$tmpfile bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"')
+		if [ "$signature" != "RT3052-AP-WNCE2001-3" ]; then
+			echo "Signature of checksum partition is wrong, bailing."
+			return 0
+		fi
+		if [ "$checksum" != "00000000" ]; then
+			echo "Checksum is set, zeroing."
+			# zero out checksum
+			dd if=$zeroes of=$tmpfile conv=notrunc bs=1 seek=0 count=4 2>/dev/null
+			# zero out bytecount to be checksummed
+			dd if=$zeroes of=$tmpfile conv=notrunc bs=1 seek=60 count=4 2>/dev/null
+			mtd write $tmpfile $partname
+		else
+			echo "Checksum is already zero, nothing to do."
+		fi
+	;;
+	esac
+
+	return 0
+}
+
+boot_hook_add preinit_main do_checksumming_disable
diff --git a/target/linux/ramips/rt305x/base-files/lib/upgrade/platform.sh b/target/linux/ramips/rt305x/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..786d57f
--- /dev/null
+++ b/target/linux/ramips/rt305x/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/rt305x/config-5.4 b/target/linux/ramips/rt305x/config-5.4
new file mode 100644
index 0000000..3f93a9d
--- /dev/null
+++ b/target/linux/ramips/rt305x/config-5.4
@@ -0,0 +1,226 @@
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_CEVT_R4K=y
+CONFIG_CEVT_SYSTICK_QUIRK=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKEVT_RT3352=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DMA_RALINK is not set
+# CONFIG_DTB_RT305X_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_RALINK=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
+CONFIG_MTD_SPLIT_JIMAGE_FW=y
+CONFIG_MTD_SPLIT_SEAMA_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK_ESW_RT3050=y
+CONFIG_NET_RALINK_RT3050=y
+CONFIG_NET_RALINK_SOC=y
+CONFIG_NET_VENDOR_RALINK=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+# CONFIG_PCI_MT7621 is not set
+# CONFIG_PCI_MT7621_PHY is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHY_RALINK_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_RALINK=y
+# CONFIG_RALINK_ILL_ACC is not set
+CONFIG_RALINK_WDT=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SOC_MT7620 is not set
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+CONFIG_SOC_RT305X=y
+# CONFIG_SOC_RT3883 is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_MT7621 is not set
+CONFIG_SPI_RT2880=y
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/ramips/rt305x/target.mk b/target/linux/ramips/rt305x/target.mk
new file mode 100644
index 0000000..27ad670
--- /dev/null
+++ b/target/linux/ramips/rt305x/target.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+
+SUBTARGET:=rt305x
+BOARDNAME:=RT3x5x/RT5350 based boards
+FEATURES+=usb ramdisk small_flash
+CPU_TYPE:=24kc
+
+DEFAULT_PACKAGES += kmod-rt2800-soc wpad-basic-wolfssl swconfig
+
+define Target/Description
+	Build firmware images for Ralink RT3x5x/RT5350 based boards.
+endef
+
diff --git a/target/linux/ramips/rt3883/base-files/etc/board.d/01_leds b/target/linux/ramips/rt3883/base-files/etc/board.d/01_leds
new file mode 100755
index 0000000..6e8497a
--- /dev/null
+++ b/target/linux/ramips/rt3883/base-files/etc/board.d/01_leds
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+. /lib/functions/leds.sh
+. /lib/functions/uci-defaults.sh
+
+board=$(board_name)
+
+board_config_update
+
+case $board in
+belkin,f9k1109v1)
+	ucidef_set_led_netdev "lan" "lan" "blue:wps" "eth0"
+	;;
+edimax,br-6475nd)
+	ucidef_set_led_netdev "wifi_led" "wifi" "amber:wlan" "wlan0"
+	;;
+omnima,hpm)
+	ucidef_set_led_netdev "eth" "ETH" "green:eth" "eth0"
+	ucidef_set_led_netdev "wifi_led" "wifi" "green:wifi" "wlan0"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt3883/base-files/etc/board.d/02_network b/target/linux/ramips/rt3883/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..f261996
--- /dev/null
+++ b/target/linux/ramips/rt3883/base-files/etc/board.d/02_network
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/uci-defaults.sh
+. /lib/functions/system.sh
+
+ramips_setup_interfaces()
+{
+	local board="$1"
+
+	case $board in
+	asus,rt-n56u)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "8@eth0"
+		;;
+	belkin,f9k1109v1)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "5@eth0"
+		;;
+	dlink,dir-645)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "6@eth0"
+		;;
+	edimax,br-6475nd)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "0:wan" "9@eth0"
+		;;
+	engenius,esr600h|\
+	sitecom,wlr-6000|\
+	trendnet,tew-691gr|\
+	trendnet,tew-692gr)
+		ucidef_add_switch "switch0" \
+			"1:lan" "2:lan" "3:lan" "4:lan" "5:wan" "0@eth0"
+		;;
+	loewe,wmdr-143n|\
+	omnima,hpm)
+		ucidef_set_interface_lan "eth0"
+		;;
+	samsung,cy-swr1100)
+		ucidef_add_switch "switch0" \
+			"0:lan" "1:lan" "2:lan" "3:lan" "4:wan" "9@eth0"
+		;;
+	esac
+}
+
+ramips_setup_macs()
+{
+	local board="$1"
+	local lan_mac=""
+	local wan_mac=""
+	local label_mac=""
+
+	case $board in
+	asus,rt-n56u)
+		lan_mac=$(macaddr_setbit_la "$(cat /sys/class/net/eth0/address)")
+		wan_mac=$(mtd_get_mac_binary factory 0x8004)
+		;;
+	belkin,f9k1109v1)
+		wan_mac=$(mtd_get_mac_ascii uboot-env HW_WAN_MAC)
+		lan_mac=$(mtd_get_mac_ascii uboot-env HW_LAN_MAC)
+		label_mac=$wan_mac
+		;;
+	dlink,dir-645)
+		lan_mac=$(mtd_get_mac_ascii nvram lanmac)
+		wan_mac=$(mtd_get_mac_ascii nvram wanmac)
+		;;
+	edimax,br-6475nd)
+		wan_mac=$(mtd_get_mac_binary devdata 0x7)
+		;;
+	engenius,esr600h)
+		wan_mac=$(mtd_get_mac_ascii u-boot-env wanaddr)
+		lan_mac=$(macaddr_add "$wan_mac" 1)
+		label_mac=$wan_mac
+		;;
+	samsung,cy-swr1100)
+		lan_mac=$(mtd_get_mac_ascii nvram lanmac)
+		wan_mac=$(mtd_get_mac_ascii nvram wanmac)
+		label_mac=$wan_mac
+		;;
+	sitecom,wlr-6000)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x8004)" 2)
+		;;
+	trendnet,tew-691gr)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 3)
+		;;
+	trendnet,tew-692gr)
+		wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x4)" 1)
+		;;
+	esac
+
+	[ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac
+	[ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac
+	[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
+}
+
+board_config_update
+board=$(board_name)
+ramips_setup_interfaces $board
+ramips_setup_macs $board
+board_config_flush
+
+exit 0
diff --git a/target/linux/ramips/rt3883/base-files/lib/preinit/04_handle_checksumming b/target/linux/ramips/rt3883/base-files/lib/preinit/04_handle_checksumming
new file mode 100644
index 0000000..62927ff
--- /dev/null
+++ b/target/linux/ramips/rt3883/base-files/lib/preinit/04_handle_checksumming
@@ -0,0 +1,30 @@
+# Netgear WNCE2001 has does a checksum check on boot and goes into recovery
+# tftp mode when the check fails.  Initializing the JFFS2 partition triggers
+# this, so we make sure to zero checksum and size to be checksummed before
+# that happens, so this needs to run very early during boot.
+
+do_checksumming_disable() {
+	. /lib/functions.sh
+
+	local board=$(board_name)
+
+	case "$board" in
+	asus,rt-n56u)
+		echo "Board is ASUS RT-N56U, replacing uImage header..."
+		local firmware_mtd=$(find_mtd_part firmware)
+		local rootfs_mtd=$(find_mtd_part rootfs)
+		local rootfs_data_mtd=$(find_mtd_part rootfs_data)
+		local rootfs_len=$(grep \"rootfs\" /proc/mtd | awk -F' ' '{print "0x"$2}')
+		local rootfs_data_len=$(grep \"rootfs_data\" /proc/mtd | awk -F' ' '{print "0x"$2}')
+		local offset=$(echo "$rootfs_len $rootfs_data_len 0x40" | awk -F' ' '{printf "%i",$1-$2-$3}')
+		local signature=$(dd if=$rootfs_mtd skip=$offset bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"')
+		if [ "$signature" = "27051956" ]; then
+			dd conv=notrunc if=$rootfs_mtd skip=$offset of=$firmware_mtd bs=1 count=64 2>/dev/null
+		fi
+	;;
+	esac
+
+	return 0
+}
+
+boot_hook_add preinit_main do_checksumming_disable
diff --git a/target/linux/ramips/rt3883/base-files/lib/upgrade/platform.sh b/target/linux/ramips/rt3883/base-files/lib/upgrade/platform.sh
new file mode 100755
index 0000000..786d57f
--- /dev/null
+++ b/target/linux/ramips/rt3883/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2010 OpenWrt.org
+#
+
+PART_NAME=firmware
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+	return 0
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	*)
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/ramips/rt3883/config-5.4 b/target/linux/ramips/rt3883/config-5.4
new file mode 100644
index 0000000..09d51fd
--- /dev/null
+++ b/target/linux/ramips/rt3883/config-5.4
@@ -0,0 +1,229 @@
+CONFIG_AR8216_PHY=y
+CONFIG_ARCH_32BIT_OFF_T=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_MMAP_RND_BITS_MAX=15
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
+CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_CEVT_R4K=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CMDLINE_OVERRIDE is not set
+CONFIG_COMPAT_32BIT_TIME=y
+CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_RIXI=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS32_R1 is not set
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
+CONFIG_CPU_R4K_CACHE_TLB=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_CPU_SUPPORTS_MSA=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CSRC_R4K=y
+CONFIG_DEBUG_PINCTRL=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
+# CONFIG_DMA_RALINK is not set
+# CONFIG_DTB_RT3883_EVAL is not set
+CONFIG_DTB_RT_NONE=y
+CONFIG_DTC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_EFI_EARLYCON=y
+CONFIG_ETHERNET_PACKET_MANGLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FW_LOADER_PAGED_BUF=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_IRQ_CHIP=y
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PHY=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_RALINK=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_COMPILER_H=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_ASM_MODVERSIONS=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_COPY_THREAD_TLS=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_GENERIC_VDSO=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_KVM=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_PCI=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
+CONFIG_HZ_PERIODIC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_INTC=y
+CONFIG_IRQ_MIPS_CPU=y
+CONFIG_IRQ_WORK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGRATION=y
+CONFIG_MIPS=y
+CONFIG_MIPS_ASID_BITS=8
+CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CLOCK_VSYSCALL=y
+# CONFIG_MIPS_CMDLINE_BUILTIN_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
+# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
+CONFIG_MIPS_CMDLINE_FROM_DTB=y
+# CONFIG_MIPS_ELF_APPENDED_DTB is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+# CONFIG_MIPS_NO_APPENDED_DTB is not set
+CONFIG_MIPS_RAW_APPENDED_DTB=y
+CONFIG_MIPS_SPRAM=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
+CONFIG_MTD_SPLIT_SEAMA_FW=y
+CONFIG_MTD_SPLIT_UIMAGE_FW=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_RALINK_MDIO=y
+CONFIG_NET_RALINK_MDIO_RT2880=y
+CONFIG_NET_RALINK_RT3883=y
+CONFIG_NET_RALINK_SOC=y
+CONFIG_NET_VENDOR_RALINK=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_OF=y
+CONFIG_OF_ADDRESS=y
+CONFIG_OF_EARLY_FLATTREE=y
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
+CONFIG_OF_MDIO=y
+CONFIG_OF_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DRIVERS_LEGACY=y
+# CONFIG_PCI_MT7621 is not set
+# CONFIG_PCI_MT7621_PHY is not set
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHY_RALINK_USB=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_RT2880=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_RALINK=y
+CONFIG_RALINK_WDT=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RTL8366_SMI=y
+CONFIG_RTL8367B_PHY=y
+CONFIG_RTL8367_PHY=y
+CONFIG_SERIAL_8250_RT288X=y
+CONFIG_SERIAL_MCTRL_GPIO=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SOC_MT7620 is not set
+# CONFIG_SOC_MT7621 is not set
+# CONFIG_SOC_RT288X is not set
+# CONFIG_SOC_RT305X is not set
+CONFIG_SOC_RT3883=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
+# CONFIG_SPI_MT7621 is not set
+CONFIG_SPI_RT2880=y
+CONFIG_SRCU=y
+CONFIG_SWCONFIG=y
+CONFIG_SWPHY=y
+CONFIG_SYSCTL_EXCEPTION_TRACE=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_MIPS16=y
+CONFIG_TARGET_ISA_REV=2
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TINY_SRCU=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
diff --git a/target/linux/ramips/rt3883/target.mk b/target/linux/ramips/rt3883/target.mk
new file mode 100644
index 0000000..ff878a0
--- /dev/null
+++ b/target/linux/ramips/rt3883/target.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+
+SUBTARGET:=rt3883
+BOARDNAME:=RT3662/RT3883 based boards
+FEATURES+=usb pci small_flash
+CPU_TYPE:=74kc
+
+DEFAULT_PACKAGES += kmod-rt2800-pci kmod-rt2800-soc wpad-basic-wolfssl swconfig
+
+define Target/Description
+	Build firmware images for Ralink RT3662/RT3883 based boards.
+endef
+