summaryrefslogtreecommitdiff
path: root/drivers/ssb/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-30 03:10:50 +0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 23:05:57 +0400
commit8fe2b65a18e49bfde56a59ed4ab3fc7aa0c2f325 (patch)
treea813fe635b7a8c248c586de847d1501c4ccaab6b /drivers/ssb/main.c
parent5100d5ac81b9330dc57e35adbe50923ba6107b8f (diff)
downloadlinux-8fe2b65a18e49bfde56a59ed4ab3fc7aa0c2f325.tar.xz
ssb: Turn suspend/resume upside down
Turn the SSB bus suspend mechanism upside down. Instead of deciding by an internal reference count when to suspend/resume, let the parent bus call us in their suspend/resume routine. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/main.c')
-rw-r--r--drivers/ssb/main.c81
1 files changed, 34 insertions, 47 deletions
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 2fcfd73b3b6e..c0cbdba07aee 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -120,35 +120,12 @@ static void ssb_device_put(struct ssb_device *dev)
put_device(dev->dev);
}
-static int ssb_bus_resume(struct ssb_bus *bus)
-{
- int err;
-
- ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
- err = ssb_pcmcia_init(bus);
- if (err) {
- /* No need to disable XTAL, as we don't have one on PCMCIA. */
- return err;
- }
- ssb_chipco_resume(&bus->chipco);
-
- return 0;
-}
-
static int ssb_device_resume(struct device *dev)
{
struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
struct ssb_driver *ssb_drv;
- struct ssb_bus *bus;
int err = 0;
- bus = ssb_dev->bus;
- if (bus->suspend_cnt == bus->nr_devices) {
- err = ssb_bus_resume(bus);
- if (err)
- return err;
- }
- bus->suspend_cnt--;
if (dev->driver) {
ssb_drv = drv_to_ssb_drv(dev->driver);
if (ssb_drv && ssb_drv->resume)
@@ -160,27 +137,10 @@ out:
return err;
}
-static void ssb_bus_suspend(struct ssb_bus *bus, pm_message_t state)
-{
- ssb_chipco_suspend(&bus->chipco, state);
- ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
-
- /* Reset HW state information in memory, so that HW is
- * completely reinitialized on resume. */
- bus->mapped_device = NULL;
-#ifdef CONFIG_SSB_DRIVER_PCICORE
- bus->pcicore.setup_done = 0;
-#endif
-#ifdef CONFIG_SSB_DEBUG
- bus->powered_up = 0;
-#endif
-}
-
static int ssb_device_suspend(struct device *dev, pm_message_t state)
{
struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
struct ssb_driver *ssb_drv;
- struct ssb_bus *bus;
int err = 0;
if (dev->driver) {
@@ -190,17 +150,44 @@ static int ssb_device_suspend(struct device *dev, pm_message_t state)
if (err)
goto out;
}
+out:
+ return err;
+}
+
+int ssb_bus_resume(struct ssb_bus *bus)
+{
+ int err;
- bus = ssb_dev->bus;
- bus->suspend_cnt++;
- if (bus->suspend_cnt == bus->nr_devices) {
- /* All devices suspended. Shutdown the bus. */
- ssb_bus_suspend(bus, state);
+ /* Reset HW state information in memory, so that HW is
+ * completely reinitialized. */
+ bus->mapped_device = NULL;
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ bus->pcicore.setup_done = 0;
+#endif
+
+ err = ssb_bus_powerup(bus, 0);
+ if (err)
+ return err;
+ err = ssb_pcmcia_hardware_setup(bus);
+ if (err) {
+ ssb_bus_may_powerdown(bus);
+ return err;
}
+ ssb_chipco_resume(&bus->chipco);
+ ssb_bus_may_powerdown(bus);
-out:
- return err;
+ return 0;
+}
+EXPORT_SYMBOL(ssb_bus_resume);
+
+int ssb_bus_suspend(struct ssb_bus *bus)
+{
+ ssb_chipco_suspend(&bus->chipco);
+ ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
+
+ return 0;
}
+EXPORT_SYMBOL(ssb_bus_suspend);
#ifdef CONFIG_SSB_PCIHOST
int ssb_devices_freeze(struct ssb_bus *bus)