[POWERPC] fsl_soc: add support to gianfar for fixed-link property
authorVitaly Bordug <vitb@kernel.crashing.org>
Thu, 6 Dec 2007 22:51:31 +0000 (01:51 +0300)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 24 Jan 2008 01:34:04 +0000 (19:34 -0600)
fixed-link says: register new "Fixed/emulated PHY", i.e. PHY that
not connected to the real MDIO bus.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Documentation/powerpc/booting-without-of.txt
arch/powerpc/sysdev/fsl_soc.c

index e58fd31bee1a5ddfccc23b105fae64764a89c9f6..f920c2459e89ee2ae7903879ae330af53bfd95e3 100644 (file)
@@ -1257,6 +1257,10 @@ platforms are moved over to use the flattened-device-tree model.
       services interrupts for this device.
     - phy-handle : The phandle for the PHY connected to this ethernet
       controller.
+    - fixed-link : <a b c d e> where a is emulated phy id - choose any,
+      but unique to the all specified fixed-links, b is duplex - 0 half,
+      1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
+      pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
 
   Recommended properties:
 
index f5c240242cfd136c31a599708871ae350b62e486..474cb8e22f64603451dae9777ac24614cec1e69f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 #include <linux/spi/spi.h>
 #include <linux/fsl_devices.h>
 #include <linux/fs_enet_pd.h>
@@ -130,6 +131,37 @@ u32 get_baudrate(void)
 EXPORT_SYMBOL(get_baudrate);
 #endif /* CONFIG_CPM2 */
 
+#ifdef CONFIG_FIXED_PHY
+static int __init of_add_fixed_phys(void)
+{
+       int ret;
+       struct device_node *np;
+       u32 *fixed_link;
+       struct fixed_phy_status status = {};
+
+       for_each_node_by_name(np, "ethernet") {
+               fixed_link  = (u32 *)of_get_property(np, "fixed-link", NULL);
+               if (!fixed_link)
+                       continue;
+
+               status.link = 1;
+               status.duplex = fixed_link[1];
+               status.speed = fixed_link[2];
+               status.pause = fixed_link[3];
+               status.asym_pause = fixed_link[4];
+
+               ret = fixed_phy_add(PHY_POLL, fixed_link[0], &status);
+               if (ret) {
+                       of_node_put(np);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+arch_initcall(of_add_fixed_phys);
+#endif /* CONFIG_FIXED_PHY */
+
 static int __init gfar_mdio_of_init(void)
 {
        struct device_node *np = NULL;
@@ -198,7 +230,6 @@ static const char *gfar_tx_intr = "tx";
 static const char *gfar_rx_intr = "rx";
 static const char *gfar_err_intr = "error";
 
-
 static int __init gfar_of_init(void)
 {
        struct device_node *np;
@@ -282,29 +313,43 @@ static int __init gfar_of_init(void)
                        gfar_data.interface = PHY_INTERFACE_MODE_MII;
 
                ph = of_get_property(np, "phy-handle", NULL);
-               phy = of_find_node_by_phandle(*ph);
+               if (ph == NULL) {
+                       u32 *fixed_link;
 
-               if (phy == NULL) {
-                       ret = -ENODEV;
-                       goto unreg;
-               }
+                       fixed_link = (u32 *)of_get_property(np, "fixed-link",
+                                                          NULL);
+                       if (!fixed_link) {
+                               ret = -ENODEV;
+                               goto unreg;
+                       }
 
-               mdio = of_get_parent(phy);
+                       gfar_data.bus_id = 0;
+                       gfar_data.phy_id = fixed_link[0];
+               } else {
+                       phy = of_find_node_by_phandle(*ph);
+
+                       if (phy == NULL) {
+                               ret = -ENODEV;
+                               goto unreg;
+                       }
+
+                       mdio = of_get_parent(phy);
+
+                       id = of_get_property(phy, "reg", NULL);
+                       ret = of_address_to_resource(mdio, 0, &res);
+                       if (ret) {
+                               of_node_put(phy);
+                               of_node_put(mdio);
+                               goto unreg;
+                       }
+
+                       gfar_data.phy_id = *id;
+                       gfar_data.bus_id = res.start;
 
-               id = of_get_property(phy, "reg", NULL);
-               ret = of_address_to_resource(mdio, 0, &res);
-               if (ret) {
                        of_node_put(phy);
                        of_node_put(mdio);
-                       goto unreg;
                }
 
-               gfar_data.phy_id = *id;
-               gfar_data.bus_id = res.start;
-
-               of_node_put(phy);
-               of_node_put(mdio);
-
                ret =
                    platform_device_add_data(gfar_dev, &gfar_data,
                                             sizeof(struct