Message ID | 20210624091813.42334-1-paweldembicki@gmail.com |
---|---|
State | Accepted |
Commit | e2f471efe1d607a7aff38ce53ec717cebe4283d6 |
Headers | show |
Series | [1/2] power: reset: linkstation-poweroff: prepare for new devices | expand |
Hi, On Thu, Jun 24, 2021 at 11:18:11AM +0200, Pawel Dembicki wrote: > 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> > --- Thanks, queued. -- Sebastian > 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..cb5a32f852c1 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 >
Hi, On Thu, Jun 24, 2021 at 11:18:12AM +0200, Pawel Dembicki wrote: > 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> > --- Thanks, queued. -- Sebastian > 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 cb5a32f852c1..5afe3ef23395 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/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c index f1e843df0e16..cb5a32f852c1 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;
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(-)