aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-29 19:10:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 15:05:57 -0400
commit8fe2b65a18e49bfde56a59ed4ab3fc7aa0c2f325 (patch)
treea813fe635b7a8c248c586de847d1501c4ccaab6b /drivers/ssb/main.c
parent5100d5ac81b9330dc57e35adbe50923ba6107b8f (diff)
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)
120 put_device(dev->dev); 120 put_device(dev->dev);
121} 121}
122 122
123static int ssb_bus_resume(struct ssb_bus *bus)
124{
125 int err;
126
127 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
128 err = ssb_pcmcia_init(bus);
129 if (err) {
130 /* No need to disable XTAL, as we don't have one on PCMCIA. */
131 return err;
132 }
133 ssb_chipco_resume(&bus->chipco);
134
135 return 0;
136}
137
138static int ssb_device_resume(struct device *dev) 123static int ssb_device_resume(struct device *dev)
139{ 124{
140 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); 125 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
141 struct ssb_driver *ssb_drv; 126 struct ssb_driver *ssb_drv;
142 struct ssb_bus *bus;
143 int err = 0; 127 int err = 0;
144 128
145 bus = ssb_dev->bus;
146 if (bus->suspend_cnt == bus->nr_devices) {
147 err = ssb_bus_resume(bus);
148 if (err)
149 return err;
150 }
151 bus->suspend_cnt--;
152 if (dev->driver) { 129 if (dev->driver) {
153 ssb_drv = drv_to_ssb_drv(dev->driver); 130 ssb_drv = drv_to_ssb_drv(dev->driver);
154 if (ssb_drv && ssb_drv->resume) 131 if (ssb_drv && ssb_drv->resume)
@@ -160,27 +137,10 @@ out:
160 return err; 137 return err;
161} 138}
162 139
163static void ssb_bus_suspend(struct ssb_bus *bus, pm_message_t state)
164{
165 ssb_chipco_suspend(&bus->chipco, state);
166 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
167
168 /* Reset HW state information in memory, so that HW is
169 * completely reinitialized on resume. */
170 bus->mapped_device = NULL;
171#ifdef CONFIG_SSB_DRIVER_PCICORE
172 bus->pcicore.setup_done = 0;
173#endif
174#ifdef CONFIG_SSB_DEBUG
175 bus->powered_up = 0;
176#endif
177}
178
179static int ssb_device_suspend(struct device *dev, pm_message_t state) 140static int ssb_device_suspend(struct device *dev, pm_message_t state)
180{ 141{
181 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); 142 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
182 struct ssb_driver *ssb_drv; 143 struct ssb_driver *ssb_drv;
183 struct ssb_bus *bus;
184 int err = 0; 144 int err = 0;
185 145
186 if (dev->driver) { 146 if (dev->driver) {
@@ -190,17 +150,44 @@ static int ssb_device_suspend(struct device *dev, pm_message_t state)
190 if (err) 150 if (err)
191 goto out; 151 goto out;
192 } 152 }
153out:
154 return err;
155}
156
157int ssb_bus_resume(struct ssb_bus *bus)
158{
159 int err;
193 160
194 bus = ssb_dev->bus; 161 /* Reset HW state information in memory, so that HW is
195 bus->suspend_cnt++; 162 * completely reinitialized. */
196 if (bus->suspend_cnt == bus->nr_devices) { 163 bus->mapped_device = NULL;
197 /* All devices suspended. Shutdown the bus. */ 164#ifdef CONFIG_SSB_DRIVER_PCICORE
198 ssb_bus_suspend(bus, state); 165 bus->pcicore.setup_done = 0;
166#endif
167
168 err = ssb_bus_powerup(bus, 0);
169 if (err)
170 return err;
171 err = ssb_pcmcia_hardware_setup(bus);
172 if (err) {
173 ssb_bus_may_powerdown(bus);
174 return err;
199 } 175 }
176 ssb_chipco_resume(&bus->chipco);
177 ssb_bus_may_powerdown(bus);
200 178
201out: 179 return 0;
202 return err; 180}
181EXPORT_SYMBOL(ssb_bus_resume);
182
183int ssb_bus_suspend(struct ssb_bus *bus)
184{
185 ssb_chipco_suspend(&bus->chipco);
186 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
187
188 return 0;
203} 189}
190EXPORT_SYMBOL(ssb_bus_suspend);
204 191
205#ifdef CONFIG_SSB_PCIHOST 192#ifdef CONFIG_SSB_PCIHOST
206int ssb_devices_freeze(struct ssb_bus *bus) 193int ssb_devices_freeze(struct ssb_bus *bus)