net: freescale: fec: add support for optional enet_out clk
authorWolfram Sang <w.sang@pengutronix.de>
Tue, 29 Jan 2013 14:46:11 +0000 (15:46 +0100)
committerShawn Guo <shawn.guo@linaro.org>
Thu, 4 Apr 2013 13:22:40 +0000 (21:22 +0800)
Some MX28 boards need the internal enet_out clock to be enabled. So, do
this in the driver iff the clock was referenced via devicetree.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec.h

index 6d965bb3290837f120f003a01e9d51fb40f66af5..dd098ea44d4881543f1ab6b708dc5ce3c767ffe2 100644 (file)
@@ -1802,6 +1802,11 @@ fec_probe(struct platform_device *pdev)
                goto failed_clk;
        }
 
+       /* enet_out is optional, depends on board */
+       fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out");
+       if (IS_ERR(fep->clk_enet_out))
+               fep->clk_enet_out = NULL;
+
        fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
        fep->bufdesc_ex =
                pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
@@ -1812,6 +1817,7 @@ fec_probe(struct platform_device *pdev)
 
        clk_prepare_enable(fep->clk_ahb);
        clk_prepare_enable(fep->clk_ipg);
+       clk_prepare_enable(fep->clk_enet_out);
        clk_prepare_enable(fep->clk_ptp);
 
        reg_phy = devm_regulator_get(&pdev->dev, "phy");
@@ -1877,6 +1883,7 @@ failed_irq:
 failed_regulator:
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
+       clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ptp);
 failed_pin:
 failed_clk:
@@ -1903,6 +1910,7 @@ fec_drv_remove(struct platform_device *pdev)
        clk_disable_unprepare(fep->clk_ptp);
        if (fep->ptp_clock)
                ptp_clock_unregister(fep->ptp_clock);
+       clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
        for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1933,6 +1941,7 @@ fec_suspend(struct device *dev)
                fec_stop(ndev);
                netif_device_detach(ndev);
        }
+       clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
 
@@ -1945,6 +1954,7 @@ 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_enet_out);
        clk_prepare_enable(fep->clk_ahb);
        clk_prepare_enable(fep->clk_ipg);
        if (netif_running(ndev)) {
index eb4372962839c216ed1ad68e29ba09a7aaf487ea..feabcb6a78b43144e31431bdcb2214e8f2a88539 100644 (file)
@@ -207,6 +207,7 @@ struct fec_enet_private {
 
        struct clk *clk_ipg;
        struct clk *clk_ahb;
+       struct clk *clk_enet_out;
        struct clk *clk_ptp;
 
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */