aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-07-21 18:29:22 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-21 19:04:30 -0400
commitb6e978e50444a063f066f058d134173de877b968 (patch)
treedbf1782c10978273644fdcdae276ea90789e511c
parent909ff5efbab85f2724c5f91ec200ebc9df50c440 (diff)
net: bcmgenet: add suspend/resume callbacks
Implement suspend/resume callbacks in the GENET driver. This makes sure that we de-initialize and re-initialize the hardware correctly before entering suspend and when resuming. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/genet/bcmgenet.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 5cab188ee323..bbd8bf326a35 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2584,6 +2584,100 @@ static int bcmgenet_remove(struct platform_device *pdev)
2584 return 0; 2584 return 0;
2585} 2585}
2586 2586
2587#ifdef CONFIG_PM_SLEEP
2588static int bcmgenet_suspend(struct device *d)
2589{
2590 struct net_device *dev = dev_get_drvdata(d);
2591 struct bcmgenet_priv *priv = netdev_priv(dev);
2592 int ret;
2593
2594 if (!netif_running(dev))
2595 return 0;
2596
2597 bcmgenet_netif_stop(dev);
2598
2599 netif_device_detach(dev);
2600
2601 /* Disable MAC receive */
2602 umac_enable_set(priv, CMD_RX_EN, false);
2603
2604 ret = bcmgenet_dma_teardown(priv);
2605 if (ret)
2606 return ret;
2607
2608 /* Disable MAC transmit. TX DMA disabled have to done before this */
2609 umac_enable_set(priv, CMD_TX_EN, false);
2610
2611 /* tx reclaim */
2612 bcmgenet_tx_reclaim_all(dev);
2613 bcmgenet_fini_dma(priv);
2614
2615 /* Turn off the clocks */
2616 clk_disable_unprepare(priv->clk);
2617
2618 return 0;
2619}
2620
2621static int bcmgenet_resume(struct device *d)
2622{
2623 struct net_device *dev = dev_get_drvdata(d);
2624 struct bcmgenet_priv *priv = netdev_priv(dev);
2625 unsigned long dma_ctrl;
2626 int ret;
2627 u32 reg;
2628
2629 if (!netif_running(dev))
2630 return 0;
2631
2632 /* Turn on the clock */
2633 ret = clk_prepare_enable(priv->clk);
2634 if (ret)
2635 return ret;
2636
2637 bcmgenet_umac_reset(priv);
2638
2639 ret = init_umac(priv);
2640 if (ret)
2641 goto out_clk_disable;
2642
2643 /* disable ethernet MAC while updating its registers */
2644 umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, false);
2645
2646 bcmgenet_set_hw_addr(priv, dev->dev_addr);
2647
2648 if (phy_is_internal(priv->phydev)) {
2649 reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
2650 reg |= EXT_ENERGY_DET_MASK;
2651 bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
2652 }
2653
2654 /* Disable RX/TX DMA and flush TX queues */
2655 dma_ctrl = bcmgenet_dma_disable(priv);
2656
2657 /* Reinitialize TDMA and RDMA and SW housekeeping */
2658 ret = bcmgenet_init_dma(priv);
2659 if (ret) {
2660 netdev_err(dev, "failed to initialize DMA\n");
2661 goto out_clk_disable;
2662 }
2663
2664 /* Always enable ring 16 - descriptor ring */
2665 bcmgenet_enable_dma(priv, dma_ctrl);
2666
2667 netif_device_attach(dev);
2668
2669 bcmgenet_netif_start(dev);
2670
2671 return 0;
2672
2673out_clk_disable:
2674 clk_disable_unprepare(priv->clk);
2675 return ret;
2676}
2677#endif /* CONFIG_PM_SLEEP */
2678
2679static SIMPLE_DEV_PM_OPS(bcmgenet_pm_ops, bcmgenet_suspend, bcmgenet_resume);
2680
2587static struct platform_driver bcmgenet_driver = { 2681static struct platform_driver bcmgenet_driver = {
2588 .probe = bcmgenet_probe, 2682 .probe = bcmgenet_probe,
2589 .remove = bcmgenet_remove, 2683 .remove = bcmgenet_remove,
@@ -2591,6 +2685,7 @@ static struct platform_driver bcmgenet_driver = {
2591 .name = "bcmgenet", 2685 .name = "bcmgenet",
2592 .owner = THIS_MODULE, 2686 .owner = THIS_MODULE,
2593 .of_match_table = bcmgenet_match, 2687 .of_match_table = bcmgenet_match,
2688 .pm = &bcmgenet_pm_ops,
2594 }, 2689 },
2595}; 2690};
2596module_platform_driver(bcmgenet_driver); 2691module_platform_driver(bcmgenet_driver);