diff options
-rw-r--r-- | Documentation/devicetree/bindings/net/cdns-emac.txt | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/cadence/at91_ether.c | 73 |
2 files changed, 89 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/net/cdns-emac.txt b/Documentation/devicetree/bindings/net/cdns-emac.txt new file mode 100644 index 000000000000..09055c2495f0 --- /dev/null +++ b/Documentation/devicetree/bindings/net/cdns-emac.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | * Cadence EMAC Ethernet controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "cdns,[<chip>-]{emac}" | ||
5 | Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. | ||
6 | or the generic form: "cdns,emac". | ||
7 | - reg: Address and length of the register set for the device | ||
8 | - interrupts: Should contain macb interrupt | ||
9 | - phy-mode: String, operation mode of the PHY interface. | ||
10 | Supported values are: "mii", "rmii". | ||
11 | |||
12 | Optional properties: | ||
13 | - local-mac-address: 6 bytes, mac address | ||
14 | |||
15 | Examples: | ||
16 | |||
17 | macb0: ethernet@fffc4000 { | ||
18 | compatible = "cdns,at91rm9200-emac"; | ||
19 | reg = <0xfffc4000 0x4000>; | ||
20 | interrupts = <21>; | ||
21 | phy-mode = "rmii"; | ||
22 | local-mac-address = [3a 0e 03 04 05 06]; | ||
23 | }; | ||
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 0d6392d24ff7..039e7ef6c50e 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c | |||
@@ -31,6 +31,9 @@ | |||
31 | #include <linux/gfp.h> | 31 | #include <linux/gfp.h> |
32 | #include <linux/phy.h> | 32 | #include <linux/phy.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/of.h> | ||
35 | #include <linux/of_device.h> | ||
36 | #include <linux/of_net.h> | ||
34 | 37 | ||
35 | #include "macb.h" | 38 | #include "macb.h" |
36 | 39 | ||
@@ -443,6 +446,50 @@ static const struct net_device_ops at91ether_netdev_ops = { | |||
443 | #endif | 446 | #endif |
444 | }; | 447 | }; |
445 | 448 | ||
449 | #if defined(CONFIG_OF) | ||
450 | static const struct of_device_id at91ether_dt_ids[] = { | ||
451 | { .compatible = "cdns,at91rm9200-emac" }, | ||
452 | { .compatible = "cdns,emac" }, | ||
453 | { /* sentinel */ } | ||
454 | }; | ||
455 | |||
456 | MODULE_DEVICE_TABLE(of, at91ether_dt_ids); | ||
457 | |||
458 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) | ||
459 | { | ||
460 | struct device_node *np = pdev->dev.of_node; | ||
461 | |||
462 | if (np) | ||
463 | return of_get_phy_mode(np); | ||
464 | |||
465 | return -ENODEV; | ||
466 | } | ||
467 | |||
468 | static int at91ether_get_hwaddr_dt(struct macb *bp) | ||
469 | { | ||
470 | struct device_node *np = bp->pdev->dev.of_node; | ||
471 | |||
472 | if (np) { | ||
473 | const char *mac = of_get_mac_address(np); | ||
474 | if (mac) { | ||
475 | memcpy(bp->dev->dev_addr, mac, ETH_ALEN); | ||
476 | return 0; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | return -ENODEV; | ||
481 | } | ||
482 | #else | ||
483 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) | ||
484 | { | ||
485 | return -ENODEV; | ||
486 | } | ||
487 | static int at91ether_get_hwaddr_dt(struct macb *bp) | ||
488 | { | ||
489 | return -ENODEV; | ||
490 | } | ||
491 | #endif | ||
492 | |||
446 | /* | 493 | /* |
447 | * Detect MAC & PHY and perform ethernet interface initialization | 494 | * Detect MAC & PHY and perform ethernet interface initialization |
448 | */ | 495 | */ |
@@ -466,7 +513,8 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
466 | lp = netdev_priv(dev); | 513 | lp = netdev_priv(dev); |
467 | lp->pdev = pdev; | 514 | lp->pdev = pdev; |
468 | lp->dev = dev; | 515 | lp->dev = dev; |
469 | lp->board_data = *board_data; | 516 | if (board_data) |
517 | lp->board_data = *board_data; | ||
470 | spin_lock_init(&lp->lock); | 518 | spin_lock_init(&lp->lock); |
471 | 519 | ||
472 | dev->base_addr = regs->start; /* physical base address */ | 520 | dev->base_addr = regs->start; /* physical base address */ |
@@ -496,18 +544,28 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
496 | platform_set_drvdata(pdev, dev); | 544 | platform_set_drvdata(pdev, dev); |
497 | SET_NETDEV_DEV(dev, &pdev->dev); | 545 | SET_NETDEV_DEV(dev, &pdev->dev); |
498 | 546 | ||
499 | get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ | 547 | res = at91ether_get_hwaddr_dt(lp); |
548 | if (res < 0) | ||
549 | get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */ | ||
550 | |||
500 | update_mac_address(dev); /* Program ethernet address into MAC */ | 551 | update_mac_address(dev); /* Program ethernet address into MAC */ |
501 | 552 | ||
553 | res = at91ether_get_phy_mode_dt(pdev); | ||
554 | if (res < 0) { | ||
555 | if (board_data && board_data->is_rmii) | ||
556 | lp->phy_interface = PHY_INTERFACE_MODE_RMII; | ||
557 | else | ||
558 | lp->phy_interface = PHY_INTERFACE_MODE_MII; | ||
559 | } else { | ||
560 | lp->phy_interface = res; | ||
561 | } | ||
562 | |||
502 | macb_writel(lp, NCR, 0); | 563 | macb_writel(lp, NCR, 0); |
503 | 564 | ||
504 | if (board_data->is_rmii) { | 565 | if (lp->phy_interface == PHY_INTERFACE_MODE_RMII) |
505 | macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG) | MACB_BIT(RM9200_RMII)); | 566 | macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG) | MACB_BIT(RM9200_RMII)); |
506 | lp->phy_interface = PHY_INTERFACE_MODE_RMII; | 567 | else |
507 | } else { | ||
508 | macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG)); | 568 | macb_writel(lp, NCFGR, MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG)); |
509 | lp->phy_interface = PHY_INTERFACE_MODE_MII; | ||
510 | } | ||
511 | 569 | ||
512 | /* Register the network interface */ | 570 | /* Register the network interface */ |
513 | res = register_netdev(dev); | 571 | res = register_netdev(dev); |
@@ -602,6 +660,7 @@ static struct platform_driver at91ether_driver = { | |||
602 | .driver = { | 660 | .driver = { |
603 | .name = DRV_NAME, | 661 | .name = DRV_NAME, |
604 | .owner = THIS_MODULE, | 662 | .owner = THIS_MODULE, |
663 | .of_match_table = of_match_ptr(at91ether_dt_ids), | ||
605 | }, | 664 | }, |
606 | }; | 665 | }; |
607 | 666 | ||