Skip to content

Commit d54f89a

Browse files
harini-katakamdavem330
authored andcommitted
net: macb: Add pm runtime support
Add runtime pm functions and move clock handling there. Add runtime PM calls to mdio functions to allow for active mdio bus. Signed-off-by: Shubhrajyoti Datta <[email protected]> Signed-off-by: Harini Katakam <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f5473d1 commit d54f89a

File tree

1 file changed

+112
-36
lines changed

1 file changed

+112
-36
lines changed

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 112 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <linux/udp.h>
3838
#include <linux/tcp.h>
3939
#include <linux/iopoll.h>
40+
#include <linux/pm_runtime.h>
4041
#include "macb.h"
4142

4243
#define MACB_RX_BUFFER_SIZE 128
@@ -80,6 +81,8 @@
8081
*/
8182
#define MACB_HALT_TIMEOUT 1230
8283

84+
#define MACB_PM_TIMEOUT 100 /* ms */
85+
8386
#define MACB_MDIO_TIMEOUT 1000000 /* in usecs */
8487

8588
/* DMA buffer descriptor might be different size
@@ -332,37 +335,48 @@ static int macb_mdio_wait_for_idle(struct macb *bp)
332335
static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
333336
{
334337
struct macb *bp = bus->priv;
335-
int value;
336-
int err;
338+
int status;
337339

338-
err = macb_mdio_wait_for_idle(bp);
339-
if (err < 0)
340-
return err;
340+
status = pm_runtime_get_sync(&bp->pdev->dev);
341+
if (status < 0)
342+
goto mdio_pm_exit;
343+
344+
status = macb_mdio_wait_for_idle(bp);
345+
if (status < 0)
346+
goto mdio_read_exit;
341347

342348
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
343349
| MACB_BF(RW, MACB_MAN_READ)
344350
| MACB_BF(PHYA, mii_id)
345351
| MACB_BF(REGA, regnum)
346352
| MACB_BF(CODE, MACB_MAN_CODE)));
347353

348-
err = macb_mdio_wait_for_idle(bp);
349-
if (err < 0)
350-
return err;
354+
status = macb_mdio_wait_for_idle(bp);
355+
if (status < 0)
356+
goto mdio_read_exit;
351357

352-
value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
358+
status = MACB_BFEXT(DATA, macb_readl(bp, MAN));
353359

354-
return value;
360+
mdio_read_exit:
361+
pm_runtime_mark_last_busy(&bp->pdev->dev);
362+
pm_runtime_put_autosuspend(&bp->pdev->dev);
363+
mdio_pm_exit:
364+
return status;
355365
}
356366

357367
static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
358368
u16 value)
359369
{
360370
struct macb *bp = bus->priv;
361-
int err;
371+
int status;
362372

363-
err = macb_mdio_wait_for_idle(bp);
364-
if (err < 0)
365-
return err;
373+
status = pm_runtime_get_sync(&bp->pdev->dev);
374+
if (status < 0)
375+
goto mdio_pm_exit;
376+
377+
status = macb_mdio_wait_for_idle(bp);
378+
if (status < 0)
379+
goto mdio_write_exit;
366380

367381
macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
368382
| MACB_BF(RW, MACB_MAN_WRITE)
@@ -371,11 +385,15 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
371385
| MACB_BF(CODE, MACB_MAN_CODE)
372386
| MACB_BF(DATA, value)));
373387

374-
err = macb_mdio_wait_for_idle(bp);
375-
if (err < 0)
376-
return err;
388+
status = macb_mdio_wait_for_idle(bp);
389+
if (status < 0)
390+
goto mdio_write_exit;
377391

378-
return 0;
392+
mdio_write_exit:
393+
pm_runtime_mark_last_busy(&bp->pdev->dev);
394+
pm_runtime_put_autosuspend(&bp->pdev->dev);
395+
mdio_pm_exit:
396+
return status;
379397
}
380398

381399
/**
@@ -2418,12 +2436,18 @@ static int macb_open(struct net_device *dev)
24182436

24192437
netdev_dbg(bp->dev, "open\n");
24202438

2439+
err = pm_runtime_get_sync(&bp->pdev->dev);
2440+
if (err < 0)
2441+
goto pm_exit;
2442+
24212443
/* carrier starts down */
24222444
netif_carrier_off(dev);
24232445

24242446
/* if the phy is not yet register, retry later*/
2425-
if (!dev->phydev)
2426-
return -EAGAIN;
2447+
if (!dev->phydev) {
2448+
err = -EAGAIN;
2449+
goto pm_exit;
2450+
}
24272451

24282452
/* RX buffers initialization */
24292453
macb_init_rx_buffer_size(bp, bufsz);
@@ -2432,7 +2456,7 @@ static int macb_open(struct net_device *dev)
24322456
if (err) {
24332457
netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
24342458
err);
2435-
return err;
2459+
goto pm_exit;
24362460
}
24372461

24382462
bp->macbgem_ops.mog_init_rings(bp);
@@ -2449,6 +2473,11 @@ static int macb_open(struct net_device *dev)
24492473
if (bp->ptp_info)
24502474
bp->ptp_info->ptp_init(dev);
24512475

2476+
pm_exit:
2477+
if (err) {
2478+
pm_runtime_put_sync(&bp->pdev->dev);
2479+
return err;
2480+
}
24522481
return 0;
24532482
}
24542483

@@ -2477,6 +2506,8 @@ static int macb_close(struct net_device *dev)
24772506
if (bp->ptp_info)
24782507
bp->ptp_info->ptp_remove(dev);
24792508

2509+
pm_runtime_put(&bp->pdev->dev);
2510+
24802511
return 0;
24812512
}
24822513

@@ -4043,6 +4074,11 @@ static int macb_probe(struct platform_device *pdev)
40434074
if (err)
40444075
return err;
40454076

4077+
pm_runtime_set_autosuspend_delay(&pdev->dev, MACB_PM_TIMEOUT);
4078+
pm_runtime_use_autosuspend(&pdev->dev);
4079+
pm_runtime_get_noresume(&pdev->dev);
4080+
pm_runtime_set_active(&pdev->dev);
4081+
pm_runtime_enable(&pdev->dev);
40464082
native_io = hw_is_native_io(mem);
40474083

40484084
macb_probe_queues(mem, native_io, &queue_mask, &num_queues);
@@ -4178,6 +4214,9 @@ static int macb_probe(struct platform_device *pdev)
41784214
macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
41794215
dev->base_addr, dev->irq, dev->dev_addr);
41804216

4217+
pm_runtime_mark_last_busy(&bp->pdev->dev);
4218+
pm_runtime_put_autosuspend(&bp->pdev->dev);
4219+
41814220
return 0;
41824221

41834222
err_out_unregister_mdio:
@@ -4197,6 +4236,9 @@ static int macb_probe(struct platform_device *pdev)
41974236
clk_disable_unprepare(pclk);
41984237
clk_disable_unprepare(rx_clk);
41994238
clk_disable_unprepare(tsu_clk);
4239+
pm_runtime_disable(&pdev->dev);
4240+
pm_runtime_set_suspended(&pdev->dev);
4241+
pm_runtime_dont_use_autosuspend(&pdev->dev);
42004242

42014243
return err;
42024244
}
@@ -4220,11 +4262,16 @@ static int macb_remove(struct platform_device *pdev)
42204262
mdiobus_free(bp->mii_bus);
42214263

42224264
unregister_netdev(dev);
4223-
clk_disable_unprepare(bp->tx_clk);
4224-
clk_disable_unprepare(bp->hclk);
4225-
clk_disable_unprepare(bp->pclk);
4226-
clk_disable_unprepare(bp->rx_clk);
4227-
clk_disable_unprepare(bp->tsu_clk);
4265+
pm_runtime_disable(&pdev->dev);
4266+
pm_runtime_dont_use_autosuspend(&pdev->dev);
4267+
if (!pm_runtime_suspended(&pdev->dev)) {
4268+
clk_disable_unprepare(bp->tx_clk);
4269+
clk_disable_unprepare(bp->hclk);
4270+
clk_disable_unprepare(bp->pclk);
4271+
clk_disable_unprepare(bp->rx_clk);
4272+
clk_disable_unprepare(bp->tsu_clk);
4273+
pm_runtime_set_suspended(&pdev->dev);
4274+
}
42284275
of_node_put(bp->phy_node);
42294276
free_netdev(dev);
42304277
}
@@ -4244,13 +4291,9 @@ static int __maybe_unused macb_suspend(struct device *dev)
42444291
macb_writel(bp, IER, MACB_BIT(WOL));
42454292
macb_writel(bp, WOL, MACB_BIT(MAG));
42464293
enable_irq_wake(bp->queues[0].irq);
4247-
} else {
4248-
clk_disable_unprepare(bp->tx_clk);
4249-
clk_disable_unprepare(bp->hclk);
4250-
clk_disable_unprepare(bp->pclk);
4251-
clk_disable_unprepare(bp->rx_clk);
42524294
}
4253-
clk_disable_unprepare(bp->tsu_clk);
4295+
4296+
pm_runtime_force_suspend(dev);
42544297

42554298
return 0;
42564299
}
@@ -4260,24 +4303,57 @@ static int __maybe_unused macb_resume(struct device *dev)
42604303
struct net_device *netdev = dev_get_drvdata(dev);
42614304
struct macb *bp = netdev_priv(netdev);
42624305

4306+
pm_runtime_force_resume(dev);
4307+
42634308
if (bp->wol & MACB_WOL_ENABLED) {
42644309
macb_writel(bp, IDR, MACB_BIT(WOL));
42654310
macb_writel(bp, WOL, 0);
42664311
disable_irq_wake(bp->queues[0].irq);
4267-
} else {
4312+
}
4313+
4314+
netif_device_attach(netdev);
4315+
4316+
return 0;
4317+
}
4318+
4319+
static int __maybe_unused macb_runtime_suspend(struct device *dev)
4320+
{
4321+
struct platform_device *pdev = to_platform_device(dev);
4322+
struct net_device *netdev = platform_get_drvdata(pdev);
4323+
struct macb *bp = netdev_priv(netdev);
4324+
4325+
if (!(device_may_wakeup(&bp->dev->dev))) {
4326+
clk_disable_unprepare(bp->tx_clk);
4327+
clk_disable_unprepare(bp->hclk);
4328+
clk_disable_unprepare(bp->pclk);
4329+
clk_disable_unprepare(bp->rx_clk);
4330+
}
4331+
clk_disable_unprepare(bp->tsu_clk);
4332+
4333+
return 0;
4334+
}
4335+
4336+
static int __maybe_unused macb_runtime_resume(struct device *dev)
4337+
{
4338+
struct platform_device *pdev = to_platform_device(dev);
4339+
struct net_device *netdev = platform_get_drvdata(pdev);
4340+
struct macb *bp = netdev_priv(netdev);
4341+
4342+
if (!(device_may_wakeup(&bp->dev->dev))) {
42684343
clk_prepare_enable(bp->pclk);
42694344
clk_prepare_enable(bp->hclk);
42704345
clk_prepare_enable(bp->tx_clk);
42714346
clk_prepare_enable(bp->rx_clk);
42724347
}
42734348
clk_prepare_enable(bp->tsu_clk);
42744349

4275-
netif_device_attach(netdev);
4276-
42774350
return 0;
42784351
}
42794352

4280-
static SIMPLE_DEV_PM_OPS(macb_pm_ops, macb_suspend, macb_resume);
4353+
static const struct dev_pm_ops macb_pm_ops = {
4354+
SET_SYSTEM_SLEEP_PM_OPS(macb_suspend, macb_resume)
4355+
SET_RUNTIME_PM_OPS(macb_runtime_suspend, macb_runtime_resume, NULL)
4356+
};
42814357

42824358
static struct platform_driver macb_driver = {
42834359
.probe = macb_probe,

0 commit comments

Comments
 (0)