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:
Родитель
293bb1c41b
Коммит
874bd42d24
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче