diff options
author | Mark A. Greer <mgreer@animalcreek.com> | 2012-07-20 11:19:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-22 15:46:42 -0400 |
commit | 3ba97381343b271296487bf073eb670d5465a8b8 (patch) | |
tree | 21eac53adab4e3bc2a43087329499c297e1d2412 /drivers/net/ethernet/ti/davinci_emac.c | |
parent | c6f0b4ea64bfd37c5aec05e87bd5596788007aa5 (diff) |
net: ethernet: davinci_emac: add pm_runtime support
Add pm_runtime support to the TI Davinci EMAC driver.
CC: Sekhar Nori <nsekhar@ti.com>
CC: Kevin Hilman <khilman@ti.com>
Signed-off-by: Mark A. Greer <mgreer@animalcreek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/davinci_emac.c')
-rw-r--r-- | drivers/net/ethernet/ti/davinci_emac.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 1a9c43f2755..fce89a0ab06 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/bitops.h> | 57 | #include <linux/bitops.h> |
58 | #include <linux/io.h> | 58 | #include <linux/io.h> |
59 | #include <linux/uaccess.h> | 59 | #include <linux/uaccess.h> |
60 | #include <linux/pm_runtime.h> | ||
60 | #include <linux/davinci_emac.h> | 61 | #include <linux/davinci_emac.h> |
61 | #include <linux/of.h> | 62 | #include <linux/of.h> |
62 | #include <linux/of_address.h> | 63 | #include <linux/of_address.h> |
@@ -353,10 +354,6 @@ struct emac_priv { | |||
353 | void (*int_disable) (void); | 354 | void (*int_disable) (void); |
354 | }; | 355 | }; |
355 | 356 | ||
356 | /* clock frequency for EMAC */ | ||
357 | static struct clk *emac_clk; | ||
358 | static unsigned long emac_bus_frequency; | ||
359 | |||
360 | /* EMAC TX Host Error description strings */ | 357 | /* EMAC TX Host Error description strings */ |
361 | static char *emac_txhost_errcodes[16] = { | 358 | static char *emac_txhost_errcodes[16] = { |
362 | "No error", "SOP error", "Ownership bit not set in SOP buffer", | 359 | "No error", "SOP error", "Ownership bit not set in SOP buffer", |
@@ -1540,6 +1537,8 @@ static int emac_dev_open(struct net_device *ndev) | |||
1540 | int k = 0; | 1537 | int k = 0; |
1541 | struct emac_priv *priv = netdev_priv(ndev); | 1538 | struct emac_priv *priv = netdev_priv(ndev); |
1542 | 1539 | ||
1540 | pm_runtime_get(&priv->pdev->dev); | ||
1541 | |||
1543 | netif_carrier_off(ndev); | 1542 | netif_carrier_off(ndev); |
1544 | for (cnt = 0; cnt < ETH_ALEN; cnt++) | 1543 | for (cnt = 0; cnt < ETH_ALEN; cnt++) |
1545 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; | 1544 | ndev->dev_addr[cnt] = priv->mac_addr[cnt]; |
@@ -1609,7 +1608,7 @@ static int emac_dev_open(struct net_device *ndev) | |||
1609 | priv->phy_id); | 1608 | priv->phy_id); |
1610 | ret = PTR_ERR(priv->phydev); | 1609 | ret = PTR_ERR(priv->phydev); |
1611 | priv->phydev = NULL; | 1610 | priv->phydev = NULL; |
1612 | return ret; | 1611 | goto err; |
1613 | } | 1612 | } |
1614 | 1613 | ||
1615 | priv->link = 0; | 1614 | priv->link = 0; |
@@ -1650,7 +1649,11 @@ rollback: | |||
1650 | res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1); | 1649 | res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1); |
1651 | m = res->end; | 1650 | m = res->end; |
1652 | } | 1651 | } |
1653 | return -EBUSY; | 1652 | |
1653 | ret = -EBUSY; | ||
1654 | err: | ||
1655 | pm_runtime_put(&priv->pdev->dev); | ||
1656 | return ret; | ||
1654 | } | 1657 | } |
1655 | 1658 | ||
1656 | /** | 1659 | /** |
@@ -1692,6 +1695,7 @@ static int emac_dev_stop(struct net_device *ndev) | |||
1692 | if (netif_msg_drv(priv)) | 1695 | if (netif_msg_drv(priv)) |
1693 | dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name); | 1696 | dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name); |
1694 | 1697 | ||
1698 | pm_runtime_put(&priv->pdev->dev); | ||
1695 | return 0; | 1699 | return 0; |
1696 | } | 1700 | } |
1697 | 1701 | ||
@@ -1856,6 +1860,9 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
1856 | struct emac_platform_data *pdata; | 1860 | struct emac_platform_data *pdata; |
1857 | struct device *emac_dev; | 1861 | struct device *emac_dev; |
1858 | struct cpdma_params dma_params; | 1862 | struct cpdma_params dma_params; |
1863 | struct clk *emac_clk; | ||
1864 | unsigned long emac_bus_frequency; | ||
1865 | |||
1859 | 1866 | ||
1860 | /* obtain emac clock from kernel */ | 1867 | /* obtain emac clock from kernel */ |
1861 | emac_clk = clk_get(&pdev->dev, NULL); | 1868 | emac_clk = clk_get(&pdev->dev, NULL); |
@@ -1864,12 +1871,14 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
1864 | return -EBUSY; | 1871 | return -EBUSY; |
1865 | } | 1872 | } |
1866 | emac_bus_frequency = clk_get_rate(emac_clk); | 1873 | emac_bus_frequency = clk_get_rate(emac_clk); |
1874 | clk_put(emac_clk); | ||
1875 | |||
1867 | /* TODO: Probe PHY here if possible */ | 1876 | /* TODO: Probe PHY here if possible */ |
1868 | 1877 | ||
1869 | ndev = alloc_etherdev(sizeof(struct emac_priv)); | 1878 | ndev = alloc_etherdev(sizeof(struct emac_priv)); |
1870 | if (!ndev) { | 1879 | if (!ndev) { |
1871 | rc = -ENOMEM; | 1880 | rc = -ENOMEM; |
1872 | goto free_clk; | 1881 | goto no_ndev; |
1873 | } | 1882 | } |
1874 | 1883 | ||
1875 | platform_set_drvdata(pdev, ndev); | 1884 | platform_set_drvdata(pdev, ndev); |
@@ -1985,15 +1994,13 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
1985 | SET_ETHTOOL_OPS(ndev, ðtool_ops); | 1994 | SET_ETHTOOL_OPS(ndev, ðtool_ops); |
1986 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); | 1995 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); |
1987 | 1996 | ||
1988 | clk_enable(emac_clk); | ||
1989 | |||
1990 | /* register the network device */ | 1997 | /* register the network device */ |
1991 | SET_NETDEV_DEV(ndev, &pdev->dev); | 1998 | SET_NETDEV_DEV(ndev, &pdev->dev); |
1992 | rc = register_netdev(ndev); | 1999 | rc = register_netdev(ndev); |
1993 | if (rc) { | 2000 | if (rc) { |
1994 | dev_err(&pdev->dev, "error in register_netdev\n"); | 2001 | dev_err(&pdev->dev, "error in register_netdev\n"); |
1995 | rc = -ENODEV; | 2002 | rc = -ENODEV; |
1996 | goto netdev_reg_err; | 2003 | goto no_irq_res; |
1997 | } | 2004 | } |
1998 | 2005 | ||
1999 | 2006 | ||
@@ -2002,10 +2009,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) | |||
2002 | "(regs: %p, irq: %d)\n", | 2009 | "(regs: %p, irq: %d)\n", |
2003 | (void *)priv->emac_base_phys, ndev->irq); | 2010 | (void *)priv->emac_base_phys, ndev->irq); |
2004 | } | 2011 | } |
2012 | |||
2013 | pm_runtime_enable(&pdev->dev); | ||
2014 | pm_runtime_resume(&pdev->dev); | ||
2015 | |||
2005 | return 0; | 2016 | return 0; |
2006 | 2017 | ||
2007 | netdev_reg_err: | ||
2008 | clk_disable(emac_clk); | ||
2009 | no_irq_res: | 2018 | no_irq_res: |
2010 | if (priv->txchan) | 2019 | if (priv->txchan) |
2011 | cpdma_chan_destroy(priv->txchan); | 2020 | cpdma_chan_destroy(priv->txchan); |
@@ -2019,8 +2028,7 @@ no_dma: | |||
2019 | 2028 | ||
2020 | probe_quit: | 2029 | probe_quit: |
2021 | free_netdev(ndev); | 2030 | free_netdev(ndev); |
2022 | free_clk: | 2031 | no_ndev: |
2023 | clk_put(emac_clk); | ||
2024 | return rc; | 2032 | return rc; |
2025 | } | 2033 | } |
2026 | 2034 | ||
@@ -2054,9 +2062,6 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) | |||
2054 | iounmap(priv->remap_addr); | 2062 | iounmap(priv->remap_addr); |
2055 | free_netdev(ndev); | 2063 | free_netdev(ndev); |
2056 | 2064 | ||
2057 | clk_disable(emac_clk); | ||
2058 | clk_put(emac_clk); | ||
2059 | |||
2060 | return 0; | 2065 | return 0; |
2061 | } | 2066 | } |
2062 | 2067 | ||
@@ -2068,8 +2073,6 @@ static int davinci_emac_suspend(struct device *dev) | |||
2068 | if (netif_running(ndev)) | 2073 | if (netif_running(ndev)) |
2069 | emac_dev_stop(ndev); | 2074 | emac_dev_stop(ndev); |
2070 | 2075 | ||
2071 | clk_disable(emac_clk); | ||
2072 | |||
2073 | return 0; | 2076 | return 0; |
2074 | } | 2077 | } |
2075 | 2078 | ||
@@ -2078,8 +2081,6 @@ static int davinci_emac_resume(struct device *dev) | |||
2078 | struct platform_device *pdev = to_platform_device(dev); | 2081 | struct platform_device *pdev = to_platform_device(dev); |
2079 | struct net_device *ndev = platform_get_drvdata(pdev); | 2082 | struct net_device *ndev = platform_get_drvdata(pdev); |
2080 | 2083 | ||
2081 | clk_enable(emac_clk); | ||
2082 | |||
2083 | if (netif_running(ndev)) | 2084 | if (netif_running(ndev)) |
2084 | emac_dev_open(ndev); | 2085 | emac_dev_open(ndev); |
2085 | 2086 | ||