diff mbox series

[OpenWrt-Devel,v3] mvebu: add support for Buffalo LinkStation LS421DE

Message ID 3972728.e9J7NaK4W3@tool
State Superseded, archived
Headers show
Series [OpenWrt-Devel,v3] mvebu: add support for Buffalo LinkStation LS421DE | expand

Commit Message

Daniel González Cabanelas April 5, 2020, 11:06 p.m. UTC
Buffalo LinkStation LS421DE is a dual bay NAS, based on Marvell Armada 370

Hardware:
   SoC:         Marvell Armada 88F6707-A1
   CPU:         Cortex-A9 1200 MHz, 1 core
   Flash:       SPI-NOR 1 MiB, NAND 512 MiB
   RAM:         DDR3 512 MiB
   Ethernet:    1x 10/100/1000 Mbps
   USB:         1x 2.0, 1x 3.0
   SATA:        2x 3.0 Gbps
   LEDs/Input : 5x / 2x (1x button, 1x slide-switch)
   RTC:         Ricoh RS5C372A, I2C, no battery

Flash instruction (UART+TFTP):
  1. Downgrade the OEM firmware to 1.34 version (BUFFALO_BOOTVER=0.13)
  2. Remove any hard drive from inside the bays.
  3. Boot the Openwrt initramfs image using the U-Boot serial console:
         tftpboot 0x1200000 buffalo_ls421de-initramfs-kernel.bin
         bootm 0x1200000
  4. Flash the sysupgrade image using the Openwrt console:
         sysupgrade -n buffalo_ls421de-squashfs-sysupgrade.bin
  5. Wait until it finish, the device will reboot with Openwrt installed
     on the NAND flash.

Note:
  - Device shuting down doesn't work, even if the power slide switch is
    used. We must first, via MDIO, set the unused LED2 at the ethernet
    phy0 to off state. Reboot works ok.

Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
---
Changes in v2:
 - dts file tuned
 - Adjusted the i2c bus speed to the max supported by the RTC
 - Deleted unneded kernel patch
 - Image creation: only included neccesary packages, delete the ubinize
   parameter

Changes in v3:
 - dts file tuned
 - Adjusted the i2c bus speed to the max supported by the SoC
 - Added vdd cpu power down pinmux
 - Image creation: adjusted the packages required by this device. 
   Deleted redundant parameters.
 - Fixed installation instructions

 .../base-files/lib/preinit/06_set_iface_mac   |   4 +
 .../base-files/lib/upgrade/platform.sh        |   3 +
 .../boot/dts/armada-370-buffalo-ls421de.dts   | 360 ++++++++++++++++++
 target/linux/mvebu/image/Makefile             |  14 +
 target/linux/mvebu/image/cortexa9.mk          |  16 +
 5 files changed, 397 insertions(+)
 create mode 100644 target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts

Comments

Tomasz Maciej Nowak April 6, 2020, 5:25 p.m. UTC | #1
W dniu 06.04.2020 o 01:06, Daniel Gonzalez Cabanelas pisze:
> Buffalo LinkStation LS421DE is a dual bay NAS, based on Marvell Armada 370
> 
> Hardware:
>    SoC:         Marvell Armada 88F6707-A1
>    CPU:         Cortex-A9 1200 MHz, 1 core
>    Flash:       SPI-NOR 1 MiB, NAND 512 MiB
>    RAM:         DDR3 512 MiB
>    Ethernet:    1x 10/100/1000 Mbps
>    USB:         1x 2.0, 1x 3.0
>    SATA:        2x 3.0 Gbps
>    LEDs/Input : 5x / 2x (1x button, 1x slide-switch)
>    RTC:         Ricoh RS5C372A, I2C, no battery
> 
> Flash instruction (UART+TFTP):
>   1. Downgrade the OEM firmware to 1.34 version (BUFFALO_BOOTVER=0.13)
>   2. Remove any hard drive from inside the bays.
>   3. Boot the Openwrt initramfs image using the U-Boot serial console:
>          tftpboot 0x1200000 buffalo_ls421de-initramfs-kernel.bin
>          bootm 0x1200000
>   4. Flash the sysupgrade image using the Openwrt console:
>          sysupgrade -n buffalo_ls421de-squashfs-sysupgrade.bin
>   5. Wait until it finish, the device will reboot with Openwrt installed
>      on the NAND flash.
> 
> Note:
>   - Device shuting down doesn't work, even if the power slide switch is
>     used. We must first, via MDIO, set the unused LED2 at the ethernet
>     phy0 to off state. Reboot works ok.
> 
> Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>

Reviewed-by: Tomasz Maciej Nowak <tomek_n@o2.pl>

> ---
> Changes in v2:
>  - dts file tuned
>  - Adjusted the i2c bus speed to the max supported by the RTC
>  - Deleted unneded kernel patch
>  - Image creation: only included neccesary packages, delete the ubinize
>    parameter
> 
> Changes in v3:
>  - dts file tuned
>  - Adjusted the i2c bus speed to the max supported by the SoC
>  - Added vdd cpu power down pinmux
>  - Image creation: adjusted the packages required by this device. 
>    Deleted redundant parameters.
>  - Fixed installation instructions
> 
>  .../base-files/lib/preinit/06_set_iface_mac   |   4 +
>  .../base-files/lib/upgrade/platform.sh        |   3 +
>  .../boot/dts/armada-370-buffalo-ls421de.dts   | 360 ++++++++++++++++++
>  target/linux/mvebu/image/Makefile             |  14 +
>  target/linux/mvebu/image/cortexa9.mk          |  16 +
>  5 files changed, 397 insertions(+)
>  create mode 100644 target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts
> 
> diff --git a/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac b/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
> index fd41836c8d..62ce2653a0 100644
> --- a/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
> +++ b/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
> @@ -9,6 +9,10 @@ preinit_set_mac_address() {
>  	. /lib/functions.sh
>  
>  	case $(board_name) in
> +	buffalo,ls421de)
> +		mac=$(mtd_get_mac_ascii u-boot-env eth1addr)
> +		ip link set dev eth0 address $mac 2>/dev/null
> +		;;
>  	linksys,caiman|linksys,cobra|linksys,rango|linksys,shelby|linksys,venom)
>  		# rename interfaces back to the way they were with 4.4
>  		case "$(readlink /sys/class/net/eth0)" in
> diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
> index 8baed969a3..63042b1535 100755
> --- a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
> +++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
> @@ -22,6 +22,9 @@ platform_check_image() {
>  
>  platform_do_upgrade() {
>  	case "$(board_name)" in
> +	buffalo,ls421de)
> +		nand_do_upgrade "$1"
> +		;;
>  	cznic,turris-omnia|\
>  	solidrun,clearfog-base-a1|\
>  	solidrun,clearfog-pro-a1)
> diff --git a/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts b/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts
> new file mode 100644
> index 0000000000..6b8a964ab3
> --- /dev/null
> +++ b/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts
> @@ -0,0 +1,360 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree file for Buffalo LinkStation LS421DE
> + *
> + * Copyright (C) 2020 Daniel González Cabanelas <dgcbueu@gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "armada-370.dtsi"
> +#include "mvebu-linkstation-fan.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +
> +/ {
> +	model = "Buffalo LinkStation LS421DE";
> +	compatible = "buffalo,ls421de", "marvell,armada370", "marvell,armada-370-xp";
> +
> +	aliases {
> +		led-boot = &led_boot;
> +		led-failsafe = &led_failsafe;
> +		led-running = &led_power;
> +		led-upgrade = &led_upgrade;
> +	};
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200 earlyprintk noinitrd rootfstype=squashfs";
> +		stdout-path = "serial0:115200n8";
> +		append-rootblock = "nullparameter="; /* override the bootloader args */
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x00000000 0x20000000>; /* 512 MB */
> +	};
> +
> +	soc {
> +		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
> +			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
> +			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
> +	};
> +
> +	gpio_fan {
> +		gpios = <&gpio0 13 GPIO_ACTIVE_HIGH
> +			&gpio0 14 GPIO_ACTIVE_HIGH>;
> +		alarm-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	gpio_keys {
> +		compatible = "gpio-keys";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_hdd_present &pmx_buttons>;
> +		pinctrl-names = "default";
> +
> +		hdd1-present {
> +			label = "HDD1 Present";
> +			linux,code = <KEY_PROG1>;
> +			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		hdd2-present {
> +			label = "HDD2 Present";
> +			linux,code = <KEY_PROG2>;
> +			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> +
> +		};
> +
> +		power {
> +			label = "Power Switch";
> +			linux,code = <KEY_POWER>;
> +			linux,input-type = <EV_SW>;
> +			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
> +		};
> +
> +		function {
> +			label = "Function Button";
> +			linux,code = <KEY_OPTION>;
> +			gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
> +		};
> +	};
> +
> +	gpio_leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
> +
> +		system_red {
> +			label = "ls421de:red:system";
> +			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led_power: power_white {
> +			label = "ls421de:white:power";
> +			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
> +			default-state = "on";
> +		};
> +
> +		led_failsafe: power_red {
> +			label = "ls421de:red:power";
> +			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led_upgrade: power_orange {
> +			label = "ls421de:orange:power";
> +			gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		led_boot: system_white {
> +			label = "ls421de:white:system";
> +			gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		hdd1_red {
> +			label = "ls421de:red:hdd1";
> +			gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			linux,default-trigger = "disk-activity";
> +		};
> +
> +		hdd2_red {
> +			label = "ls421de:red:hdd2";
> +			gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
> +			default-state = "off";
> +			linux,default-trigger = "disk-activity";
> +		};
> +	};
> +
> +	regulators {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		pinctrl-0 = <&pmx_power_usb &pmx_power_hdd1 &pmx_power_hdd2>;
> +
> +		pinctrl-names = "default";
> +
> +		usb_v5_regulator: usb-v5-regulator {
> +			compatible = "regulator-fixed";
> +			regulator-name = "USB";
> +			regulator-min-microvolt = <5000000>;
> +			regulator-max-microvolt = <5000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		ata1_regulator: ata1-regulator {
> +			compatible = "regulator-fixed";
> +			reg = <1>;
> +			regulator-name = "HDD1";
> +			regulator-min-microvolt = <12000000>;
> +			regulator-max-microvolt = <12000000>;
> +			startup-delay-us = <2000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>;
> +		};
> +
> +		ata2_regulator: ata2-regulator {
> +			compatible = "regulator-fixed";
> +			reg = <2>;
> +			regulator-name = "HDD2";
> +			regulator-min-microvolt = <12000000>;
> +			regulator-max-microvolt = <12000000>;
> +			startup-delay-us = <4000000>;
> +			enable-active-high;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>;
> +		};
> +	};
> +
> +	/* FIXME: this driver needs to be aware of the LED2 eth phy use,
> +	   which must be set to off state before shutting down the machine */
> +	restart_poweroff {
> +		compatible = "restart-poweroff";
> +	};
> +};
> +
> +&eth1 {
> +	pinctrl-0 = <&ge1_rgmii_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	phy = <&phy0>;
> +	phy-mode = "rgmii-id";
> +};
> +
> +&i2c0 {
> +	clock-frequency = <100000>;
> +	status = "okay";
> +
> +	rs5c372a: rs5c372a@32 {
> +		compatible = "ricoh,rs5c372a";
> +		reg = <0x32>;
> +	};
> +};
> +
> +&mdio {
> +	pinctrl-0 = <&mdio_pins>;
> +	pinctrl-names = "default";
> +
> +	phy0: ethernet-phy@0 { /* Marvell 88E1518 */
> +		reg = <0>;
> +		/* LED2 is used to inform uBoot if the power-switch was slided
> +		   to the "off" position, and then power off the machine.
> +		   Page 0x3, Register 0x10, bit 8:
> +				0x800: LED2 off, power off the machine
> +				0x900: LED2 on, boot the machine */
> +		marvell,reg-init = <0x3 0x10 0x1 0x1991>, /* LED Function */
> +					<0x3 0x11 0x1 0x4401>, /* LED polarity */
> +					<0x3 0x12 0x1 0x4905>; /* LED Timer */
> +	};
> +};
> +
> +&pciec {
> +	status = "okay";
> +	/* Connected to uPD720202 USB 3.0 Host */
> +	pcie@1,0 {
> +		status = "okay";
> +	};
> +};
> +
> +&pmsu {
> +	pinctrl-0 = <&pmx_power_cpu>;
> +	pinctrl-names = "default";
> +};
> +
> +&rtc {
> +	status = "disabled";
> +};
> +
> +&sata {
> +	nr-ports = <2>;
> +	status = "okay";
> +};
> +
> +&sdio {
> +	pinctrl-0 = <&sdio_pins2>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	/* No CD or WP GPIOs */
> +	broken-cd;
> +};
> +
> +&uart0 {
> +	status = "okay";
> +};
> +
> +&usb0 {
> +	status = "okay";
> +};
> +
> +&nand_controller {
> +	status = "okay";
> +
> +	nand@0 {
> +		reg = <0>;
> +		label = "pxa3xx_nand-0";
> +		nand-rb = <0>;
> +		marvell,nand-keep-config;
> +		nand-on-flash-bbt;
> +		nand-ecc-strength = <4>;
> +		nand-ecc-step-size = <512>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition@0 {
> +				label = "kernel";
> +				reg = <0x00000000 0x02000000>;  /* 32 MiB */
> +			};
> +
> +			partition@2000000 {
> +				label = "ubi";
> +				reg = <0x02000000 0x1e000000>;  /* 480 MiB */
> +			};
> +		};
> +	};
> +};
> +
> +&spi0 {
> +	status = "okay";
> +	pinctrl-0 = <&spi0_pins2>;
> +	pinctrl-names = "default";
> +
> +	spi-flash@0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "mxicy,mx25l8005", "jedec,spi-nor";
> +		reg = <0>; /* Chip select 0 */
> +		spi-max-frequency = <50000000>;
> +
> +		partitions {
> +			compatible = "fixed-partitions";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			partition@0 {
> +				reg = <0x00000 0xf0000>; /* 960 KiB*/
> +				label = "u-boot";
> +				read-only;
> +			};
> +			partition@f0000 {
> +				reg = <0xf0000 0x10000>; /* 64 KiB */
> +				label = "u-boot-env";
> +			};
> +		};
> +	};
> +};
> +
> +&pinctrl {
> +	pmx_power_cpu: pmx-power-cpu {
> +		marvell,pins = "mpp4";
> +		marvell,function = "vdd";
> +	};
> +	pmx_power_usb: pmx-power-usb {
> +		marvell,pins = "mpp5";
> +		marvell,function = "gpo";
> +	};
> +	pmx_power_hdd1: pmx-power-hdd1 {
> +		marvell,pins = "mpp8";
> +		marvell,function = "gpio";
> +	};
> +	pmx_power_hdd2: pmx-power-hdd2 {
> +		marvell,pins = "mpp9";
> +		marvell,function = "gpo";
> +	};
> +	pmx_fan_lock: pmx-fan-lock {
> +		marvell,pins = "mpp10";
> +		marvell,function = "gpio";
> +	};
> +	pmx_hdd_present: pmx-hdd-present {
> +		marvell,pins = "mpp11", "mpp12";
> +		marvell,function = "gpio";
> +	};
> +	pmx_fan_high: pmx-fan-high {
> +		marvell,pins = "mpp13";
> +		marvell,function = "gpio";
> +	};
> +	pmx_fan_low: pmx-fan-low {
> +		marvell,pins = "mpp14";
> +		marvell,function = "gpio";
> +	};
> +	pmx_buttons: pmx-buttons {
> +		marvell,pins = "mpp15", "mpp16";
> +		marvell,function = "gpio";
> +	};
> +	pmx_leds1: pmx-leds {
> +		marvell,pins = "mpp7", "mpp54", "mpp59", "mpp61";
> +		marvell,function = "gpo";
> +	};
> +	pmx_leds2: pmx-leds {
> +		marvell,pins = "mpp55", "mpp57", "mpp62";
> +		marvell,function = "gpio";
> +	};
> +};
> diff --git a/target/linux/mvebu/image/Makefile b/target/linux/mvebu/image/Makefile
> index ef9274866d..3a47878069 100644
> --- a/target/linux/mvebu/image/Makefile
> +++ b/target/linux/mvebu/image/Makefile
> @@ -40,6 +40,20 @@ define Build/boot-img-ext4
>  	make_ext4fs -J -L kernel -l $(CONFIG_TARGET_KERNEL_PARTSIZE)M $@.bootimg $@.boot
>  endef
>  
> +define Build/buffalo-kernel-jffs2
> +	rm -rf $(KDIR)/kernel_jffs2 $@.fakerd
> +	mkdir -p $(KDIR)/kernel_jffs2
> +	dd if=/dev/zero of=$@.fakerd bs=131008 count=1 conv=sync
> +	$(STAGING_DIR_HOST)/bin/mkimage \
> +		-T ramdisk -A $(LINUX_KARCH) -O linux -C gzip -n 'fake initrd' \
> +		-d $@.fakerd $(KDIR)/kernel_jffs2/initrd.buffalo
> +	cp $@ $(KDIR)/kernel_jffs2/uImage.buffalo
> +	$(STAGING_DIR_HOST)/bin/mkfs.jffs2 \
> +		--little-endian -v --squash-uids -q -f -n -x lzma -x rtime -m none \
> +		--eraseblock=128KiB --pad=$(KERNEL_SIZE) -d $(KDIR)/kernel_jffs2 -o $@
> +	rm -rf $(KDIR)/kernel_jffs2 $@.fakerd
> +endef
> +
>  define Build/sdcard-img
>  	SIGNATURE="$(IMG_PART_SIGNATURE)" \
>  	./gen_mvebu_sdcard_img.sh $@ \
> diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk
> index 85bfa94dbd..4ab6f4a7e8 100644
> --- a/target/linux/mvebu/image/cortexa9.mk
> +++ b/target/linux/mvebu/image/cortexa9.mk
> @@ -6,6 +6,22 @@
>  # See /LICENSE for more information.
>  #
>  
> +define Device/buffalo_ls421de
> +  $(Device/NAND-128K)
> +  DEVICE_VENDOR := Buffalo
> +  DEVICE_MODEL := LinkStation LS421DE
> +  SUBPAGESIZE :=
> +  KERNEL_SIZE := 33554432
> +  FILESYSTEMS := squashfs ubifs
> +  KERNEL := kernel-bin | append-dtb | uImage none | buffalo-kernel-jffs2
> +  KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none
> +  DEVICE_DTS := armada-370-buffalo-ls421de
> +  DEVICE_PACKAGES :=  \
> +    kmod-rtc-rs5c372a kmod-hwmon-gpiofan kmod-usb3 kmod-md-raid0 \
> +    kmod-md-raid1 kmod-md-mod kmod-fs-xfs mkf2fs e2fsprogs partx-utils
> +endef
> +TARGET_DEVICES += buffalo_ls421de
> +
>  define Device/cznic_turris-omnia
>    DEVICE_VENDOR := CZ.NIC
>    DEVICE_MODEL := Turris Omnia
>
diff mbox series

Patch

diff --git a/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac b/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
index fd41836c8d..62ce2653a0 100644
--- a/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
+++ b/target/linux/mvebu/cortexa9/base-files/lib/preinit/06_set_iface_mac
@@ -9,6 +9,10 @@  preinit_set_mac_address() {
 	. /lib/functions.sh
 
 	case $(board_name) in
+	buffalo,ls421de)
+		mac=$(mtd_get_mac_ascii u-boot-env eth1addr)
+		ip link set dev eth0 address $mac 2>/dev/null
+		;;
 	linksys,caiman|linksys,cobra|linksys,rango|linksys,shelby|linksys,venom)
 		# rename interfaces back to the way they were with 4.4
 		case "$(readlink /sys/class/net/eth0)" in
diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
index 8baed969a3..63042b1535 100755
--- a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
@@ -22,6 +22,9 @@  platform_check_image() {
 
 platform_do_upgrade() {
 	case "$(board_name)" in
+	buffalo,ls421de)
+		nand_do_upgrade "$1"
+		;;
 	cznic,turris-omnia|\
 	solidrun,clearfog-base-a1|\
 	solidrun,clearfog-pro-a1)
diff --git a/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts b/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts
new file mode 100644
index 0000000000..6b8a964ab3
--- /dev/null
+++ b/target/linux/mvebu/files-4.19/arch/arm/boot/dts/armada-370-buffalo-ls421de.dts
@@ -0,0 +1,360 @@ 
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for Buffalo LinkStation LS421DE
+ *
+ * Copyright (C) 2020 Daniel González Cabanelas <dgcbueu@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "armada-370.dtsi"
+#include "mvebu-linkstation-fan.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Buffalo LinkStation LS421DE";
+	compatible = "buffalo,ls421de", "marvell,armada370", "marvell,armada-370-xp";
+
+	aliases {
+		led-boot = &led_boot;
+		led-failsafe = &led_failsafe;
+		led-running = &led_power;
+		led-upgrade = &led_upgrade;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk noinitrd rootfstype=squashfs";
+		stdout-path = "serial0:115200n8";
+		append-rootblock = "nullparameter="; /* override the bootloader args */
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* 512 MB */
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
+	};
+
+	gpio_fan {
+		gpios = <&gpio0 13 GPIO_ACTIVE_HIGH
+			&gpio0 14 GPIO_ACTIVE_HIGH>;
+		alarm-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_hdd_present &pmx_buttons>;
+		pinctrl-names = "default";
+
+		hdd1-present {
+			label = "HDD1 Present";
+			linux,code = <KEY_PROG1>;
+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+		};
+
+		hdd2-present {
+			label = "HDD2 Present";
+			linux,code = <KEY_PROG2>;
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+
+		};
+
+		power {
+			label = "Power Switch";
+			linux,code = <KEY_POWER>;
+			linux,input-type = <EV_SW>;
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		function {
+			label = "Function Button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio0 16 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmx_leds1 &pmx_leds2>;
+
+		system_red {
+			label = "ls421de:red:system";
+			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_power: power_white {
+			label = "ls421de:white:power";
+			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led_failsafe: power_red {
+			label = "ls421de:red:power";
+			gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_upgrade: power_orange {
+			label = "ls421de:orange:power";
+			gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+		};
+
+		led_boot: system_white {
+			label = "ls421de:white:system";
+			gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+		};
+
+		hdd1_red {
+			label = "ls421de:red:hdd1";
+			gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			linux,default-trigger = "disk-activity";
+		};
+
+		hdd2_red {
+			label = "ls421de:red:hdd2";
+			gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			linux,default-trigger = "disk-activity";
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_power_usb &pmx_power_hdd1 &pmx_power_hdd2>;
+
+		pinctrl-names = "default";
+
+		usb_v5_regulator: usb-v5-regulator {
+			compatible = "regulator-fixed";
+			regulator-name = "USB";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+		};
+
+		ata1_regulator: ata1-regulator {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "HDD1";
+			regulator-min-microvolt = <12000000>;
+			regulator-max-microvolt = <12000000>;
+			startup-delay-us = <2000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		};
+
+		ata2_regulator: ata2-regulator {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "HDD2";
+			regulator-min-microvolt = <12000000>;
+			regulator-max-microvolt = <12000000>;
+			startup-delay-us = <4000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	/* FIXME: this driver needs to be aware of the LED2 eth phy use,
+	   which must be set to off state before shutting down the machine */
+	restart_poweroff {
+		compatible = "restart-poweroff";
+	};
+};
+
+&eth1 {
+	pinctrl-0 = <&ge1_rgmii_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	phy = <&phy0>;
+	phy-mode = "rgmii-id";
+};
+
+&i2c0 {
+	clock-frequency = <100000>;
+	status = "okay";
+
+	rs5c372a: rs5c372a@32 {
+		compatible = "ricoh,rs5c372a";
+		reg = <0x32>;
+	};
+};
+
+&mdio {
+	pinctrl-0 = <&mdio_pins>;
+	pinctrl-names = "default";
+
+	phy0: ethernet-phy@0 { /* Marvell 88E1518 */
+		reg = <0>;
+		/* LED2 is used to inform uBoot if the power-switch was slided
+		   to the "off" position, and then power off the machine.
+		   Page 0x3, Register 0x10, bit 8:
+				0x800: LED2 off, power off the machine
+				0x900: LED2 on, boot the machine */
+		marvell,reg-init = <0x3 0x10 0x1 0x1991>, /* LED Function */
+					<0x3 0x11 0x1 0x4401>, /* LED polarity */
+					<0x3 0x12 0x1 0x4905>; /* LED Timer */
+	};
+};
+
+&pciec {
+	status = "okay";
+	/* Connected to uPD720202 USB 3.0 Host */
+	pcie@1,0 {
+		status = "okay";
+	};
+};
+
+&pmsu {
+	pinctrl-0 = <&pmx_power_cpu>;
+	pinctrl-names = "default";
+};
+
+&rtc {
+	status = "disabled";
+};
+
+&sata {
+	nr-ports = <2>;
+	status = "okay";
+};
+
+&sdio {
+	pinctrl-0 = <&sdio_pins2>;
+	pinctrl-names = "default";
+	status = "okay";
+	/* No CD or WP GPIOs */
+	broken-cd;
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usb0 {
+	status = "okay";
+};
+
+&nand_controller {
+	status = "okay";
+
+	nand@0 {
+		reg = <0>;
+		label = "pxa3xx_nand-0";
+		nand-rb = <0>;
+		marvell,nand-keep-config;
+		nand-on-flash-bbt;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "kernel";
+				reg = <0x00000000 0x02000000>;  /* 32 MiB */
+			};
+
+			partition@2000000 {
+				label = "ubi";
+				reg = <0x02000000 0x1e000000>;  /* 480 MiB */
+			};
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-0 = <&spi0_pins2>;
+	pinctrl-names = "default";
+
+	spi-flash@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "mxicy,mx25l8005", "jedec,spi-nor";
+		reg = <0>; /* Chip select 0 */
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x00000 0xf0000>; /* 960 KiB*/
+				label = "u-boot";
+				read-only;
+			};
+			partition@f0000 {
+				reg = <0xf0000 0x10000>; /* 64 KiB */
+				label = "u-boot-env";
+			};
+		};
+	};
+};
+
+&pinctrl {
+	pmx_power_cpu: pmx-power-cpu {
+		marvell,pins = "mpp4";
+		marvell,function = "vdd";
+	};
+	pmx_power_usb: pmx-power-usb {
+		marvell,pins = "mpp5";
+		marvell,function = "gpo";
+	};
+	pmx_power_hdd1: pmx-power-hdd1 {
+		marvell,pins = "mpp8";
+		marvell,function = "gpio";
+	};
+	pmx_power_hdd2: pmx-power-hdd2 {
+		marvell,pins = "mpp9";
+		marvell,function = "gpo";
+	};
+	pmx_fan_lock: pmx-fan-lock {
+		marvell,pins = "mpp10";
+		marvell,function = "gpio";
+	};
+	pmx_hdd_present: pmx-hdd-present {
+		marvell,pins = "mpp11", "mpp12";
+		marvell,function = "gpio";
+	};
+	pmx_fan_high: pmx-fan-high {
+		marvell,pins = "mpp13";
+		marvell,function = "gpio";
+	};
+	pmx_fan_low: pmx-fan-low {
+		marvell,pins = "mpp14";
+		marvell,function = "gpio";
+	};
+	pmx_buttons: pmx-buttons {
+		marvell,pins = "mpp15", "mpp16";
+		marvell,function = "gpio";
+	};
+	pmx_leds1: pmx-leds {
+		marvell,pins = "mpp7", "mpp54", "mpp59", "mpp61";
+		marvell,function = "gpo";
+	};
+	pmx_leds2: pmx-leds {
+		marvell,pins = "mpp55", "mpp57", "mpp62";
+		marvell,function = "gpio";
+	};
+};
diff --git a/target/linux/mvebu/image/Makefile b/target/linux/mvebu/image/Makefile
index ef9274866d..3a47878069 100644
--- a/target/linux/mvebu/image/Makefile
+++ b/target/linux/mvebu/image/Makefile
@@ -40,6 +40,20 @@  define Build/boot-img-ext4
 	make_ext4fs -J -L kernel -l $(CONFIG_TARGET_KERNEL_PARTSIZE)M $@.bootimg $@.boot
 endef
 
+define Build/buffalo-kernel-jffs2
+	rm -rf $(KDIR)/kernel_jffs2 $@.fakerd
+	mkdir -p $(KDIR)/kernel_jffs2
+	dd if=/dev/zero of=$@.fakerd bs=131008 count=1 conv=sync
+	$(STAGING_DIR_HOST)/bin/mkimage \
+		-T ramdisk -A $(LINUX_KARCH) -O linux -C gzip -n 'fake initrd' \
+		-d $@.fakerd $(KDIR)/kernel_jffs2/initrd.buffalo
+	cp $@ $(KDIR)/kernel_jffs2/uImage.buffalo
+	$(STAGING_DIR_HOST)/bin/mkfs.jffs2 \
+		--little-endian -v --squash-uids -q -f -n -x lzma -x rtime -m none \
+		--eraseblock=128KiB --pad=$(KERNEL_SIZE) -d $(KDIR)/kernel_jffs2 -o $@
+	rm -rf $(KDIR)/kernel_jffs2 $@.fakerd
+endef
+
 define Build/sdcard-img
 	SIGNATURE="$(IMG_PART_SIGNATURE)" \
 	./gen_mvebu_sdcard_img.sh $@ \
diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk
index 85bfa94dbd..4ab6f4a7e8 100644
--- a/target/linux/mvebu/image/cortexa9.mk
+++ b/target/linux/mvebu/image/cortexa9.mk
@@ -6,6 +6,22 @@ 
 # See /LICENSE for more information.
 #
 
+define Device/buffalo_ls421de
+  $(Device/NAND-128K)
+  DEVICE_VENDOR := Buffalo
+  DEVICE_MODEL := LinkStation LS421DE
+  SUBPAGESIZE :=
+  KERNEL_SIZE := 33554432
+  FILESYSTEMS := squashfs ubifs
+  KERNEL := kernel-bin | append-dtb | uImage none | buffalo-kernel-jffs2
+  KERNEL_INITRAMFS := kernel-bin | append-dtb | uImage none
+  DEVICE_DTS := armada-370-buffalo-ls421de
+  DEVICE_PACKAGES :=  \
+    kmod-rtc-rs5c372a kmod-hwmon-gpiofan kmod-usb3 kmod-md-raid0 \
+    kmod-md-raid1 kmod-md-mod kmod-fs-xfs mkf2fs e2fsprogs partx-utils
+endef
+TARGET_DEVICES += buffalo_ls421de
+
 define Device/cznic_turris-omnia
   DEVICE_VENDOR := CZ.NIC
   DEVICE_MODEL := Turris Omnia