aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-12-09 16:16:07 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-13 15:33:30 -0500
commit775ab52142b02237a54184238e922251c59a2b5c (patch)
tree0bc161bb6b0c15c095c96f0b46a99d7231a414b3 /drivers/bcma
parentbbea3bc432dc5c08d09ca5c80afdd82515470688 (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.h3
-rw-r--r--drivers/bcma/host_pci.c37
-rw-r--r--drivers/bcma/main.c16
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);
18int __init bcma_bus_early_register(struct bcma_bus *bus, 18int __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
22int bcma_bus_resume(struct bcma_bus *bus);
23#endif
21 24
22/* scan.c */ 25/* scan.c */
23int bcma_bus_scan(struct bcma_bus *bus); 26int 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
238static 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
248static 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
237static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { 272static 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
254int __init bcma_host_pci_init(void) 291int __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
244int 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
243int __bcma_driver_register(struct bcma_driver *drv, struct module *owner) 259int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
244{ 260{
245 drv->drv.name = drv->name; 261 drv->drv.name = drv->name;