ath79: ag71xx: add support for optional mdio reset
authorChuanhong Guo <gch981213@gmail.com>
Sat, 15 Dec 2018 07:44:34 +0000 (15:44 +0800)
committerDaniel Golle <daniel@makrotopia.org>
Tue, 5 Mar 2019 02:02:34 +0000 (03:02 +0100)
On ar933x and later chips, there are separated mac/mdio resets, but
resetting the entire gmac block with register values requires both
mac_reset and mdio_reset to be asserted together.

Add support for optional mdio reset so that we can do a full reset
if needed.

This patch also replaced deprecated devm_reset_control_get for
mac reset.

To use this feature, the following is needed:
 1. drop "simple-mfd" compatible to register mdio0 after gmac init
    so that mdio registers aren't reset after initialization.
 2. move mdio reset from mdio-bus to its parent eth node.

NOTE: This can't be applied on gmac1 with builtin switch since we
haven't add a feature to defer probe if phy connection failed.

Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx.h
target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c

index 9aac1998a87d69e03817dddb14cc599d5c66690e..fde9db37456d5ce261ff3d4414f3e1dc69f40be0 100644 (file)
@@ -188,6 +188,7 @@ struct ag71xx {
        struct timer_list       oom_timer;
 
        struct reset_control *mac_reset;
        struct timer_list       oom_timer;
 
        struct reset_control *mac_reset;
+       struct reset_control *mdio_reset;
 
        u32                     fifodata[3];
        u32                     plldata[3];
 
        u32                     fifodata[3];
        u32                     plldata[3];
index bf9239163dd31b6642512f70b56eedf0114fbab9..1f8c5b409b2017e8ae63ce6f6db871aa8c12aab1 100644 (file)
@@ -453,8 +453,12 @@ static void ag71xx_hw_init(struct ag71xx *ag)
        udelay(20);
 
        reset_control_assert(ag->mac_reset);
        udelay(20);
 
        reset_control_assert(ag->mac_reset);
+       if (ag->mdio_reset)
+               reset_control_assert(ag->mdio_reset);
        msleep(100);
        reset_control_deassert(ag->mac_reset);
        msleep(100);
        reset_control_deassert(ag->mac_reset);
+       if (ag->mdio_reset)
+               reset_control_deassert(ag->mdio_reset);
        msleep(200);
 
        ag71xx_hw_setup(ag);
        msleep(200);
 
        ag71xx_hw_setup(ag);
@@ -1352,12 +1356,14 @@ static int ag71xx_probe(struct platform_device *pdev)
                                        AG71XX_DEFAULT_MSG_ENABLE);
        spin_lock_init(&ag->lock);
 
                                        AG71XX_DEFAULT_MSG_ENABLE);
        spin_lock_init(&ag->lock);
 
-       ag->mac_reset = devm_reset_control_get(&pdev->dev, "mac");
+       ag->mac_reset = devm_reset_control_get_exclusive(&pdev->dev, "mac");
        if (IS_ERR(ag->mac_reset)) {
                dev_err(&pdev->dev, "missing mac reset\n");
                return PTR_ERR(ag->mac_reset);
        }
 
        if (IS_ERR(ag->mac_reset)) {
                dev_err(&pdev->dev, "missing mac reset\n");
                return PTR_ERR(ag->mac_reset);
        }
 
+       ag->mdio_reset = devm_reset_control_get_optional_exclusive(&pdev->dev, "mdio");
+
        if (of_property_read_u32_array(np, "fifo-data", ag->fifodata, 3)) {
                if (of_device_is_compatible(np, "qca,ar9130-eth") ||
                    of_device_is_compatible(np, "qca,ar7100-eth")) {
        if (of_property_read_u32_array(np, "fifo-data", ag->fifodata, 3)) {
                if (of_device_is_compatible(np, "qca,ar9130-eth") ||
                    of_device_is_compatible(np, "qca,ar7100-eth")) {