diff options
-rw-r--r-- | Documentation/devicetree/bindings/net/macb.txt | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/macb.c | 73 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/macb.h | 2 |
3 files changed, 92 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt new file mode 100644 index 000000000000..44afa0e5057d --- /dev/null +++ b/Documentation/devicetree/bindings/net/macb.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | * Cadence MACB/GEM Ethernet controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "cdns,[<chip>-]{macb|gem}" | ||
5 | Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs. | ||
6 | Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". | ||
7 | Use "cnds,pc302-gem" for Picochip picoXcell pc302 and later devices based on | ||
8 | the Cadence GEM, or the generic form: "cdns,gem". | ||
9 | - reg: Address and length of the register set for the device | ||
10 | - interrupts: Should contain macb interrupt | ||
11 | - phy-mode: String, operation mode of the PHY interface. | ||
12 | Supported values are: "mii", "rmii", "gmii", "rgmii". | ||
13 | |||
14 | Optional properties: | ||
15 | - local-mac-address: 6 bytes, mac address | ||
16 | |||
17 | Examples: | ||
18 | |||
19 | macb0: ethernet@fffc4000 { | ||
20 | compatible = "cdns,at32ap7000-macb"; | ||
21 | reg = <0xfffc4000 0x4000>; | ||
22 | interrupts = <21>; | ||
23 | phy-mode = "rmii"; | ||
24 | local-mac-address = [3a 0e 03 04 05 06]; | ||
25 | }; | ||
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 64d61461bdc7..baf1a0d88d8a 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/platform_data/macb.h> | 23 | #include <linux/platform_data/macb.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/phy.h> | 25 | #include <linux/phy.h> |
26 | #include <linux/of_device.h> | ||
27 | #include <linux/of_net.h> | ||
26 | 28 | ||
27 | #include "macb.h" | 29 | #include "macb.h" |
28 | 30 | ||
@@ -191,7 +193,6 @@ static int macb_mii_probe(struct net_device *dev) | |||
191 | { | 193 | { |
192 | struct macb *bp = netdev_priv(dev); | 194 | struct macb *bp = netdev_priv(dev); |
193 | struct phy_device *phydev; | 195 | struct phy_device *phydev; |
194 | struct macb_platform_data *pdata; | ||
195 | int ret; | 196 | int ret; |
196 | 197 | ||
197 | phydev = phy_find_first(bp->mii_bus); | 198 | phydev = phy_find_first(bp->mii_bus); |
@@ -200,14 +201,11 @@ static int macb_mii_probe(struct net_device *dev) | |||
200 | return -1; | 201 | return -1; |
201 | } | 202 | } |
202 | 203 | ||
203 | pdata = bp->pdev->dev.platform_data; | ||
204 | /* TODO : add pin_irq */ | 204 | /* TODO : add pin_irq */ |
205 | 205 | ||
206 | /* attach the mac to the phy */ | 206 | /* attach the mac to the phy */ |
207 | ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, | 207 | ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, |
208 | pdata && pdata->is_rmii ? | 208 | bp->phy_interface); |
209 | PHY_INTERFACE_MODE_RMII : | ||
210 | PHY_INTERFACE_MODE_MII); | ||
211 | if (ret) { | 209 | if (ret) { |
212 | netdev_err(dev, "Could not attach to PHY\n"); | 210 | netdev_err(dev, "Could not attach to PHY\n"); |
213 | return ret; | 211 | return ret; |
@@ -1244,6 +1242,52 @@ static const struct net_device_ops macb_netdev_ops = { | |||
1244 | #endif | 1242 | #endif |
1245 | }; | 1243 | }; |
1246 | 1244 | ||
1245 | #if defined(CONFIG_OF) | ||
1246 | static const struct of_device_id macb_dt_ids[] = { | ||
1247 | { .compatible = "cdns,at32ap7000-macb" }, | ||
1248 | { .compatible = "cdns,at91sam9260-macb" }, | ||
1249 | { .compatible = "cdns,macb" }, | ||
1250 | { .compatible = "cdns,pc302-gem" }, | ||
1251 | { .compatible = "cdns,gem" }, | ||
1252 | { /* sentinel */ } | ||
1253 | }; | ||
1254 | |||
1255 | MODULE_DEVICE_TABLE(of, macb_dt_ids); | ||
1256 | |||
1257 | static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev) | ||
1258 | { | ||
1259 | struct device_node *np = pdev->dev.of_node; | ||
1260 | |||
1261 | if (np) | ||
1262 | return of_get_phy_mode(np); | ||
1263 | |||
1264 | return -ENODEV; | ||
1265 | } | ||
1266 | |||
1267 | static int __devinit macb_get_hwaddr_dt(struct macb *bp) | ||
1268 | { | ||
1269 | struct device_node *np = bp->pdev->dev.of_node; | ||
1270 | if (np) { | ||
1271 | const char *mac = of_get_mac_address(np); | ||
1272 | if (mac) { | ||
1273 | memcpy(bp->dev->dev_addr, mac, ETH_ALEN); | ||
1274 | return 0; | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | return -ENODEV; | ||
1279 | } | ||
1280 | #else | ||
1281 | static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev) | ||
1282 | { | ||
1283 | return -ENODEV; | ||
1284 | } | ||
1285 | static int __devinit macb_get_hwaddr_dt(struct macb *bp) | ||
1286 | { | ||
1287 | return -ENODEV; | ||
1288 | } | ||
1289 | #endif | ||
1290 | |||
1247 | static int __init macb_probe(struct platform_device *pdev) | 1291 | static int __init macb_probe(struct platform_device *pdev) |
1248 | { | 1292 | { |
1249 | struct macb_platform_data *pdata; | 1293 | struct macb_platform_data *pdata; |
@@ -1318,10 +1362,22 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1318 | config |= macb_dbw(bp); | 1362 | config |= macb_dbw(bp); |
1319 | macb_writel(bp, NCFGR, config); | 1363 | macb_writel(bp, NCFGR, config); |
1320 | 1364 | ||
1321 | macb_get_hwaddr(bp); | 1365 | err = macb_get_hwaddr_dt(bp); |
1322 | pdata = pdev->dev.platform_data; | 1366 | if (err < 0) |
1367 | macb_get_hwaddr(bp); | ||
1368 | |||
1369 | err = macb_get_phy_mode_dt(pdev); | ||
1370 | if (err < 0) { | ||
1371 | pdata = pdev->dev.platform_data; | ||
1372 | if (pdata && pdata->is_rmii) | ||
1373 | bp->phy_interface = PHY_INTERFACE_MODE_RMII; | ||
1374 | else | ||
1375 | bp->phy_interface = PHY_INTERFACE_MODE_MII; | ||
1376 | } else { | ||
1377 | bp->phy_interface = err; | ||
1378 | } | ||
1323 | 1379 | ||
1324 | if (pdata && pdata->is_rmii) | 1380 | if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) |
1325 | #if defined(CONFIG_ARCH_AT91) | 1381 | #if defined(CONFIG_ARCH_AT91) |
1326 | macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | | 1382 | macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | |
1327 | MACB_BIT(CLKEN))); | 1383 | MACB_BIT(CLKEN))); |
@@ -1444,6 +1500,7 @@ static struct platform_driver macb_driver = { | |||
1444 | .driver = { | 1500 | .driver = { |
1445 | .name = "macb", | 1501 | .name = "macb", |
1446 | .owner = THIS_MODULE, | 1502 | .owner = THIS_MODULE, |
1503 | .of_match_table = of_match_ptr(macb_dt_ids), | ||
1447 | }, | 1504 | }, |
1448 | }; | 1505 | }; |
1449 | 1506 | ||
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index 193107884a5a..335e288f5314 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -532,6 +532,8 @@ struct macb { | |||
532 | unsigned int link; | 532 | unsigned int link; |
533 | unsigned int speed; | 533 | unsigned int speed; |
534 | unsigned int duplex; | 534 | unsigned int duplex; |
535 | |||
536 | phy_interface_t phy_interface; | ||
535 | }; | 537 | }; |
536 | 538 | ||
537 | static inline bool macb_is_gem(struct macb *bp) | 539 | static inline bool macb_is_gem(struct macb *bp) |