From aef81259a944186a120d51e4462a5f974de99fb8 Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Sun, 15 Mar 2009 15:37:29 +0100
Subject: [PATCH] rt2x00: Add PM support for SoC (rt2800pci)

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   52 +++++++++++++++++++++++++++++--
 1 files changed, 49 insertions(+), 3 deletions(-)

--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -2934,7 +2934,7 @@ exit:
 
 static int rt2800soc_probe(struct platform_device *pdev)
 {
-	const struct rt2x00_ops *ops = &rt2800pci_ops;
+	struct rt2x00_ops *ops = (struct rt2x00_ops *)pdev->driver->p;
 	struct ieee80211_hw *hw;
 	struct rt2x00_dev *rt2x00dev;
 	int retval;
@@ -2990,10 +2990,56 @@ static int rt2800soc_remove(struct platf
 	return 0;
 }
 
+#ifdef CONFIG_PM
+int rt2x00soc_suspend(struct device *dev, pm_message_t state)
+{
+	struct ieee80211_hw *hw = dev_get_drvdata(dev);
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	int retval;
+
+	retval = rt2x00lib_suspend(rt2x00dev, state);
+	if (retval)
+		return retval;
+
+	rt2800soc_free_reg(rt2x00dev);
+
+	return 0;
+}
+
+int rt2x00soc_resume(struct device *dev)
+{
+	struct ieee80211_hw *hw = dev_get_drvdata(dev);
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	int retval;
+
+	retval = rt2x00soc_alloc_reg(rt2x00dev);
+	if (retval)
+		return retval;
+
+	retval = rt2x00lib_resume(rt2x00dev);
+	if (retval)
+		goto exit_free_reg;
+
+	return 0;
+
+exit_free_reg:
+	rt2x00pci_free_reg(rt2x00dev);
+
+	return retval;
+}
+#endif /* CONFIG_PM */
+
 static struct platform_driver rt2800soc_driver = {
-	.driver.name	= "rt2800_wmac",
+	.driver		= {
+		.name		= "rt2800_wmac",
+		.owner		= THIS_MODULE,
+		.mod_name	= KBUILD_MODNAME,
+		.p		= &rt2800pci_ops;
+	}
 	.probe		= rt2800soc_probe,
-	.remove		= rt2800soc_remove,
+	.remove		= __devexit_p(rt2800soc_remove),
+	.suspend	= rt2x00soc_suspend,
+	.resume		= rt2x00soc_resume,
 };
 #endif /* CONFIG_RT2800PCI_WISOC */
 
