preinit: move cmdline failsafe= handling ot the generic code
[openwrt.git] / target / linux / ramips / patches-3.8 / 0132-NET-ramips-fix-mdio-bus-support.patch
1 --- a/drivers/net/ethernet/ramips/ramips_main.c
2 +++ b/drivers/net/ethernet/ramips/ramips_main.c
3 @@ -28,6 +28,7 @@
4  #include <linux/of_device.h>
5  #include <linux/clk.h>
6  #include <linux/of_net.h>
7 +#include <linux/of_mdio.h>
8  
9  #include "ramips_eth.h"
10  
11 @@ -406,12 +407,25 @@ ramips_mdio_reset(struct mii_bus *bus)
12  static int
13  ramips_mdio_init(struct raeth_priv *re)
14  {
15 +       struct device_node *mii_np;
16         int err;
17 -       int i;
18 +
19 +       mii_np = of_get_child_by_name(re->of_node, "mdio-bus");
20 +       if (!mii_np) {
21 +               dev_err(re->parent, "no %s child node found", "mdio-bus");
22 +               return -ENODEV;
23 +       }
24 +
25 +       if (!of_device_is_available(mii_np)) {
26 +               err = 0;
27 +               goto err_put_node;
28 +       }
29  
30         re->mii_bus = mdiobus_alloc();
31 -       if (re->mii_bus == NULL)
32 -               return -ENOMEM;
33 +       if (re->mii_bus == NULL) {
34 +               err = -ENOMEM;
35 +               goto err_put_node;
36 +       }
37  
38         re->mii_bus->name = "ramips_mdio";
39         re->mii_bus->read = ramips_mdio_read;
40 @@ -422,12 +436,7 @@ ramips_mdio_init(struct raeth_priv *re)
41         re->mii_bus->parent = re->parent;
42  
43         snprintf(re->mii_bus->id, MII_BUS_ID_SIZE, "%s", "ramips_mdio");
44 -       re->mii_bus->phy_mask = 0;
45 -
46 -       for (i = 0; i < PHY_MAX_ADDR; i++)
47 -               re->mii_irq[i] = PHY_POLL;
48 -
49 -       err = mdiobus_register(re->mii_bus);
50 +       err = of_mdiobus_register(re->mii_bus, mii_np);
51         if (err)
52                 goto err_free_bus;
53  
54 @@ -435,13 +444,20 @@ ramips_mdio_init(struct raeth_priv *re)
55  
56  err_free_bus:
57         kfree(re->mii_bus);
58 +err_put_node:
59 +       of_node_put(mii_np);
60 +       re->mii_bus = NULL;
61         return err;
62  }
63  
64  static void
65  ramips_mdio_cleanup(struct raeth_priv *re)
66  {
67 +       if (!re->mii_bus)
68 +               return;
69 +
70         mdiobus_unregister(re->mii_bus);
71 +       of_node_put(re->mii_bus->dev.of_node);
72         kfree(re->mii_bus);
73  }
74  
75 @@ -474,106 +490,86 @@ ramips_phy_link_adjust(struct net_device
76  }
77  
78  static int
79 -ramips_phy_connect_multi(struct raeth_priv *re)
80 +ramips_phy_connect_by_node(struct raeth_priv *re, struct device_node *phy_node)
81  {
82 -       struct net_device *netdev = re->netdev;
83 -       struct phy_device *phydev = NULL;
84 -       int phy_addr;
85 -       int ret = 0;
86 -
87 -       for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
88 -               if (!(re->phy_mask & (1 << phy_addr)))
89 -                       continue;
90 -
91 -               if (re->mii_bus->phy_map[phy_addr] == NULL)
92 -                       continue;
93 +       struct phy_device *phydev;
94 +       int phy_mode;
95  
96 -               RADEBUG("%s: PHY found at %s, uid=%08x\n",
97 -                       netdev->name,
98 -                       dev_name(&re->mii_bus->phy_map[phy_addr]->dev),
99 -                       re->mii_bus->phy_map[phy_addr]->phy_id);
100 -
101 -               if (phydev == NULL)
102 -                       phydev = re->mii_bus->phy_map[phy_addr];
103 -       }
104 -
105 -       if (!phydev) {
106 -               netdev_err(netdev, "no PHY found with phy_mask=%08x\n",
107 -                          re->phy_mask);
108 -               return -ENODEV;
109 +       phy_mode = of_get_phy_mode(re->of_node);
110 +       if (phy_mode < 0) {
111 +               dev_err(re->parent, "incorrect phy-mode\n");
112 +               return -EINVAL;
113         }
114  
115 -       re->phy_dev = phy_connect(netdev, dev_name(&phydev->dev),
116 -                                 ramips_phy_link_adjust, 0, re->phy_if_mode);
117 -
118 -       if (IS_ERR(re->phy_dev)) {
119 -               netdev_err(netdev, "could not connect to PHY at %s\n",
120 -                          dev_name(&phydev->dev));
121 +       phydev = of_phy_connect(re->netdev, phy_node, ramips_phy_link_adjust,
122 +                               0, phy_mode);
123 +       if (IS_ERR(phydev)) {
124 +               dev_err(re->parent, "could not connect to PHY\n");
125                 return PTR_ERR(re->phy_dev);
126         }
127  
128         phydev->supported &= PHY_GBIT_FEATURES;
129         phydev->advertising = phydev->supported;
130  
131 -       RADEBUG("%s: connected to PHY at %s [uid=%08x, driver=%s]\n",
132 -               netdev->name, dev_name(&phydev->dev),
133 -               phydev->phy_id, phydev->drv->name);
134 +       dev_info(re->parent,
135 +                "connected to PHY at %s [uid=%08x, driver=%s]\n",
136 +                dev_name(&phydev->dev), phydev->phy_id,
137 +                phydev->drv->name);
138  
139 +       re->phy_dev = phydev;
140         re->link = 0;
141         re->speed = 0;
142         re->duplex = -1;
143         re->rx_fc = 0;
144         re->tx_fc = 0;
145  
146 -       return ret;
147 +       return 0;
148  }
149  
150  static int
151 -ramips_phy_connect_fixed(struct raeth_priv *re)
152 +ramips_phy_connect_fixed(struct raeth_priv *re, const __be32 *link, int size)
153  {
154 -       if (!re->speed) {
155 -               const __be32 *link;
156 -               int size;
157 -
158 -               link = of_get_property(re->of_node,
159 -                                       "ralink,fixed-link", &size);
160 -               if (!link || size != (4 * sizeof(*link)))
161 -                       return -ENOENT;
162 -
163 -               re->speed = be32_to_cpup(link++);
164 -               re->duplex = be32_to_cpup(link++);
165 -               re->tx_fc = be32_to_cpup(link++);
166 -               re->rx_fc = be32_to_cpup(link++);
167 +       if (size != (4 * sizeof(*link))) {
168 +               dev_err(re->parent, "invalid fixed-link property\n");
169 +               return -EINVAL;
170         }
171  
172 +       re->speed = be32_to_cpup(link++);
173 +       re->duplex = be32_to_cpup(link++);
174 +       re->tx_fc = be32_to_cpup(link++);
175 +       re->rx_fc = be32_to_cpup(link++);
176 +
177         switch (re->speed) {
178         case SPEED_10:
179         case SPEED_100:
180         case SPEED_1000:
181                 break;
182         default:
183 -               netdev_err(re->netdev, "invalid speed specified\n");
184 +               dev_err(re->parent, "invalid link speed: %d\n", re->speed);
185                 return -EINVAL;
186         }
187  
188 -       pr_info("%s: using fixed link parameters\n", re->netdev->name);
189 +       dev_info(re->parent, "using fixed link parameters\n");
190         return 0;
191  }
192  
193  static int
194  ramips_phy_connect(struct raeth_priv *re)
195  {
196 -       const __be32 *mask;
197 -
198 -       mask = of_get_property(re->of_node, "ralink,phy-mask", NULL);
199 -       re->phy_if_mode = of_get_phy_mode(re->of_node);
200 -
201 -       if (!re->phy_if_mode || !mask)
202 -               return ramips_phy_connect_fixed(re);
203 -
204 -       re->phy_mask = be32_to_cpup(mask);
205 -       return ramips_phy_connect_multi(re);
206 +       struct device_node *phy_node;
207 +       const __be32 *p32;
208 +       int size;
209 +
210 +       phy_node = of_parse_phandle(re->of_node, "phy-handle", 0);
211 +       if (phy_node)
212 +               return ramips_phy_connect_by_node(re, phy_node);
213 +
214 +       p32 = of_get_property(re->of_node, "ralink,fixed-link", &size);
215 +       if (p32)
216 +               return ramips_phy_connect_fixed(re, p32, size);
217  
218 +       dev_err(re->parent, "unable to get connection type\n");
219 +       return -EINVAL;
220  }
221  
222  static void