diff options
author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2010-11-23 21:38:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-24 14:14:25 -0500 |
commit | 874bd42d24c2a74f5dbd65e81e175982240fecd8 (patch) | |
tree | 103428754c9212ece589a000db3e79218e6b8d35 /drivers | |
parent | 293bb1c41b728d4aa248fe8a0acd2b9066ff5c34 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/stmmac/stmmac.h | 1 | ||||
-rw-r--r-- | drivers/net/stmmac/stmmac_main.c | 124 |
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 |
1802 | static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) | 1800 | static 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 | ||
1851 | static int stmmac_resume(struct platform_device *pdev) | 1841 | static 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 | ||
1898 | static struct platform_driver stmmac_driver = { | 1888 | static 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 | |||
1898 | static 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 | |||
1908 | static 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 | ||
1916 | static const struct dev_pm_ops stmmac_pm_ops; | ||
1917 | #endif /* CONFIG_PM */ | ||
1908 | 1918 | ||
1919 | static 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 | /** |