Skip to content

Commit 775ab52

Browse files
rmileckilinvjw
authored andcommitted
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>
1 parent bbea3bc commit 775ab52

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

drivers/bcma/bcma_private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ void bcma_bus_unregister(struct bcma_bus *bus);
1818
int __init bcma_bus_early_register(struct bcma_bus *bus,
1919
struct bcma_device *core_cc,
2020
struct bcma_device *core_mips);
21+
#ifdef CONFIG_PM
22+
int bcma_bus_resume(struct bcma_bus *bus);
23+
#endif
2124

2225
/* scan.c */
2326
int bcma_bus_scan(struct bcma_bus *bus);

drivers/bcma/host_pci.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,41 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
234234
pci_set_drvdata(dev, NULL);
235235
}
236236

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+
237272
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
238273
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
239274
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
@@ -249,6 +284,8 @@ static struct pci_driver bcma_pci_bridge_driver = {
249284
.id_table = bcma_pci_bridge_tbl,
250285
.probe = bcma_host_pci_probe,
251286
.remove = bcma_host_pci_remove,
287+
.suspend = bcma_host_pci_suspend,
288+
.resume = bcma_host_pci_resume,
252289
};
253290

254291
int __init bcma_host_pci_init(void)

drivers/bcma/main.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,22 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
240240
return 0;
241241
}
242242

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+
243259
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
244260
{
245261
drv->drv.name = drv->name;

0 commit comments

Comments
 (0)