kirkwood: add support for NETGEAR ReadyNAS Duo v2
authorPawel Dembicki <paweldembicki@gmail.com>
Sun, 30 Aug 2020 20:26:14 +0000 (22:26 +0200)
committerChristian Lamparter <chunkeey@gmail.com>
Wed, 29 Dec 2021 19:35:57 +0000 (20:35 +0100)
NETGEAR ReadyNAS Duo v2 is a NAS based on Marvell kirkwood SoC.

Specification:
 - Processor Marvell 88F6282 (1.6 GHz)
 - 256MB RAM
 - 128MB NAND
 - 1x GBE LAN port (PHY: Marvell 88E1318)
 - 1x USB 2.0
 - 2x USB 3.0
 - 2x SATA
 - 3x button
 - 5x leds
 - serial on J5 connector accessible from rear panel
   (115200 8N1) (VCC,TX,RX,GND) (3V3 LOGIC!)

Installation by USB + serial:
  - Copy initramfs image to fat32 usb drive
  - Connect pendrive to USB 2.0 front socket
  - Connect serial console
  - Stop booting in u-boot
  - Do:
usb reset
        setenv bootargs 'console=ttyS0,115200n8 earlyprintk'
        setenv bootcmd 'nand read.e 0x1200000 0x200000 0x600000;bootm 0x1200000'
        saveenv
fatload usb 0:1 0x1200000 openwrt-kirkwood-netgear_readynas-duo-v2-initramfs-uImage
bootm 0x1200000
  - copy sysupgrade image via ssh.
  - run sysupgrade

Installation by TFTP + serial:
  - Setup TFTP server and copy initramfs image
  - Connect serial console
  - Stop booting in u-boot
  - Do:
setenv bootargs 'console=ttyS0,115200n8 earlyprintk'
setenv bootcmd 'nand read.e 0x1200000 0x200000 0x600000;bootm 0x1200000'
saveenv
setenv serverip 192.168.1.1
setenv ipaddr 192.168.1.2
tftpboot 0x1200000 openwrt-kirkwood-netgear_readynas-duo-v2-initramfs-uImage
bootm 0x1200000
  - copy sysupgrade image via ssh.
  - run sysupgrade

Known issues:
  - Power button and PHY INTn pin are connected to the same GPIO. It
    causes that every network restart button is pressed in system.
    As workaround, button is used as regular BTN_1.

For more info please look at file:
RND_5.3.13_WW.src/u-boot/board/mv_feroceon/mv_hal/usibootup/usibootup.c
from Netgear GPL sources.

Tested-by: Raylynn Knight <rayknight@me.com>
Tested-by: Lech Perczak <lech.perczak@gmail.com>
Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
13 files changed:
package/boot/uboot-envtools/files/kirkwood
target/linux/kirkwood/base-files/etc/board.d/02_network
target/linux/kirkwood/base-files/etc/init.d/hwmon_fancontrol
target/linux/kirkwood/base-files/lib/upgrade/platform.sh
target/linux/kirkwood/config-5.10
target/linux/kirkwood/config-5.4
target/linux/kirkwood/image/Makefile
target/linux/kirkwood/patches-5.10/113-readynas_duo_v2.patch [new file with mode: 0644]
target/linux/kirkwood/patches-5.10/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch [new file with mode: 0644]
target/linux/kirkwood/patches-5.10/801-power-reset-linkstation-poweroff-add-new-device.patch [new file with mode: 0644]
target/linux/kirkwood/patches-5.4/113-readynas_duo_v2.patch [new file with mode: 0644]
target/linux/kirkwood/patches-5.4/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch [new file with mode: 0644]
target/linux/kirkwood/patches-5.4/801-power-reset-linkstation-poweroff-add-new-device.patch [new file with mode: 0644]

index 6a3dfcaba81ba061021e0a8ccc1ce2a6b2ed3e39..240371f48d85ed8795de53cdb852aa7a60be9629 100644 (file)
@@ -19,6 +19,7 @@ globalscale,sheevaplug|\
 iom,ix2-200|\
 linksys,e4200-v2|\
 linksys,ea4500|\
+netgear,readynas-duo-v2|\
 raidsonic,ib-nas62x0|\
 seagate,dockstar|\
 zyxel,nsa310b|\
index c98e30adcbbb0f57cf62cdf32e5413c8c691afbd..972ee68fba0e289950cce9a2398f2b0c2f78a131 100644 (file)
@@ -22,6 +22,7 @@ ctera,c200-v1|\
 globalscale,sheevaplug|\
 iom,iconnect-1.1|\
 iom,ix2-200|\
+netgear,readynas-duo-v2|\
 raidsonic,ib-nas62x0|\
 seagate,blackarmor-nas220|\
 seagate,dockstar|\
index ec85b56ca16c7fd656ee14b4132d2d3d06ec43c1..1bd086a489f63c823cbf9bd3f286d293a311c533 100755 (executable)
@@ -3,7 +3,7 @@
 START=98
 
 boot() {
-       # configuring (lm85/lm63) onboard temp/fan controller to run the fan on its own
+       # configuring onboard temp/fan controller to run the fan on its own
        # for more information, please read https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
 
        case $(board_name) in
@@ -18,6 +18,10 @@ boot() {
                path_to_hwmon='/sys/class/hwmon/hwmon0'
                echo 2 > "$path_to_hwmon/pwm1_enable" # fan is on pwm1
                ;;
+       netgear,readynas-duo-v2)
+               path_to_hwmon='/sys/class/hwmon/hwmon0'
+               echo 1200 > "$path_to_hwmon/fan1_target" # set target rpm
+               ;;
        seagate,blackarmor-nas220)
                path_to_hwmon='/sys/devices/platform/ocp@f1000000/f1011000.i2c/i2c-0/0-002e/hwmon/hwmon0'
                # adt7476 fan control chip. 3 temp sensors. Set to 1/4 speed at 35C and max speed at 48C.
index 3f84df280860ac3494a424f45e1b15051a2774c1..e2f6dec44a2fcd14d5985fd86d6f0c3e1017d807 100644 (file)
@@ -4,7 +4,18 @@ RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
 REQUIRE_IMAGE_METADATA=1
 
 platform_check_image() {
-       return 0
+       local board="$(board_name)"
+
+       case "$board" in
+       netgear,readynas-duo-v2)
+               # let's store how rootfs is mounted
+               cp /proc/mounts /tmp/mounts
+               return 0
+               ;;
+       *)
+               return 0
+               ;;
+       esac
 }
 
 platform_do_upgrade() {
index fbb8916c152e243c890539ebae7ffae542a13623..f80a7d8f20829429fdf3df946dc186e066a64434 100644 (file)
@@ -221,6 +221,7 @@ CONFIG_PINCTRL_SX150X=y
 CONFIG_PLAT_ORION=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_LINKSTATION=y
 # CONFIG_POWER_RESET_QNAP is not set
 CONFIG_POWER_SUPPLY=y
 CONFIG_RATIONAL=y
index 7d7f70b43ec01a9b545fa3e216c8c850c4d404dd..258ddce5cf2fcd7ba344cbfb4affac5423646f6b 100644 (file)
@@ -219,6 +219,7 @@ CONFIG_PINCTRL_SX150X=y
 CONFIG_PLAT_ORION=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
+CONFIG_POWER_RESET_LINKSTATION=y
 # CONFIG_POWER_RESET_QNAP is not set
 CONFIG_POWER_SUPPLY=y
 CONFIG_RATIONAL=y
index 51772692cc75259d354a926e09b68f45160eac1d..eb3d684c8061ef0a464f4e9f3a1af07a2289cc0f 100644 (file)
@@ -212,6 +212,18 @@ define Device/linksys_ea4500
 endef
 TARGET_DEVICES += linksys_ea4500
 
+define Device/netgear_readynas-duo-v2
+  DEVICE_VENDOR := NETGEAR
+  DEVICE_MODEL := ReadyNAS Duo
+  DEVICE_VARIANT := v2
+  DEVICE_DTS := kirkwood-netgear_readynas_duo_v2
+  KERNEL_IN_UBI :=
+  IMAGES := sysupgrade.bin
+  DEVICE_PACKAGES := kmod-ata-marvell-sata kmod-fs-ext4 \
+       kmod-gpio-button-hotplug kmod-hwmon-g762 kmod-rtc-rs5c372a kmod-usb3
+endef
+TARGET_DEVICES += netgear_readynas-duo-v2
+
 define Device/raidsonic_ib-nas62x0
   DEVICE_VENDOR := RaidSonic
   DEVICE_MODEL := ICY BOX IB-NAS62x0
diff --git a/target/linux/kirkwood/patches-5.10/113-readynas_duo_v2.patch b/target/linux/kirkwood/patches-5.10/113-readynas_duo_v2.patch
new file mode 100644 (file)
index 0000000..c6452c5
--- /dev/null
@@ -0,0 +1,76 @@
+--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
++++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
+@@ -19,6 +19,13 @@
+               reg = <0x00000000 0x10000000>;
+       };
++      aliases {
++              led-boot = &led_power;
++              led-failsafe = &led_power;
++              led-running = &led_power;
++              led-upgrade = &led_power;
++      };
++
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+               stdout-path = &uart0;
+@@ -115,7 +122,7 @@
+                             &pmx_led_blue_backup >;
+               pinctrl-names = "default";
+-              power_led {
++              led_power: power_led {
+                       label = "status:blue:power_led";
+                       gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+                       default-state = "keep";
+@@ -129,11 +136,13 @@
+               disk1_led {
+                       label = "status:blue:disk1_led";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "ata1";
+               };
+               disk2_led {
+                       label = "status:blue:disk2_led";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "ata2";
+               };
+               backup_led {
+@@ -150,7 +159,13 @@
+               power-button {
+                       label = "Power Button";
+-                      linux,code = <KEY_POWER>;
++                      /* Power button and INT pin from PHY are both connected
++                       * to this GPIO. Every network restart causes PHY restart
++                       * and button is pressed. It's difficult to use it as
++                       * KEY_POWER without changes in kernel (or netifd) so
++                       * the button is configured as regular one.
++                       */
++                      linux,code = <BTN_1>;
+                       gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+               };
+@@ -208,18 +223,13 @@
+       };
+       partition@200000 {
+-              label = "uImage";
++              label = "kernel";
+               reg = <0x0200000 0x600000>;
+       };
+       partition@800000 {
+-              label = "minirootfs";
+-              reg = <0x0800000 0x1000000>;
+-      };
+-
+-      partition@1800000 {
+-              label = "jffs2";
+-              reg = <0x1800000 0x6800000>;
++              label = "ubi";
++              reg = <0x0800000 0x7800000>;
+       };
+ };
diff --git a/target/linux/kirkwood/patches-5.10/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch b/target/linux/kirkwood/patches-5.10/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch
new file mode 100644 (file)
index 0000000..03253cf
--- /dev/null
@@ -0,0 +1,106 @@
+From 11cab9f5cd9390cd83747e579957c8f5b807c09c Mon Sep 17 00:00:00 2001
+From: Pawel Dembicki <paweldembicki@gmail.com>
+Date: Fri, 18 Jun 2021 12:37:27 +0200
+Subject: [PATCH 1/2] power: reset: linkstation-poweroff: prepare for new
+ devices
+
+This commit prepare driver for another device support.
+
+New power_off_cfg structure describes two most important things: name of
+mdio bus and pointer to register setting function. It allow to add new
+device with different mdio bus node and other phy register config.
+
+Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
+---
+ drivers/power/reset/linkstation-poweroff.c | 35 ++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c
+index f1e843df0e16..8691cf98600d 100644
+--- a/drivers/power/reset/linkstation-poweroff.c
++++ b/drivers/power/reset/linkstation-poweroff.c
+@@ -29,11 +29,21 @@
+ #define LED2_FORCE_ON                                 (0x8 << 8)
+ #define LEDMASK                                               GENMASK(11,8)
++struct power_off_cfg {
++      char *mdio_node_name;
++      void (*phy_set_reg)(bool restart);
++};
++
+ static struct phy_device *phydev;
++static const struct power_off_cfg *cfg;
+-static void mvphy_reg_intn(u16 data)
++static void linkstation_mvphy_reg_intn(bool restart)
+ {
+       int rc = 0, saved_page;
++      u16 data = 0;
++
++      if(restart)
++              data = MII_88E1318S_PHY_LED_TCR_FORCE_INT;
+       saved_page = phy_select_page(phydev, MII_MARVELL_LED_PAGE);
+       if (saved_page < 0)
+@@ -66,11 +76,16 @@ static void mvphy_reg_intn(u16 data)
+               dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
+ }
++static const struct power_off_cfg linkstation_power_off_cfg = {
++      .mdio_node_name = "mdio",
++      .phy_set_reg = linkstation_mvphy_reg_intn,
++};
++
+ static int linkstation_reboot_notifier(struct notifier_block *nb,
+                                      unsigned long action, void *unused)
+ {
+       if (action == SYS_RESTART)
+-              mvphy_reg_intn(MII_88E1318S_PHY_LED_TCR_FORCE_INT);
++              cfg->phy_set_reg(true);
+       return NOTIFY_DONE;
+ }
+@@ -82,14 +97,18 @@ static struct notifier_block linkstation_reboot_nb = {
+ static void linkstation_poweroff(void)
+ {
+       unregister_reboot_notifier(&linkstation_reboot_nb);
+-      mvphy_reg_intn(0);
++      cfg->phy_set_reg(false);
+       kernel_restart("Power off");
+ }
+ static const struct of_device_id ls_poweroff_of_match[] = {
+-      { .compatible = "buffalo,ls421d" },
+-      { .compatible = "buffalo,ls421de" },
++      { .compatible = "buffalo,ls421d",
++        .data = &linkstation_power_off_cfg,
++      },
++      { .compatible = "buffalo,ls421de",
++        .data = &linkstation_power_off_cfg,
++      },
+       { },
+ };
+@@ -97,13 +116,17 @@ static int __init linkstation_poweroff_init(void)
+ {
+       struct mii_bus *bus;
+       struct device_node *dn;
++      const struct of_device_id *match;
+       dn = of_find_matching_node(NULL, ls_poweroff_of_match);
+       if (!dn)
+               return -ENODEV;
+       of_node_put(dn);
+-      dn = of_find_node_by_name(NULL, "mdio");
++      match = of_match_node(ls_poweroff_of_match, dn);
++      cfg = match->data;
++
++      dn = of_find_node_by_name(NULL, cfg->mdio_node_name);
+       if (!dn)
+               return -ENODEV;
+-- 
+2.25.1
+
diff --git a/target/linux/kirkwood/patches-5.10/801-power-reset-linkstation-poweroff-add-new-device.patch b/target/linux/kirkwood/patches-5.10/801-power-reset-linkstation-poweroff-add-new-device.patch
new file mode 100644 (file)
index 0000000..0b3b4ad
--- /dev/null
@@ -0,0 +1,102 @@
+From a2d9c86df8d12646f5bf66920e4f1e6d940cfc62 Mon Sep 17 00:00:00 2001
+From: Pawel Dembicki <paweldembicki@gmail.com>
+Date: Fri, 18 Jun 2021 13:25:33 +0200
+Subject: [PATCH 2/2] power: reset: linkstation-poweroff: add new device
+
+This commit introduces support for NETGEAR ReadyNAS Duo v2.
+This device use bit 4 of LED[2:0] Polarity Control Register to indicate
+AC Power loss.
+
+For more details about AC loss detection in NETGEAR ReadyNAS Duo v2,
+please look at the file:
+RND_5.3.13_WW.src/u-boot/board/mv_feroceon/mv_hal/usibootup/usibootup.c
+from Netgear GPL sources.
+
+Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
+---
+ drivers/power/reset/linkstation-poweroff.c | 43 ++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c
+index 8691cf98600d..2a92b6052cac 100644
+--- a/drivers/power/reset/linkstation-poweroff.c
++++ b/drivers/power/reset/linkstation-poweroff.c
+@@ -19,6 +19,7 @@
+ #define MII_MARVELL_PHY_PAGE          22
+ #define MII_PHY_LED_CTRL              16
++#define MII_PHY_LED_POL_CTRL          17
+ #define MII_88E1318S_PHY_LED_TCR      18
+ #define MII_88E1318S_PHY_WOL_CTRL     16
+ #define MII_M1011_IEVENT              19
+@@ -29,6 +30,8 @@
+ #define LED2_FORCE_ON                                 (0x8 << 8)
+ #define LEDMASK                                               GENMASK(11,8)
++#define MII_88E1318S_PHY_LED_POL_LED2         BIT(4)
++
+ struct power_off_cfg {
+       char *mdio_node_name;
+       void (*phy_set_reg)(bool restart);
+@@ -76,11 +79,48 @@ static void linkstation_mvphy_reg_intn(bool restart)
+               dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
+ }
++static void readynas_mvphy_set_reg(bool restart)
++{
++      int rc = 0, saved_page;
++      u16 data = 0;
++
++      if(restart)
++              data = MII_88E1318S_PHY_LED_POL_LED2;
++
++      saved_page = phy_select_page(phydev, MII_MARVELL_LED_PAGE);
++      if (saved_page < 0)
++              goto err;
++
++      /* Set the LED[2].0 Polarity bit to the required state */
++      __phy_modify(phydev, MII_PHY_LED_POL_CTRL,
++                   MII_88E1318S_PHY_LED_POL_LED2, data);
++
++      if (!data) {
++
++              /* If WOL was enabled and a magic packet was received before powering
++               * off, we won't be able to wake up by sending another magic packet.
++               * Clear WOL status.
++               */
++              __phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_WOL_PAGE);
++              __phy_set_bits(phydev, MII_88E1318S_PHY_WOL_CTRL,
++                             MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
++      }
++err:
++      rc = phy_restore_page(phydev, saved_page, rc);
++      if (rc < 0)
++              dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
++}
++
+ static const struct power_off_cfg linkstation_power_off_cfg = {
+       .mdio_node_name = "mdio",
+       .phy_set_reg = linkstation_mvphy_reg_intn,
+ };
++static const struct power_off_cfg readynas_power_off_cfg = {
++      .mdio_node_name = "mdio-bus",
++      .phy_set_reg = readynas_mvphy_set_reg,
++};
++
+ static int linkstation_reboot_notifier(struct notifier_block *nb,
+                                      unsigned long action, void *unused)
+ {
+@@ -109,6 +149,9 @@ static const struct of_device_id ls_poweroff_of_match[] = {
+       { .compatible = "buffalo,ls421de",
+         .data = &linkstation_power_off_cfg,
+       },
++      { .compatible = "netgear,readynas-duo-v2",
++        .data = &readynas_power_off_cfg,
++      },
+       { },
+ };
+-- 
+2.25.1
+
diff --git a/target/linux/kirkwood/patches-5.4/113-readynas_duo_v2.patch b/target/linux/kirkwood/patches-5.4/113-readynas_duo_v2.patch
new file mode 100644 (file)
index 0000000..c6452c5
--- /dev/null
@@ -0,0 +1,76 @@
+--- a/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
++++ b/arch/arm/boot/dts/kirkwood-netgear_readynas_duo_v2.dts
+@@ -19,6 +19,13 @@
+               reg = <0x00000000 0x10000000>;
+       };
++      aliases {
++              led-boot = &led_power;
++              led-failsafe = &led_power;
++              led-running = &led_power;
++              led-upgrade = &led_power;
++      };
++
+       chosen {
+               bootargs = "console=ttyS0,115200n8 earlyprintk";
+               stdout-path = &uart0;
+@@ -115,7 +122,7 @@
+                             &pmx_led_blue_backup >;
+               pinctrl-names = "default";
+-              power_led {
++              led_power: power_led {
+                       label = "status:blue:power_led";
+                       gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+                       default-state = "keep";
+@@ -129,11 +136,13 @@
+               disk1_led {
+                       label = "status:blue:disk1_led";
+                       gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "ata1";
+               };
+               disk2_led {
+                       label = "status:blue:disk2_led";
+                       gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
++                      linux,default-trigger = "ata2";
+               };
+               backup_led {
+@@ -150,7 +159,13 @@
+               power-button {
+                       label = "Power Button";
+-                      linux,code = <KEY_POWER>;
++                      /* Power button and INT pin from PHY are both connected
++                       * to this GPIO. Every network restart causes PHY restart
++                       * and button is pressed. It's difficult to use it as
++                       * KEY_POWER without changes in kernel (or netifd) so
++                       * the button is configured as regular one.
++                       */
++                      linux,code = <BTN_1>;
+                       gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+               };
+@@ -208,18 +223,13 @@
+       };
+       partition@200000 {
+-              label = "uImage";
++              label = "kernel";
+               reg = <0x0200000 0x600000>;
+       };
+       partition@800000 {
+-              label = "minirootfs";
+-              reg = <0x0800000 0x1000000>;
+-      };
+-
+-      partition@1800000 {
+-              label = "jffs2";
+-              reg = <0x1800000 0x6800000>;
++              label = "ubi";
++              reg = <0x0800000 0x7800000>;
+       };
+ };
diff --git a/target/linux/kirkwood/patches-5.4/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch b/target/linux/kirkwood/patches-5.4/800-power-reset-linkstation-poweroff-prepare-for-new-dev.patch
new file mode 100644 (file)
index 0000000..03253cf
--- /dev/null
@@ -0,0 +1,106 @@
+From 11cab9f5cd9390cd83747e579957c8f5b807c09c Mon Sep 17 00:00:00 2001
+From: Pawel Dembicki <paweldembicki@gmail.com>
+Date: Fri, 18 Jun 2021 12:37:27 +0200
+Subject: [PATCH 1/2] power: reset: linkstation-poweroff: prepare for new
+ devices
+
+This commit prepare driver for another device support.
+
+New power_off_cfg structure describes two most important things: name of
+mdio bus and pointer to register setting function. It allow to add new
+device with different mdio bus node and other phy register config.
+
+Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
+---
+ drivers/power/reset/linkstation-poweroff.c | 35 ++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c
+index f1e843df0e16..8691cf98600d 100644
+--- a/drivers/power/reset/linkstation-poweroff.c
++++ b/drivers/power/reset/linkstation-poweroff.c
+@@ -29,11 +29,21 @@
+ #define LED2_FORCE_ON                                 (0x8 << 8)
+ #define LEDMASK                                               GENMASK(11,8)
++struct power_off_cfg {
++      char *mdio_node_name;
++      void (*phy_set_reg)(bool restart);
++};
++
+ static struct phy_device *phydev;
++static const struct power_off_cfg *cfg;
+-static void mvphy_reg_intn(u16 data)
++static void linkstation_mvphy_reg_intn(bool restart)
+ {
+       int rc = 0, saved_page;
++      u16 data = 0;
++
++      if(restart)
++              data = MII_88E1318S_PHY_LED_TCR_FORCE_INT;
+       saved_page = phy_select_page(phydev, MII_MARVELL_LED_PAGE);
+       if (saved_page < 0)
+@@ -66,11 +76,16 @@ static void mvphy_reg_intn(u16 data)
+               dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
+ }
++static const struct power_off_cfg linkstation_power_off_cfg = {
++      .mdio_node_name = "mdio",
++      .phy_set_reg = linkstation_mvphy_reg_intn,
++};
++
+ static int linkstation_reboot_notifier(struct notifier_block *nb,
+                                      unsigned long action, void *unused)
+ {
+       if (action == SYS_RESTART)
+-              mvphy_reg_intn(MII_88E1318S_PHY_LED_TCR_FORCE_INT);
++              cfg->phy_set_reg(true);
+       return NOTIFY_DONE;
+ }
+@@ -82,14 +97,18 @@ static struct notifier_block linkstation_reboot_nb = {
+ static void linkstation_poweroff(void)
+ {
+       unregister_reboot_notifier(&linkstation_reboot_nb);
+-      mvphy_reg_intn(0);
++      cfg->phy_set_reg(false);
+       kernel_restart("Power off");
+ }
+ static const struct of_device_id ls_poweroff_of_match[] = {
+-      { .compatible = "buffalo,ls421d" },
+-      { .compatible = "buffalo,ls421de" },
++      { .compatible = "buffalo,ls421d",
++        .data = &linkstation_power_off_cfg,
++      },
++      { .compatible = "buffalo,ls421de",
++        .data = &linkstation_power_off_cfg,
++      },
+       { },
+ };
+@@ -97,13 +116,17 @@ static int __init linkstation_poweroff_init(void)
+ {
+       struct mii_bus *bus;
+       struct device_node *dn;
++      const struct of_device_id *match;
+       dn = of_find_matching_node(NULL, ls_poweroff_of_match);
+       if (!dn)
+               return -ENODEV;
+       of_node_put(dn);
+-      dn = of_find_node_by_name(NULL, "mdio");
++      match = of_match_node(ls_poweroff_of_match, dn);
++      cfg = match->data;
++
++      dn = of_find_node_by_name(NULL, cfg->mdio_node_name);
+       if (!dn)
+               return -ENODEV;
+-- 
+2.25.1
+
diff --git a/target/linux/kirkwood/patches-5.4/801-power-reset-linkstation-poweroff-add-new-device.patch b/target/linux/kirkwood/patches-5.4/801-power-reset-linkstation-poweroff-add-new-device.patch
new file mode 100644 (file)
index 0000000..0b3b4ad
--- /dev/null
@@ -0,0 +1,102 @@
+From a2d9c86df8d12646f5bf66920e4f1e6d940cfc62 Mon Sep 17 00:00:00 2001
+From: Pawel Dembicki <paweldembicki@gmail.com>
+Date: Fri, 18 Jun 2021 13:25:33 +0200
+Subject: [PATCH 2/2] power: reset: linkstation-poweroff: add new device
+
+This commit introduces support for NETGEAR ReadyNAS Duo v2.
+This device use bit 4 of LED[2:0] Polarity Control Register to indicate
+AC Power loss.
+
+For more details about AC loss detection in NETGEAR ReadyNAS Duo v2,
+please look at the file:
+RND_5.3.13_WW.src/u-boot/board/mv_feroceon/mv_hal/usibootup/usibootup.c
+from Netgear GPL sources.
+
+Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
+---
+ drivers/power/reset/linkstation-poweroff.c | 43 ++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c
+index 8691cf98600d..2a92b6052cac 100644
+--- a/drivers/power/reset/linkstation-poweroff.c
++++ b/drivers/power/reset/linkstation-poweroff.c
+@@ -19,6 +19,7 @@
+ #define MII_MARVELL_PHY_PAGE          22
+ #define MII_PHY_LED_CTRL              16
++#define MII_PHY_LED_POL_CTRL          17
+ #define MII_88E1318S_PHY_LED_TCR      18
+ #define MII_88E1318S_PHY_WOL_CTRL     16
+ #define MII_M1011_IEVENT              19
+@@ -29,6 +30,8 @@
+ #define LED2_FORCE_ON                                 (0x8 << 8)
+ #define LEDMASK                                               GENMASK(11,8)
++#define MII_88E1318S_PHY_LED_POL_LED2         BIT(4)
++
+ struct power_off_cfg {
+       char *mdio_node_name;
+       void (*phy_set_reg)(bool restart);
+@@ -76,11 +79,48 @@ static void linkstation_mvphy_reg_intn(bool restart)
+               dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
+ }
++static void readynas_mvphy_set_reg(bool restart)
++{
++      int rc = 0, saved_page;
++      u16 data = 0;
++
++      if(restart)
++              data = MII_88E1318S_PHY_LED_POL_LED2;
++
++      saved_page = phy_select_page(phydev, MII_MARVELL_LED_PAGE);
++      if (saved_page < 0)
++              goto err;
++
++      /* Set the LED[2].0 Polarity bit to the required state */
++      __phy_modify(phydev, MII_PHY_LED_POL_CTRL,
++                   MII_88E1318S_PHY_LED_POL_LED2, data);
++
++      if (!data) {
++
++              /* If WOL was enabled and a magic packet was received before powering
++               * off, we won't be able to wake up by sending another magic packet.
++               * Clear WOL status.
++               */
++              __phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_MARVELL_WOL_PAGE);
++              __phy_set_bits(phydev, MII_88E1318S_PHY_WOL_CTRL,
++                             MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS);
++      }
++err:
++      rc = phy_restore_page(phydev, saved_page, rc);
++      if (rc < 0)
++              dev_err(&phydev->mdio.dev, "Write register failed, %d\n", rc);
++}
++
+ static const struct power_off_cfg linkstation_power_off_cfg = {
+       .mdio_node_name = "mdio",
+       .phy_set_reg = linkstation_mvphy_reg_intn,
+ };
++static const struct power_off_cfg readynas_power_off_cfg = {
++      .mdio_node_name = "mdio-bus",
++      .phy_set_reg = readynas_mvphy_set_reg,
++};
++
+ static int linkstation_reboot_notifier(struct notifier_block *nb,
+                                      unsigned long action, void *unused)
+ {
+@@ -109,6 +149,9 @@ static const struct of_device_id ls_poweroff_of_match[] = {
+       { .compatible = "buffalo,ls421de",
+         .data = &linkstation_power_off_cfg,
+       },
++      { .compatible = "netgear,readynas-duo-v2",
++        .data = &readynas_power_off_cfg,
++      },
+       { },
+ };
+-- 
+2.25.1
+