Skip to content

Commit e8fcfcd

Browse files
Nimrod Andydavem330
authored andcommitted
net: fec: optimize the clock management to save power
Add below clock management to save fec power: - After probe, disable all clocks incluing ipg, ahb, enet_out, ptp clock. - Open ethx interface enable necessary clocks. Close ethx interface disable all clocks. The patch also encapsulates the all enet clocks enable/disable to .fec_enet_clk_enable(), which can reduce the repetitional code in driver. Signed-off-by: Fugang Duan <[email protected]> Acked-by: Frank Li <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fddb887 commit e8fcfcd

File tree

1 file changed

+56
-64
lines changed

1 file changed

+56
-64
lines changed

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,49 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
12551255
return 0;
12561256
}
12571257

1258+
static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
1259+
{
1260+
struct fec_enet_private *fep = netdev_priv(ndev);
1261+
int ret;
1262+
1263+
if (enable) {
1264+
ret = clk_prepare_enable(fep->clk_ahb);
1265+
if (ret)
1266+
return ret;
1267+
ret = clk_prepare_enable(fep->clk_ipg);
1268+
if (ret)
1269+
goto failed_clk_ipg;
1270+
if (fep->clk_enet_out) {
1271+
ret = clk_prepare_enable(fep->clk_enet_out);
1272+
if (ret)
1273+
goto failed_clk_enet_out;
1274+
}
1275+
if (fep->clk_ptp) {
1276+
ret = clk_prepare_enable(fep->clk_ptp);
1277+
if (ret)
1278+
goto failed_clk_ptp;
1279+
}
1280+
} else {
1281+
clk_disable_unprepare(fep->clk_ahb);
1282+
clk_disable_unprepare(fep->clk_ipg);
1283+
if (fep->clk_enet_out)
1284+
clk_disable_unprepare(fep->clk_enet_out);
1285+
if (fep->clk_ptp)
1286+
clk_disable_unprepare(fep->clk_ptp);
1287+
}
1288+
1289+
return 0;
1290+
failed_clk_ptp:
1291+
if (fep->clk_enet_out)
1292+
clk_disable_unprepare(fep->clk_enet_out);
1293+
failed_clk_enet_out:
1294+
clk_disable_unprepare(fep->clk_ipg);
1295+
failed_clk_ipg:
1296+
clk_disable_unprepare(fep->clk_ahb);
1297+
1298+
return ret;
1299+
}
1300+
12581301
static int fec_enet_mii_probe(struct net_device *ndev)
12591302
{
12601303
struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1773,6 +1816,10 @@ fec_enet_open(struct net_device *ndev)
17731816
struct fec_enet_private *fep = netdev_priv(ndev);
17741817
int ret;
17751818

1819+
ret = fec_enet_clk_enable(ndev, true);
1820+
if (ret)
1821+
return ret;
1822+
17761823
/* I should reset the ring buffers here, but I don't yet know
17771824
* a simple way to do that.
17781825
*/
@@ -1811,6 +1858,7 @@ fec_enet_close(struct net_device *ndev)
18111858
phy_disconnect(fep->phy_dev);
18121859
}
18131860

1861+
fec_enet_clk_enable(ndev, false);
18141862
fec_enet_free_buffers(ndev);
18151863

18161864
return 0;
@@ -2164,26 +2212,10 @@ fec_probe(struct platform_device *pdev)
21642212
fep->bufdesc_ex = 0;
21652213
}
21662214

2167-
ret = clk_prepare_enable(fep->clk_ahb);
2215+
ret = fec_enet_clk_enable(ndev, true);
21682216
if (ret)
21692217
goto failed_clk;
21702218

2171-
ret = clk_prepare_enable(fep->clk_ipg);
2172-
if (ret)
2173-
goto failed_clk_ipg;
2174-
2175-
if (fep->clk_enet_out) {
2176-
ret = clk_prepare_enable(fep->clk_enet_out);
2177-
if (ret)
2178-
goto failed_clk_enet_out;
2179-
}
2180-
2181-
if (fep->clk_ptp) {
2182-
ret = clk_prepare_enable(fep->clk_ptp);
2183-
if (ret)
2184-
goto failed_clk_ptp;
2185-
}
2186-
21872219
fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
21882220
if (!IS_ERR(fep->reg_phy)) {
21892221
ret = regulator_enable(fep->reg_phy);
@@ -2225,6 +2257,7 @@ fec_probe(struct platform_device *pdev)
22252257

22262258
/* Carrier starts down, phylib will bring it up */
22272259
netif_carrier_off(ndev);
2260+
fec_enet_clk_enable(ndev, false);
22282261

22292262
ret = register_netdev(ndev);
22302263
if (ret)
@@ -2244,15 +2277,7 @@ fec_probe(struct platform_device *pdev)
22442277
if (fep->reg_phy)
22452278
regulator_disable(fep->reg_phy);
22462279
failed_regulator:
2247-
if (fep->clk_ptp)
2248-
clk_disable_unprepare(fep->clk_ptp);
2249-
failed_clk_ptp:
2250-
if (fep->clk_enet_out)
2251-
clk_disable_unprepare(fep->clk_enet_out);
2252-
failed_clk_enet_out:
2253-
clk_disable_unprepare(fep->clk_ipg);
2254-
failed_clk_ipg:
2255-
clk_disable_unprepare(fep->clk_ahb);
2280+
fec_enet_clk_enable(ndev, false);
22562281
failed_clk:
22572282
failed_ioremap:
22582283
free_netdev(ndev);
@@ -2272,14 +2297,9 @@ fec_drv_remove(struct platform_device *pdev)
22722297
del_timer_sync(&fep->time_keep);
22732298
if (fep->reg_phy)
22742299
regulator_disable(fep->reg_phy);
2275-
if (fep->clk_ptp)
2276-
clk_disable_unprepare(fep->clk_ptp);
22772300
if (fep->ptp_clock)
22782301
ptp_clock_unregister(fep->ptp_clock);
2279-
if (fep->clk_enet_out)
2280-
clk_disable_unprepare(fep->clk_enet_out);
2281-
clk_disable_unprepare(fep->clk_ipg);
2282-
clk_disable_unprepare(fep->clk_ahb);
2302+
fec_enet_clk_enable(ndev, false);
22832303
free_netdev(ndev);
22842304

22852305
return 0;
@@ -2296,12 +2316,7 @@ fec_suspend(struct device *dev)
22962316
fec_stop(ndev);
22972317
netif_device_detach(ndev);
22982318
}
2299-
if (fep->clk_ptp)
2300-
clk_disable_unprepare(fep->clk_ptp);
2301-
if (fep->clk_enet_out)
2302-
clk_disable_unprepare(fep->clk_enet_out);
2303-
clk_disable_unprepare(fep->clk_ipg);
2304-
clk_disable_unprepare(fep->clk_ahb);
2319+
fec_enet_clk_enable(ndev, false);
23052320

23062321
if (fep->reg_phy)
23072322
regulator_disable(fep->reg_phy);
@@ -2322,25 +2337,9 @@ fec_resume(struct device *dev)
23222337
return ret;
23232338
}
23242339

2325-
ret = clk_prepare_enable(fep->clk_ahb);
2326-
if (ret)
2327-
goto failed_clk_ahb;
2328-
2329-
ret = clk_prepare_enable(fep->clk_ipg);
2340+
ret = fec_enet_clk_enable(ndev, true);
23302341
if (ret)
2331-
goto failed_clk_ipg;
2332-
2333-
if (fep->clk_enet_out) {
2334-
ret = clk_prepare_enable(fep->clk_enet_out);
2335-
if (ret)
2336-
goto failed_clk_enet_out;
2337-
}
2338-
2339-
if (fep->clk_ptp) {
2340-
ret = clk_prepare_enable(fep->clk_ptp);
2341-
if (ret)
2342-
goto failed_clk_ptp;
2343-
}
2342+
goto failed_clk;
23442343

23452344
if (netif_running(ndev)) {
23462345
fec_restart(ndev, fep->full_duplex);
@@ -2349,14 +2348,7 @@ fec_resume(struct device *dev)
23492348

23502349
return 0;
23512350

2352-
failed_clk_ptp:
2353-
if (fep->clk_enet_out)
2354-
clk_disable_unprepare(fep->clk_enet_out);
2355-
failed_clk_enet_out:
2356-
clk_disable_unprepare(fep->clk_ipg);
2357-
failed_clk_ipg:
2358-
clk_disable_unprepare(fep->clk_ahb);
2359-
failed_clk_ahb:
2351+
failed_clk:
23602352
if (fep->reg_phy)
23612353
regulator_disable(fep->reg_phy);
23622354
return ret;

0 commit comments

Comments
 (0)