diff options
author | Pawel Dembicki <paweldembicki@gmail.com> | 2021-06-24 12:18:12 +0300 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2021-08-13 20:16:41 +0300 |
commit | 0c77ec3da8c156d6d02ce0934b590cfe8a313cae (patch) | |
tree | 611fbdf7b9c5723f7f945540175d06e4b410ac60 /drivers/power | |
parent | e2f471efe1d607a7aff38ce53ec717cebe4283d6 (diff) | |
download | linux-0c77ec3da8c156d6d02ce0934b590cfe8a313cae.tar.xz |
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>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/reset/linkstation-poweroff.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c index cb5a32f852c1..02f5fdb8ffc4 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,47 @@ err: 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 +148,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, + }, { }, }; |