[PATCH v3] fec: fix clk handling for Coldfire.

Subsystems: networking drivers, the rest

STALE5180d

2 messages, 2 authors, 2012-06-17 · open the first message on its own page

[PATCH v3] fec: fix clk handling for Coldfire.

From: Steven King <hidden>
Date: 2012-06-17 23:39:46

commit f4d40de39a23f0c39cca55ac63e1175c69c3d2f7
'net fec: do not depend on grouped clocks' broke fec for Coldfire.

Hide the details of the fec clk management in a trio of new functions: 
fec_clk_get, fec_clk_prepare and fec_clk_disable_unprepare.  these then can 
be modified as needed to manage the clks for the different arches that use
the fec controller.

Signed-off-by: Steven King <redacted>
---
 drivers/net/ethernet/freescale/fec.c |   84 ++++++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index ff7f4c5..1072da6 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -207,8 +207,12 @@ struct fec_enet_private {
 
 	struct net_device *netdev;
 
+#ifdef CONFIG_COLDFIRE
+	struct clk *clk;
+#else
 	struct clk *clk_ipg;
 	struct clk *clk_ahb;
+#endif
 
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	unsigned char *tx_bounce[TX_RING_SIZE];
@@ -248,6 +252,56 @@ struct fec_enet_private {
 	int	irq[FEC_IRQ_NUM];
 };
 
+static int fec_clk_get(struct platform_device *pdev,
+		       struct fec_enet_private *fep)
+{
+	int ret;
+
+#ifdef CONFIG_COLDFIRE
+	fep->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(fep->clk)) {
+		ret = PTR_ERR(fep->clk);
+		goto failed_clk;
+	}
+#else
+	fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(fep->clk_ipg)) {
+		ret = PTR_ERR(fep->clk_ipg);
+		goto failed_clk;
+	}
+
+	fep->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(fep->clk_ahb)) {
+		ret = PTR_ERR(fep->clk_ahb);
+		goto failed_clk;
+	}
+#endif
+	return 0;
+
+failed_clk:
+	return ret;
+}
+
+static void fec_clk_prepare(struct fec_enet_private *fep)
+{
+#ifdef CONFIG_COLDFIRE
+	clk_prepare_enable(fep->clk);
+#else
+	clk_prepare_enable(fep->clk_ahb);
+	clk_prepare_enable(fep->clk_ipg);
+#endif
+}
+
+static void fec_clk_disable_unprepare(struct fec_enet_private *fep)
+{
+#ifdef CONFIG_COLDFIRE
+	clk_disable_unprepare(fep->clk);
+#else
+	clk_disable_unprepare(fep->clk_ahb);
+	clk_disable_unprepare(fep->clk_ipg);
+#endif
+}
+
 /* FEC MII MMFR bits definition */
 #define FEC_MMFR_ST		(1 << 30)
 #define FEC_MMFR_OP_READ	(2 << 28)
@@ -1066,7 +1120,11 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	 * Reference Manual has an error on this, and gets fixed on i.MX6Q
 	 * document.
 	 */
+#ifdef CONFIG_COLDFIRE
+	fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000);
+#else
 	fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ahb), 5000000);
+#endif
 	if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
 		fep->phy_speed--;
 	fep->phy_speed <<= 1;
@@ -1619,20 +1677,11 @@ fec_probe(struct platform_device *pdev)
 		goto failed_pin;
 	}
 
-	fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
-	if (IS_ERR(fep->clk_ipg)) {
-		ret = PTR_ERR(fep->clk_ipg);
-		goto failed_clk;
-	}
 
-	fep->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(fep->clk_ahb)) {
-		ret = PTR_ERR(fep->clk_ahb);
+	if (fec_clk_get(pdev, fep))
 		goto failed_clk;
-	}
 
-	clk_prepare_enable(fep->clk_ahb);
-	clk_prepare_enable(fep->clk_ipg);
+	fec_clk_prepare(fep);
 
 	ret = fec_enet_init(ndev);
 	if (ret)
@@ -1655,8 +1704,7 @@ failed_register:
 	fec_enet_mii_remove(fep);
 failed_mii_init:
 failed_init:
-	clk_disable_unprepare(fep->clk_ahb);
-	clk_disable_unprepare(fep->clk_ipg);
+	fec_clk_disable_unprepare(fep);
 failed_pin:
 failed_clk:
 	for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1689,8 +1737,7 @@ fec_drv_remove(struct platform_device *pdev)
 		if (irq > 0)
 			free_irq(irq, ndev);
 	}
-	clk_disable_unprepare(fep->clk_ahb);
-	clk_disable_unprepare(fep->clk_ipg);
+	fec_clk_disable_unprepare(fep);
 	iounmap(fep->hwp);
 	free_netdev(ndev);
 
@@ -1714,8 +1761,7 @@ fec_suspend(struct device *dev)
 		fec_stop(ndev);
 		netif_device_detach(ndev);
 	}
-	clk_disable_unprepare(fep->clk_ahb);
-	clk_disable_unprepare(fep->clk_ipg);
+	fec_clk_disable_unprepare(fep);
 
 	return 0;
 }
@@ -1726,8 +1772,8 @@ fec_resume(struct device *dev)
 	struct net_device *ndev = dev_get_drvdata(dev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
-	clk_prepare_enable(fep->clk_ahb);
-	clk_prepare_enable(fep->clk_ipg);
+	fec_clk_prepare(fep);
+
 	if (netif_running(ndev)) {
 		fec_restart(ndev, fep->full_duplex);
 		netif_device_attach(ndev);

Re: [PATCH v3] fec: fix clk handling for Coldfire.

From: David Miller <davem@davemloft.net>
Date: 2012-06-17 23:47:04

From: Steven King <redacted>
Date: Sun, 17 Jun 2012 16:39:43 -0700
commit f4d40de39a23f0c39cca55ac63e1175c69c3d2f7
'net fec: do not depend on grouped clocks' broke fec for Coldfire.

Hide the details of the fec clk management in a trio of new functions: 
fec_clk_get, fec_clk_prepare and fec_clk_disable_unprepare.  these then can 
be modified as needed to manage the clks for the different arches that use
the fec controller.

Signed-off-by: Steven King <redacted>
I said keep the ifdefs out of the foo.c code.

Put this ifdef'y into one of the driver's header files, such
as fec.h
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help