ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/target/linux/gemini/Makefile b/target/linux/gemini/Makefile
new file mode 100644
index 0000000..d2acb52
--- /dev/null
+++ b/target/linux/gemini/Makefile
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2009-2018 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+
+ARCH:=arm
+BOARD:=gemini
+BOARDNAME:=Cortina Systems CS351x
+FEATURES:=squashfs pci rtc usb dt gpio display ext4 rootfs-part boot-part
+CPU_TYPE:=fa526
+
+KERNEL_PATCHVER:=5.4
+
+define Target/Description
+	Build firmware images for the StorLink/Cortina Gemini CS351x ARM FA526 CPU
+endef
+
+KERNELNAME:=zImage dtbs
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += \
+	kmod-usb-fotg210 \
+	kmod-usb-ledtrig-usbport \
+	kmod-leds-gpio \
+	kmod-gpio-button-hotplug
+
+$(eval $(call BuildTarget))
diff --git a/target/linux/gemini/base-files/etc/board.d/02_network b/target/linux/gemini/base-files/etc/board.d/02_network
new file mode 100755
index 0000000..9e80fee
--- /dev/null
+++ b/target/linux/gemini/base-files/etc/board.d/02_network
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+case "$(board_name)" in
+dlink,dir-685)
+	# These are all connected to eth0 thru RTL8366RB
+	ucidef_set_interface "eth" device "eth0" protocol "none"
+	ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" "wan"
+	;;
+itian,sq201)
+	# These are all connected to eth1 thru VSC7395
+	ucidef_set_interface "eth" device "eth1" protocol "none"
+	ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth0"
+	;;
+storlink,gemini324)
+	# These are all connected to eth1 thru VSC7385
+	ucidef_set_interface "eth" device "eth1" protocol "none"
+	ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "eth0"
+	;;
+esac
+
+board_config_flush
+
+exit 0
diff --git a/target/linux/gemini/base-files/etc/uci-defaults/09_fix-checksum b/target/linux/gemini/base-files/etc/uci-defaults/09_fix-checksum
new file mode 100644
index 0000000..3acf20d
--- /dev/null
+++ b/target/linux/gemini/base-files/etc/uci-defaults/09_fix-checksum
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2019 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+board=$(board_name)
+
+fixwrgg() {
+	local kernel_size=$(sed -n 's/mtd[0-9]*: \([0-9a-f]*\).*"kernel".*/\1/p' /proc/mtd)
+
+	[ "$kernel_size" ] && mtd -c 0x$kernel_size fixwrgg firmware
+}
+
+case "$board" in
+dlink,dir-685)
+	fixwrgg
+	;;
+esac
diff --git a/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini b/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini
new file mode 100644
index 0000000..07edd85
--- /dev/null
+++ b/target/linux/gemini/base-files/lib/preinit/05_set_ether_mac_gemini
@@ -0,0 +1,53 @@
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+set_ether_mac() {
+	local part
+	local DEVID
+	local MAC1
+	local MAC2
+
+	case "$(board_name)" in
+	dlink,dns-313)
+		# The DNS-313 has a special field in its RedBoot
+		# binary that we need to check
+		part="$(find_mtd_part RedBoot)"
+		if [ -n "$part" ]; then
+			DEVID="$(dd if=$part bs=1 skip=119508 count=7 2>/dev/null)"
+			if [ "$DEVID" = "dns-313" ]; then
+				MAC1="$(mtd_get_mac_binary RedBoot 0x1d2f4)"
+				ip link set eth0 address "$MAC1" 2>/dev/null
+				return 0
+			fi
+		fi
+		;;
+	dlink,dir-685)
+		# The DIR-685 has a special field in its RedBoot
+		# binary that we need to check
+		part=$(find_mtd_part RedBoot)
+		if [ -n "$part" ] ; then
+			DEVID="$(dd if=$part bs=1 skip=81516 count=7 2>/dev/null)"
+			if [ "$DEVID" = "ILI9322" ] ; then
+				MAC1=$(mtd_get_mac_binary RedBoot 0x17340)
+				MAC2=$(mtd_get_mac_binary RedBoot 0x17346)
+				ip link set eth0 address "$MAC1" 2>/dev/null
+				ip link set eth1 address "$MAC2" 2>/dev/null
+				return 0
+			fi
+		fi
+		;;
+	esac
+
+	# Most devices have a standard "VCTL" partition
+	part="$(find_mtd_part VCTL)"
+	if [ -n "$part" ]; then
+		MAC1="$(strings $part |grep MAC|cut -d: -f2|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')"
+		MAC2="$(strings $part |grep MAC|cut -d: -f8|cut -c3-14|sed -e 's,\(..\),:\1,g' -e 's,^:,,')"
+
+		ip link set eth0 address "$MAC1" 2>/dev/null
+		ip link set eth1 address "$MAC2" 2>/dev/null
+		return 0
+	fi
+}
+
+boot_hook_add preinit_main set_ether_mac
diff --git a/target/linux/gemini/base-files/lib/upgrade/platform.sh b/target/linux/gemini/base-files/lib/upgrade/platform.sh
new file mode 100644
index 0000000..bab2f98
--- /dev/null
+++ b/target/linux/gemini/base-files/lib/upgrade/platform.sh
@@ -0,0 +1,25 @@
+REQUIRE_IMAGE_METADATA=1
+
+platform_check_image() {
+	local board=$(board_name)
+
+	case "$board" in
+	dlink,dir-685)
+		return 0
+		;;
+	esac
+
+	echo "Sysupgrade is not yet supported on $board."
+	return 1
+}
+
+platform_do_upgrade() {
+	local board=$(board_name)
+
+	case "$board" in
+	dlink,dir-685)
+		PART_NAME=firmware
+		default_do_upgrade "$1"
+		;;
+	esac
+}
diff --git a/target/linux/gemini/config-5.4 b/target/linux/gemini/config-5.4
new file mode 100644
index 0000000..087da4f
--- /dev/null
+++ b/target/linux/gemini/config-5.4
@@ -0,0 +1,465 @@
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_AMBA_PL08X=y
+CONFIG_ARCH_CLOCKSOURCE_DATA=y
+CONFIG_ARCH_GEMINI=y
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
+CONFIG_ARCH_HAS_KCOV=y
+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
+CONFIG_ARCH_HAS_PHYS_TO_DMA=y
+CONFIG_ARCH_HAS_RESET_CONTROLLER=y
+CONFIG_ARCH_HAS_SET_MEMORY=y
+CONFIG_ARCH_HAS_SG_CHAIN=y
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
+# CONFIG_ARCH_MOXART is not set
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V4=y
+# CONFIG_ARCH_MULTI_V4T is not set
+CONFIG_ARCH_MULTI_V4_V5=y
+# CONFIG_ARCH_MULTI_V5 is not set
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
+CONFIG_ARCH_SUPPORTS_UPROBES=y
+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+CONFIG_ARM=y
+CONFIG_ARM_AMBA=y
+CONFIG_ARM_APPENDED_DTB=y
+# CONFIG_ARM_ATAG_DTB_COMPAT is not set
+CONFIG_ARM_HAS_SG_CHAIN=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+# CONFIG_ARM_SMMU is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_ATA=y
+CONFIG_ATAGS=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_MQ_PCI=y
+CONFIG_BLK_SCSI_REQUEST=y
+CONFIG_BOUNCE=y
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
+CONFIG_CMA=y
+CONFIG_CMA_ALIGNMENT=8
+CONFIG_CMA_AREAS=7
+# CONFIG_CMA_DEBUG is not set
+# CONFIG_CMA_DEBUGFS is not set
+CONFIG_CMA_SIZE_MBYTES=16
+# CONFIG_CMA_SIZE_SEL_MAX is not set
+CONFIG_CMA_SIZE_SEL_MBYTES=y
+# CONFIG_CMA_SIZE_SEL_MIN is not set
+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_GEMINI=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_COREDUMP=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_CACHE_FA=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_FA=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+CONFIG_CPU_FA526=y
+CONFIG_CPU_NO_EFFICIENT_FFS=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_TLB_FA=y
+CONFIG_CPU_USE_DOMAINS=y
+CONFIG_CRASH_CORE=y
+CONFIG_CRC16=y
+# CONFIG_CRC32_SARWATE is not set
+CONFIG_CRC32_SLICEBY8=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CROSS_MEMORY_ATTACH=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_CMAC=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DRBG=y
+CONFIG_CRYPTO_DRBG_HMAC=y
+CONFIG_CRYPTO_DRBG_MENU=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_GHASH=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_JITTERENTROPY=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_NULL2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_RNG_DEFAULT=y
+CONFIG_CRYPTO_SEQIV=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_LZ4=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_DMADEVICES=y
+CONFIG_DMATEST=y
+CONFIG_DMA_CMA=y
+CONFIG_DMA_ENGINE=y
+CONFIG_DMA_ENGINE_RAID=y
+CONFIG_DMA_OF=y
+CONFIG_DMA_SHARED_BUFFER=y
+CONFIG_DMA_VIRTUAL_CHANNELS=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_FBDEV_EMULATION=y
+CONFIG_DRM_FBDEV_OVERALLOC=100
+CONFIG_DRM_GEM_CMA_HELPER=y
+CONFIG_DRM_KMS_CMA_HELPER=y
+CONFIG_DRM_KMS_FB_HELPER=y
+CONFIG_DRM_KMS_HELPER=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_BRIDGE=y
+CONFIG_DRM_PANEL_ILITEK_IL9322=y
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
+CONFIG_DRM_TVE200=y
+CONFIG_DTC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_EDAC_ATOMIC_SCRUB=y
+CONFIG_EDAC_SUPPORT=y
+CONFIG_EEPROM_93CX6=y
+CONFIG_ELF_CORE=y
+# CONFIG_EMBEDDED is not set
+# CONFIG_EXPERT is not set
+CONFIG_EXT4_FS=y
+CONFIG_FARADAY_FTINTC010=y
+CONFIG_FB=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_CMDLINE=y
+CONFIG_FB_DEFERRED_IO=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+CONFIG_FHANDLE=y
+CONFIG_FIXED_PHY=y
+CONFIG_FIX_EARLYCON_MEM=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_SUPPORT=y
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FS_IOMAP=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FTTMR010_TIMER=y
+CONFIG_FTWDT010_WATCHDOG=y
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
+CONFIG_GEMINI_ETHERNET=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_ATOMIC64=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CPU_AUTOPROBE=y
+CONFIG_GENERIC_EARLY_IOREMAP=y
+CONFIG_GENERIC_IDLE_POLL_SETUP=y
+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_PINCONF=y
+CONFIG_GENERIC_SCHED_CLOCK=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GLOB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIOLIB_IRQCHIP=y
+CONFIG_GPIO_FTGPIO010=y
+CONFIG_GPIO_GENERIC=y
+CONFIG_HANDLE_DOMAIN_IRQ=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_HAS_DMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT_MAP=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_CLK_PREPARE=y
+CONFIG_HAVE_CONTEXT_TRACKING=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_HAVE_DEBUG_KMEMLEAK=y
+CONFIG_HAVE_DMA_CONTIGUOUS=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
+CONFIG_HAVE_EBPF_JIT=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
+CONFIG_HAVE_NET_DSA=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_OPTPROBES=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_HAVE_PERF_REGS=y
+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_HAVE_UID16=y
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
+CONFIG_HDMI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_HWMON=y
+CONFIG_HW_CONSOLE=y
+CONFIG_HZ_FIXED=0
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_IOMMU_DEBUGFS is not set
+# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
+# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
+CONFIG_IOMMU_SUPPORT=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_IPC_NS=y
+CONFIG_IRQCHIP=y
+CONFIG_IRQ_DOMAIN=y
+CONFIG_IRQ_FORCED_THREADING=y
+CONFIG_IRQ_WORK=y
+# CONFIG_ISDN is not set
+CONFIG_JBD2=y
+CONFIG_KALLSYMS=y
+CONFIG_KERNEL_LZMA=y
+# CONFIG_KERNEL_XZ is not set
+CONFIG_KEXEC=y
+CONFIG_KEXEC_CORE=y
+CONFIG_KEYBOARD_DLINK_DIR685=y
+# CONFIG_LDM_DEBUG is not set
+CONFIG_LDM_PARTITION=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LIBFDT=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_LINUX_MONO is not set
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LZ4_DECOMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_MANDATORY_FILE_LOCKING=y
+CONFIG_MARVELL_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_BUS=y
+CONFIG_MDIO_DEVICE=y
+CONFIG_MDIO_GPIO=y
+CONFIG_MEMFD_CREATE=y
+CONFIG_MEMORY_ISOLATION=y
+CONFIG_MFD_SYSCON=y
+CONFIG_MIGHT_HAVE_PCI=y
+CONFIG_MIGRATION=y
+CONFIG_MODULES_USE_ELF_REL=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MQ_IOSCHED_DEADLINE=y
+CONFIG_MQ_IOSCHED_KYBER=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_GEMINI=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_SPLIT_FIRMWARE=y
+CONFIG_MTD_SPLIT_WRGG_FW=y
+CONFIG_NAMESPACES=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_KUSER_HELPERS=y
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_REALTEK_SMI=y
+CONFIG_NET_DSA_VITESSE_VSC73XX=y
+CONFIG_NET_NS=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NLS=y
+CONFIG_NO_HZ_COMMON=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_NVMEM=y
+CONFIG_OABI_COMPAT=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_OF_RESERVED_MEM=y
+CONFIG_OLD_SIGACTION=y
+CONFIG_OLD_SIGSUSPEND3=y
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PATA_FTIDE010=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_DOMAINS_GENERIC=y
+CONFIG_PCI_FTPCI100=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PGTABLE_LEVELS=2
+CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
+CONFIG_PID_NS=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_GEMINI=y
+# CONFIG_PINCTRL_SINGLE is not set
+CONFIG_PM=y
+CONFIG_PM_CLK=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GEMINI_POWEROFF=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_COUNT=y
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_RATIONAL=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=21
+# CONFIG_RCU_EXPERT is not set
+CONFIG_RCU_NEED_SEGCBLIST=y
+CONFIG_RCU_STALL_COMMON=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_GZIP=y
+CONFIG_RD_LZ4=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_RD_XZ=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REFCOUNT_FULL=y
+CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
+CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_RELAY=y
+CONFIG_RESET_CONTROLLER=y
+CONFIG_RSEQ=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_FTRTC010=y
+CONFIG_RTC_I2C_AND_SPI=y
+CONFIG_RTC_NVMEM=y
+CONFIG_SATA_GEMINI=y
+CONFIG_SATA_PMP=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_SENSORS_DRIVETEMP=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
+CONFIG_SERIAL_8250_EXAR=y
+CONFIG_SERIAL_8250_FSL=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIO=y
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SG_POOL=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+CONFIG_SRCU=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_SWPHY=y
+CONFIG_SYNC_FILE=y
+CONFIG_SYSFS_SYSCALL=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_TASKS_RCU=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
+CONFIG_THERMAL_GOV_STEP_WISE=y
+CONFIG_THERMAL_HWMON=y
+CONFIG_THERMAL_OF=y
+CONFIG_TICK_CPU_ACCOUNTING=y
+CONFIG_TIMER_OF=y
+CONFIG_TIMER_PROBE=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TREE_SRCU=y
+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
+CONFIG_UNINLINE_SPIN_UNLOCK=y
+CONFIG_UNWINDER_ARM=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USERIO is not set
+CONFIG_USER_NS=y
+CONFIG_USE_OF=y
+CONFIG_UTS_NS=y
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
+CONFIG_VITESSE_PHY=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_WATCHDOG_CORE=y
+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_BCJ=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/gemini/image/ImageInfo-itian_sq201 b/target/linux/gemini/image/ImageInfo-itian_sq201
new file mode 100644
index 0000000..86040ab
--- /dev/null
+++ b/target/linux/gemini/image/ImageInfo-itian_sq201
@@ -0,0 +1,18 @@
+UpgradeImages="zImage rd.gz hddapp.tgz"
+Procduction="SL3516"
+BOOT_VER="1.0.5"
+FIRMWARE_VER="firmware-openwrt-DATESTR"
+INTERNAL_FIRMWARE_VER="firmware-openwrt-DATESTR"
+CONFIGURATION_VER="firmware-openwrt"
+DESCRIPTION="Square One Router/Nas"
+TSS="enabled"
+DIRECT_MODE="disabled"
+DEFAULT_LAN_IPADDR="192.168.1.1"
+DEFAULT_LAN_NETMASK="255.255.255.0"
+DEFAULT_LAN_BOOTPROTO="none"
+DEFAULT_WAN_BOOTPROTO="dhcp"
+DEFAULT_WAN_ENABLED="yes"
+DEFAULT_WLAN_DEVICENAME="eth0"
+VER_zImage="DATESTR"
+VER_Ramdisk="DATESTR"
+VER_hddapp="DATESTR"
diff --git a/target/linux/gemini/image/ImageInfo-raidsonic_ib-4220-b b/target/linux/gemini/image/ImageInfo-raidsonic_ib-4220-b
new file mode 100644
index 0000000..68fca5b
--- /dev/null
+++ b/target/linux/gemini/image/ImageInfo-raidsonic_ib-4220-b
@@ -0,0 +1,19 @@
+Distribution="OpenWrt"
+Layout="Compact"
+UpgradeImages="zImage rd.gz hddapp.tgz"
+productName="IB-NAS4220-B"
+hardwareName="MP-LNU23SL"
+productVendor="   "
+VendorID="macpower"
+ProductID="pddlan"
+UpgradeVersion="300"
+ExtraVersion=""
+manufacturerURL="   "
+Description="IB-NAS4220-B"
+hostname="IB-NAS4220-B"
+softwareVersion="3.0"
+TSS="enabled"
+DIRECT_MODE="disabled"
+Raid_Support="raid0_raid1_raid5_linear"
+RaidTestDiskSize="0"
+Raid_Show_Disk="2"
diff --git a/target/linux/gemini/image/ImageInfo-storlink_sl93512r b/target/linux/gemini/image/ImageInfo-storlink_sl93512r
new file mode 100644
index 0000000..722e9b4
--- /dev/null
+++ b/target/linux/gemini/image/ImageInfo-storlink_sl93512r
@@ -0,0 +1,18 @@
+UpgradeImages="zImage rd.gz hddapp.tgz"
+Procduction="SL3516"
+BOOT_VER="1.0.5"
+FIRMWARE_VER="firmware-openwrt-DATESTR"
+INTERNAL_FIRMWARE_VER="firmware-openwrt-DATESTR"
+CONFIGURATION_VER="firmware-openwrt"
+DESCRIPTION="Storlink SL93512r Reference Design"
+TSS="enabled"
+DIRECT_MODE="disabled"
+DEFAULT_LAN_IPADDR="192.168.1.1"
+DEFAULT_LAN_NETMASK="255.255.255.0"
+DEFAULT_LAN_BOOTPROTO="none"
+DEFAULT_WAN_BOOTPROTO="dhcp"
+DEFAULT_WAN_ENABLED="yes"
+DEFAULT_WLAN_DEVICENAME="eth0"
+VER_zImage="DATESTR"
+VER_Ramdisk="DATESTR"
+VER_hddapp="DATESTR"
diff --git a/target/linux/gemini/image/Makefile b/target/linux/gemini/image/Makefile
new file mode 100644
index 0000000..9906808
--- /dev/null
+++ b/target/linux/gemini/image/Makefile
@@ -0,0 +1,241 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2009-2018 OpenWrt.org
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+define Build/copy-kernel.bin
+	$(call locked,$(MAKE) -C copy-kernel CROSS_COMPILE=$(TARGET_CROSS) O=$(KDIR),gemini-copy-kernel.bin)
+endef
+
+# Cook a "WRGG" image, this board is apparently one in the D-Link
+# WRGG family and uses the exact same firmware format as other
+# D-Link devices.
+define Build/dir685-image
+	mkwrggimg -i $@ \
+	-o $@.new \
+	-d /dev/mtdblock/1 \
+	-s wrgns01_dlwbr_dir685RBWW \
+	-v 'N/A' \
+	-m dir685 \
+	-B 96bb
+
+	mv $@.new $@
+endef
+
+# Padding added after the rootfs to an even 128k boundary
+# as this is 128k eraseblocks flash.
+define Build/dir685-pad-rootfs
+	$(STAGING_DIR_HOST)/bin/padjffs2 $(IMAGE_ROOTFS) -c 128 >>$@
+endef
+
+# Build D-Link DNS-313 images using the special header tool.
+# rootfs.tgz and rd.tgz contains nothing, we only need them
+# to satisfy the boot loader on the device. The zImage is
+# the only real content.
+define Build/dns313-images
+	mkdir -p $@.tmp/.boot
+	chmod 755 $@.tmp/.boot
+
+	echo "dummy" > $@.tmp/dummyfile
+
+	dns313-header $@.tmp/dummyfile \
+		$@.tmp/.boot/rootfs.tgz
+	dns313-header $@.tmp/dummyfile \
+		$@.tmp/.boot/rd.gz
+	dns313-header $(IMAGE_KERNEL) \
+		$@.tmp/.boot/zImage
+
+	rm $@.tmp/dummyfile
+
+	genext2fs --block-size $(BLOCKSIZE:%k=%Ki) \
+		--size-in-blocks $$((1024 * $(CONFIG_TARGET_KERNEL_PARTSIZE))) \
+		--squash-uids \
+		--root $@.tmp $@.tmp-boot
+
+	# The device firmware needs revision 1 of EXT2
+	tune2fs -O filetype $@.tmp-boot
+	e2fsck -pDf $@.tmp-boot > /dev/null
+
+	./dns313_gen_hdd_img.sh $@ $@.tmp-boot $(IMAGE_ROOTFS) \
+		$(CONFIG_TARGET_KERNEL_PARTSIZE) \
+		$(CONFIG_TARGET_ROOTFS_PARTSIZE)
+
+	rm -rf $@.tmp
+endef
+
+define Build/wiligear-image
+	$(STAGING_DIR_HOST)/bin/mkfwimage2 \
+		-m GEOS -f 0x30000000 -z \
+		-v $(1).v5.00.SL3512.OpenWrt.00000.000000.000000 \
+		-p Kernel:0x020000:0x100000:0:0:$(IMAGE_KERNEL) \
+		-p Ramdisk:0x120000:0x500000:0:0:$@ \
+		-o $@.new
+
+	mv $@.new $@
+endef
+
+# Create the default image format used by the StorLink reference design
+# SL93512r, Raidsonic NAS4220B and Itian Square One SQ201
+# with the squashfs and overlay inside the "application" partition.
+#
+# These devices have a hard-coded partition table that the boot loader
+# constantly reflashes back, so we need to work around it like this:
+#
+# 0x000000120000-0x000000320000 : "Kern" - small copy routine and first
+#                                 part of the kernel goes here
+# 0x000000320000-0x000000920000 : "Ramdisk" - second part of the kernel and
+#                                 some padding goes here
+# 0x000000920000-0x000000f20000 : "Application" - rootfs goes here
+define Build/storlink-default-images
+	mkdir -p $@.tmp
+
+	# "App" partition is the rootfs
+	mv $@ $@.tmp/hddapp.tgz
+	# 256 bytes copy routine
+	dd if=$(KDIR)/copy-kernel.bin of=$@.tmp/zImage
+	$(call Image/pad-to,$@.tmp/zImage,512)
+	# Copy first part of the kernel into zImage
+	dd if=$(IMAGE_KERNEL) of=$@.tmp/zImage bs=1 seek=512 count=2096640
+	# Put the rest of the kernel into the "ramdisk"
+	dd if=$(IMAGE_KERNEL) of=$@.tmp/rd.gz bs=1 skip=2096640 count=6144k conv=sync
+	cp ./ImageInfo-$(1) $@.tmp/ImageInfo
+
+	sed -i -e "s/DATESTR/`date +%Y%m%d $(if $(SOURCE_DATE_EPOCH),--date "@$(SOURCE_DATE_EPOCH)")`/g" $@.tmp/ImageInfo
+
+	(cd $@.tmp; tar --sort=name --owner=0 --group=0 --numeric-owner -czf $@ * \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)"))
+
+	rm -rf $@.tmp
+endef
+
+# WBD-111 and WBD-222:
+# work around the bootloader's bug with extra nops
+# FIXME: is this really needed now that we no longer append the code
+# to change the machine ID number? Needs testing on Wiliboard.
+define Build/wbd-nops
+	mv $@ $@.tmp
+	echo -en "\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1\x00\x00\xa0\xe1" > $@
+	cat $@.tmp >> $@
+	rm -f $@.tmp
+endef
+
+# All DTB files are prefixed with "gemini-"
+define Device/Default
+	PROFILES := Default
+	KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
+	KERNEL_NAME := zImage
+	KERNEL := kernel-bin | append-dtb
+	BLOCKSIZE := 128k
+endef
+
+# A reasonable set of default packages handling the NAS type
+# of devices out of the box (former NAS42x0 IcyBox defaults)
+GEMINI_NAS_PACKAGES := $(DEFAULT_PACKAGES.nas) \
+		kmod-md-mod kmod-md-linear kmod-md-multipath \
+		kmod-md-raid0 kmod-md-raid1 kmod-md-raid10 kmod-md-raid456 \
+		kmod-fs-btrfs kmod-fs-cifs kmod-fs-nfs \
+		kmod-fs-nfsd kmod-fs-ntfs kmod-fs-reiserfs kmod-fs-vfat \
+		kmod-nls-utf8 kmod-usb-storage-extras kmod-hwmon-drivetemp \
+		cfdisk e2fsprogs badblocks \
+		partx-utils
+
+# The DIR-685 flash layout is kernel in WRGG format, padded and followed
+# by the appended rootfs followed by some reasonable JFFS padding, the
+# remainder will be used by JFFS2 through overlayfs.
+#
+# - For the factory image, the WRGG image includes the rootfs so that the
+#   default firmware will flash it properly as all it knows is WRGG format.
+# - For the sysupgrade, we do not include the rootfs in the kernel image
+#   so it is not needelessly tossed into the RAM by the boot loader.
+#   This will be flashed from OpenWrt userland anyways so we only need
+#   the minimum to make the boot loader happy.
+define Device/dlink_dir-685
+	DEVICE_VENDOR := D-Link
+	DEVICE_MODEL := DIR-685 Xtreme N Storage Router
+	DEVICE_DTS := gemini-dlink-dir-685
+	DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES) \
+			kmod-rt2800-pci
+	IMAGES := factory.bin sysupgrade.bin
+	# Pad to 128k erase blocks with 160 bytes WRGG header
+	IMAGE/factory.bin := append-kernel | pad-offset 128k 160 | append-rootfs | dir685-pad-rootfs | dir685-image
+	IMAGE/sysupgrade.bin := append-kernel | pad-offset 128k 160 | dir685-image | append-rootfs | dir685-pad-rootfs | append-metadata
+endef
+TARGET_DEVICES += dlink_dir-685
+
+define Device/dlink_dns-313
+	DEVICE_VENDOR := D-Link
+	DEVICE_MODEL := DNS-313 1-Bay Network Storage Enclosure
+	DEVICE_DTS := gemini-dlink-dns-313
+	DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES)
+	BLOCKSIZE := 1k
+	FILESYSTEMS := ext4
+	IMAGES := factory.bin.gz
+	IMAGE/factory.bin.gz := dns313-images | gzip
+endef
+TARGET_DEVICES += dlink_dns-313
+
+# Default images setup used by the StorLink reference designs
+define Device/storlink-reference
+	COMPILE := copy-kernel-$(1).bin
+	COMPILE/copy-kernel-$(1).bin := copy-kernel.bin
+	IMAGES := factory.bin
+	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 6144k | \
+		storlink-default-images $(1)
+	DEVICE_PACKAGES := $(GEMINI_NAS_PACKAGES)
+endef
+
+define Device/itian_sq201
+	$(Device/storlink-reference)
+	DEVICE_VENDOR := ITian
+	DEVICE_MODEL := Square One SQ201
+	DEVICE_DTS := gemini-sq201
+	DEVICE_PACKAGES += kmod-rt61-pci kmod-usb2-pci
+endef
+TARGET_DEVICES += itian_sq201
+
+define Device/raidsonic_ib-4220-b
+	$(Device/storlink-reference)
+	DEVICE_VENDOR := Raidsonic
+	DEVICE_MODEL := NAS IB-4220-B
+	DEVICE_DTS := gemini-nas4220b
+endef
+TARGET_DEVICES += raidsonic_ib-4220-b
+
+define Device/storlink_sl93512r
+	$(Device/storlink-reference)
+	DEVICE_VENDOR := StorLink
+	DEVICE_MODEL := SL93512r
+	DEVICE_DTS := gemini-sl93512r
+endef
+TARGET_DEVICES += storlink_sl93512r
+
+
+# The wiliboard images need some changes to be functional and buildable.
+#
+# The dts would need to use the ecoscentric,redboot-fis-partitions partition
+# parser to get the correct partition offsets and size.
+#
+# The mkfwimage2 call need to be adjusted to reflect the real size of kernel
+# and rootfs. It is expected that the OEM firmware adjusts the on flash
+# partition table with the values defined in the image header.
+define Device/wiliboard_wbd111
+	DEVICE_VENDOR := Wiliboard
+	DEVICE_MODEL := WBD-111
+	DEVICE_DTS := gemini-wbd111
+	KERNEL := kernel-bin | append-dtb | wbd-nops
+	IMAGES := factory.bin
+	IMAGE/factory.bin := append-rootfs | pad-rootfs | wiligear-image "WILI-S.WILIBOARD"
+endef
+
+define Device/wiliboard_wbd222
+	DEVICE_VENDOR := Wiliboard
+	DEVICE_MODEL := WBD-222
+	DEVICE_DTS := gemini-wbd222
+	KERNEL := kernel-bin | append-dtb | wbd-nops
+	IMAGES := factory.bin
+	IMAGE/factory.bin := append-rootfs | pad-rootfs | wiligear-image "WILI-S.WBD222"
+endef
+
+$(eval $(call BuildImage))
diff --git a/target/linux/gemini/image/copy-kernel/.gitignore b/target/linux/gemini/image/copy-kernel/.gitignore
new file mode 100644
index 0000000..e5939df
--- /dev/null
+++ b/target/linux/gemini/image/copy-kernel/.gitignore
@@ -0,0 +1 @@
+copy-kernel.bin
diff --git a/target/linux/gemini/image/copy-kernel/Makefile b/target/linux/gemini/image/copy-kernel/Makefile
new file mode 100644
index 0000000..9ba283b
--- /dev/null
+++ b/target/linux/gemini/image/copy-kernel/Makefile
@@ -0,0 +1,38 @@
+#
+# Makefile for Gemin kernel copy stub
+#
+# Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.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.
+#
+
+AS		:= $(CROSS_COMPILE)as
+OBJCOPY		:= $(CROSS_COMPILE)objcopy
+
+BIN_FLAGS	:= -O binary -S
+
+SRC_DIR		:= $(CURDIR)/
+OUT_DIR		:= $(if $(O),$(if $(patsubst %/,,$(O)),$(O)/,$(O)),$(SRC_DIR))
+
+all: $(OUT_DIR)copy-kernel.bin
+
+# Don't build dependencies, this may die if $(CC) isn't gcc
+dep:
+
+install:
+
+$(OUT_DIR):
+	mkdir -p $(OUT_DIR)
+
+$(OUT_DIR)%.o : $(SRC_DIR)%.S | $(OUT_DIR)
+	$(AS) $(ASFLAGS) -k -o $@ $<
+
+$(OUT_DIR)%.bin: $(OUT_DIR)%.o
+	$(OBJCOPY) $(BIN_FLAGS) $< $@
+
+mrproper: clean
+
+clean:
+	rm -f $(OUT_DIR)copy-kernel.bin $(OUT_DIR)copy-kernel.o
diff --git a/target/linux/gemini/image/copy-kernel/copy-kernel.S b/target/linux/gemini/image/copy-kernel/copy-kernel.S
new file mode 100644
index 0000000..a287e40
--- /dev/null
+++ b/target/linux/gemini/image/copy-kernel/copy-kernel.S
@@ -0,0 +1,45 @@
+	// Arm assembly to copy the Gemini kernel on Storlink reference
+	// designs and derived devices with the same flash layout and
+	// boot loader.
+	//
+	// This will execute at 0x01600000
+	//
+	// Copies the kernel from two fragments (originally zImage
+	// and initramdisk) to 0x00400000 making space for a kernel
+	// image of up to 8 MB except for these 512 bytes used for
+	// this bootstrap.
+	//
+	// 0x01600200 .. 0x017fffff -> 0x00400000 .. 0x005ffdff
+	// 0x00800000 .. 0x00dfffff -> 0x005ffe00 .. 0x00bffdff
+
+	// Memory used for this bootstrap
+	.equ BOOT_HEADROOM,	0x200
+
+	.global _start // Stand-alone assembly code
+_start:
+	mov r1, #0x01600000
+	mov r2, #0x00400000
+	mov r3, #0x00200000
+	add r1, r1, #BOOT_HEADROOM
+	sub r3, r3, #BOOT_HEADROOM
+copyloop1:
+	ldr r0, [r1]
+	str r0, [r2]
+	add r1, r1, #4
+	add r2, r2, #4
+	sub r3, r3, #4
+	cmp r3, #0
+	bne copyloop1
+	mov r1, #0x00800000
+	mov r3, #0x00600000
+copyloop2:
+	ldr r0, [r1]
+	str r0, [r2]
+	add r1, r1, #4
+	add r2, r2, #4
+	sub r3, r3, #4
+	cmp r3, #0
+	bne copyloop2
+	mov r0, #0x00400000
+	// Let's go
+	mov pc, r0
diff --git a/target/linux/gemini/image/dns313_gen_hdd_img.sh b/target/linux/gemini/image/dns313_gen_hdd_img.sh
new file mode 100755
index 0000000..d302ca6
--- /dev/null
+++ b/target/linux/gemini/image/dns313_gen_hdd_img.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+set -x
+[ $# -eq 5 ] || {
+	echo "SYNTAX: $0 <file> <bootfs image> <rootfs image> <bootfs size> <rootfs size>"
+	exit 1
+}
+
+OUTPUT="$1"
+BOOTFS="$2"
+ROOTFS="$3"
+BOOTFSSIZE="$4"
+ROOTFSSIZE="$5"
+
+head=4
+sect=63
+
+# Create one empty partitions followed by the swap partition, then the
+# boot partition with the ./boot/zImage and then the rootfs partition.
+# The swap partition with type 82 is 128 MB since the DNS-313 has 64 MB of
+# memory so we assign twice of that as swap.
+# The boot partition must always be the third partition.
+# The user should use the first (blank) partition for user data storage,
+# this will typically be named /dev/sda1
+set $(ptgen -o $OUTPUT -h $head -s $sect -n -t 83 -p 0 -t 82 -p 128M -t 83 -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M)
+
+# Swapoffset and swapsize will be $1 and $2
+BOOTOFFSET="$(($3 / 512))"
+BOOTSIZE="$(($4 / 512))"
+ROOTFSOFFSET="$(($5 / 512))"
+ROOTFSSIZE="$(($6 / 512))"
+
+dd bs=512 if="$BOOTFS" of="$OUTPUT" seek="$BOOTOFFSET" conv=notrunc
+dd bs=512 if="$ROOTFS" of="$OUTPUT" seek="$ROOTFSOFFSET" conv=notrunc
diff --git a/target/linux/gemini/patches-5.4/0001-usb-host-fotg2-add-Gemini-specific-handling.patch b/target/linux/gemini/patches-5.4/0001-usb-host-fotg2-add-Gemini-specific-handling.patch
new file mode 100644
index 0000000..df68adc
--- /dev/null
+++ b/target/linux/gemini/patches-5.4/0001-usb-host-fotg2-add-Gemini-specific-handling.patch
@@ -0,0 +1,131 @@
+From 3aaff88a0f5e154aa5a489d59fd4015a2a937c23 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Fri, 21 Apr 2017 22:19:00 +0200
+Subject: [PATCH 1/7] usb: host: fotg2: add Gemini-specific handling
+
+The Cortina Systems Gemini has bolted on a PHY inside the
+silicon that can be handled by six bits in a MISC register in
+the system controller.
+
+If we are running on Gemini, look up a syscon regmap through
+a phandle and enable VBUS and optionally the Mini-B connector.
+
+If the device is flagged as "wakeup-source" using the standard
+DT bindings, we also enable this in the global controller for
+respective port.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ drivers/usb/host/Kconfig       |  1 +
+ drivers/usb/host/fotg210-hcd.c | 76 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 77 insertions(+)
+
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -363,6 +363,7 @@ config USB_ISP1362_HCD
+ config USB_FOTG210_HCD
+ 	tristate "FOTG210 HCD support"
+ 	depends on USB && HAS_DMA && HAS_IOMEM
++	select MFD_SYSCON
+ 	---help---
+ 	  Faraday FOTG210 is an OTG controller which can be configured as
+ 	  an USB2.0 host. It is designed to meet USB2.0 EHCI specification
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -33,6 +33,10 @@
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/clk.h>
++#include <linux/bitops.h>
++/* For Cortina Gemini */
++#include <linux/mfd/syscon.h>
++#include <linux/regmap.h>
+ 
+ #include <asm/byteorder.h>
+ #include <asm/irq.h>
+@@ -5555,6 +5559,72 @@ static void fotg210_init(struct fotg210_
+ 	iowrite32(value, &fotg210->regs->otgcsr);
+ }
+ 
++/*
++ * Gemini-specific initialization function, only executed on the
++ * Gemini SoC using the global misc control register.
++ */
++#define GEMINI_GLOBAL_MISC_CTRL		0x30
++#define GEMINI_MISC_USB0_WAKEUP		BIT(14)
++#define GEMINI_MISC_USB1_WAKEUP		BIT(15)
++#define GEMINI_MISC_USB0_VBUS_ON	BIT(22)
++#define GEMINI_MISC_USB1_VBUS_ON	BIT(23)
++#define GEMINI_MISC_USB0_MINI_B		BIT(29)
++#define GEMINI_MISC_USB1_MINI_B		BIT(30)
++
++static int fotg210_gemini_init(struct device *dev, struct usb_hcd *hcd)
++{
++	struct device_node *np = dev->of_node;
++	struct regmap *map;
++	bool mini_b;
++	bool wakeup;
++	u32 mask, val;
++	int ret;
++
++	map = syscon_regmap_lookup_by_phandle(np, "syscon");
++	if (IS_ERR(map)) {
++		dev_err(dev, "no syscon\n");
++		return PTR_ERR(map);
++	}
++	mini_b = of_property_read_bool(np, "cortina,gemini-mini-b");
++	wakeup = of_property_read_bool(np, "wakeup-source");
++
++	/*
++	 * Figure out if this is USB0 or USB1 by simply checking the
++	 * physical base address.
++	 */
++	mask = 0;
++	if (hcd->rsrc_start == 0x69000000) {
++		val = GEMINI_MISC_USB1_VBUS_ON;
++		if (mini_b)
++			val |= GEMINI_MISC_USB1_MINI_B;
++		else
++			mask |= GEMINI_MISC_USB1_MINI_B;
++		if (wakeup)
++			val |= GEMINI_MISC_USB1_WAKEUP;
++		else
++			mask |= GEMINI_MISC_USB1_WAKEUP;
++	} else {
++		val = GEMINI_MISC_USB0_VBUS_ON;
++		if (mini_b)
++			val |= GEMINI_MISC_USB0_MINI_B;
++		else
++			mask |= GEMINI_MISC_USB0_MINI_B;
++		if (wakeup)
++			val |= GEMINI_MISC_USB0_WAKEUP;
++		else
++			mask |= GEMINI_MISC_USB0_WAKEUP;
++	}
++
++	ret = regmap_update_bits(map, GEMINI_GLOBAL_MISC_CTRL, mask, val);
++	if (ret) {
++		dev_err(dev, "failed to initialize Gemini PHY\n");
++		return ret;
++	}
++
++	dev_info(dev, "initialized Gemini PHY\n");
++	return 0;
++}
++
+ /**
+  * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
+  *
+@@ -5632,6 +5702,12 @@ static int fotg210_hcd_probe(struct plat
+ 
+ 	fotg210_init(fotg210);
+ 
++	if (of_device_is_compatible(dev->of_node, "cortina,gemini-usb")) {
++		retval = fotg210_gemini_init(dev, hcd);
++		if (retval)
++			goto failed_dis_clk;
++	}
++
+ 	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ 	if (retval) {
+ 		dev_err(dev, "failed to add hcd with err %d\n", retval);
diff --git a/target/linux/gemini/patches-5.4/0002-ARM-dts-Augment-DIR-685-partition-table-for-OpenWrt.patch b/target/linux/gemini/patches-5.4/0002-ARM-dts-Augment-DIR-685-partition-table-for-OpenWrt.patch
new file mode 100644
index 0000000..39dfd3d
--- /dev/null
+++ b/target/linux/gemini/patches-5.4/0002-ARM-dts-Augment-DIR-685-partition-table-for-OpenWrt.patch
@@ -0,0 +1,37 @@
+From a2de8560885469f3d76c80207a669029e4fc8a45 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Mon, 11 Mar 2019 15:44:29 +0100
+Subject: [PATCH 2/7] ARM: dts: Augment DIR-685 partition table for OpenWrt
+
+Rename the firmware partition so that the firmware MTD
+splitter will do its job, drop the rootfs arguments as
+the MTD splitter will set this up automatically.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/gemini-dlink-dir-685.dts | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
+@@ -20,7 +20,7 @@
+ 	};
+ 
+ 	chosen {
+-		bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300";
++		bootargs = "console=ttyS0,19200n8 consoleblank=300";
+ 		stdout-path = "uart0:19200n8";
+ 	};
+ 
+@@ -285,9 +285,9 @@
+ 				 * this is called "upgrade" on the vendor system.
+ 				 */
+ 				partition@40000 {
+-					label = "upgrade";
++					compatible = "wrg";
++					label = "firmware";
+ 					reg = <0x00040000 0x01f40000>;
+-					read-only;
+ 				};
+ 				/* RGDB, Residental Gateway Database? */
+ 				partition@1f80000 {
diff --git a/target/linux/gemini/patches-5.4/0003-ARM-dts-gemini-Rename-IDE-nodes.patch b/target/linux/gemini/patches-5.4/0003-ARM-dts-gemini-Rename-IDE-nodes.patch
new file mode 100644
index 0000000..cf4a74f
--- /dev/null
+++ b/target/linux/gemini/patches-5.4/0003-ARM-dts-gemini-Rename-IDE-nodes.patch
@@ -0,0 +1,117 @@
+From 9b95b301b219df19c20f4a563f1da6338b09b0d0 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Tue, 31 Dec 2019 18:14:28 +0100
+Subject: [PATCH 3/7] ARM: dts: gemini: Rename IDE nodes
+
+By renaming the ATA drive nodes to "ide@" we activate the
+semantic checks to the DT schema for the controller and use
+the correct notation for PATA drives.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/gemini-dlink-dir-685.dts | 2 +-
+ arch/arm/boot/dts/gemini-dlink-dns-313.dts | 2 +-
+ arch/arm/boot/dts/gemini-nas4220b.dts      | 4 ++--
+ arch/arm/boot/dts/gemini-sl93512r.dts      | 4 ++--
+ arch/arm/boot/dts/gemini-sq201.dts         | 2 +-
+ arch/arm/boot/dts/gemini.dtsi              | 8 ++++++--
+ 6 files changed, 13 insertions(+), 9 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
+@@ -443,7 +443,7 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			status = "okay";
+ 		};
+ 
+--- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts
++++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts
+@@ -297,7 +297,7 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			status = "okay";
+ 		};
+ 	};
+--- a/arch/arm/boot/dts/gemini-nas4220b.dts
++++ b/arch/arm/boot/dts/gemini-nas4220b.dts
+@@ -170,11 +170,11 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			status = "okay";
+ 		};
+ 
+-		ata@63400000 {
++		ide@63400000 {
+ 			status = "okay";
+ 		};
+ 
+--- a/arch/arm/boot/dts/gemini-sl93512r.dts
++++ b/arch/arm/boot/dts/gemini-sl93512r.dts
+@@ -293,11 +293,11 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			status = "okay";
+ 		};
+ 
+-		ata@63400000 {
++		ide@63400000 {
+ 			status = "okay";
+ 		};
+ 
+--- a/arch/arm/boot/dts/gemini-sq201.dts
++++ b/arch/arm/boot/dts/gemini-sq201.dts
+@@ -289,7 +289,7 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			status = "okay";
+ 		};
+ 
+--- a/arch/arm/boot/dts/gemini.dtsi
++++ b/arch/arm/boot/dts/gemini.dtsi
+@@ -357,7 +357,7 @@
+ 			};
+ 		};
+ 
+-		ata@63000000 {
++		ide@63000000 {
+ 			compatible = "cortina,gemini-pata", "faraday,ftide010";
+ 			reg = <0x63000000 0x1000>;
+ 			interrupts = <4 IRQ_TYPE_EDGE_RISING>;
+@@ -366,9 +366,11 @@
+ 			clock-names = "PCLK";
+ 			sata = <&sata>;
+ 			status = "disabled";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 		};
+ 
+-		ata@63400000 {
++		ide@63400000 {
+ 			compatible = "cortina,gemini-pata", "faraday,ftide010";
+ 			reg = <0x63400000 0x1000>;
+ 			interrupts = <5 IRQ_TYPE_EDGE_RISING>;
+@@ -377,6 +379,8 @@
+ 			clock-names = "PCLK";
+ 			sata = <&sata>;
+ 			status = "disabled";
++			#address-cells = <1>;
++			#size-cells = <0>;
+ 		};
+ 
+ 		dma-controller@67000000 {
diff --git a/target/linux/gemini/patches-5.4/0004-ARM-dts-gemini-Add-thermal-zone-to-DIR-685.patch b/target/linux/gemini/patches-5.4/0004-ARM-dts-gemini-Add-thermal-zone-to-DIR-685.patch
new file mode 100644
index 0000000..5949b92
--- /dev/null
+++ b/target/linux/gemini/patches-5.4/0004-ARM-dts-gemini-Add-thermal-zone-to-DIR-685.patch
@@ -0,0 +1,101 @@
+From 2b2e9d0e1ee4765b21c648235489028c6dc7e336 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Tue, 31 Dec 2019 18:18:08 +0100
+Subject: [PATCH 4/7] ARM: dts: gemini: Add thermal zone to DIR-685
+
+The DIR-685 can now exploit the thermal zone added by the
+drive temperature sensor inside the hard drive. We have
+patched the libata subsystem to assign the device nodes
+properly to the SCSI devices and this is what the drivetemp
+driver will use to populate the sensor and the thermal
+zone, so pick that up into the thermal zone and let this
+control the fan.
+
+The hardware lacks an embedded temperature sensor so the
+D-Link vendor firmware uses this method to control the
+temperature of the NAS enclosure using the thermal sensor
+inside the hard drive.
+
+The drive temperature trigger points to be used comes from
+the vendor firmware.
+
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ arch/arm/boot/dts/gemini-dlink-dir-685.dts | 48 ++++++++++++++++++++--
+ 1 file changed, 45 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/boot/dts/gemini-dlink-dir-685.dts
++++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts
+@@ -119,13 +119,11 @@
+ 
+ 	/*
+ 	 * This is a Sunon Maglev GM0502PFV2-8 cooling fan @10000 RPM.
+-	 * Since the platform has no temperature sensor, this is controlled
+-	 * from userspace by using the hard disks S.M.A.R.T. temperature
+ 	 * sensor. It is turned on when the temperature exceeds 46 degrees
+ 	 * and turned off when the temperatures goes below 41 degrees
+ 	 * (celsius).
+ 	 */
+-	gpio-fan {
++	fan0: gpio-fan {
+ 		compatible = "gpio-fan";
+ 		/* Collides with IDE */
+ 		gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+@@ -133,6 +131,40 @@
+ 		#cooling-cells = <2>;
+ 	};
+ 
++	thermal-zones {
++		chassis-thermal {
++			/* Poll every 20 seconds */
++			polling-delay = <20000>;
++			/* Poll every 2nd second when cooling */
++			polling-delay-passive = <2000>;
++			/*  Use the thermal sensor in the hard drive */
++			thermal-sensors = <&drive0>;
++
++			/* Tripping points from the fan.script in the rootfs */
++			trips {
++				alert: chassis-alert {
++					/* At 43 degrees turn on the fan */
++					temperature = <43000>;
++					hysteresis = <3000>;
++					type = "active";
++				};
++				crit: chassis-crit {
++					/* Just shut down at 60 degrees */
++					temperature = <60000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
++
++			cooling-maps {
++				map0 {
++					trip = <&alert>;
++					cooling-device = <&fan0 1 1>;
++				};
++			};
++		};
++	};
++
+ 	/*
+ 	 * The touchpad input is connected to a GPIO bit-banged
+ 	 * I2C bus.
+@@ -445,6 +477,16 @@
+ 
+ 		ide@63000000 {
+ 			status = "okay";
++
++			/*
++			 * This drive may have a temperature sensor with a
++			 * thermal zone we can use for thermal control of the
++			 * chassis temperature using the fan.
++			 */
++			drive0: ide-port@0 {
++				reg = <0>;
++				#thermal-sensor-cells = <0>;
++			};
+ 		};
+ 
+ 		display-controller@6a000000 {