From 439678f8b0fca7aeca06c6581e3679eef618721a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 5 Dec 2011 19:13:39 +0100 Subject: bcma: pci: use fixed windows when possible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some cores are mapped in the fixed way, they registers can be accessed all the time. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/host_pci.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers/bcma/host_pci.c') diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 1b51d8b7ac80..b0994c0e05dc 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -21,48 +21,58 @@ static void bcma_host_pci_switch_core(struct bcma_device *core) pr_debug("Switched to core: 0x%X\n", core->id.id); } -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) +/* Provides access to the requested core. Returns base offset that has to be + * used. It makes use of fixed windows when possible. */ +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core) { + switch (core->id.id) { + case BCMA_CORE_CHIPCOMMON: + return 3 * BCMA_CORE_SIZE; + case BCMA_CORE_PCIE: + return 2 * BCMA_CORE_SIZE; + } + if (core->bus->mapped_core != core) bcma_host_pci_switch_core(core); + return 0; +} + +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) +{ + offset += bcma_host_pci_provide_access_to_core(core); return ioread8(core->bus->mmio + offset); } static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset) { - if (core->bus->mapped_core != core) - bcma_host_pci_switch_core(core); + offset += bcma_host_pci_provide_access_to_core(core); return ioread16(core->bus->mmio + offset); } static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset) { - if (core->bus->mapped_core != core) - bcma_host_pci_switch_core(core); + offset += bcma_host_pci_provide_access_to_core(core); return ioread32(core->bus->mmio + offset); } static void bcma_host_pci_write8(struct bcma_device *core, u16 offset, u8 value) { - if (core->bus->mapped_core != core) - bcma_host_pci_switch_core(core); + offset += bcma_host_pci_provide_access_to_core(core); iowrite8(value, core->bus->mmio + offset); } static void bcma_host_pci_write16(struct bcma_device *core, u16 offset, u16 value) { - if (core->bus->mapped_core != core) - bcma_host_pci_switch_core(core); + offset += bcma_host_pci_provide_access_to_core(core); iowrite16(value, core->bus->mmio + offset); } static void bcma_host_pci_write32(struct bcma_device *core, u16 offset, u32 value) { - if (core->bus->mapped_core != core) - bcma_host_pci_switch_core(core); + offset += bcma_host_pci_provide_access_to_core(core); iowrite32(value, core->bus->mmio + offset); } -- cgit v1.2.3 From 775ab52142b02237a54184238e922251c59a2b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 9 Dec 2011 22:16:07 +0100 Subject: bcma: support for suspend and resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bcma used to lock up machine without enabling PCI or initializing CC. Cc: stable@vger.kernel.org Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/host_pci.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'drivers/bcma/host_pci.c') 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) pci_set_drvdata(dev, NULL); } +#ifdef CONFIG_PM +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state) +{ + /* Host specific */ + pci_save_state(dev); + pci_disable_device(dev); + pci_set_power_state(dev, pci_choose_state(dev, state)); + + return 0; +} + +static int bcma_host_pci_resume(struct pci_dev *dev) +{ + struct bcma_bus *bus = pci_get_drvdata(dev); + int err; + + /* Host specific */ + pci_set_power_state(dev, 0); + err = pci_enable_device(dev); + if (err) + return err; + pci_restore_state(dev); + + /* Bus specific */ + err = bcma_bus_resume(bus); + if (err) + return err; + + return 0; +} +#else /* CONFIG_PM */ +# define bcma_host_pci_suspend NULL +# define bcma_host_pci_resume NULL +#endif /* CONFIG_PM */ + static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, @@ -249,6 +284,8 @@ static struct pci_driver bcma_pci_bridge_driver = { .id_table = bcma_pci_bridge_tbl, .probe = bcma_host_pci_probe, .remove = bcma_host_pci_remove, + .suspend = bcma_host_pci_suspend, + .resume = bcma_host_pci_resume, }; int __init bcma_host_pci_init(void) -- cgit v1.2.3 From 28e7d218da975f6ae1751e293aed938952c55c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 13 Jan 2012 23:58:38 +0100 Subject: bcma: invalidate the mapped core over suspend/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This clears the currently mapped core when suspending, to force re-mapping after resume. Without that we were touching default core registers believing some other core is mapped. Such a behaviour resulted in lockups on some machines. Cc: stable@vger.kernel.org Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/host_pci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/bcma/host_pci.c') diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 443b83a2fd7a..c1ca9e3ada5c 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -237,11 +237,14 @@ static void bcma_host_pci_remove(struct pci_dev *dev) #ifdef CONFIG_PM static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state) { + struct bcma_bus *bus = pci_get_drvdata(dev); + /* Host specific */ pci_save_state(dev); pci_disable_device(dev); pci_set_power_state(dev, pci_choose_state(dev, state)); + bus->mapped_core = NULL; return 0; } -- cgit v1.2.3 From 5d2031f2395728c765cf2bd7c1ebb6d51c4fe076 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 13 Jan 2012 23:58:39 +0100 Subject: bcma: convert suspend/resume to pm_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .. and avoid doing the unnecessary PCI operations - the PCI layer will do them for us. Signed-off-by: Linus Torvalds Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/host_pci.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'drivers/bcma/host_pci.c') diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index c1ca9e3ada5c..86dfeea77e1a 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -235,41 +235,32 @@ static void bcma_host_pci_remove(struct pci_dev *dev) } #ifdef CONFIG_PM -static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state) +static int bcma_host_pci_suspend(struct device *dev) { - struct bcma_bus *bus = pci_get_drvdata(dev); - - /* Host specific */ - pci_save_state(dev); - pci_disable_device(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); + struct pci_dev *pdev = to_pci_dev(dev); + struct bcma_bus *bus = pci_get_drvdata(pdev); bus->mapped_core = NULL; + return 0; } -static int bcma_host_pci_resume(struct pci_dev *dev) +static int bcma_host_pci_resume(struct device *dev) { - struct bcma_bus *bus = pci_get_drvdata(dev); - int err; + struct pci_dev *pdev = to_pci_dev(dev); + struct bcma_bus *bus = pci_get_drvdata(pdev); - /* Host specific */ - pci_set_power_state(dev, 0); - err = pci_enable_device(dev); - if (err) - return err; - pci_restore_state(dev); + return bcma_bus_resume(bus); +} - /* Bus specific */ - err = bcma_bus_resume(bus); - if (err) - return err; +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, + bcma_host_pci_resume); +#define BCMA_PM_OPS (&bcma_pm_ops) - return 0; -} #else /* CONFIG_PM */ -# define bcma_host_pci_suspend NULL -# define bcma_host_pci_resume NULL + +#define BCMA_PM_OPS NULL + #endif /* CONFIG_PM */ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { @@ -287,8 +278,7 @@ static struct pci_driver bcma_pci_bridge_driver = { .id_table = bcma_pci_bridge_tbl, .probe = bcma_host_pci_probe, .remove = bcma_host_pci_remove, - .suspend = bcma_host_pci_suspend, - .resume = bcma_host_pci_resume, + .driver.pm = BCMA_PM_OPS, }; int __init bcma_host_pci_init(void) -- cgit v1.2.3 From 685a4ef0df23b97eea1842c2698da9a2e35fc976 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 13 Jan 2012 23:58:40 +0100 Subject: bcma: add stub for bcma_bus_suspend() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .. and connect it up with the pci host bcma driver. Now, the next step is to connect those bcma bus-level suspend/resume functions to the actual bcma device suspend resume functions. Signed-off-by: Linus Torvalds Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/host_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/bcma/host_pci.c') diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 86dfeea77e1a..f59244e33971 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -242,7 +242,7 @@ static int bcma_host_pci_suspend(struct device *dev) bus->mapped_core = NULL; - return 0; + return bcma_bus_suspend(bus); } static int bcma_host_pci_resume(struct device *dev) -- cgit v1.2.3