Commit 0c77ec3d authored by Pawel Dembicki's avatar Pawel Dembicki Committed by Sebastian Reichel
Browse files

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: default avatarPawel Dembicki <paweldembicki@gmail.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent e2f471ef
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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 @@ 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 +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,
	},
	{ },
};