diff options
author | Cyril Chemparathy <cyril@ti.com> | 2010-09-15 10:11:24 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-09-24 10:40:30 -0400 |
commit | 5d69e0076a726588265af040b21ac3f8266856d1 (patch) | |
tree | 8267790f6468ab07c232c147dec3f9a2ad88dee9 /drivers/net/davinci_emac.c | |
parent | 433cdb0ac4c4660e98412e441589a7a712010325 (diff) |
net: davinci_emac: switch to new mdio
This patch switches the emac implementation over to the newly separated
MDIO driver.
With this, the mdio bus frequency defaults to a safe 2.2MHz. Boards may
optionally specify a bus frequency via platform data.
The phy identification scheme has been modified to use a phy bus id instead
of a mask. This largely serves to eliminate the "phy search" code in emac
init.
Signed-off-by: Cyril Chemparathy <cyril@ti.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Michael Williamson <michael.williamson@criticallink.com>
Tested-by: Caglar Akyuz <caglarakyuz@gmail.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'drivers/net/davinci_emac.c')
-rw-r--r-- | drivers/net/davinci_emac.c | 88 |
1 files changed, 30 insertions, 58 deletions
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 7fbd052ddb0a..997f5995fce1 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -500,6 +500,7 @@ struct emac_priv { | |||
500 | u32 phy_mask; | 500 | u32 phy_mask; |
501 | /* mii_bus,phy members */ | 501 | /* mii_bus,phy members */ |
502 | struct mii_bus *mii_bus; | 502 | struct mii_bus *mii_bus; |
503 | const char *phy_id; | ||
503 | struct phy_device *phydev; | 504 | struct phy_device *phydev; |
504 | spinlock_t lock; | 505 | spinlock_t lock; |
505 | /*platform specific members*/ | 506 | /*platform specific members*/ |
@@ -686,7 +687,7 @@ static int emac_get_settings(struct net_device *ndev, | |||
686 | struct ethtool_cmd *ecmd) | 687 | struct ethtool_cmd *ecmd) |
687 | { | 688 | { |
688 | struct emac_priv *priv = netdev_priv(ndev); | 689 | struct emac_priv *priv = netdev_priv(ndev); |
689 | if (priv->phy_mask) | 690 | if (priv->phydev) |
690 | return phy_ethtool_gset(priv->phydev, ecmd); | 691 | return phy_ethtool_gset(priv->phydev, ecmd); |
691 | else | 692 | else |
692 | return -EOPNOTSUPP; | 693 | return -EOPNOTSUPP; |
@@ -704,7 +705,7 @@ static int emac_get_settings(struct net_device *ndev, | |||
704 | static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) | 705 | static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) |
705 | { | 706 | { |
706 | struct emac_priv *priv = netdev_priv(ndev); | 707 | struct emac_priv *priv = netdev_priv(ndev); |
707 | if (priv->phy_mask) | 708 | if (priv->phydev) |
708 | return phy_ethtool_sset(priv->phydev, ecmd); | 709 | return phy_ethtool_sset(priv->phydev, ecmd); |
709 | else | 710 | else |
710 | return -EOPNOTSUPP; | 711 | return -EOPNOTSUPP; |
@@ -841,7 +842,7 @@ static void emac_update_phystatus(struct emac_priv *priv) | |||
841 | mac_control = emac_read(EMAC_MACCONTROL); | 842 | mac_control = emac_read(EMAC_MACCONTROL); |
842 | cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ? | 843 | cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ? |
843 | DUPLEX_FULL : DUPLEX_HALF; | 844 | DUPLEX_FULL : DUPLEX_HALF; |
844 | if (priv->phy_mask) | 845 | if (priv->phydev) |
845 | new_duplex = priv->phydev->duplex; | 846 | new_duplex = priv->phydev->duplex; |
846 | else | 847 | else |
847 | new_duplex = DUPLEX_FULL; | 848 | new_duplex = DUPLEX_FULL; |
@@ -2485,6 +2486,11 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) | |||
2485 | return -EOPNOTSUPP; | 2486 | return -EOPNOTSUPP; |
2486 | } | 2487 | } |
2487 | 2488 | ||
2489 | static int match_first_device(struct device *dev, void *data) | ||
2490 | { | ||
2491 | return 1; | ||
2492 | } | ||
2493 | |||
2488 | /** | 2494 | /** |
2489 | * emac_dev_open: EMAC device open | 2495 | * emac_dev_open: EMAC device open |
2490 | * @ndev: The DaVinci EMAC network adapter | 2496 | * @ndev: The DaVinci EMAC network adapter |
@@ -2499,7 +2505,6 @@ static int emac_dev_open(struct net_device *ndev) | |||
2499 | { | 2505 | { |
2500 | struct device *emac_dev = &ndev->dev; | 2506 | struct device *emac_dev = &ndev->dev; |
2501 | u32 rc, cnt, ch; | 2507 | u32 rc, cnt, ch; |
2502 | int phy_addr; | ||
2503 | struct resource *res; | 2508 | struct resource *res; |
2504 | int q, m; | 2509 | int q, m; |
2505 | int i = 0; | 2510 | int i = 0; |
@@ -2560,28 +2565,26 @@ static int emac_dev_open(struct net_device *ndev) | |||
2560 | emac_set_coalesce(ndev, &coal); | 2565 | emac_set_coalesce(ndev, &coal); |
2561 | } | 2566 | } |
2562 | 2567 | ||
2563 | /* find the first phy */ | ||
2564 | priv->phydev = NULL; | 2568 | priv->phydev = NULL; |
2565 | if (priv->phy_mask) { | 2569 | /* use the first phy on the bus if pdata did not give us a phy id */ |
2566 | emac_mii_reset(priv->mii_bus); | 2570 | if (!priv->phy_id) { |
2567 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | 2571 | struct device *phy; |
2568 | if (priv->mii_bus->phy_map[phy_addr]) { | ||
2569 | priv->phydev = priv->mii_bus->phy_map[phy_addr]; | ||
2570 | break; | ||
2571 | } | ||
2572 | } | ||
2573 | 2572 | ||
2574 | if (!priv->phydev) { | 2573 | phy = bus_find_device(&mdio_bus_type, NULL, NULL, |
2575 | printk(KERN_ERR "%s: no PHY found\n", ndev->name); | 2574 | match_first_device); |
2576 | return -1; | 2575 | if (phy) |
2577 | } | 2576 | priv->phy_id = dev_name(phy); |
2577 | } | ||
2578 | 2578 | ||
2579 | priv->phydev = phy_connect(ndev, dev_name(&priv->phydev->dev), | 2579 | if (priv->phy_id && *priv->phy_id) { |
2580 | &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII); | 2580 | priv->phydev = phy_connect(ndev, priv->phy_id, |
2581 | &emac_adjust_link, 0, | ||
2582 | PHY_INTERFACE_MODE_MII); | ||
2581 | 2583 | ||
2582 | if (IS_ERR(priv->phydev)) { | 2584 | if (IS_ERR(priv->phydev)) { |
2583 | printk(KERN_ERR "%s: Could not attach to PHY\n", | 2585 | dev_err(emac_dev, "could not connect to phy %s\n", |
2584 | ndev->name); | 2586 | priv->phy_id); |
2587 | priv->phydev = NULL; | ||
2585 | return PTR_ERR(priv->phydev); | 2588 | return PTR_ERR(priv->phydev); |
2586 | } | 2589 | } |
2587 | 2590 | ||
@@ -2589,12 +2592,13 @@ static int emac_dev_open(struct net_device *ndev) | |||
2589 | priv->speed = 0; | 2592 | priv->speed = 0; |
2590 | priv->duplex = ~0; | 2593 | priv->duplex = ~0; |
2591 | 2594 | ||
2592 | printk(KERN_INFO "%s: attached PHY driver [%s] " | 2595 | dev_info(emac_dev, "attached PHY driver [%s] " |
2593 | "(mii_bus:phy_addr=%s, id=%x)\n", ndev->name, | 2596 | "(mii_bus:phy_addr=%s, id=%x)\n", |
2594 | priv->phydev->drv->name, dev_name(&priv->phydev->dev), | 2597 | priv->phydev->drv->name, dev_name(&priv->phydev->dev), |
2595 | priv->phydev->phy_id); | 2598 | priv->phydev->phy_id); |
2596 | } else{ | 2599 | } else { |
2597 | /* No PHY , fix the link, speed and duplex settings */ | 2600 | /* No PHY , fix the link, speed and duplex settings */ |
2601 | dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); | ||
2598 | priv->link = 1; | 2602 | priv->link = 1; |
2599 | priv->speed = SPEED_100; | 2603 | priv->speed = SPEED_100; |
2600 | priv->duplex = DUPLEX_FULL; | 2604 | priv->duplex = DUPLEX_FULL; |
@@ -2607,7 +2611,7 @@ static int emac_dev_open(struct net_device *ndev) | |||
2607 | if (netif_msg_drv(priv)) | 2611 | if (netif_msg_drv(priv)) |
2608 | dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name); | 2612 | dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name); |
2609 | 2613 | ||
2610 | if (priv->phy_mask) | 2614 | if (priv->phydev) |
2611 | phy_start(priv->phydev); | 2615 | phy_start(priv->phydev); |
2612 | 2616 | ||
2613 | return 0; | 2617 | return 0; |
@@ -2794,7 +2798,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2794 | 2798 | ||
2795 | /* MAC addr and PHY mask , RMII enable info from platform_data */ | 2799 | /* MAC addr and PHY mask , RMII enable info from platform_data */ |
2796 | memcpy(priv->mac_addr, pdata->mac_addr, 6); | 2800 | memcpy(priv->mac_addr, pdata->mac_addr, 6); |
2797 | priv->phy_mask = pdata->phy_mask; | 2801 | priv->phy_id = pdata->phy_id; |
2798 | priv->rmii_en = pdata->rmii_en; | 2802 | priv->rmii_en = pdata->rmii_en; |
2799 | priv->version = pdata->version; | 2803 | priv->version = pdata->version; |
2800 | priv->int_enable = pdata->interrupt_enable; | 2804 | priv->int_enable = pdata->interrupt_enable; |
@@ -2871,32 +2875,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2871 | } | 2875 | } |
2872 | 2876 | ||
2873 | 2877 | ||
2874 | /* MII/Phy intialisation, mdio bus registration */ | ||
2875 | emac_mii = mdiobus_alloc(); | ||
2876 | if (emac_mii == NULL) { | ||
2877 | dev_err(emac_dev, "DaVinci EMAC: Error allocating mii_bus\n"); | ||
2878 | rc = -ENOMEM; | ||
2879 | goto mdio_alloc_err; | ||
2880 | } | ||
2881 | |||
2882 | priv->mii_bus = emac_mii; | ||
2883 | emac_mii->name = "emac-mii", | ||
2884 | emac_mii->read = emac_mii_read, | ||
2885 | emac_mii->write = emac_mii_write, | ||
2886 | emac_mii->reset = emac_mii_reset, | ||
2887 | emac_mii->irq = mii_irqs, | ||
2888 | emac_mii->phy_mask = ~(priv->phy_mask); | ||
2889 | emac_mii->parent = &pdev->dev; | ||
2890 | emac_mii->priv = priv->remap_addr + pdata->mdio_reg_offset; | ||
2891 | snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", priv->pdev->id); | ||
2892 | mdio_max_freq = pdata->mdio_max_freq; | ||
2893 | emac_mii->reset(emac_mii); | ||
2894 | |||
2895 | /* Register the MII bus */ | ||
2896 | rc = mdiobus_register(emac_mii); | ||
2897 | if (rc) | ||
2898 | goto mdiobus_quit; | ||
2899 | |||
2900 | if (netif_msg_probe(priv)) { | 2878 | if (netif_msg_probe(priv)) { |
2901 | dev_notice(emac_dev, "DaVinci EMAC Probe found device "\ | 2879 | dev_notice(emac_dev, "DaVinci EMAC Probe found device "\ |
2902 | "(regs: %p, irq: %d)\n", | 2880 | "(regs: %p, irq: %d)\n", |
@@ -2904,11 +2882,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2904 | } | 2882 | } |
2905 | return 0; | 2883 | return 0; |
2906 | 2884 | ||
2907 | mdiobus_quit: | ||
2908 | mdiobus_free(emac_mii); | ||
2909 | |||
2910 | netdev_reg_err: | 2885 | netdev_reg_err: |
2911 | mdio_alloc_err: | ||
2912 | clk_disable(emac_clk); | 2886 | clk_disable(emac_clk); |
2913 | no_irq_res: | 2887 | no_irq_res: |
2914 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2888 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -2938,8 +2912,6 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) | |||
2938 | 2912 | ||
2939 | platform_set_drvdata(pdev, NULL); | 2913 | platform_set_drvdata(pdev, NULL); |
2940 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2914 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2941 | mdiobus_unregister(priv->mii_bus); | ||
2942 | mdiobus_free(priv->mii_bus); | ||
2943 | 2915 | ||
2944 | release_mem_region(res->start, res->end - res->start + 1); | 2916 | release_mem_region(res->start, res->end - res->start + 1); |
2945 | 2917 | ||