aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2014-04-25 04:06:13 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-27 19:46:17 -0400
commit88154c96ee2dab84ae78ad41562b4a3a23d83788 (patch)
tree8b5892907536e3d31a325ce0587e3e1a6e416535
parent796bec1efbbd3be98d84cd68279c6ec03a4782f9 (diff)
arc_emac: add clock handling
This adds ability for the arc_emac to really handle its supplying clock. To get the needed clock-frequency either a real clock or the previous clock-frequency property must be provided. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Tested-by: Max Schwarz <max.schwarz@online.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/arc_emac.txt12
-rw-r--r--drivers/net/ethernet/arc/emac.h2
-rw-r--r--drivers/net/ethernet/arc/emac_main.c46
3 files changed, 47 insertions, 13 deletions
diff --git a/Documentation/devicetree/bindings/net/arc_emac.txt b/Documentation/devicetree/bindings/net/arc_emac.txt
index 7fbb027218a1..a1d71eb43b20 100644
--- a/Documentation/devicetree/bindings/net/arc_emac.txt
+++ b/Documentation/devicetree/bindings/net/arc_emac.txt
@@ -4,11 +4,15 @@ Required properties:
4- compatible: Should be "snps,arc-emac" 4- compatible: Should be "snps,arc-emac"
5- reg: Address and length of the register set for the device 5- reg: Address and length of the register set for the device
6- interrupts: Should contain the EMAC interrupts 6- interrupts: Should contain the EMAC interrupts
7- clock-frequency: CPU frequency. It is needed to calculate and set polling
8period of EMAC.
9- max-speed: see ethernet.txt file in the same directory. 7- max-speed: see ethernet.txt file in the same directory.
10- phy: see ethernet.txt file in the same directory. 8- phy: see ethernet.txt file in the same directory.
11 9
10Clock handling:
11The clock frequency is needed to calculate and set polling period of EMAC.
12It must be provided by one of:
13- clock-frequency: CPU frequency.
14- clocks: reference to the clock supplying the EMAC.
15
12Child nodes of the driver are the individual PHY devices connected to the 16Child nodes of the driver are the individual PHY devices connected to the
13MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus. 17MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus.
14 18
@@ -19,7 +23,11 @@ Examples:
19 reg = <0xc0fc2000 0x3c>; 23 reg = <0xc0fc2000 0x3c>;
20 interrupts = <6>; 24 interrupts = <6>;
21 mac-address = [ 00 11 22 33 44 55 ]; 25 mac-address = [ 00 11 22 33 44 55 ];
26
22 clock-frequency = <80000000>; 27 clock-frequency = <80000000>;
28 /* or */
29 clocks = <&emac_clock>;
30
23 max-speed = <100>; 31 max-speed = <100>;
24 phy = <&phy0>; 32 phy = <&phy0>;
25 33
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h
index 928fac6dd10a..53f85bf71526 100644
--- a/drivers/net/ethernet/arc/emac.h
+++ b/drivers/net/ethernet/arc/emac.h
@@ -11,6 +11,7 @@
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/phy.h> 13#include <linux/phy.h>
14#include <linux/clk.h>
14 15
15/* STATUS and ENABLE Register bit masks */ 16/* STATUS and ENABLE Register bit masks */
16#define TXINT_MASK (1<<0) /* Transmit interrupt */ 17#define TXINT_MASK (1<<0) /* Transmit interrupt */
@@ -131,6 +132,7 @@ struct arc_emac_priv {
131 struct mii_bus *bus; 132 struct mii_bus *bus;
132 133
133 void __iomem *regs; 134 void __iomem *regs;
135 struct clk *clk;
134 136
135 struct napi_struct napi; 137 struct napi_struct napi;
136 struct net_device_stats stats; 138 struct net_device_stats stats;
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index 9747ddaf6ad2..d647a7d115ac 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -649,13 +649,6 @@ static int arc_emac_probe(struct platform_device *pdev)
649 return -ENODEV; 649 return -ENODEV;
650 } 650 }
651 651
652 /* Get CPU clock frequency from device tree */
653 if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
654 &clock_frequency)) {
655 dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n");
656 return -EINVAL;
657 }
658
659 /* Get IRQ from device tree */ 652 /* Get IRQ from device tree */
660 irq = irq_of_parse_and_map(pdev->dev.of_node, 0); 653 irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
661 if (!irq) { 654 if (!irq) {
@@ -687,13 +680,32 @@ static int arc_emac_probe(struct platform_device *pdev)
687 } 680 }
688 dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); 681 dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs);
689 682
683 priv->clk = of_clk_get(pdev->dev.of_node, 0);
684 if (IS_ERR(priv->clk)) {
685 /* Get CPU clock frequency from device tree */
686 if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
687 &clock_frequency)) {
688 dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n");
689 err = -EINVAL;
690 goto out_netdev;
691 }
692 } else {
693 err = clk_prepare_enable(priv->clk);
694 if (err) {
695 dev_err(&pdev->dev, "failed to enable clock\n");
696 goto out_clkget;
697 }
698
699 clock_frequency = clk_get_rate(priv->clk);
700 }
701
690 id = arc_reg_get(priv, R_ID); 702 id = arc_reg_get(priv, R_ID);
691 703
692 /* Check for EMAC revision 5 or 7, magic number */ 704 /* Check for EMAC revision 5 or 7, magic number */
693 if (!(id == 0x0005fd02 || id == 0x0007fd02)) { 705 if (!(id == 0x0005fd02 || id == 0x0007fd02)) {
694 dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); 706 dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id);
695 err = -ENODEV; 707 err = -ENODEV;
696 goto out_netdev; 708 goto out_clken;
697 } 709 }
698 dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); 710 dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id);
699 711
@@ -708,7 +720,7 @@ static int arc_emac_probe(struct platform_device *pdev)
708 ndev->name, ndev); 720 ndev->name, ndev);
709 if (err) { 721 if (err) {
710 dev_err(&pdev->dev, "could not allocate IRQ\n"); 722 dev_err(&pdev->dev, "could not allocate IRQ\n");
711 goto out_netdev; 723 goto out_clken;
712 } 724 }
713 725
714 /* Get MAC address from device tree */ 726 /* Get MAC address from device tree */
@@ -729,7 +741,7 @@ static int arc_emac_probe(struct platform_device *pdev)
729 if (!priv->rxbd) { 741 if (!priv->rxbd) {
730 dev_err(&pdev->dev, "failed to allocate data buffers\n"); 742 dev_err(&pdev->dev, "failed to allocate data buffers\n");
731 err = -ENOMEM; 743 err = -ENOMEM;
732 goto out_netdev; 744 goto out_clken;
733 } 745 }
734 746
735 priv->txbd = priv->rxbd + RX_BD_NUM; 747 priv->txbd = priv->rxbd + RX_BD_NUM;
@@ -741,7 +753,7 @@ static int arc_emac_probe(struct platform_device *pdev)
741 err = arc_mdio_probe(pdev, priv); 753 err = arc_mdio_probe(pdev, priv);
742 if (err) { 754 if (err) {
743 dev_err(&pdev->dev, "failed to probe MII bus\n"); 755 dev_err(&pdev->dev, "failed to probe MII bus\n");
744 goto out_netdev; 756 goto out_clken;
745 } 757 }
746 758
747 priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, 759 priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0,
@@ -771,6 +783,12 @@ out_netif_api:
771 priv->phy_dev = NULL; 783 priv->phy_dev = NULL;
772out_mdio: 784out_mdio:
773 arc_mdio_remove(priv); 785 arc_mdio_remove(priv);
786out_clken:
787 if (!IS_ERR(priv->clk))
788 clk_disable_unprepare(priv->clk);
789out_clkget:
790 if (!IS_ERR(priv->clk))
791 clk_put(priv->clk);
774out_netdev: 792out_netdev:
775 free_netdev(ndev); 793 free_netdev(ndev);
776 return err; 794 return err;
@@ -786,6 +804,12 @@ static int arc_emac_remove(struct platform_device *pdev)
786 arc_mdio_remove(priv); 804 arc_mdio_remove(priv);
787 unregister_netdev(ndev); 805 unregister_netdev(ndev);
788 netif_napi_del(&priv->napi); 806 netif_napi_del(&priv->napi);
807
808 if (!IS_ERR(priv->clk)) {
809 clk_disable_unprepare(priv->clk);
810 clk_put(priv->clk);
811 }
812
789 free_netdev(ndev); 813 free_netdev(ndev);
790 814
791 return 0; 815 return 0;