]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
net: macb: Add support for fixed link
authorHarini Katakam <harini.katakam@xilinx.com>
Fri, 7 Oct 2016 09:04:23 +0000 (14:34 +0530)
committerMichal Simek <monstr@monstr.eu>
Tue, 3 Oct 2017 15:26:12 +0000 (17:26 +0200)
This patch adds support for fixed link to use in setups where
there is not phy negotiation required.

Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
Signed-off-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/cadence/macb.h

index 3d67d442c4af488419955082866ac73609fb80cd..b28dd61ed61ff173a3f1bb6661b85b3e8304acfe 100644 (file)
@@ -381,28 +381,37 @@ static int macb_mii_probe(struct net_device *dev)
        int phy_irq;
        int ret;
 
-       phydev = phy_find_first(bp->mii_bus);
-       if (!phydev) {
-               netdev_err(dev, "no PHY found\n");
-               return -ENXIO;
-       }
+       if (bp->phy_node) {
+               phydev = of_phy_connect(dev, bp->phy_node,
+                                       &macb_handle_link_change, 0,
+                                       bp->phy_interface);
+               if (!phydev)
+                       return -ENODEV;
+       } else {
+               phydev = phy_find_first(bp->mii_bus);
+               if (!phydev) {
+                       netdev_err(dev, "no PHY found\n");
+                       return -ENXIO;
+               }
 
-       pdata = dev_get_platdata(&bp->pdev->dev);
-       if (pdata && gpio_is_valid(pdata->phy_irq_pin)) {
-               ret = devm_gpio_request(&bp->pdev->dev, pdata->phy_irq_pin,
-                                       "phy int");
-               if (!ret) {
-                       phy_irq = gpio_to_irq(pdata->phy_irq_pin);
-                       phydev->irq = (phy_irq < 0) ? PHY_POLL : phy_irq;
+               pdata = dev_get_platdata(&bp->pdev->dev);
+               if (pdata && gpio_is_valid(pdata->phy_irq_pin)) {
+                       ret = devm_gpio_request(&bp->pdev->dev,
+                                               pdata->phy_irq_pin, "phy int");
+                       if (!ret) {
+                               phy_irq = gpio_to_irq(pdata->phy_irq_pin);
+                               phydev->irq = (phy_irq < 0) ?
+                                             PHY_POLL : phy_irq;
+                       }
                }
-       }
 
-       /* attach the mac to the phy */
-       ret = phy_connect_direct(dev, phydev, &macb_handle_link_change,
-                                bp->phy_interface);
-       if (ret) {
-               netdev_err(dev, "Could not attach to PHY\n");
-               return ret;
+               /* attach the mac to the phy */
+               ret = phy_connect_direct(dev, phydev, &macb_handle_link_change,
+                                        bp->phy_interface);
+               if (ret) {
+                       netdev_err(dev, "Could not attach to PHY\n");
+                       return ret;
+               }
        }
 
        /* mask with MAC supported features */
@@ -3483,8 +3492,16 @@ static int macb_probe(struct platform_device *pdev)
                macb_get_hwaddr(bp);
 
        /* Power up the PHY if there is a GPIO reset */
-       phy_node =  of_get_next_available_child(np, NULL);
-       if (phy_node) {
+       phy_node = of_parse_phandle(np, "phy-handle", 0);
+       if (!phy_node && of_phy_is_fixed_link(np)) {
+               err = of_phy_register_fixed_link(np);
+               if (err < 0) {
+                       dev_err(&pdev->dev, "broken fixed-link specification");
+                       goto failed_phy;
+               }
+               phy_node = of_node_get(np);
+               bp->phy_node = phy_node;
+       } else {
                int gpio = of_get_named_gpio(phy_node, "reset-gpios", 0);
 
                if (gpio_is_valid(gpio)) {
@@ -3492,7 +3509,6 @@ static int macb_probe(struct platform_device *pdev)
                        gpiod_direction_output(bp->reset_gpio, 1);
                }
        }
-       of_node_put(phy_node);
 
        err = of_get_phy_mode(np);
        if (err < 0) {
@@ -3549,6 +3565,9 @@ err_out_unregister_mdio:
 err_out_free_netdev:
        free_netdev(dev);
 
+failed_phy:
+       of_node_put(phy_node);
+
 err_disable_clocks:
        clk_disable_unprepare(tx_clk);
        clk_disable_unprepare(hclk);
@@ -3582,6 +3601,7 @@ static int macb_remove(struct platform_device *pdev)
                clk_disable_unprepare(bp->hclk);
                clk_disable_unprepare(bp->pclk);
                clk_disable_unprepare(bp->rx_clk);
+               of_node_put(bp->phy_node);
                free_netdev(dev);
        }
 
index 4b17855dcb128f2a5db5573e7565b39bac7453ce..d8447d45c90cff5a3235ce3325f65a783a71887d 100644 (file)
@@ -909,6 +909,7 @@ struct macb {
 
        struct mii_bus          *mii_bus;
        struct phy_device       *phy_dev;
+       struct device_node      *phy_node;
        int                     link;
        int                     speed;
        int                     duplex;