Skip to content

Commit

Permalink
gianfar: Add support for hibernation
Browse files Browse the repository at this point in the history
Thanks to various cleanups and refactorings this is now straightforward:
convert the gianfar driver to dev_pm_ops, plus add ->restore() callback
that will fully reinitialize MAC internal registers and BDs.

Note that I kept legacy suspend/resume callbacks so that this patch
doesn't depend on PowerPC changes (i.e. dev_pm_ops support for OF
platform drivers).

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Anton Vorontsov authored and David S. Miller committed Oct 13, 2009
1 parent 8728327 commit be926fc
Showing 1 changed file with 70 additions and 17 deletions.
87 changes: 70 additions & 17 deletions drivers/net/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,23 +700,24 @@ static int gfar_remove(struct of_device *ofdev)
}

#ifdef CONFIG_PM
static int gfar_suspend(struct of_device *ofdev, pm_message_t state)

static int gfar_suspend(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
struct net_device *dev = priv->ndev;
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
unsigned long flags;
u32 tempval;

int magic_packet = priv->wol_en &&
(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);

netif_device_detach(dev);
netif_device_detach(ndev);

if (netif_running(dev)) {
if (netif_running(ndev)) {
spin_lock_irqsave(&priv->txlock, flags);
spin_lock(&priv->rxlock);

gfar_halt_nodisable(dev);
gfar_halt_nodisable(ndev);

/* Disable Tx, and Rx if wake-on-LAN is disabled. */
tempval = gfar_read(&priv->regs->maccfg1);
Expand Down Expand Up @@ -749,17 +750,17 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
return 0;
}

static int gfar_resume(struct of_device *ofdev)
static int gfar_resume(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
struct net_device *dev = priv->ndev;
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);

if (!netif_running(dev)) {
netif_device_attach(dev);
if (!netif_running(ndev)) {
netif_device_attach(ndev);
return 0;
}

Expand All @@ -777,20 +778,71 @@ static int gfar_resume(struct of_device *ofdev)
tempval &= ~MACCFG2_MPEN;
gfar_write(&priv->regs->maccfg2, tempval);

gfar_start(dev);
gfar_start(ndev);

spin_unlock(&priv->rxlock);
spin_unlock_irqrestore(&priv->txlock, flags);

netif_device_attach(dev);
netif_device_attach(ndev);

napi_enable(&priv->napi);

return 0;
}

static int gfar_restore(struct device *dev)
{
struct gfar_private *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->ndev;

if (!netif_running(ndev))
return 0;

gfar_init_bds(ndev);
init_registers(ndev);
gfar_set_mac_address(ndev);
gfar_init_mac(ndev);
gfar_start(ndev);

priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;

if (priv->phydev)
phy_start(priv->phydev);

netif_device_attach(ndev);
napi_enable(&priv->napi);

return 0;
}

static struct dev_pm_ops gfar_pm_ops = {
.suspend = gfar_suspend,
.resume = gfar_resume,
.freeze = gfar_suspend,
.thaw = gfar_resume,
.restore = gfar_restore,
};

#define GFAR_PM_OPS (&gfar_pm_ops)

static int gfar_legacy_suspend(struct of_device *ofdev, pm_message_t state)
{
return gfar_suspend(&ofdev->dev);
}

static int gfar_legacy_resume(struct of_device *ofdev)
{
return gfar_resume(&ofdev->dev);
}

#else
#define gfar_suspend NULL
#define gfar_resume NULL

#define GFAR_PM_OPS NULL
#define gfar_legacy_suspend NULL
#define gfar_legacy_resume NULL

#endif

/* Reads the controller's registers to determine what interface
Expand Down Expand Up @@ -2364,8 +2416,9 @@ static struct of_platform_driver gfar_driver = {

.probe = gfar_probe,
.remove = gfar_remove,
.suspend = gfar_suspend,
.resume = gfar_resume,
.suspend = gfar_legacy_suspend,
.resume = gfar_legacy_resume,
.driver.pm = GFAR_PM_OPS,
};

static int __init gfar_init(void)
Expand Down

0 comments on commit be926fc

Please sign in to comment.