Files
wlan-ap/backports/0008-realtek-update-to-latest-owrt-HEAD.patch
John Crispin 668f79f021 ucentral: development update
* add dhcp snooping
* add wired 802.1x
* add firewall4
* add tplink low cost outdoor AP
* update ucentral-wifi
* fix wan bridge setup
* got to latest OpenWrt 21.02
* fix ratelimit on DFS interfaces

Signed-off-by: John Crispin <john@phrozen.org>
2021-04-13 12:45:19 +02:00

1507 lines
43 KiB
Diff

From 9f20103ebfb0b3a07b87157299353ff4984f94bc Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 16 Mar 2021 10:46:51 +0100
Subject: [PATCH 8/9] realtek: update to latest owrt HEAD
Signed-off-by: John Crispin <john@phrozen.org>
---
package/boot/uboot-envtools/files/realtek | 7 +
.../realtek/base-files/etc/board.d/01_leds | 1 -
.../realtek/base-files/etc/board.d/02_network | 3 +
target/linux/realtek/config-5.4 | 30 +-
.../realtek/dts/rtl8380_zyxel_gs1900-10hp.dts | 20 +-
.../dts/rtl8392_edgecore_ecs4100-12ph.dts | 297 ++++++++++++++++++
target/linux/realtek/dts/rtl839x.dtsi | 198 ++++++++++++
.../files-5.4/arch/mips/rtl838x/setup.c | 18 --
.../files-5.4/drivers/gpio/edgecore_reboot.c | 61 ++++
.../files-5.4/drivers/gpio/gpio-rtl838x.c | 3 +
.../drivers/net/dsa/rtl83xx/common.c | 22 +-
.../files-5.4/drivers/net/dsa/rtl83xx/dsa.c | 56 +++-
.../drivers/net/dsa/rtl83xx/rtl839x.c | 8 +-
.../drivers/net/ethernet/rtl838x_eth.c | 4 +-
.../files-5.4/drivers/net/phy/rtl83xx-phy.c | 9 +-
target/linux/realtek/image/Makefile | 9 +
.../realtek/patches-5.4/706-sysled.patch | 294 +++++++++++++++++
.../realtek/patches-5.4/707-reboot.patch | 9 +
.../realtek/patches-5.4/708-poor-stp.patch | 16 +
.../realtek/patches-5.4/710-adt7470.patch | 22 ++
20 files changed, 1024 insertions(+), 63 deletions(-)
create mode 100644 target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts
create mode 100644 target/linux/realtek/dts/rtl839x.dtsi
create mode 100644 target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c
create mode 100644 target/linux/realtek/patches-5.4/706-sysled.patch
create mode 100644 target/linux/realtek/patches-5.4/707-reboot.patch
create mode 100644 target/linux/realtek/patches-5.4/708-poor-stp.patch
create mode 100644 target/linux/realtek/patches-5.4/710-adt7470.patch
diff --git a/package/boot/uboot-envtools/files/realtek b/package/boot/uboot-envtools/files/realtek
index cce0628ffc..a4b7089d62 100644
--- a/package/boot/uboot-envtools/files/realtek
+++ b/package/boot/uboot-envtools/files/realtek
@@ -11,11 +11,18 @@ case "$board" in
d-link,dgs-1210-16|\
d-link,dgs-1210-28|\
d-link,dgs-1210-10p|\
+zyxel,gs1900-8hp-v1|\
+zyxel,gs1900-8hp-v2|\
zyxel,gs1900-10hp)
idx="$(find_mtd_index u-boot-env)"
[ -n "$idx" ] && \
ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x400" "0x10000"
;;
+edgecore,ecs4100-12ph)
+ idx="$(find_mtd_index u-boot-env)"
+ [ -n "$idx" ] && \
+ ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x20000" "0x10000"
+ ;;
*)
idx="$(find_mtd_index u-boot-env)"
[ -n "$idx" ] && \
diff --git a/target/linux/realtek/base-files/etc/board.d/01_leds b/target/linux/realtek/base-files/etc/board.d/01_leds
index 699ab817dd..36ca01a696 100755
--- a/target/linux/realtek/base-files/etc/board.d/01_leds
+++ b/target/linux/realtek/base-files/etc/board.d/01_leds
@@ -1,5 +1,4 @@
#!/bin/sh
-
. /lib/functions/uci-defaults.sh
board=$(board_name)
diff --git a/target/linux/realtek/base-files/etc/board.d/02_network b/target/linux/realtek/base-files/etc/board.d/02_network
index 2568fd2e0e..4d025b0975 100755
--- a/target/linux/realtek/base-files/etc/board.d/02_network
+++ b/target/linux/realtek/base-files/etc/board.d/02_network
@@ -49,6 +49,9 @@ done
[ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac
case $board in
+edgecore,ecs4100-12ph)
+ ucidef_set_poe 60 "$lan_list"
+ ;;
netgear,gs110tpp-v1)
ucidef_set_poe 130 "$lan_list"
;;
diff --git a/target/linux/realtek/config-5.4 b/target/linux/realtek/config-5.4
index 2fbd904376..3b455f17e9 100644
--- a/target/linux/realtek/config-5.4
+++ b/target/linux/realtek/config-5.4
@@ -2,17 +2,18 @@ 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_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_HAVE_CLK=y
CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_BOSTON=y
+CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
@@ -40,14 +41,10 @@ CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_8250=y
-CONFIG_EFI_EARLYCON=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_EXTRA_FIRMWARE="rtl838x_phy/rtl838x_8214fc.fw rtl838x_phy/rtl838x_8218b.fw rtl838x_phy/rtl838x_8380.fw"
CONFIG_EXTRA_FIRMWARE_DIR="firmware"
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
@@ -74,7 +71,8 @@ CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_RTL8231=y
CONFIG_GPIO_RTL838X=y
-CONFIG_REALTEK_SOC_PHY=y
+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
@@ -82,12 +80,14 @@ CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_HWMON=y
CONFIG_HZ=250
CONFIG_HZ_250=y
CONFIG_HZ_PERIODIC=y
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
CONFIG_I2C_GPIO=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQCHIP=y
@@ -101,10 +101,13 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_MARVELL_PHY=y
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_I2C=y
CONFIG_MEMFD_CREATE=y
+CONFIG_MFD_CORE=y
+CONFIG_MFD_REALTEK_EIO=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
@@ -159,11 +162,17 @@ CONFIG_PINCTRL=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_PSB6970_PHY=y
+CONFIG_RATIONAL=y
+CONFIG_REALTEK_PHY=y
+CONFIG_REALTEK_SOC_PHY=y
CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RTL838X=y
CONFIG_RTL9300_TIMER=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SFP=y
@@ -172,7 +181,7 @@ CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SPI_RTL838X=y
CONFIG_SRCU=y
-CONFIG_SWAP_IO_SPACE=y
+CONFIG_SWCONFIG=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
@@ -184,8 +193,11 @@ CONFIG_SYS_SUPPORTS_BIG_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_USE_GENERIC_EARLY_PRINTK_8250=y
CONFIG_USE_OF=y
+CONFIG_WATCHDOG_CORE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts
index 92d0e25fc4..a590450055 100644
--- a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts
+++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts
@@ -55,29 +55,17 @@
port@24 {
reg = <24>;
label = "lan9";
- phy-mode = "rgmii-id";
- phy-handle = <&phy24>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
sfp = <&sfp0>;
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- pause;
- };
};
port@26 {
reg = <26>;
label = "lan10";
- phy-mode = "rgmii-id";
- phy-handle = <&phy26>;
+ phy-mode = "1000base-x";
+ managed = "in-band-status";
sfp = <&sfp1>;
-
- fixed-link {
- speed = <1000>;
- full-duplex;
- pause;
- };
};
};
};
diff --git a/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts b/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts
new file mode 100644
index 0000000000..7a1bccfa00
--- /dev/null
+++ b/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts
@@ -0,0 +1,297 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rtl839x.dtsi"
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "edgecore,ecs4100-12ph", "realtek,rtl838x-soc";
+ model = "Edgecore ECS4100-12PH Switch";
+
+ aliases {
+ led-boot = &led_sys;
+ led-failsafe = &led_sys;
+ led-running = &led_sys;
+ led-upgrade = &led_sys;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x10000000>;
+ };
+
+ /* i2c of the left SFP cage: port 9 */
+ i2c0: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp0: sfp-p9 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c0>;
+ los-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>;
+ };
+
+ i2c1: i2c-gpio-1 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp1: sfp-p10 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c1>;
+ los-gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+ };
+
+ i2c2: i2c-gpio-2 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 22 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp2: sfp-p11 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c2>;
+ los-gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 24 GPIO_ACTIVE_LOW>;
+ };
+
+ i2c3: i2c-gpio-3 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ sfp3: sfp-p12 {
+ compatible = "sff,sfp";
+ i2c-bus = <&i2c3>;
+ los-gpio = <&gpio0 22 GPIO_ACTIVE_HIGH>;
+ mod-def0-gpio = <&gpio1 13 GPIO_ACTIVE_LOW>;
+ };
+
+ i2c4: i2c-gpio-4 {
+ compatible = "i2c-gpio";
+ sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ scl-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adt7470@2f {
+ compatible = "adi,adt7470";
+ reg = <0x2f>;
+ };
+
+ lm75b@48 {
+ compatible = "nxp,lm75a";
+ reg = <0x48>;
+ };
+
+ eeprom@506 {
+ compatible = "atmel,24c32";
+ reg = <0x56>;
+ };
+ };
+
+ watchdog {
+ compatible = "linux,wdt-gpio";
+ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+ hw_algo = "toggle";
+ hw_margin_ms = <1200>;
+ };
+
+ reboot@0 {
+ compatible = "edgecore,reboot";
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ };
+
+ fan0: gpio-fan {
+ #cooling-cells = <2>;
+ compatible = "gpio-fan";
+ gpio-fan,speed-map = <0 0 3000 1>;
+ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ status = "okay";
+ };
+};
+
+&gpio1 {
+ status = "okay";
+};
+
+&gpio0 {
+ poe_enable {
+ gpio-hog;
+ gpios = <16 GPIO_ACTIVE_HIGH>;
+ output-high;
+ };
+
+ poe_reset {
+ gpio-hog;
+ gpios = <18 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 0x40000>;
+ read-only;
+ };
+ partition@100000 {
+ label = "u-boot-env";
+ reg = <0x100000 0x120000>;
+ read-only;
+ };
+ partition@b260000 {
+ label = "firmware";
+ reg = <0x200000 0xe00000>;
+ compatible = "openwrt,uimage", "denx,uimage";
+ };
+ };
+ };
+};
+
+&ethernet0 {
+ mdio: mdio-bus {
+ compatible = "realtek,rtl838x-mdio";
+ regmap = <&ethernet0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ INTERNAL_PHY(0)
+ INTERNAL_PHY(1)
+ INTERNAL_PHY(2)
+ INTERNAL_PHY(3)
+ INTERNAL_PHY(4)
+ INTERNAL_PHY(5)
+ INTERNAL_PHY(6)
+ INTERNAL_PHY(7)
+
+ phy48: ethernet-phy@48 {
+ reg = <48>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ sfp = <&sfp0>;
+ };
+
+ phy49: ethernet-phy@49 {
+ reg = <49>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ sfp = <&sfp1>;
+ };
+
+ phy50: ethernet-phy@50 {
+ reg = <50>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ sfp = <&sfp2>;
+ };
+
+ phy51: ethernet-phy@51 {
+ reg = <51>;
+ compatible = "ethernet-phy-ieee802.3-c22";
+ sfp = <&sfp3>;
+ };
+ };
+};
+
+&switch0 {
+ ext_io: ext-io@e4 {
+ compatible = "realtek,rtl8390-eio", "syscon";
+ reg = <0xe4 0x17c>;
+
+ led_sys: sys-led {
+ active-low;
+ label = "green:status";
+ linux,default-trigger = "default-on";
+ };
+ };
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ SWITCH_PORT(0, 1, internal)
+ SWITCH_PORT(1, 2, internal)
+ SWITCH_PORT(2, 3, internal)
+ SWITCH_PORT(3, 4, internal)
+ SWITCH_PORT(4, 5, internal)
+ SWITCH_PORT(5, 6, internal)
+ SWITCH_PORT(6, 7, internal)
+ SWITCH_PORT(7, 8, internal)
+
+ port@48 {
+ reg = <48>;
+ label = "lan9";
+ phy-mode = "sgmii";
+ phy-handle = <&phy48>;
+ managed = "in-band-status";
+ };
+
+ port@49 {
+ reg = <49>;
+ label = "lan10";
+ phy-mode = "sgmii";
+ phy-handle = <&phy49>;
+ managed = "in-band-status";
+ };
+
+ port@50 {
+ reg = <50>;
+ label = "lan11";
+ phy-mode = "sgmii";
+ phy-handle = <&phy50>;
+ managed = "in-band-status";
+ };
+
+ port@51 {
+ reg = <51>;
+ label = "lan12";
+ phy-mode = "sgmii";
+ phy-handle = <&phy51>;
+ managed = "in-band-status";
+ };
+
+ port@28 {
+ ethernet = <&ethernet0>;
+ reg = <28>;
+ phy-mode = "internal";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+};
diff --git a/target/linux/realtek/dts/rtl839x.dtsi b/target/linux/realtek/dts/rtl839x.dtsi
new file mode 100644
index 0000000000..1eda5b77b4
--- /dev/null
+++ b/target/linux/realtek/dts/rtl839x.dtsi
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+
+#define STRINGIZE(s) #s
+#define LAN_LABEL(p, s) STRINGIZE(p ## s)
+#define SWITCH_PORT_LABEL(n) LAN_LABEL(lan, n)
+
+#define INTERNAL_PHY(n) \
+ phy##n: ethernet-phy@##n { \
+ reg = <##n>; \
+ compatible = "ethernet-phy-ieee802.3-c22"; \
+ phy-is-integrated; \
+ };
+
+#define EXTERNAL_PHY(n) \
+ phy##n: ethernet-phy@##n { \
+ reg = <##n>; \
+ compatible = "ethernet-phy-ieee802.3-c22"; \
+ };
+
+#define EXTERNAL_SFP_PHY(n) \
+ phy##n: ethernet-phy@##n { \
+ compatible = "ethernet-phy-ieee802.3-c22"; \
+ sfp; \
+ media = "fibre"; \
+ reg = <##n>; \
+ };
+
+#define SWITCH_PORT(n, s, m) \
+ port@##n { \
+ reg = <##n>; \
+ label = SWITCH_PORT_LABEL(s) ; \
+ phy-handle = <&phy##n>; \
+ phy-mode = #m ; \
+ };
+
+#define SWITCH_SFP_PORT(n, s, m) \
+ port@##n { \
+ reg = <##n>; \
+ label = SWITCH_PORT_LABEL(s) ; \
+ phy-handle = <&phy##n>; \
+ phy-mode = #m ; \
+ fixed-link { \
+ speed = <1000>; \
+ full-duplex; \
+ }; \
+ };
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "realtek,rtl838x-soc";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ frequency = <700000000>;
+
+ cpu@0 {
+ compatible = "mips,mips34Kc";
+ reg = <0>;
+ };
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x8000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,38400";
+ };
+
+
+ cpuintc: cpuintc {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ intc: rtlintc {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "realtek,rt8380-intc";
+ reg = <0xb8003000 0x20>;
+ };
+
+ spi0: spi@b8001200 {
+ status = "okay";
+
+ compatible = "realtek,rtl838x-nor";
+ reg = <0xb8001200 0x100>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ uart0: uart@b8002000 {
+ status = "okay";
+
+ compatible = "ns16550a";
+ reg = <0xb8002000 0x100>;
+
+ clock-frequency = <200000000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <31>;
+
+ reg-io-width = <1>;
+ reg-shift = <2>;
+ fifo-size = <1>;
+ no-loopback-test;
+ };
+
+ uart1: uart@b8002100 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&enable_uart1>;
+
+ status = "okay";
+
+ compatible = "ns16550a";
+ reg = <0xb8002100 0x100>;
+
+ clock-frequency = <200000000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <30>;
+
+ reg-io-width = <1>;
+ reg-shift = <2>;
+ fifo-size = <1>;
+ no-loopback-test;
+ };
+
+ gpio0: gpio-controller@b8003500 {
+ compatible = "realtek,rtl838x-gpio";
+ reg = <0xb8003500 0x20>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-parent = <&intc>;
+ interrupts = <23>;
+ };
+
+ gpio1: rtl8231-gpio {
+ status = "disabled";
+ compatible = "realtek,rtl8231-gpio";
+ #gpio-cells = <2>;
+ indirect-access-bus-id = <3>;
+ gpio-controller;
+ };
+
+ pinmux: pinmux@bb001000 {
+ compatible = "pinctrl-single";
+ reg = <0xbb000004 0x4>;
+
+ pinctrl-single,bit-per-mux;
+ pinctrl-single,register-width = <32>;
+ pinctrl-single,function-mask = <0x1>;
+ #pinctrl-cells = <2>;
+
+ enable_uart1: pinmux_enable_uart1 {
+ pinctrl-single,bits = <0x0 0x01 0x03>;
+ };
+ };
+
+ ethernet0: ethernet@bb00a300 {
+ status = "okay";
+
+ compatible = "realtek,rtl838x-eth";
+ reg = <0xbb00a300 0x100>;
+ interrupt-parent = <&intc>;
+ interrupts = <24>;
+ #interrupt-cells = <1>;
+ phy-mode = "internal";
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+
+ switch0: switch@bb000000 {
+ status = "okay";
+
+ interrupt-parent = <&intc>;
+ interrupts = <20>;
+
+ compatible = "realtek,rtl83xx-switch", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0xbb000000 0x10000>;
+
+ };
+};
diff --git a/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c b/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c
index ef97d485e1..ea2dd0c866 100644
--- a/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c
+++ b/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c
@@ -46,21 +46,6 @@ static void rtl838x_restart(char *command)
sw_w32(1, RTL838X_RST_GLB_CTRL_1);
}
-static void rtl839x_restart(char *command)
-{
- /* SoC reset vector (in flash memory): on RTL839x platform preferred way to reset */
- void (*f)(void) = (void *) 0xbfc00000;
-
- pr_info("System restart.\n");
- /* Reset SoC */
- sw_w32(0xFFFFFFFF, RTL839X_RST_GLB_CTRL);
- /* and call reset vector */
- f();
- /* If this fails, halt the CPU */
- while
- (1);
-}
-
static void rtl930x_restart(char *command)
{
pr_info("System restart.\n");
@@ -109,8 +94,6 @@ static void __init rtl838x_setup(void)
static void __init rtl839x_setup(void)
{
pr_info("Registering _machine_restart\n");
- _machine_restart = rtl839x_restart;
- _machine_halt = rtl838x_halt;
/* Setup System LED. Bit 14 of RTL839X_LED_GLB_CTRL then allows to toggle it */
sw_w32_mask(0, 3 << 15, RTL839X_LED_GLB_CTRL);
@@ -141,7 +124,6 @@ void __init plat_mem_setup(void)
void *dtb;
set_io_port_base(KSEG1);
- _machine_restart = rtl838x_restart;
if (fw_passed_dtb) /* UHI interface */
dtb = (void *)fw_passed_dtb;
diff --git a/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c b/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c
new file mode 100644
index 0000000000..2cafab4279
--- /dev/null
+++ b/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (C) 2021 John Crispin <john@phrozen.org> */
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/notifier.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+
+static struct notifier_block edgecore_reboot_handler;
+static struct gpio_desc *gpiod;
+static int edgecore_reboot_handle(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ gpiod_direction_output(gpiod, 0);
+ mdelay(1000);
+
+ pr_emerg("Unable to restart system\n");
+ return NOTIFY_DONE;
+}
+
+static int __init edgecore_reboot_probe(struct platform_device *pdev)
+{
+ int err;
+ unsigned long flags = GPIOF_IN;
+
+ gpiod = devm_gpiod_get_index(&pdev->dev, NULL, 0, flags);
+ if (!IS_ERR(gpiod))
+ gpiod_set_consumer_name(gpiod, "reboot");
+ else
+ return -EPROBE_DEFER;
+
+ edgecore_reboot_handler.notifier_call = edgecore_reboot_handle;
+ edgecore_reboot_handler.priority = 255;
+ err = register_restart_handler(&edgecore_reboot_handler);
+ if (err)
+ printk("can't register restart notifier (err=%d)\n", err);
+
+
+ return 0;
+}
+
+static const struct of_device_id edgecore_reboot_of_ids[] = {
+ { .compatible = "edgecore,reboot"},
+ { /* sentinel */ }
+};
+
+
+static struct platform_driver edgecore_reboot_driver = {
+ .probe = edgecore_reboot_probe,
+ .driver = {
+ .name = "edgecore_reboot",
+ .of_match_table = edgecore_reboot_of_ids,
+ },
+};
+
+module_platform_driver(edgecore_reboot_driver);
diff --git a/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c b/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c
index 8207e4bb73..60b6f08834 100644
--- a/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c
+++ b/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c
@@ -348,6 +348,9 @@ static int rtl838x_gpio_probe(struct platform_device *pdev)
case 0x8391:
pr_debug("Found RTL8391 GPIO\n");
break;
+ case 0x8392:
+ pr_debug("Found RTL8392 GPIO\n");
+ break;
case 0x8393:
pr_debug("Found RTL8393 GPIO\n");
break;
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
index 698f2892ea..2f0e568bc2 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c
@@ -368,8 +368,8 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
/* Enable PHY control via SoC */
if (priv->family_id == RTL8380_FAMILY_ID) {
- /* Enable PHY control via SoC */
- sw_w32_mask(0, BIT(15), RTL838X_SMI_GLB_CTRL);
+ /* Enable SerDes NWAY and PHY control via SoC */
+ sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL);
} else {
/* Disable PHY polling via SoC */
sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL);
@@ -555,7 +555,6 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
int err = 0, i;
struct rtl838x_switch_priv *priv;
struct device *dev = &pdev->dev;
- u64 irq_mask;
u64 bpdu_mask;
pr_debug("Probing RTL838X switch device\n");
@@ -650,9 +649,9 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
/* Enable link and media change interrupts. Are the SERDES masks needed? */
sw_w32_mask(0, 3, priv->r->isr_glb_src);
-
- priv->r->set_port_reg_le(irq_mask, priv->r->isr_port_link_sts_chg);
- priv->r->set_port_reg_le(irq_mask, priv->r->imr_port_link_sts_chg);
+
+ priv->r->set_port_reg_le(priv->irq_mask, priv->r->isr_port_link_sts_chg);
+ priv->r->set_port_reg_le(priv->irq_mask, priv->r->imr_port_link_sts_chg);
priv->link_state_irq = platform_get_irq(pdev, 0);
pr_info("LINK state irq: %d\n", priv->link_state_irq);
@@ -708,6 +707,17 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
rtl838x_dbgfs_init(priv);
}
+ if (of_machine_is_compatible("edgecore,ecs4100-12ph")) {
+ sw_w32(0x000000FF, 0x110);
+ sw_w32(0x00000000, 0x114);
+ sw_w32(0x00000000, 0x118);
+ sw_w32(0x000f0000, 0x11c);
+ sw_w32(0x00000000, 0x120);
+ sw_w32(0x000f0000, 0x124);
+ sw_w32(0x3DEA, 0xec);
+ sw_w32(0x707568, 0xe4);
+ }
+
return err;
}
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
index e0832c42b8..9c088ea8b1 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c
@@ -79,7 +79,7 @@ static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv)
/* Enable all ports with a PHY, including the SFP-ports */
for (i = 0; i < priv->cpu_port; i++) {
if (priv->ports[i].phy)
- v |= BIT(i);
+ v |= BIT_ULL(i);
}
pr_debug("%s: %16llx\n", __func__, v);
@@ -174,7 +174,7 @@ static int rtl83xx_setup(struct dsa_switch *ds)
*/
for (i = 0; i < priv->cpu_port; i++) {
if (priv->ports[i].phy) {
- priv->r->set_port_reg_be(BIT_ULL(priv->cpu_port) | BIT(i),
+ priv->r->set_port_reg_be(BIT_ULL(priv->cpu_port) | BIT_ULL(i),
priv->r->port_iso_ctrl(i));
port_bitmap |= BIT_ULL(i);
}
@@ -218,8 +218,8 @@ static int rtl930x_setup(struct dsa_switch *ds)
for (i = 0; i < priv->cpu_port; i++) {
if (priv->ports[i].phy) {
- priv->r->traffic_set(i, BIT(priv->cpu_port) | BIT(i));
- port_bitmap |= 1ULL << i;
+ priv->r->traffic_set(i, BIT_ULL(priv->cpu_port) | BIT_ULL(i));
+ port_bitmap |= BIT_ULL(i);
}
}
priv->r->traffic_set(priv->cpu_port, port_bitmap);
@@ -245,6 +245,7 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port,
pr_debug("In %s port %d", __func__, port);
if (!phy_interface_mode_is_rgmii(state->interface) &&
+ state->interface != PHY_INTERFACE_MODE_NA &&
state->interface != PHY_INTERFACE_MODE_1000BASEX &&
state->interface != PHY_INTERFACE_MODE_MII &&
state->interface != PHY_INTERFACE_MODE_REVMII &&
@@ -278,6 +279,10 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port,
if (port >= 24 && port <= 27 && priv->family_id == RTL8380_FAMILY_ID)
phylink_set(mask, 1000baseX_Full);
+ /* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */
+ if (port >=48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID)
+ phylink_set(mask, 1000baseX_Full);
+
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 10baseT_Full);
phylink_set(mask, 100baseT_Half);
@@ -310,7 +315,7 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
if (link & BIT_ULL(port))
state->link = 1;
- pr_info("%s: link state: %llx\n", __func__, link & BIT_ULL(port));
+ pr_info("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port));
state->duplex = 0;
if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
@@ -343,6 +348,44 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port,
return 1;
}
+
+static void rtl83xx_config_interface(int port, phy_interface_t interface)
+{
+ u32 old, int_shift, sds_shift;
+
+ switch (port) {
+ case 24:
+ int_shift = 0;
+ sds_shift = 5;
+ break;
+ case 26:
+ int_shift = 3;
+ sds_shift = 0;
+ break;
+ default:
+ return;
+ }
+
+ old = sw_r32(RTL838X_SDS_MODE_SEL);
+ switch (interface) {
+ case PHY_INTERFACE_MODE_1000BASEX:
+ if ((old >> sds_shift & 0x1f) == 4)
+ return;
+ sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL);
+ sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL);
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ if ((old >> sds_shift & 0x1f) == 2)
+ return;
+ sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL);
+ sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL);
+ break;
+ default:
+ return;
+ }
+ pr_debug("configured port %d for interface %s\n", port, phy_modes(interface));
+}
+
static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
unsigned int mode,
const struct phylink_link_state *state)
@@ -376,10 +419,11 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port,
reg = sw_r32(priv->r->mac_force_mode_ctrl(port));
/* Auto-Negotiation does not work for MAC in RTL8390 */
if (priv->family_id == RTL8380_FAMILY_ID) {
- if (mode == MLO_AN_PHY) {
+ if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) {
pr_debug("PHY autonegotiates\n");
reg |= BIT(2);
sw_w32(reg, priv->r->mac_force_mode_ctrl(port));
+ rtl83xx_config_interface(port, state->interface);
return;
}
}
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
index 5106bd2e9d..91947a20ed 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
@@ -275,7 +275,7 @@ void rtl839x_traffic_enable(int source, int dest)
void rtl839x_traffic_disable(int source, int dest)
{
- rtl839x_mask_port_reg_be(BIT(dest), 0, rtl839x_port_iso_ctrl(source));
+ rtl839x_mask_port_reg_be(BIT_ULL(dest), 0, rtl839x_port_iso_ctrl(source));
}
irqreturn_t rtl839x_switch_irq(int irq, void *dev_id)
@@ -290,10 +290,10 @@ irqreturn_t rtl839x_switch_irq(int irq, void *dev_id)
rtl839x_set_port_reg_le(ports, RTL839X_ISR_PORT_LINK_STS_CHG);
pr_debug("RTL8390 Link change: status: %x, ports %llx\n", status, ports);
- for (i = 0; i < 52; i++) {
- if (ports & (1ULL << i)) {
+ for (i = 0; i < RTL839X_CPU_PORT; i++) {
+ if (ports & BIT_ULL(i)) {
link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS);
- if (link & (1ULL << i))
+ if (link & BIT_ULL(i))
dsa_port_phylink_mac_change(ds, i, true);
else
dsa_port_phylink_mac_change(ds, i, false);
diff --git a/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c
index 7931daff07..7d0f692ee3 100644
--- a/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c
+++ b/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c
@@ -1580,7 +1580,7 @@ static int rtl839x_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
int err;
struct rtl838x_eth_priv *priv = bus->priv;
- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393)
+ if (mii_id >= 48 && mii_id <= 51 && priv->id == 0x8393)
return rtl839x_read_sds_phy(mii_id, regnum);
err = rtl839x_read_phy(mii_id, 0, regnum, &val);
@@ -1644,7 +1644,7 @@ static int rtl839x_mdio_write(struct mii_bus *bus, int mii_id,
{
struct rtl838x_eth_priv *priv = bus->priv;
- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393)
+ if (mii_id >= 48 && mii_id <= 51 && priv->id == 0x8393)
return rtl839x_write_sds_phy(mii_id, regnum, value);
return rtl839x_write_phy(mii_id, 0, regnum, value);
diff --git a/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c
index 78953c6d17..7a153ec7bd 100644
--- a/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c
@@ -1296,7 +1296,7 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
for (i = 0; i < 4; i++) {
for (l = 0; l < 100; l++) {
read_phy(mac + i, 0xb80, 0x10, &val);
- if (val & 0x40)
+ if (val & 0x80)
break;
}
if (l >= 100) {
@@ -1336,6 +1336,13 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
write_phy(mac + i, 0xfff, 0x1e, 0x0000);
}
+ if (of_machine_is_compatible("edgecore,ecs4100-12ph")) {
+ printk("setting edgecore specific SFP modes\n");
+ rtl8380_rtl8214fc_media_set(mac + 0, 0);
+ rtl8380_rtl8214fc_media_set(mac + 1, 0);
+ rtl8380_rtl8214fc_media_set(mac + 2, 1);
+ rtl8380_rtl8214fc_media_set(mac + 3, 1);
+ }
return 0;
}
diff --git a/target/linux/realtek/image/Makefile b/target/linux/realtek/image/Makefile
index 424726c8a9..760ebc6bc1 100644
--- a/target/linux/realtek/image/Makefile
+++ b/target/linux/realtek/image/Makefile
@@ -118,4 +118,13 @@ define Device/zyxel_gs1900-8hp-v2
endef
TARGET_DEVICES += zyxel_gs1900-8hp-v2
+define Device/edgecore_ecs4100-12ph
+ SOC := rtl8392
+ IMAGE_SIZE := 6976k
+ DEVICE_VENDOR := Edgecore
+ DEVICE_MODEL := ECS4100-12PH
+ DEVICE_PACKAGES += lua-rs232
+endef
+TARGET_DEVICES += edgecore_ecs4100-12ph
+
$(eval $(call BuildImage))
diff --git a/target/linux/realtek/patches-5.4/706-sysled.patch b/target/linux/realtek/patches-5.4/706-sysled.patch
new file mode 100644
index 0000000000..c13885d5ac
--- /dev/null
+++ b/target/linux/realtek/patches-5.4/706-sysled.patch
@@ -0,0 +1,294 @@
+From c1a89fdf22862379bb4150fc76504e2d3384cd67 Mon Sep 17 00:00:00 2001
+From: Bert Vermeulen <bert@biot.com>
+Date: Mon, 1 Mar 2021 12:41:35 +0100
+Subject: [PATCH] mfd: Add Realtek RTL838x/RTL839x sys-led driver
+
+---
+ drivers/mfd/Kconfig | 11 ++
+ drivers/mfd/Makefile | 1 +
+ drivers/mfd/realtek-eio.c | 243 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 255 insertions(+)
+ create mode 100644 drivers/mfd/realtek-eio.c
+
+Index: linux-5.4.92/drivers/mfd/Kconfig
+===================================================================
+--- linux-5.4.92.orig/drivers/mfd/Kconfig
++++ linux-5.4.92/drivers/mfd/Kconfig
+@@ -923,6 +923,16 @@ config MFD_RETU
+ Retu and Tahvo are a multi-function devices found on Nokia
+ Internet Tablets (770, N800 and N810).
+
++config MFD_REALTEK_EIO
++ tristate "Realtek external LED and GPIO driver"
++ select MFD_CORE
++ select MFD_SYSCON
++ select GENERIC_PINCONF
++ default y
++ help
++ Say yes here if you want external LED/GPIO support for Realtek
++ switch SoCs.
++
+ config MFD_PCF50633
+ tristate "NXP PCF50633"
+ depends on I2C
+Index: linux-5.4.92/drivers/mfd/realtek-eio.c
+===================================================================
+--- /dev/null
++++ linux-5.4.92/drivers/mfd/realtek-eio.c
+@@ -0,0 +1,246 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++
++#include <linux/leds.h>
++#include <linux/mfd/core.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/of_address.h>
++#include <linux/of_platform.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++
++#define REALTEK_EIO_GLOBAL_CTRL 0x0
++
++/*
++ * Management of external RTL8231 GPIO expanders.
++ * One RTL8231's GPIO registers can be shadowed to the internal GPIO_DIR
++ * and GPIO_DAT registers.
++ */
++#define RTL8380_EIO_GPIO_INDIRECT_ACCESS 0x9C
++#define RTL8380_EIO_GPIO_CTRL 0xE0
++#define RTL8380_EIO_GPIO_DIR(pin) (0xE4 + 4*((pin)/32))
++#define RTL8380_EIO_GPIO_DAT(pin) (0xEC + 4*((pin)/32))
++
++struct realtek_eio_ctrl;
++
++struct realtek_eio_data {
++ unsigned int sys_led_pos;
++ const struct mfd_cell *mfd_devices;
++ unsigned int mfd_device_count;
++};
++
++struct realtek_eio_ctrl {
++ struct device *dev;
++ struct regmap *map;
++ const struct realtek_eio_data *data;
++ struct led_classdev sys_led;
++ bool active_low;
++};
++
++
++#define OF_MFD_CELL(_name, _compat) \
++ { \
++ .name = (_name), \
++ .of_compatible = (_compat), \
++ }
++
++/*
++ * Realtek hardware system LED
++ *
++ * The switch SoC supports one hardware managed direct LED output
++ * to manage a system LED, with two supported blinking rates.
++ */
++enum {
++ REALTEK_SYS_LED_OFF = 0,
++ REALTEK_SYS_LED_BLINK_64MS,
++ REALTEK_SYS_LED_BLINK_1024MS,
++ REALTEK_SYS_LED_ON
++};
++
++static void realtek_sys_led_set(const struct realtek_eio_ctrl *ctrl,
++ unsigned int mode)
++{
++ regmap_update_bits(ctrl->map, REALTEK_EIO_GLOBAL_CTRL,
++ (0x3 << ctrl->data->sys_led_pos),
++ ((mode & 0x3) << ctrl->data->sys_led_pos));
++}
++
++static void realtek_sys_led_brightness_set(struct led_classdev *led_cdev,
++ enum led_brightness brightness)
++{
++ struct realtek_eio_ctrl *ctrl =
++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led);
++
++ if ((!ctrl->active_low && brightness == LED_OFF) ||
++ (ctrl->active_low && brightness != LED_OFF))
++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_OFF);
++ else
++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_ON);
++}
++
++static enum led_brightness realtek_sys_led_brightness_get(
++ struct led_classdev *led_cdev)
++{
++ struct realtek_eio_ctrl *ctrl =
++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led);
++ u32 val;
++
++ regmap_read(ctrl->map, REALTEK_EIO_GLOBAL_CTRL, &val);
++ val = (val >> ctrl->data->sys_led_pos) & 0x3;
++
++ if ((!ctrl->active_low && val == REALTEK_SYS_LED_OFF) ||
++ (ctrl->active_low && val == REALTEK_SYS_LED_ON))
++ return LED_OFF;
++ else
++ return LED_ON;
++}
++
++static int realtek_sys_led_blink_set(struct led_classdev *led_cdev,
++ unsigned long *delay_on, unsigned long *delay_off)
++{
++ struct realtek_eio_ctrl *ctrl =
++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led);
++ u32 blink_interval = *delay_on + *delay_off;
++
++ /* Split range at geometric mean of 64 and 1024 */
++ if (blink_interval == 0 || blink_interval > 2*256) {
++ *delay_on = 1024;
++ *delay_off = 1024;
++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_BLINK_1024MS);
++ }
++ else {
++ *delay_on = 64;
++ *delay_off = 64;
++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_BLINK_64MS);
++ }
++
++ return 0;
++}
++
++static int realtek_sys_led_probe(struct realtek_eio_ctrl *ctrl,
++ struct device *parent, struct device_node *np)
++{
++ struct led_classdev *sys_led = &ctrl->sys_led;
++ struct led_init_data init_data = {};
++
++ init_data.fwnode = of_fwnode_handle(np);
++
++ ctrl->active_low = of_property_read_bool(np, "active-low");
++
++ sys_led->max_brightness = 1;
++ sys_led->brightness_set = realtek_sys_led_brightness_set;
++ sys_led->brightness_get = realtek_sys_led_brightness_get;
++ sys_led->blink_set = realtek_sys_led_blink_set;
++
++ return devm_led_classdev_register_ext(parent, sys_led, &init_data);
++}
++
++static const struct mfd_cell rtl8380_mfd_devices[] = {
++ OF_MFD_CELL("realtek-eio-port-leds", "realtek,rtl8380-eio-port-led"),
++ OF_MFD_CELL("realtek-eio-mdio", "realtek,rtl8380-eio-mdio"),
++ OF_MFD_CELL("realtek-eio-pinctrl", "realtek,rtl8380-eio-pinctrl"),
++};
++
++static const struct realtek_eio_data rtl8380_eio_data = {
++ .sys_led_pos = 16,
++ .mfd_devices = rtl8380_mfd_devices,
++ .mfd_device_count = ARRAY_SIZE(rtl8380_mfd_devices)
++};
++
++static const struct mfd_cell rtl8390_mfd_devices[] = {
++ OF_MFD_CELL("realtek-eio-port-leds", "realtek,rtl8390-eio-port-led"),
++};
++
++static struct realtek_eio_data rtl8390_eio_data = {
++ .sys_led_pos = 15,
++ .mfd_devices = rtl8390_mfd_devices,
++ .mfd_device_count = ARRAY_SIZE(rtl8390_mfd_devices)
++};
++
++static const struct of_device_id of_realtek_eio_match[] = {
++ {
++ .compatible = "realtek,rtl8380-eio",
++ .data = &rtl8380_eio_data,
++ },
++ {
++ .compatible = "realtek,rtl8390-eio",
++ .data = &rtl8390_eio_data,
++ },
++};
++
++MODULE_DEVICE_TABLE(of, of_realtek_eio_match);
++
++static int realtek_eio_probe(struct platform_device *pdev)
++{
++ struct device *dev = &pdev->dev;
++ struct device_node *np = dev->of_node;
++ struct device_node *np_sys_led;
++ const struct of_device_id *match;
++ struct realtek_eio_ctrl *ctrl;
++ int err, val;
++ unsigned r;
++
++ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
++ if (!ctrl)
++ return -ENOMEM;
++
++ match = of_match_device(of_realtek_eio_match, dev);
++ if (match)
++ ctrl->data = (struct realtek_eio_data *) match->data;
++ else {
++ dev_err(dev, "no device match\n");
++ return -EINVAL;
++ }
++
++ ctrl->dev = dev;
++
++ if (!np) {
++ dev_err(dev, "no DT node found\n");
++ return -EINVAL;
++ }
++
++ ctrl->map = device_node_to_regmap(np);
++ if (!ctrl->map) {
++ dev_err(dev, "failed to get regmap\n");
++ return -EINVAL;
++ }
++
++ /* Parse optional sys-led child */
++ np_sys_led = of_get_child_by_name(np, "sys-led");
++ if (IS_ERR(np_sys_led))
++ return PTR_ERR(np_sys_led);
++
++ if (np_sys_led) {
++ err = realtek_sys_led_probe(ctrl, dev, np_sys_led);
++ if (err)
++ return err;
++ }
++
++ /* Find sub-devices */
++ if (ctrl->data->mfd_devices)
++ mfd_add_devices(dev, 0, ctrl->data->mfd_devices,
++ ctrl->data->mfd_device_count, NULL, 0, NULL);
++
++ /* Dump register values */
++ for (r = 0; r <= regmap_get_max_register(ctrl->map); r += 4) {
++ regmap_read(ctrl->map, r, &val);
++ dev_info(dev, "%02x %08x\n", r, val);
++ }
++
++ return 0;
++}
++
++static struct platform_driver realtek_eio_driver = {
++ .probe = realtek_eio_probe,
++ .driver = {
++ .name = "realtek-ext-io",
++ .of_match_table = of_realtek_eio_match
++ }
++};
++
++module_platform_driver(realtek_eio_driver);
++
++MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
++MODULE_DESCRIPTION("Realtek switch SoC external LED/GPIO driver");
++MODULE_LICENSE("GPL v2");
+Index: linux-5.4.92/drivers/mfd/Makefile
+===================================================================
+--- linux-5.4.92.orig/drivers/mfd/Makefile
++++ linux-5.4.92/drivers/mfd/Makefile
+@@ -255,4 +255,4 @@ obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
+ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o
+ obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
+ obj-$(CONFIG_MFD_STMFX) += stmfx.o
+-
++obj-$(CONFIG_MFD_REALTEK_EIO) += realtek-eio.o
diff --git a/target/linux/realtek/patches-5.4/707-reboot.patch b/target/linux/realtek/patches-5.4/707-reboot.patch
new file mode 100644
index 0000000000..420b91d809
--- /dev/null
+++ b/target/linux/realtek/patches-5.4/707-reboot.patch
@@ -0,0 +1,9 @@
+Index: linux-5.4.92/drivers/gpio/Makefile
+===================================================================
+--- linux-5.4.92.orig/drivers/gpio/Makefile
++++ linux-5.4.92/drivers/gpio/Makefile
+@@ -171,3 +171,4 @@ obj-$(CONFIG_GPIO_XTENSA) += gpio-xtens
+ obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
+ obj-$(CONFIG_GPIO_ZX) += gpio-zx.o
+ obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
++obj-y += edgecore_reboot.o
diff --git a/target/linux/realtek/patches-5.4/708-poor-stp.patch b/target/linux/realtek/patches-5.4/708-poor-stp.patch
new file mode 100644
index 0000000000..1980914961
--- /dev/null
+++ b/target/linux/realtek/patches-5.4/708-poor-stp.patch
@@ -0,0 +1,16 @@
+Index: linux-5.4.102/net/bridge/br_fdb.c
+===================================================================
+--- linux-5.4.102.orig/net/bridge/br_fdb.c
++++ linux-5.4.102/net/bridge/br_fdb.c
+@@ -573,9 +573,9 @@ void br_fdb_update(struct net_bridge *br
+ if (likely(fdb)) {
+ /* attempt to update an entry for a local interface */
+ if (unlikely(fdb->is_local)) {
+- if (net_ratelimit())
+- br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n",
++ br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u) shutting port down\n",
+ source->dev->name, addr, vid);
++ br_set_state(source, BR_STATE_BLOCKING);
+ } else {
+ unsigned long now = jiffies;
+
diff --git a/target/linux/realtek/patches-5.4/710-adt7470.patch b/target/linux/realtek/patches-5.4/710-adt7470.patch
new file mode 100644
index 0000000000..b76b0b33cf
--- /dev/null
+++ b/target/linux/realtek/patches-5.4/710-adt7470.patch
@@ -0,0 +1,22 @@
+Index: linux-5.4.92/drivers/hwmon/adt7470.c
+===================================================================
+--- linux-5.4.92.orig/drivers/hwmon/adt7470.c
++++ linux-5.4.92/drivers/hwmon/adt7470.c
+@@ -1271,10 +1271,17 @@ static const struct i2c_device_id adt747
+ };
+ MODULE_DEVICE_TABLE(i2c, adt7470_id);
+
++static const struct of_device_id __maybe_unused adt7470_of_match =
++{
++ .compatible = "adi,adt7470",
++};
++MODULE_DEVICE_TABLE(of, adt7470_of_match);
++
+ static struct i2c_driver adt7470_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "adt7470",
++ .of_match_table = of_match_ptr(&adt7470_of_match),
+ },
+ .probe = adt7470_probe,
+ .remove = adt7470_remove,
--
2.25.1