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:
parent
293bb1c41b
commit
874bd42d24
|
@ -77,7 +77,6 @@ struct stmmac_priv {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
int wolopts;
|
int wolopts;
|
||||||
int wolenabled;
|
int wolenabled;
|
||||||
int shutdown;
|
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
struct stmmac_timer *tm;
|
struct stmmac_timer *tm;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -844,8 +844,6 @@ static int stmmac_open(struct net_device *dev)
|
||||||
if (priv->plat->tx_coe)
|
if (priv->plat->tx_coe)
|
||||||
pr_info("\tTX Checksum insertion supported\n");
|
pr_info("\tTX Checksum insertion supported\n");
|
||||||
|
|
||||||
priv->shutdown = 0;
|
|
||||||
|
|
||||||
/* Initialise the MMC (if present) to disable all interrupts. */
|
/* Initialise the MMC (if present) to disable all interrupts. */
|
||||||
writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
|
writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
|
||||||
writel(0xffffffff, priv->ioaddr + MMC_LOW_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
|
#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 net_device *ndev = dev_get_drvdata(dev);
|
||||||
struct stmmac_priv *priv = netdev_priv(dev);
|
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||||
int dis_ic = 0;
|
int dis_ic = 0;
|
||||||
|
|
||||||
if (!dev || !netif_running(dev))
|
if (!ndev || !netif_running(ndev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spin_lock(&priv->lock);
|
spin_lock(&priv->lock);
|
||||||
|
|
||||||
if (state.event == PM_EVENT_SUSPEND) {
|
netif_device_detach(ndev);
|
||||||
netif_device_detach(dev);
|
netif_stop_queue(ndev);
|
||||||
netif_stop_queue(dev);
|
if (priv->phydev)
|
||||||
if (priv->phydev)
|
phy_stop(priv->phydev);
|
||||||
phy_stop(priv->phydev);
|
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
priv->tm->timer_stop();
|
priv->tm->timer_stop();
|
||||||
if (likely(priv->tm->enable))
|
if (likely(priv->tm->enable))
|
||||||
dis_ic = 1;
|
dis_ic = 1;
|
||||||
#endif
|
#endif
|
||||||
napi_disable(&priv->napi);
|
napi_disable(&priv->napi);
|
||||||
|
|
||||||
/* Stop TX/RX DMA */
|
/* Stop TX/RX DMA */
|
||||||
priv->hw->dma->stop_tx(priv->ioaddr);
|
priv->hw->dma->stop_tx(priv->ioaddr);
|
||||||
priv->hw->dma->stop_rx(priv->ioaddr);
|
priv->hw->dma->stop_rx(priv->ioaddr);
|
||||||
/* Clear the Rx/Tx descriptors */
|
/* Clear the Rx/Tx descriptors */
|
||||||
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
|
priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size,
|
||||||
dis_ic);
|
dis_ic);
|
||||||
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
|
priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
|
||||||
|
|
||||||
/* Enable Power down mode by programming the PMT regs */
|
/* Enable Power down mode by programming the PMT regs */
|
||||||
if (device_can_wakeup(priv->device))
|
if (device_may_wakeup(priv->device))
|
||||||
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
|
priv->hw->mac->pmt(priv->ioaddr, priv->wolopts);
|
||||||
else
|
else
|
||||||
stmmac_disable_mac(priv->ioaddr);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&priv->lock);
|
spin_unlock(&priv->lock);
|
||||||
return 0;
|
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 net_device *ndev = dev_get_drvdata(dev);
|
||||||
struct stmmac_priv *priv = netdev_priv(dev);
|
struct stmmac_priv *priv = netdev_priv(ndev);
|
||||||
|
|
||||||
if (!netif_running(dev))
|
if (!netif_running(ndev))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (priv->shutdown) {
|
if (priv->shutdown) {
|
||||||
|
@ -1870,10 +1860,10 @@ static int stmmac_resume(struct platform_device *pdev)
|
||||||
* is received. Anyway, it's better to manually clear
|
* is received. Anyway, it's better to manually clear
|
||||||
* this bit because it can generate problems while resuming
|
* this bit because it can generate problems while resuming
|
||||||
* from another devices (e.g. serial console). */
|
* 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);
|
priv->hw->mac->pmt(priv->ioaddr, 0);
|
||||||
|
|
||||||
netif_device_attach(dev);
|
netif_device_attach(ndev);
|
||||||
|
|
||||||
/* Enable the MAC and DMA */
|
/* Enable the MAC and DMA */
|
||||||
stmmac_enable_mac(priv->ioaddr);
|
stmmac_enable_mac(priv->ioaddr);
|
||||||
|
@ -1881,31 +1871,59 @@ static int stmmac_resume(struct platform_device *pdev)
|
||||||
priv->hw->dma->start_rx(priv->ioaddr);
|
priv->hw->dma->start_rx(priv->ioaddr);
|
||||||
|
|
||||||
#ifdef CONFIG_STMMAC_TIMER
|
#ifdef CONFIG_STMMAC_TIMER
|
||||||
priv->tm->timer_start(tmrate);
|
if (likely(priv->tm->enable))
|
||||||
|
priv->tm->timer_start(tmrate);
|
||||||
#endif
|
#endif
|
||||||
napi_enable(&priv->napi);
|
napi_enable(&priv->napi);
|
||||||
|
|
||||||
if (priv->phydev)
|
if (priv->phydev)
|
||||||
phy_start(priv->phydev);
|
phy_start(priv->phydev);
|
||||||
|
|
||||||
netif_start_queue(dev);
|
netif_start_queue(ndev);
|
||||||
|
|
||||||
spin_unlock(&priv->lock);
|
spin_unlock(&priv->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct platform_driver stmmac_driver = {
|
static int stmmac_freeze(struct device *dev)
|
||||||
.driver = {
|
{
|
||||||
.name = STMMAC_RESOURCE_NAME,
|
struct net_device *ndev = dev_get_drvdata(dev);
|
||||||
},
|
|
||||||
.probe = stmmac_dvr_probe,
|
if (!ndev || !netif_running(ndev))
|
||||||
.remove = stmmac_dvr_remove,
|
return 0;
|
||||||
#ifdef CONFIG_PM
|
|
||||||
|
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,
|
.suspend = stmmac_suspend,
|
||||||
.resume = stmmac_resume,
|
.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,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue