diff options
Diffstat (limited to 'drivers/net/ethernet/arc/emac_main.c')
-rw-r--r-- | drivers/net/ethernet/arc/emac_main.c | 127 |
1 files changed, 46 insertions, 81 deletions
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index fe5cfeace6e3..a7773923a7a0 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | #include "emac.h" | 27 | #include "emac.h" |
28 | 28 | ||
29 | #define DRV_NAME "arc_emac" | ||
30 | #define DRV_VERSION "1.0" | ||
31 | 29 | ||
32 | /** | 30 | /** |
33 | * arc_emac_adjust_link - Adjust the PHY link duplex. | 31 | * arc_emac_adjust_link - Adjust the PHY link duplex. |
@@ -120,8 +118,10 @@ static int arc_emac_set_settings(struct net_device *ndev, | |||
120 | static void arc_emac_get_drvinfo(struct net_device *ndev, | 118 | static void arc_emac_get_drvinfo(struct net_device *ndev, |
121 | struct ethtool_drvinfo *info) | 119 | struct ethtool_drvinfo *info) |
122 | { | 120 | { |
123 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); | 121 | struct arc_emac_priv *priv = netdev_priv(ndev); |
124 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | 122 | |
123 | strlcpy(info->driver, priv->drv_name, sizeof(info->driver)); | ||
124 | strlcpy(info->version, priv->drv_version, sizeof(info->version)); | ||
125 | } | 125 | } |
126 | 126 | ||
127 | static const struct ethtool_ops arc_emac_ethtool_ops = { | 127 | static const struct ethtool_ops arc_emac_ethtool_ops = { |
@@ -671,46 +671,38 @@ static const struct net_device_ops arc_emac_netdev_ops = { | |||
671 | #endif | 671 | #endif |
672 | }; | 672 | }; |
673 | 673 | ||
674 | static int arc_emac_probe(struct platform_device *pdev) | 674 | int arc_emac_probe(struct net_device *ndev, int interface) |
675 | { | 675 | { |
676 | struct device *dev = ndev->dev.parent; | ||
676 | struct resource res_regs; | 677 | struct resource res_regs; |
677 | struct device_node *phy_node; | 678 | struct device_node *phy_node; |
678 | struct arc_emac_priv *priv; | 679 | struct arc_emac_priv *priv; |
679 | struct net_device *ndev; | ||
680 | const char *mac_addr; | 680 | const char *mac_addr; |
681 | unsigned int id, clock_frequency, irq; | 681 | unsigned int id, clock_frequency, irq; |
682 | int err; | 682 | int err; |
683 | 683 | ||
684 | if (!pdev->dev.of_node) | ||
685 | return -ENODEV; | ||
686 | 684 | ||
687 | /* Get PHY from device tree */ | 685 | /* Get PHY from device tree */ |
688 | phy_node = of_parse_phandle(pdev->dev.of_node, "phy", 0); | 686 | phy_node = of_parse_phandle(dev->of_node, "phy", 0); |
689 | if (!phy_node) { | 687 | if (!phy_node) { |
690 | dev_err(&pdev->dev, "failed to retrieve phy description from device tree\n"); | 688 | dev_err(dev, "failed to retrieve phy description from device tree\n"); |
691 | return -ENODEV; | 689 | return -ENODEV; |
692 | } | 690 | } |
693 | 691 | ||
694 | /* Get EMAC registers base address from device tree */ | 692 | /* Get EMAC registers base address from device tree */ |
695 | err = of_address_to_resource(pdev->dev.of_node, 0, &res_regs); | 693 | err = of_address_to_resource(dev->of_node, 0, &res_regs); |
696 | if (err) { | 694 | if (err) { |
697 | dev_err(&pdev->dev, "failed to retrieve registers base from device tree\n"); | 695 | dev_err(dev, "failed to retrieve registers base from device tree\n"); |
698 | return -ENODEV; | 696 | return -ENODEV; |
699 | } | 697 | } |
700 | 698 | ||
701 | /* Get IRQ from device tree */ | 699 | /* Get IRQ from device tree */ |
702 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | 700 | irq = irq_of_parse_and_map(dev->of_node, 0); |
703 | if (!irq) { | 701 | if (!irq) { |
704 | dev_err(&pdev->dev, "failed to retrieve <irq> value from device tree\n"); | 702 | dev_err(dev, "failed to retrieve <irq> value from device tree\n"); |
705 | return -ENODEV; | 703 | return -ENODEV; |
706 | } | 704 | } |
707 | 705 | ||
708 | ndev = alloc_etherdev(sizeof(struct arc_emac_priv)); | ||
709 | if (!ndev) | ||
710 | return -ENOMEM; | ||
711 | |||
712 | platform_set_drvdata(pdev, ndev); | ||
713 | SET_NETDEV_DEV(ndev, &pdev->dev); | ||
714 | 706 | ||
715 | ndev->netdev_ops = &arc_emac_netdev_ops; | 707 | ndev->netdev_ops = &arc_emac_netdev_ops; |
716 | ndev->ethtool_ops = &arc_emac_ethtool_ops; | 708 | ndev->ethtool_ops = &arc_emac_ethtool_ops; |
@@ -719,60 +711,57 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
719 | ndev->flags &= ~IFF_MULTICAST; | 711 | ndev->flags &= ~IFF_MULTICAST; |
720 | 712 | ||
721 | priv = netdev_priv(ndev); | 713 | priv = netdev_priv(ndev); |
722 | priv->dev = &pdev->dev; | 714 | priv->dev = dev; |
723 | 715 | ||
724 | priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs); | 716 | priv->regs = devm_ioremap_resource(dev, &res_regs); |
725 | if (IS_ERR(priv->regs)) { | 717 | if (IS_ERR(priv->regs)) { |
726 | err = PTR_ERR(priv->regs); | 718 | return PTR_ERR(priv->regs); |
727 | goto out_netdev; | ||
728 | } | 719 | } |
729 | dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); | 720 | dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs); |
730 | 721 | ||
731 | priv->clk = of_clk_get(pdev->dev.of_node, 0); | 722 | if (priv->clk) { |
732 | if (IS_ERR(priv->clk)) { | ||
733 | /* Get CPU clock frequency from device tree */ | ||
734 | if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
735 | &clock_frequency)) { | ||
736 | dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
737 | err = -EINVAL; | ||
738 | goto out_netdev; | ||
739 | } | ||
740 | } else { | ||
741 | err = clk_prepare_enable(priv->clk); | 723 | err = clk_prepare_enable(priv->clk); |
742 | if (err) { | 724 | if (err) { |
743 | dev_err(&pdev->dev, "failed to enable clock\n"); | 725 | dev_err(dev, "failed to enable clock\n"); |
744 | goto out_clkget; | 726 | return err; |
745 | } | 727 | } |
746 | 728 | ||
747 | clock_frequency = clk_get_rate(priv->clk); | 729 | clock_frequency = clk_get_rate(priv->clk); |
730 | } else { | ||
731 | /* Get CPU clock frequency from device tree */ | ||
732 | if (of_property_read_u32(dev->of_node, "clock-frequency", | ||
733 | &clock_frequency)) { | ||
734 | dev_err(dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
735 | return -EINVAL; | ||
736 | } | ||
748 | } | 737 | } |
749 | 738 | ||
750 | id = arc_reg_get(priv, R_ID); | 739 | id = arc_reg_get(priv, R_ID); |
751 | 740 | ||
752 | /* Check for EMAC revision 5 or 7, magic number */ | 741 | /* Check for EMAC revision 5 or 7, magic number */ |
753 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { | 742 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { |
754 | dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); | 743 | dev_err(dev, "ARC EMAC not detected, id=0x%x\n", id); |
755 | err = -ENODEV; | 744 | err = -ENODEV; |
756 | goto out_clken; | 745 | goto out_clken; |
757 | } | 746 | } |
758 | dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); | 747 | dev_info(dev, "ARC EMAC detected with id: 0x%x\n", id); |
759 | 748 | ||
760 | /* Set poll rate so that it polls every 1 ms */ | 749 | /* Set poll rate so that it polls every 1 ms */ |
761 | arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000); | 750 | arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000); |
762 | 751 | ||
763 | ndev->irq = irq; | 752 | ndev->irq = irq; |
764 | dev_info(&pdev->dev, "IRQ is %d\n", ndev->irq); | 753 | dev_info(dev, "IRQ is %d\n", ndev->irq); |
765 | 754 | ||
766 | /* Register interrupt handler for device */ | 755 | /* Register interrupt handler for device */ |
767 | err = devm_request_irq(&pdev->dev, ndev->irq, arc_emac_intr, 0, | 756 | err = devm_request_irq(dev, ndev->irq, arc_emac_intr, 0, |
768 | ndev->name, ndev); | 757 | ndev->name, ndev); |
769 | if (err) { | 758 | if (err) { |
770 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 759 | dev_err(dev, "could not allocate IRQ\n"); |
771 | goto out_clken; | 760 | goto out_clken; |
772 | } | 761 | } |
773 | 762 | ||
774 | /* Get MAC address from device tree */ | 763 | /* Get MAC address from device tree */ |
775 | mac_addr = of_get_mac_address(pdev->dev.of_node); | 764 | mac_addr = of_get_mac_address(dev->of_node); |
776 | 765 | ||
777 | if (mac_addr) | 766 | if (mac_addr) |
778 | memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); | 767 | memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); |
@@ -780,14 +769,14 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
780 | eth_hw_addr_random(ndev); | 769 | eth_hw_addr_random(ndev); |
781 | 770 | ||
782 | arc_emac_set_address_internal(ndev); | 771 | arc_emac_set_address_internal(ndev); |
783 | dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr); | 772 | dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); |
784 | 773 | ||
785 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ | 774 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ |
786 | priv->rxbd = dmam_alloc_coherent(&pdev->dev, RX_RING_SZ + TX_RING_SZ, | 775 | priv->rxbd = dmam_alloc_coherent(dev, RX_RING_SZ + TX_RING_SZ, |
787 | &priv->rxbd_dma, GFP_KERNEL); | 776 | &priv->rxbd_dma, GFP_KERNEL); |
788 | 777 | ||
789 | if (!priv->rxbd) { | 778 | if (!priv->rxbd) { |
790 | dev_err(&pdev->dev, "failed to allocate data buffers\n"); | 779 | dev_err(dev, "failed to allocate data buffers\n"); |
791 | err = -ENOMEM; | 780 | err = -ENOMEM; |
792 | goto out_clken; | 781 | goto out_clken; |
793 | } | 782 | } |
@@ -795,31 +784,31 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
795 | priv->txbd = priv->rxbd + RX_BD_NUM; | 784 | priv->txbd = priv->rxbd + RX_BD_NUM; |
796 | 785 | ||
797 | priv->txbd_dma = priv->rxbd_dma + RX_RING_SZ; | 786 | priv->txbd_dma = priv->rxbd_dma + RX_RING_SZ; |
798 | dev_dbg(&pdev->dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n", | 787 | dev_dbg(dev, "EMAC Device addr: Rx Ring [0x%x], Tx Ring[%x]\n", |
799 | (unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma); | 788 | (unsigned int)priv->rxbd_dma, (unsigned int)priv->txbd_dma); |
800 | 789 | ||
801 | err = arc_mdio_probe(pdev, priv); | 790 | err = arc_mdio_probe(priv); |
802 | if (err) { | 791 | if (err) { |
803 | dev_err(&pdev->dev, "failed to probe MII bus\n"); | 792 | dev_err(dev, "failed to probe MII bus\n"); |
804 | goto out_clken; | 793 | goto out_clken; |
805 | } | 794 | } |
806 | 795 | ||
807 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, | 796 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, |
808 | PHY_INTERFACE_MODE_MII); | 797 | interface); |
809 | if (!priv->phy_dev) { | 798 | if (!priv->phy_dev) { |
810 | dev_err(&pdev->dev, "of_phy_connect() failed\n"); | 799 | dev_err(dev, "of_phy_connect() failed\n"); |
811 | err = -ENODEV; | 800 | err = -ENODEV; |
812 | goto out_mdio; | 801 | goto out_mdio; |
813 | } | 802 | } |
814 | 803 | ||
815 | dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n", | 804 | dev_info(dev, "connected to %s phy with id 0x%x\n", |
816 | priv->phy_dev->drv->name, priv->phy_dev->phy_id); | 805 | priv->phy_dev->drv->name, priv->phy_dev->phy_id); |
817 | 806 | ||
818 | netif_napi_add(ndev, &priv->napi, arc_emac_poll, ARC_EMAC_NAPI_WEIGHT); | 807 | netif_napi_add(ndev, &priv->napi, arc_emac_poll, ARC_EMAC_NAPI_WEIGHT); |
819 | 808 | ||
820 | err = register_netdev(ndev); | 809 | err = register_netdev(ndev); |
821 | if (err) { | 810 | if (err) { |
822 | dev_err(&pdev->dev, "failed to register network device\n"); | 811 | dev_err(dev, "failed to register network device\n"); |
823 | goto out_netif_api; | 812 | goto out_netif_api; |
824 | } | 813 | } |
825 | 814 | ||
@@ -832,19 +821,14 @@ out_netif_api: | |||
832 | out_mdio: | 821 | out_mdio: |
833 | arc_mdio_remove(priv); | 822 | arc_mdio_remove(priv); |
834 | out_clken: | 823 | out_clken: |
835 | if (!IS_ERR(priv->clk)) | 824 | if (priv->clk) |
836 | clk_disable_unprepare(priv->clk); | 825 | clk_disable_unprepare(priv->clk); |
837 | out_clkget: | ||
838 | if (!IS_ERR(priv->clk)) | ||
839 | clk_put(priv->clk); | ||
840 | out_netdev: | ||
841 | free_netdev(ndev); | ||
842 | return err; | 826 | return err; |
843 | } | 827 | } |
828 | EXPORT_SYMBOL_GPL(arc_emac_probe); | ||
844 | 829 | ||
845 | static int arc_emac_remove(struct platform_device *pdev) | 830 | int arc_emac_remove(struct net_device *ndev) |
846 | { | 831 | { |
847 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
848 | struct arc_emac_priv *priv = netdev_priv(ndev); | 832 | struct arc_emac_priv *priv = netdev_priv(ndev); |
849 | 833 | ||
850 | phy_disconnect(priv->phy_dev); | 834 | phy_disconnect(priv->phy_dev); |
@@ -855,31 +839,12 @@ static int arc_emac_remove(struct platform_device *pdev) | |||
855 | 839 | ||
856 | if (!IS_ERR(priv->clk)) { | 840 | if (!IS_ERR(priv->clk)) { |
857 | clk_disable_unprepare(priv->clk); | 841 | clk_disable_unprepare(priv->clk); |
858 | clk_put(priv->clk); | ||
859 | } | 842 | } |
860 | 843 | ||
861 | free_netdev(ndev); | ||
862 | 844 | ||
863 | return 0; | 845 | return 0; |
864 | } | 846 | } |
865 | 847 | EXPORT_SYMBOL_GPL(arc_emac_remove); | |
866 | static const struct of_device_id arc_emac_dt_ids[] = { | ||
867 | { .compatible = "snps,arc-emac" }, | ||
868 | { /* Sentinel */ } | ||
869 | }; | ||
870 | MODULE_DEVICE_TABLE(of, arc_emac_dt_ids); | ||
871 | |||
872 | static struct platform_driver arc_emac_driver = { | ||
873 | .probe = arc_emac_probe, | ||
874 | .remove = arc_emac_remove, | ||
875 | .driver = { | ||
876 | .name = DRV_NAME, | ||
877 | .owner = THIS_MODULE, | ||
878 | .of_match_table = arc_emac_dt_ids, | ||
879 | }, | ||
880 | }; | ||
881 | |||
882 | module_platform_driver(arc_emac_driver); | ||
883 | 848 | ||
884 | MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>"); | 849 | MODULE_AUTHOR("Alexey Brodkin <abrodkin@synopsys.com>"); |
885 | MODULE_DESCRIPTION("ARC EMAC driver"); | 850 | MODULE_DESCRIPTION("ARC EMAC driver"); |