18369ae33SRafał Miłecki /* 28369ae33SRafał Miłecki * Broadcom specific AMBA 38369ae33SRafał Miłecki * PCI Host 48369ae33SRafał Miłecki * 58369ae33SRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 68369ae33SRafał Miłecki */ 78369ae33SRafał Miłecki 88369ae33SRafał Miłecki #include "bcma_private.h" 9ba7328b2SAndrew Morton #include <linux/slab.h> 108369ae33SRafał Miłecki #include <linux/bcma/bcma.h> 118369ae33SRafał Miłecki #include <linux/pci.h> 12200351c7SPaul Gortmaker #include <linux/module.h> 138369ae33SRafał Miłecki 148369ae33SRafał Miłecki static void bcma_host_pci_switch_core(struct bcma_device *core) 158369ae33SRafał Miłecki { 168be08a39SRafał Miłecki int win2 = core->bus->host_is_pcie2 ? 178be08a39SRafał Miłecki BCMA_PCIE2_BAR0_WIN2 : BCMA_PCI_BAR0_WIN2; 188be08a39SRafał Miłecki 198369ae33SRafał Miłecki pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, 208369ae33SRafał Miłecki core->addr); 218be08a39SRafał Miłecki pci_write_config_dword(core->bus->host_pci, win2, core->wrap); 228369ae33SRafał Miłecki core->bus->mapped_core = core; 233d9d8af3SRafał Miłecki bcma_debug(core->bus, "Switched to core: 0x%X\n", core->id.id); 248369ae33SRafał Miłecki } 258369ae33SRafał Miłecki 26439678f8SRafał Miłecki /* Provides access to the requested core. Returns base offset that has to be 27439678f8SRafał Miłecki * used. It makes use of fixed windows when possible. */ 28439678f8SRafał Miłecki static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core) 298369ae33SRafał Miłecki { 30439678f8SRafał Miłecki switch (core->id.id) { 31439678f8SRafał Miłecki case BCMA_CORE_CHIPCOMMON: 32439678f8SRafał Miłecki return 3 * BCMA_CORE_SIZE; 33439678f8SRafał Miłecki case BCMA_CORE_PCIE: 34439678f8SRafał Miłecki return 2 * BCMA_CORE_SIZE; 35439678f8SRafał Miłecki } 36439678f8SRafał Miłecki 378369ae33SRafał Miłecki if (core->bus->mapped_core != core) 388369ae33SRafał Miłecki bcma_host_pci_switch_core(core); 39439678f8SRafał Miłecki return 0; 40439678f8SRafał Miłecki } 41439678f8SRafał Miłecki 42439678f8SRafał Miłecki static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) 43439678f8SRafał Miłecki { 44439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 458369ae33SRafał Miłecki return ioread8(core->bus->mmio + offset); 468369ae33SRafał Miłecki } 478369ae33SRafał Miłecki 488369ae33SRafał Miłecki static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset) 498369ae33SRafał Miłecki { 50439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 518369ae33SRafał Miłecki return ioread16(core->bus->mmio + offset); 528369ae33SRafał Miłecki } 538369ae33SRafał Miłecki 548369ae33SRafał Miłecki static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset) 558369ae33SRafał Miłecki { 56439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 578369ae33SRafał Miłecki return ioread32(core->bus->mmio + offset); 588369ae33SRafał Miłecki } 598369ae33SRafał Miłecki 608369ae33SRafał Miłecki static void bcma_host_pci_write8(struct bcma_device *core, u16 offset, 618369ae33SRafał Miłecki u8 value) 628369ae33SRafał Miłecki { 63439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 648369ae33SRafał Miłecki iowrite8(value, core->bus->mmio + offset); 658369ae33SRafał Miłecki } 668369ae33SRafał Miłecki 678369ae33SRafał Miłecki static void bcma_host_pci_write16(struct bcma_device *core, u16 offset, 688369ae33SRafał Miłecki u16 value) 698369ae33SRafał Miłecki { 70439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 718369ae33SRafał Miłecki iowrite16(value, core->bus->mmio + offset); 728369ae33SRafał Miłecki } 738369ae33SRafał Miłecki 748369ae33SRafał Miłecki static void bcma_host_pci_write32(struct bcma_device *core, u16 offset, 758369ae33SRafał Miłecki u32 value) 768369ae33SRafał Miłecki { 77439678f8SRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 788369ae33SRafał Miłecki iowrite32(value, core->bus->mmio + offset); 798369ae33SRafał Miłecki } 808369ae33SRafał Miłecki 819d75ef0fSRafał Miłecki #ifdef CONFIG_BCMA_BLOCKIO 8294f3457fSHauke Mehrtens static void bcma_host_pci_block_read(struct bcma_device *core, void *buffer, 839d75ef0fSRafał Miłecki size_t count, u16 offset, u8 reg_width) 849d75ef0fSRafał Miłecki { 859d75ef0fSRafał Miłecki void __iomem *addr = core->bus->mmio + offset; 869d75ef0fSRafał Miłecki if (core->bus->mapped_core != core) 879d75ef0fSRafał Miłecki bcma_host_pci_switch_core(core); 889d75ef0fSRafał Miłecki switch (reg_width) { 899d75ef0fSRafał Miłecki case sizeof(u8): 909d75ef0fSRafał Miłecki ioread8_rep(addr, buffer, count); 919d75ef0fSRafał Miłecki break; 929d75ef0fSRafał Miłecki case sizeof(u16): 939d75ef0fSRafał Miłecki WARN_ON(count & 1); 949d75ef0fSRafał Miłecki ioread16_rep(addr, buffer, count >> 1); 959d75ef0fSRafał Miłecki break; 969d75ef0fSRafał Miłecki case sizeof(u32): 979d75ef0fSRafał Miłecki WARN_ON(count & 3); 989d75ef0fSRafał Miłecki ioread32_rep(addr, buffer, count >> 2); 999d75ef0fSRafał Miłecki break; 1009d75ef0fSRafał Miłecki default: 1019d75ef0fSRafał Miłecki WARN_ON(1); 1029d75ef0fSRafał Miłecki } 1039d75ef0fSRafał Miłecki } 1049d75ef0fSRafał Miłecki 10594f3457fSHauke Mehrtens static void bcma_host_pci_block_write(struct bcma_device *core, 10694f3457fSHauke Mehrtens const void *buffer, size_t count, 10794f3457fSHauke Mehrtens u16 offset, u8 reg_width) 1089d75ef0fSRafał Miłecki { 1099d75ef0fSRafał Miłecki void __iomem *addr = core->bus->mmio + offset; 1109d75ef0fSRafał Miłecki if (core->bus->mapped_core != core) 1119d75ef0fSRafał Miłecki bcma_host_pci_switch_core(core); 1129d75ef0fSRafał Miłecki switch (reg_width) { 1139d75ef0fSRafał Miłecki case sizeof(u8): 1149d75ef0fSRafał Miłecki iowrite8_rep(addr, buffer, count); 1159d75ef0fSRafał Miłecki break; 1169d75ef0fSRafał Miłecki case sizeof(u16): 1179d75ef0fSRafał Miłecki WARN_ON(count & 1); 1189d75ef0fSRafał Miłecki iowrite16_rep(addr, buffer, count >> 1); 1199d75ef0fSRafał Miłecki break; 1209d75ef0fSRafał Miłecki case sizeof(u32): 1219d75ef0fSRafał Miłecki WARN_ON(count & 3); 1229d75ef0fSRafał Miłecki iowrite32_rep(addr, buffer, count >> 2); 1239d75ef0fSRafał Miłecki break; 1249d75ef0fSRafał Miłecki default: 1259d75ef0fSRafał Miłecki WARN_ON(1); 1269d75ef0fSRafał Miłecki } 1279d75ef0fSRafał Miłecki } 1289d75ef0fSRafał Miłecki #endif 1299d75ef0fSRafał Miłecki 1308369ae33SRafał Miłecki static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) 1318369ae33SRafał Miłecki { 1328369ae33SRafał Miłecki if (core->bus->mapped_core != core) 1338369ae33SRafał Miłecki bcma_host_pci_switch_core(core); 1348369ae33SRafał Miłecki return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); 1358369ae33SRafał Miłecki } 1368369ae33SRafał Miłecki 1378369ae33SRafał Miłecki static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset, 1388369ae33SRafał Miłecki u32 value) 1398369ae33SRafał Miłecki { 1408369ae33SRafał Miłecki if (core->bus->mapped_core != core) 1418369ae33SRafał Miłecki bcma_host_pci_switch_core(core); 1428369ae33SRafał Miłecki iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); 1438369ae33SRafał Miłecki } 1448369ae33SRafał Miłecki 14594f3457fSHauke Mehrtens static const struct bcma_host_ops bcma_host_pci_ops = { 1468369ae33SRafał Miłecki .read8 = bcma_host_pci_read8, 1478369ae33SRafał Miłecki .read16 = bcma_host_pci_read16, 1488369ae33SRafał Miłecki .read32 = bcma_host_pci_read32, 1498369ae33SRafał Miłecki .write8 = bcma_host_pci_write8, 1508369ae33SRafał Miłecki .write16 = bcma_host_pci_write16, 1518369ae33SRafał Miłecki .write32 = bcma_host_pci_write32, 1529d75ef0fSRafał Miłecki #ifdef CONFIG_BCMA_BLOCKIO 1539d75ef0fSRafał Miłecki .block_read = bcma_host_pci_block_read, 1549d75ef0fSRafał Miłecki .block_write = bcma_host_pci_block_write, 1559d75ef0fSRafał Miłecki #endif 1568369ae33SRafał Miłecki .aread32 = bcma_host_pci_aread32, 1578369ae33SRafał Miłecki .awrite32 = bcma_host_pci_awrite32, 1588369ae33SRafał Miłecki }; 1598369ae33SRafał Miłecki 1600f58a01dSGreg Kroah-Hartman static int bcma_host_pci_probe(struct pci_dev *dev, 1618369ae33SRafał Miłecki const struct pci_device_id *id) 1628369ae33SRafał Miłecki { 1638369ae33SRafał Miłecki struct bcma_bus *bus; 1648369ae33SRafał Miłecki int err = -ENOMEM; 1658369ae33SRafał Miłecki const char *name; 1668369ae33SRafał Miłecki u32 val; 1678369ae33SRafał Miłecki 1688369ae33SRafał Miłecki /* Alloc */ 1698369ae33SRafał Miłecki bus = kzalloc(sizeof(*bus), GFP_KERNEL); 1708369ae33SRafał Miłecki if (!bus) 1718369ae33SRafał Miłecki goto out; 1728369ae33SRafał Miłecki 1738369ae33SRafał Miłecki /* Basic PCI configuration */ 1748369ae33SRafał Miłecki err = pci_enable_device(dev); 1758369ae33SRafał Miłecki if (err) 1768369ae33SRafał Miłecki goto err_kfree_bus; 1778369ae33SRafał Miłecki 1788369ae33SRafał Miłecki name = dev_name(&dev->dev); 1798369ae33SRafał Miłecki if (dev->driver && dev->driver->name) 1808369ae33SRafał Miłecki name = dev->driver->name; 1818369ae33SRafał Miłecki err = pci_request_regions(dev, name); 1828369ae33SRafał Miłecki if (err) 1838369ae33SRafał Miłecki goto err_pci_disable; 1848369ae33SRafał Miłecki pci_set_master(dev); 1858369ae33SRafał Miłecki 1868369ae33SRafał Miłecki /* Disable the RETRY_TIMEOUT register (0x41) to keep 1878369ae33SRafał Miłecki * PCI Tx retries from interfering with C3 CPU state */ 1888369ae33SRafał Miłecki pci_read_config_dword(dev, 0x40, &val); 1898369ae33SRafał Miłecki if ((val & 0x0000ff00) != 0) 1908369ae33SRafał Miłecki pci_write_config_dword(dev, 0x40, val & 0xffff00ff); 1918369ae33SRafał Miłecki 1928369ae33SRafał Miłecki /* SSB needed additional powering up, do we have any AMBA PCI cards? */ 193dfa0415bSHauke Mehrtens if (!pci_is_pcie(dev)) { 194dfa0415bSHauke Mehrtens bcma_err(bus, "PCI card detected, they are not supported.\n"); 195dfa0415bSHauke Mehrtens err = -ENXIO; 196dfa0415bSHauke Mehrtens goto err_pci_release_regions; 197dfa0415bSHauke Mehrtens } 1988369ae33SRafał Miłecki 1998369ae33SRafał Miłecki /* Map MMIO */ 2008369ae33SRafał Miłecki err = -ENOMEM; 2018369ae33SRafał Miłecki bus->mmio = pci_iomap(dev, 0, ~0UL); 2028369ae33SRafał Miłecki if (!bus->mmio) 2038369ae33SRafał Miłecki goto err_pci_release_regions; 2048369ae33SRafał Miłecki 2058369ae33SRafał Miłecki /* Host specific */ 2068369ae33SRafał Miłecki bus->host_pci = dev; 2078369ae33SRafał Miłecki bus->hosttype = BCMA_HOSTTYPE_PCI; 2088369ae33SRafał Miłecki bus->ops = &bcma_host_pci_ops; 2098369ae33SRafał Miłecki 2100a2fcaa7SHauke Mehrtens bus->boardinfo.vendor = bus->host_pci->subsystem_vendor; 2110a2fcaa7SHauke Mehrtens bus->boardinfo.type = bus->host_pci->subsystem_device; 2120a2fcaa7SHauke Mehrtens 213dc8ecdd3SRafał Miłecki /* Initialize struct, detect chip */ 214dc8ecdd3SRafał Miłecki bcma_init_bus(bus); 215dc8ecdd3SRafał Miłecki 2169b6cc9a8SRafał Miłecki /* Scan bus to find out generation of PCIe core */ 2179b6cc9a8SRafał Miłecki err = bcma_bus_scan(bus); 2189b6cc9a8SRafał Miłecki if (err) 2199b6cc9a8SRafał Miłecki goto err_pci_unmap_mmio; 2209b6cc9a8SRafał Miłecki 2219b6cc9a8SRafał Miłecki if (bcma_find_core(bus, BCMA_CORE_PCIE2)) 2229b6cc9a8SRafał Miłecki bus->host_is_pcie2 = true; 2239b6cc9a8SRafał Miłecki 2248369ae33SRafał Miłecki /* Register */ 2258369ae33SRafał Miłecki err = bcma_bus_register(bus); 2268369ae33SRafał Miłecki if (err) 2279b6cc9a8SRafał Miłecki goto err_unregister_cores; 2288369ae33SRafał Miłecki 2298369ae33SRafał Miłecki pci_set_drvdata(dev, bus); 2308369ae33SRafał Miłecki 2318369ae33SRafał Miłecki out: 2328369ae33SRafał Miłecki return err; 2338369ae33SRafał Miłecki 2349b6cc9a8SRafał Miłecki err_unregister_cores: 2359b6cc9a8SRafał Miłecki bcma_unregister_cores(bus); 2368369ae33SRafał Miłecki err_pci_unmap_mmio: 2378369ae33SRafał Miłecki pci_iounmap(dev, bus->mmio); 2388369ae33SRafał Miłecki err_pci_release_regions: 2398369ae33SRafał Miłecki pci_release_regions(dev); 2408369ae33SRafał Miłecki err_pci_disable: 2418369ae33SRafał Miłecki pci_disable_device(dev); 2428369ae33SRafał Miłecki err_kfree_bus: 2438369ae33SRafał Miłecki kfree(bus); 2448369ae33SRafał Miłecki return err; 2458369ae33SRafał Miłecki } 2468369ae33SRafał Miłecki 2470f58a01dSGreg Kroah-Hartman static void bcma_host_pci_remove(struct pci_dev *dev) 2488369ae33SRafał Miłecki { 2498369ae33SRafał Miłecki struct bcma_bus *bus = pci_get_drvdata(dev); 2508369ae33SRafał Miłecki 2518369ae33SRafał Miłecki bcma_bus_unregister(bus); 2528369ae33SRafał Miłecki pci_iounmap(dev, bus->mmio); 2538369ae33SRafał Miłecki pci_release_regions(dev); 2548369ae33SRafał Miłecki pci_disable_device(dev); 2558369ae33SRafał Miłecki kfree(bus); 2568369ae33SRafał Miłecki } 2578369ae33SRafał Miłecki 258ccd60953SYuanhan Liu #ifdef CONFIG_PM_SLEEP 2595d2031f2SLinus Torvalds static int bcma_host_pci_suspend(struct device *dev) 260775ab521SRafał Miłecki { 2615d2031f2SLinus Torvalds struct pci_dev *pdev = to_pci_dev(dev); 2625d2031f2SLinus Torvalds struct bcma_bus *bus = pci_get_drvdata(pdev); 263775ab521SRafał Miłecki 26428e7d218SRafał Miłecki bus->mapped_core = NULL; 2655d2031f2SLinus Torvalds 266685a4ef0SLinus Torvalds return bcma_bus_suspend(bus); 267775ab521SRafał Miłecki } 268775ab521SRafał Miłecki 2695d2031f2SLinus Torvalds static int bcma_host_pci_resume(struct device *dev) 270775ab521SRafał Miłecki { 2715d2031f2SLinus Torvalds struct pci_dev *pdev = to_pci_dev(dev); 2725d2031f2SLinus Torvalds struct bcma_bus *bus = pci_get_drvdata(pdev); 273775ab521SRafał Miłecki 2745d2031f2SLinus Torvalds return bcma_bus_resume(bus); 275775ab521SRafał Miłecki } 2765d2031f2SLinus Torvalds 2775d2031f2SLinus Torvalds static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend, 2785d2031f2SLinus Torvalds bcma_host_pci_resume); 2795d2031f2SLinus Torvalds #define BCMA_PM_OPS (&bcma_pm_ops) 2805d2031f2SLinus Torvalds 281ccd60953SYuanhan Liu #else /* CONFIG_PM_SLEEP */ 2825d2031f2SLinus Torvalds 2835d2031f2SLinus Torvalds #define BCMA_PM_OPS NULL 2845d2031f2SLinus Torvalds 285ccd60953SYuanhan Liu #endif /* CONFIG_PM_SLEEP */ 286775ab521SRafał Miłecki 287342a11e1SJingoo Han static const struct pci_device_id bcma_pci_bridge_tbl[] = { 2889594b56dSRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, 289b9f54bd0SHauke Mehrtens { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) }, 29034b6d429SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) }, /* 0xa8d8 */ 2918369ae33SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, 2928369ae33SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, 29391fa4b0aSRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, 294646e0827SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, 295c263c2c1SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, 2969b6cc9a8SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, 29788f9b65dSRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, 2989b6cc9a8SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, 299d1d3799fSRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, 30027cfdb05SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, 3019b6cc9a8SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) }, 3028369ae33SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, 30334b6d429SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ 30434b6d429SRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ 3058369ae33SRafał Miłecki { 0, }, 3068369ae33SRafał Miłecki }; 3078369ae33SRafał Miłecki MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); 3088369ae33SRafał Miłecki 3098369ae33SRafał Miłecki static struct pci_driver bcma_pci_bridge_driver = { 3108369ae33SRafał Miłecki .name = "bcma-pci-bridge", 3118369ae33SRafał Miłecki .id_table = bcma_pci_bridge_tbl, 3128369ae33SRafał Miłecki .probe = bcma_host_pci_probe, 3130f58a01dSGreg Kroah-Hartman .remove = bcma_host_pci_remove, 3145d2031f2SLinus Torvalds .driver.pm = BCMA_PM_OPS, 3158369ae33SRafał Miłecki }; 3168369ae33SRafał Miłecki 3178369ae33SRafał Miłecki int __init bcma_host_pci_init(void) 3188369ae33SRafał Miłecki { 3198369ae33SRafał Miłecki return pci_register_driver(&bcma_pci_bridge_driver); 3208369ae33SRafał Miłecki } 3218369ae33SRafał Miłecki 3228369ae33SRafał Miłecki void __exit bcma_host_pci_exit(void) 3238369ae33SRafał Miłecki { 3248369ae33SRafał Miłecki pci_unregister_driver(&bcma_pci_bridge_driver); 3258369ae33SRafał Miłecki } 3264186721dSRafał Miłecki 3274186721dSRafał Miłecki /************************************************** 3284186721dSRafał Miłecki * Runtime ops for drivers. 3294186721dSRafał Miłecki **************************************************/ 3304186721dSRafał Miłecki 3314186721dSRafał Miłecki /* See also pcicore_up */ 3324186721dSRafał Miłecki void bcma_host_pci_up(struct bcma_bus *bus) 3334186721dSRafał Miłecki { 3344186721dSRafał Miłecki if (bus->hosttype != BCMA_HOSTTYPE_PCI) 3354186721dSRafał Miłecki return; 3364186721dSRafał Miłecki 3374186721dSRafał Miłecki if (bus->host_is_pcie2) 338804e27deSRafał Miłecki bcma_core_pcie2_up(&bus->drv_pcie2); 3394186721dSRafał Miłecki else 3404186721dSRafał Miłecki bcma_core_pci_up(&bus->drv_pci[0]); 3414186721dSRafał Miłecki } 3424186721dSRafał Miłecki EXPORT_SYMBOL_GPL(bcma_host_pci_up); 3434186721dSRafał Miłecki 3444186721dSRafał Miłecki /* See also pcicore_down */ 3454186721dSRafał Miłecki void bcma_host_pci_down(struct bcma_bus *bus) 3464186721dSRafał Miłecki { 3474186721dSRafał Miłecki if (bus->hosttype != BCMA_HOSTTYPE_PCI) 3484186721dSRafał Miłecki return; 3494186721dSRafał Miłecki 3504186721dSRafał Miłecki if (!bus->host_is_pcie2) 3514186721dSRafał Miłecki bcma_core_pci_down(&bus->drv_pci[0]); 3524186721dSRafał Miłecki } 3534186721dSRafał Miłecki EXPORT_SYMBOL_GPL(bcma_host_pci_down); 354*702131e2SRafał Miłecki 355*702131e2SRafał Miłecki /* See also si_pci_setup */ 356*702131e2SRafał Miłecki int bcma_host_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core, 357*702131e2SRafał Miłecki bool enable) 358*702131e2SRafał Miłecki { 359*702131e2SRafał Miłecki struct pci_dev *pdev; 360*702131e2SRafał Miłecki u32 coremask, tmp; 361*702131e2SRafał Miłecki int err = 0; 362*702131e2SRafał Miłecki 363*702131e2SRafał Miłecki if (bus->hosttype != BCMA_HOSTTYPE_PCI) { 364*702131e2SRafał Miłecki /* This bcma device is not on a PCI host-bus. So the IRQs are 365*702131e2SRafał Miłecki * not routed through the PCI core. 366*702131e2SRafał Miłecki * So we must not enable routing through the PCI core. */ 367*702131e2SRafał Miłecki goto out; 368*702131e2SRafał Miłecki } 369*702131e2SRafał Miłecki 370*702131e2SRafał Miłecki pdev = bus->host_pci; 371*702131e2SRafał Miłecki 372*702131e2SRafał Miłecki err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); 373*702131e2SRafał Miłecki if (err) 374*702131e2SRafał Miłecki goto out; 375*702131e2SRafał Miłecki 376*702131e2SRafał Miłecki coremask = BIT(core->core_index) << 8; 377*702131e2SRafał Miłecki if (enable) 378*702131e2SRafał Miłecki tmp |= coremask; 379*702131e2SRafał Miłecki else 380*702131e2SRafał Miłecki tmp &= ~coremask; 381*702131e2SRafał Miłecki 382*702131e2SRafał Miłecki err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp); 383*702131e2SRafał Miłecki 384*702131e2SRafał Miłecki out: 385*702131e2SRafał Miłecki return err; 386*702131e2SRafał Miłecki } 387*702131e2SRafał Miłecki EXPORT_SYMBOL_GPL(bcma_host_pci_irq_ctl); 388