aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2010-11-23 21:38:11 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-24 14:14:25 -0500
commit874bd42d24c2a74f5dbd65e81e175982240fecd8 (patch)
tree103428754c9212ece589a000db3e79218e6b8d35
parent293bb1c41b728d4aa248fe8a0acd2b9066ff5c34 (diff)
stmmac: convert to dev_pm_ops.
This patch updates the PM support using the dev_pm_ops and reviews the hibernation support. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/stmmac/stmmac.h1
-rw-r--r--drivers/net/stmmac/stmmac_main.c124
2 files changed, 71 insertions, 54 deletions
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index 8ae76501eb74..eb258e2319e1 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -77,7 +77,6 @@ struct stmmac_priv {
77 spinlock_t lock; 77 spinlock_t lock;
78 int wolopts; 78 int wolopts;
79 int wolenabled; 79 int wolenabled;
80 int shutdown;
81#ifdef CONFIG_STMMAC_TIMER 80#ifdef CONFIG_STMMAC_TIMER
82 struct stmmac_timer *tm; 81 struct stmmac_timer *tm;
83#endif 82#endif
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index b806cd3515b4..f1dbc182c8df 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -844,8 +844,6 @@ static int stmmac_open(struct net_device *dev)
844 if (priv->plat->tx_coe) 844 if (priv->plat->tx_coe)
845 pr_info("\tTX Checksum insertion supported\n"); 845 pr_info("\tTX Checksum insertion supported\n");
846 846
847 priv->shutdown = 0;
848
849 /* Initialise the MMC (if present) to disable all interrupts. */ 847 /* Initialise the MMC (if present) to disable all interrupts. */
850 writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); 848 writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
851 writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); 849 writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
@@ -1799,61 +1797,53 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
1799} 1797}
1800 1798
1801#ifdef CONFIG_PM 1799#ifdef CONFIG_PM
1802static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) 1800static int stmmac_suspend(struct device *dev)
1803{ 1801{
1804 struct net_device *dev = platform_get_drvdata(pdev); 1802 struct net_device *ndev = dev_get_drvdata(dev);
1805 struct stmmac_priv *priv = netdev_priv(dev); 1803 struct stmmac_priv *priv = netdev_priv(ndev);
1806 int dis_ic = 0; 1804 int dis_ic = 0;
1807 1805
1808 if (!dev || !netif_running(dev)) 1806 if (!ndev || !netif_running(ndev))
1809 return 0; 1807 return 0;
1810 1808
1811 spin_lock(&priv->lock); 1809 spin_lock(&priv->lock);
1812 1810
1813 if (state.event == PM_EVENT_SUSPEND) { 1811 netif_device_detach(ndev);
1814 netif_device_detach(dev); 1812 netif_stop_queue(ndev);
1815 netif_stop_queue(dev); 1813 if (priv->phydev)
1816 if (priv->phydev) 1814 phy_stop(priv->phydev);
1817 phy_stop(priv->phydev);
1818 1815
1819#ifdef CONFIG_STMMAC_TIMER 1816#ifdef CONFIG_STMMAC_TIMER
1820 priv->tm->timer_stop(); 1817 priv->tm->timer_stop();
1821 if (likely(priv->tm->enable)) 1818 if (likely(priv->tm->enable))
1822 dis_ic = 1; 1819 dis_ic = 1;
1823#endif 1820#endif
1824 napi_disable(&priv->napi); 1821 napi_disable(&priv->napi);
1825 1822
1826 /* Stop TX/RX DMA */ 1823 /* Stop TX/RX DMA */
1827 priv->hw->dma->stop_tx(priv->ioaddr); 1824 priv->hw->dma->stop_tx(priv->ioaddr);
1828 priv->hw->dma->stop_rx(priv->ioaddr); 1825 priv->hw->dma->stop_rx(priv->ioaddr);
1829 /* Clear the Rx/Tx descriptors */ 1826 /* Clear the Rx/Tx descriptors */
1830 priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, 1827 priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
1831 dis_ic); 1828 dis_ic);
1832 priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); 1829 priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
1833 1830
1834 /* Enable Power down mode by programming the PMT regs */ 1831 /* Enable Power down mode by programming the PMT regs */
1835 if (device_can_wakeup(priv->device)) 1832 if (device_may_wakeup(priv->device))
1836 priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); 1833 priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
1837 else 1834 else
1838 stmmac_disable_mac(priv->ioaddr); 1835 stmmac_disable_mac(priv->ioaddr);
1839 } else {
1840 priv->shutdown = 1;
1841 /* Although this can appear slightly redundant it actually
1842 * makes fast the standby operation and guarantees the driver
1843 * working if hibernation is on media. */
1844 stmmac_release(dev);
1845 }
1846 1836
1847 spin_unlock(&priv->lock); 1837 spin_unlock(&priv->lock);
1848 return 0; 1838 return 0;
1849} 1839}
1850 1840
1851static int stmmac_resume(struct platform_device *pdev) 1841static int stmmac_resume(struct device *dev)
1852{ 1842{
1853 struct net_device *dev = platform_get_drvdata(pdev); 1843 struct net_device *ndev = dev_get_drvdata(dev);
1854 struct stmmac_priv *priv = netdev_priv(dev); 1844 struct stmmac_priv *priv = netdev_priv(ndev);
1855 1845
1856 if (!netif_running(dev)) 1846 if (!netif_running(ndev))
1857 return 0; 1847 return 0;
1858 1848
1859 if (priv->shutdown) { 1849 if (priv->shutdown) {
@@ -1870,10 +1860,10 @@ static int stmmac_resume(struct platform_device *pdev)
1870 * is received. Anyway, it's better to manually clear 1860 * is received. Anyway, it's better to manually clear
1871 * this bit because it can generate problems while resuming 1861 * this bit because it can generate problems while resuming
1872 * from another devices (e.g. serial console). */ 1862 * from another devices (e.g. serial console). */
1873 if (device_can_wakeup(priv->device)) 1863 if (device_may_wakeup(priv->device))
1874 priv->hw->mac->pmt(priv->ioaddr, 0); 1864 priv->hw->mac->pmt(priv->ioaddr, 0);
1875 1865
1876 netif_device_attach(dev); 1866 netif_device_attach(ndev);
1877 1867
1878 /* Enable the MAC and DMA */ 1868 /* Enable the MAC and DMA */
1879 stmmac_enable_mac(priv->ioaddr); 1869 stmmac_enable_mac(priv->ioaddr);
@@ -1881,31 +1871,59 @@ static int stmmac_resume(struct platform_device *pdev)
1881 priv->hw->dma->start_rx(priv->ioaddr); 1871 priv->hw->dma->start_rx(priv->ioaddr);
1882 1872
1883#ifdef CONFIG_STMMAC_TIMER 1873#ifdef CONFIG_STMMAC_TIMER
1884 priv->tm->timer_start(tmrate); 1874 if (likely(priv->tm->enable))
1875 priv->tm->timer_start(tmrate);
1885#endif 1876#endif
1886 napi_enable(&priv->napi); 1877 napi_enable(&priv->napi);
1887 1878
1888 if (priv->phydev) 1879 if (priv->phydev)
1889 phy_start(priv->phydev); 1880 phy_start(priv->phydev);
1890 1881
1891 netif_start_queue(dev); 1882 netif_start_queue(ndev);
1892 1883
1893 spin_unlock(&priv->lock); 1884 spin_unlock(&priv->lock);
1894 return 0; 1885 return 0;
1895} 1886}
1896#endif
1897 1887
1898static struct platform_driver stmmac_driver = { 1888static int stmmac_freeze(struct device *dev)
1899 .driver = { 1889{
1900 .name = STMMAC_RESOURCE_NAME, 1890 struct net_device *ndev = dev_get_drvdata(dev);
1901 }, 1891
1902 .probe = stmmac_dvr_probe, 1892 if (!ndev || !netif_running(ndev))
1903 .remove = stmmac_dvr_remove, 1893 return 0;
1904#ifdef CONFIG_PM 1894
1895 return stmmac_release(ndev);
1896}
1897
1898static int stmmac_restore(struct device *dev)
1899{
1900 struct net_device *ndev = dev_get_drvdata(dev);
1901
1902 if (!ndev || !netif_running(ndev))
1903 return 0;
1904
1905 return stmmac_open(ndev);
1906}
1907
1908static const struct dev_pm_ops stmmac_pm_ops = {
1905 .suspend = stmmac_suspend, 1909 .suspend = stmmac_suspend,
1906 .resume = stmmac_resume, 1910 .resume = stmmac_resume,
1907#endif 1911 .freeze = stmmac_freeze,
1912 .thaw = stmmac_restore,
1913 .restore = stmmac_restore,
1914};
1915#else
1916static const struct dev_pm_ops stmmac_pm_ops;
1917#endif /* CONFIG_PM */
1908 1918
1919static struct platform_driver stmmac_driver = {
1920 .probe = stmmac_dvr_probe,
1921 .remove = stmmac_dvr_remove,
1922 .driver = {
1923 .name = STMMAC_RESOURCE_NAME,
1924 .owner = THIS_MODULE,
1925 .pm = &stmmac_pm_ops,
1926 },
1909}; 1927};
1910 1928
1911/** 1929/**