diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2011-12-09 16:16:07 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-13 15:33:30 -0500 |
commit | 775ab52142b02237a54184238e922251c59a2b5c (patch) | |
tree | 0bc161bb6b0c15c095c96f0b46a99d7231a414b3 /drivers/bcma | |
parent | bbea3bc432dc5c08d09ca5c80afdd82515470688 (diff) |
bcma: support for suspend and resume
bcma used to lock up machine without enabling PCI or initializing CC.
Cc: stable@vger.kernel.org
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/bcma')
-rw-r--r-- | drivers/bcma/bcma_private.h | 3 | ||||
-rw-r--r-- | drivers/bcma/host_pci.c | 37 | ||||
-rw-r--r-- | drivers/bcma/main.c | 16 |
3 files changed, 56 insertions, 0 deletions
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 30a3085d3354..fda56bde36b8 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -18,6 +18,9 @@ void bcma_bus_unregister(struct bcma_bus *bus); | |||
18 | int __init bcma_bus_early_register(struct bcma_bus *bus, | 18 | int __init bcma_bus_early_register(struct bcma_bus *bus, |
19 | struct bcma_device *core_cc, | 19 | struct bcma_device *core_cc, |
20 | struct bcma_device *core_mips); | 20 | struct bcma_device *core_mips); |
21 | #ifdef CONFIG_PM | ||
22 | int bcma_bus_resume(struct bcma_bus *bus); | ||
23 | #endif | ||
21 | 24 | ||
22 | /* scan.c */ | 25 | /* scan.c */ |
23 | int bcma_bus_scan(struct bcma_bus *bus); | 26 | int bcma_bus_scan(struct bcma_bus *bus); |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index b0994c0e05dc..443b83a2fd7a 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -234,6 +234,41 @@ static void bcma_host_pci_remove(struct pci_dev *dev) | |||
234 | pci_set_drvdata(dev, NULL); | 234 | pci_set_drvdata(dev, NULL); |
235 | } | 235 | } |
236 | 236 | ||
237 | #ifdef CONFIG_PM | ||
238 | static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state) | ||
239 | { | ||
240 | /* Host specific */ | ||
241 | pci_save_state(dev); | ||
242 | pci_disable_device(dev); | ||
243 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int bcma_host_pci_resume(struct pci_dev *dev) | ||
249 | { | ||
250 | struct bcma_bus *bus = pci_get_drvdata(dev); | ||
251 | int err; | ||
252 | |||
253 | /* Host specific */ | ||
254 | pci_set_power_state(dev, 0); | ||
255 | err = pci_enable_device(dev); | ||
256 | if (err) | ||
257 | return err; | ||
258 | pci_restore_state(dev); | ||
259 | |||
260 | /* Bus specific */ | ||
261 | err = bcma_bus_resume(bus); | ||
262 | if (err) | ||
263 | return err; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | #else /* CONFIG_PM */ | ||
268 | # define bcma_host_pci_suspend NULL | ||
269 | # define bcma_host_pci_resume NULL | ||
270 | #endif /* CONFIG_PM */ | ||
271 | |||
237 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | 272 | static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { |
238 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, | 273 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, |
239 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, | 274 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, |
@@ -249,6 +284,8 @@ static struct pci_driver bcma_pci_bridge_driver = { | |||
249 | .id_table = bcma_pci_bridge_tbl, | 284 | .id_table = bcma_pci_bridge_tbl, |
250 | .probe = bcma_host_pci_probe, | 285 | .probe = bcma_host_pci_probe, |
251 | .remove = bcma_host_pci_remove, | 286 | .remove = bcma_host_pci_remove, |
287 | .suspend = bcma_host_pci_suspend, | ||
288 | .resume = bcma_host_pci_resume, | ||
252 | }; | 289 | }; |
253 | 290 | ||
254 | int __init bcma_host_pci_init(void) | 291 | int __init bcma_host_pci_init(void) |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 70c84b951098..10f92b371e58 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -240,6 +240,22 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | #ifdef CONFIG_PM | ||
244 | int bcma_bus_resume(struct bcma_bus *bus) | ||
245 | { | ||
246 | struct bcma_device *core; | ||
247 | |||
248 | /* Init CC core */ | ||
249 | core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); | ||
250 | if (core) { | ||
251 | bus->drv_cc.setup_done = false; | ||
252 | bcma_core_chipcommon_init(&bus->drv_cc); | ||
253 | } | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | #endif | ||
258 | |||
243 | int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) | 259 | int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) |
244 | { | 260 | { |
245 | drv->drv.name = drv->name; | 261 | drv->drv.name = drv->name; |