aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2009-10-12 02:00:42 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-13 02:54:05 -0400
commitbe926fc4046913d9ad921aeacdf9329978241c38 (patch)
treeb8299b4cc899913a3072e002a304c6bcdc6a92b5 /drivers/net/gianfar.c
parent8728327e7a7a7f21f3a7109e65503f4cc3305e78 (diff)
gianfar: Add support for hibernation
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>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c87
1 files changed, 70 insertions, 17 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index c2a508fe1cce..c6f6d3b7f4df 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -700,23 +700,24 @@ static int gfar_remove(struct of_device *ofdev)
700} 700}
701 701
702#ifdef CONFIG_PM 702#ifdef CONFIG_PM
703static int gfar_suspend(struct of_device *ofdev, pm_message_t state) 703
704static int gfar_suspend(struct device *dev)
704{ 705{
705 struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); 706 struct gfar_private *priv = dev_get_drvdata(dev);
706 struct net_device *dev = priv->ndev; 707 struct net_device *ndev = priv->ndev;
707 unsigned long flags; 708 unsigned long flags;
708 u32 tempval; 709 u32 tempval;
709 710
710 int magic_packet = priv->wol_en && 711 int magic_packet = priv->wol_en &&
711 (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); 712 (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
712 713
713 netif_device_detach(dev); 714 netif_device_detach(ndev);
714 715
715 if (netif_running(dev)) { 716 if (netif_running(ndev)) {
716 spin_lock_irqsave(&priv->txlock, flags); 717 spin_lock_irqsave(&priv->txlock, flags);
717 spin_lock(&priv->rxlock); 718 spin_lock(&priv->rxlock);
718 719
719 gfar_halt_nodisable(dev); 720 gfar_halt_nodisable(ndev);
720 721
721 /* Disable Tx, and Rx if wake-on-LAN is disabled. */ 722 /* Disable Tx, and Rx if wake-on-LAN is disabled. */
722 tempval = gfar_read(&priv->regs->maccfg1); 723 tempval = gfar_read(&priv->regs->maccfg1);
@@ -749,17 +750,17 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
749 return 0; 750 return 0;
750} 751}
751 752
752static int gfar_resume(struct of_device *ofdev) 753static int gfar_resume(struct device *dev)
753{ 754{
754 struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); 755 struct gfar_private *priv = dev_get_drvdata(dev);
755 struct net_device *dev = priv->ndev; 756 struct net_device *ndev = priv->ndev;
756 unsigned long flags; 757 unsigned long flags;
757 u32 tempval; 758 u32 tempval;
758 int magic_packet = priv->wol_en && 759 int magic_packet = priv->wol_en &&
759 (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); 760 (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
760 761
761 if (!netif_running(dev)) { 762 if (!netif_running(ndev)) {
762 netif_device_attach(dev); 763 netif_device_attach(ndev);
763 return 0; 764 return 0;
764 } 765 }
765 766
@@ -777,20 +778,71 @@ static int gfar_resume(struct of_device *ofdev)
777 tempval &= ~MACCFG2_MPEN; 778 tempval &= ~MACCFG2_MPEN;
778 gfar_write(&priv->regs->maccfg2, tempval); 779 gfar_write(&priv->regs->maccfg2, tempval);
779 780
780 gfar_start(dev); 781 gfar_start(ndev);
781 782
782 spin_unlock(&priv->rxlock); 783 spin_unlock(&priv->rxlock);
783 spin_unlock_irqrestore(&priv->txlock, flags); 784 spin_unlock_irqrestore(&priv->txlock, flags);
784 785
785 netif_device_attach(dev); 786 netif_device_attach(ndev);
787
788 napi_enable(&priv->napi);
789
790 return 0;
791}
792
793static int gfar_restore(struct device *dev)
794{
795 struct gfar_private *priv = dev_get_drvdata(dev);
796 struct net_device *ndev = priv->ndev;
797
798 if (!netif_running(ndev))
799 return 0;
800
801 gfar_init_bds(ndev);
802 init_registers(ndev);
803 gfar_set_mac_address(ndev);
804 gfar_init_mac(ndev);
805 gfar_start(ndev);
806
807 priv->oldlink = 0;
808 priv->oldspeed = 0;
809 priv->oldduplex = -1;
810
811 if (priv->phydev)
812 phy_start(priv->phydev);
786 813
814 netif_device_attach(ndev);
787 napi_enable(&priv->napi); 815 napi_enable(&priv->napi);
788 816
789 return 0; 817 return 0;
790} 818}
819
820static struct dev_pm_ops gfar_pm_ops = {
821 .suspend = gfar_suspend,
822 .resume = gfar_resume,
823 .freeze = gfar_suspend,
824 .thaw = gfar_resume,
825 .restore = gfar_restore,
826};
827
828#define GFAR_PM_OPS (&gfar_pm_ops)
829
830static int gfar_legacy_suspend(struct of_device *ofdev, pm_message_t state)
831{
832 return gfar_suspend(&ofdev->dev);
833}
834
835static int gfar_legacy_resume(struct of_device *ofdev)
836{
837 return gfar_resume(&ofdev->dev);
838}
839
791#else 840#else
792#define gfar_suspend NULL 841
793#define gfar_resume NULL 842#define GFAR_PM_OPS NULL
843#define gfar_legacy_suspend NULL
844#define gfar_legacy_resume NULL
845
794#endif 846#endif
795 847
796/* Reads the controller's registers to determine what interface 848/* Reads the controller's registers to determine what interface
@@ -2364,8 +2416,9 @@ static struct of_platform_driver gfar_driver = {
2364 2416
2365 .probe = gfar_probe, 2417 .probe = gfar_probe,
2366 .remove = gfar_remove, 2418 .remove = gfar_remove,
2367 .suspend = gfar_suspend, 2419 .suspend = gfar_legacy_suspend,
2368 .resume = gfar_resume, 2420 .resume = gfar_legacy_resume,
2421 .driver.pm = GFAR_PM_OPS,
2369}; 2422};
2370 2423
2371static int __init gfar_init(void) 2424static int __init gfar_init(void)