]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
net: fec: add post PHY reset delay DT property
authorQuentin Schulz <quentin.schulz@free-electrons.com>
Tue, 23 May 2017 09:48:08 +0000 (11:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 May 2017 19:25:22 +0000 (15:25 -0400)
Some PHY require to wait for a bit after the reset GPIO has been
toggled. This adds support for the DT property `phy-reset-post-delay`
which gives the delay in milliseconds to wait after reset.

If the DT property is not given, no delay is observed. Post reset delay
greater than 1000ms are invalid.

Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/devicetree/bindings/net/fsl-fec.txt
drivers/net/ethernet/freescale/fec_main.c

index a1e3693cca1601e47096dc2edc2a9580b8b0569a..6f55bdd52f8a99be3c0741cf6411a00554c85778 100644 (file)
@@ -15,6 +15,10 @@ Optional properties:
 - phy-reset-active-high : If present then the reset sequence using the GPIO
   specified in the "phy-reset-gpios" property is reversed (H=reset state,
   L=operation state).
+- phy-reset-post-delay : Post reset delay in milliseconds. If present then
+  a delay of phy-reset-post-delay milliseconds will be observed after the
+  phy-reset-gpios has been toggled. Can be omitted thus no delay is
+  observed. Delay is in range of 1ms to 1000ms. Other delays are invalid.
 - phy-supply : regulator that powers the Ethernet PHY.
 - phy-handle : phandle to the PHY device connected to this device.
 - fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
index 56a563f90b0bf51d189dac8eb7da14791cc2b078..f7c8649fd28f695a1ff0519a85491bf85ec11f0b 100644 (file)
@@ -3192,7 +3192,7 @@ static int fec_reset_phy(struct platform_device *pdev)
 {
        int err, phy_reset;
        bool active_high = false;
-       int msec = 1;
+       int msec = 1, phy_post_delay = 0;
        struct device_node *np = pdev->dev.of_node;
 
        if (!np)
@@ -3209,6 +3209,11 @@ static int fec_reset_phy(struct platform_device *pdev)
        else if (!gpio_is_valid(phy_reset))
                return 0;
 
+       err = of_property_read_u32(np, "phy-reset-post-delay", &phy_post_delay);
+       /* valid reset duration should be less than 1s */
+       if (!err && phy_post_delay > 1000)
+               return -EINVAL;
+
        active_high = of_property_read_bool(np, "phy-reset-active-high");
 
        err = devm_gpio_request_one(&pdev->dev, phy_reset,
@@ -3226,6 +3231,15 @@ static int fec_reset_phy(struct platform_device *pdev)
 
        gpio_set_value_cansleep(phy_reset, !active_high);
 
+       if (!phy_post_delay)
+               return 0;
+
+       if (phy_post_delay > 20)
+               msleep(phy_post_delay);
+       else
+               usleep_range(phy_post_delay * 1000,
+                            phy_post_delay * 1000 + 1000);
+
        return 0;
 }
 #else /* CONFIG_OF */