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>
This commit is contained in:
Giuseppe CAVALLARO 2010-11-24 02:38:11 +00:00 committed by David S. Miller
parent 293bb1c41b
commit 874bd42d24
2 changed files with 69 additions and 52 deletions

View File

@ -77,7 +77,6 @@ struct stmmac_priv {
spinlock_t lock;
int wolopts;
int wolenabled;
int shutdown;
#ifdef CONFIG_STMMAC_TIMER
struct stmmac_timer *tm;
#endif

View File

@ -844,8 +844,6 @@ static int stmmac_open(struct net_device *dev)
if (priv->plat->tx_coe)
pr_info("\tTX Checksum insertion supported\n");
priv->shutdown = 0;
/* Initialise the MMC (if present) to disable all interrupts. */
writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK);
@ -1799,61 +1797,53 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
static int stmmac_suspend(struct device *dev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(dev);
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
int dis_ic = 0;
if (!dev || !netif_running(dev))
if (!ndev || !netif_running(ndev))
return 0;
spin_lock(&priv->lock);
if (state.event == PM_EVENT_SUSPEND) {
netif_device_detach(dev);
netif_stop_queue(dev);
if (priv->phydev)
phy_stop(priv->phydev);
netif_device_detach(ndev);
netif_stop_queue(ndev);
if (priv->phydev)
phy_stop(priv->phydev);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_stop();
if (likely(priv->tm->enable))
dis_ic = 1;
priv->tm->timer_stop();
if (likely(priv->tm->enable))
dis_ic = 1;
#endif
napi_disable(&priv->napi);
napi_disable(&priv->napi);
/* Stop TX/RX DMA */
priv->hw->dma->stop_tx(priv->ioaddr);
priv->hw->dma->stop_rx(priv->ioaddr);
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
dis_ic);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
/* Stop TX/RX DMA */
priv->hw->dma->stop_tx(priv->ioaddr);
priv->hw->dma->stop_rx(priv->ioaddr);
/* Clear the Rx/Tx descriptors */
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
dis_ic);
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
/* Enable Power down mode by programming the PMT regs */
if (device_can_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
else
stmmac_disable_mac(priv->ioaddr);
} else {
priv->shutdown = 1;
/* Although this can appear slightly redundant it actually
* makes fast the standby operation and guarantees the driver
* working if hibernation is on media. */
stmmac_release(dev);
}
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
else
stmmac_disable_mac(priv->ioaddr);
spin_unlock(&priv->lock);
return 0;
}
static int stmmac_resume(struct platform_device *pdev)
static int stmmac_resume(struct device *dev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct stmmac_priv *priv = netdev_priv(dev);
struct net_device *ndev = dev_get_drvdata(dev);
struct stmmac_priv *priv = netdev_priv(ndev);
if (!netif_running(dev))
if (!netif_running(ndev))
return 0;
if (priv->shutdown) {
@ -1870,10 +1860,10 @@ static int stmmac_resume(struct platform_device *pdev)
* is received. Anyway, it's better to manually clear
* this bit because it can generate problems while resuming
* from another devices (e.g. serial console). */
if (device_can_wakeup(priv->device))
if (device_may_wakeup(priv->device))
priv->hw->mac->pmt(priv->ioaddr, 0);
netif_device_attach(dev);
netif_device_attach(ndev);
/* Enable the MAC and DMA */
stmmac_enable_mac(priv->ioaddr);
@ -1881,31 +1871,59 @@ static int stmmac_resume(struct platform_device *pdev)
priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
priv->tm->timer_start(tmrate);
if (likely(priv->tm->enable))
priv->tm->timer_start(tmrate);
#endif
napi_enable(&priv->napi);
if (priv->phydev)
phy_start(priv->phydev);
netif_start_queue(dev);
netif_start_queue(ndev);
spin_unlock(&priv->lock);
return 0;
}
#endif
static struct platform_driver stmmac_driver = {
.driver = {
.name = STMMAC_RESOURCE_NAME,
},
.probe = stmmac_dvr_probe,
.remove = stmmac_dvr_remove,
#ifdef CONFIG_PM
static int stmmac_freeze(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
if (!ndev || !netif_running(ndev))
return 0;
return stmmac_release(ndev);
}
static int stmmac_restore(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
if (!ndev || !netif_running(ndev))
return 0;
return stmmac_open(ndev);
}
static const struct dev_pm_ops stmmac_pm_ops = {
.suspend = stmmac_suspend,
.resume = stmmac_resume,
#endif
.freeze = stmmac_freeze,
.thaw = stmmac_restore,
.restore = stmmac_restore,
};
#else
static const struct dev_pm_ops stmmac_pm_ops;
#endif /* CONFIG_PM */
static struct platform_driver stmmac_driver = {
.probe = stmmac_dvr_probe,
.remove = stmmac_dvr_remove,
.driver = {
.name = STMMAC_RESOURCE_NAME,
.owner = THIS_MODULE,
.pm = &stmmac_pm_ops,
},
};
/**