host_pci.c revision 28e7d218da975f6ae1751e293aed938952c55c98
18369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki/* 28369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki * Broadcom specific AMBA 38369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki * PCI Host 48369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki * 58369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 68369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki */ 78369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 88369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki#include "bcma_private.h" 9ba7328b2d83090c2440b8d0baa6ccfc2ddf1bda6Andrew Morton#include <linux/slab.h> 108369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki#include <linux/bcma/bcma.h> 118369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki#include <linux/pci.h> 12200351c77d6aa7fc36d3a49132c68e95ad9654c8Paul Gortmaker#include <linux/module.h> 138369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 148369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_switch_core(struct bcma_device *core) 158369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 168369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, 178369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki core->addr); 188369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2, 198369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki core->wrap); 208369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki core->bus->mapped_core = core; 218369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pr_debug("Switched to core: 0x%X\n", core->id.id); 228369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 238369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 24439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki/* Provides access to the requested core. Returns base offset that has to be 25439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki * used. It makes use of fixed windows when possible. */ 26439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłeckistatic u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core) 278369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 28439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki switch (core->id.id) { 29439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki case BCMA_CORE_CHIPCOMMON: 30439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki return 3 * BCMA_CORE_SIZE; 31439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki case BCMA_CORE_PCIE: 32439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki return 2 * BCMA_CORE_SIZE; 33439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki } 34439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki 358369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (core->bus->mapped_core != core) 368369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bcma_host_pci_switch_core(core); 37439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki return 0; 38439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki} 39439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki 40439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłeckistatic u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset) 41439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki{ 42439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 438369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return ioread8(core->bus->mmio + offset); 448369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 458369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 468369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset) 478369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 48439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 498369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return ioread16(core->bus->mmio + offset); 508369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 518369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 528369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset) 538369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 54439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 558369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return ioread32(core->bus->mmio + offset); 568369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 578369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 588369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_write8(struct bcma_device *core, u16 offset, 598369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki u8 value) 608369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 61439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 628369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki iowrite8(value, core->bus->mmio + offset); 638369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 648369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 658369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_write16(struct bcma_device *core, u16 offset, 668369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki u16 value) 678369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 68439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 698369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki iowrite16(value, core->bus->mmio + offset); 708369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 718369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 728369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_write32(struct bcma_device *core, u16 offset, 738369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki u32 value) 748369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 75439678f8b0fca7aeca06c6581e3679eef618721aRafał Miłecki offset += bcma_host_pci_provide_access_to_core(core); 768369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki iowrite32(value, core->bus->mmio + offset); 778369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 788369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 799d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki#ifdef CONFIG_BCMA_BLOCKIO 809d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłeckivoid bcma_host_pci_block_read(struct bcma_device *core, void *buffer, 819d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki size_t count, u16 offset, u8 reg_width) 829d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki{ 839d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki void __iomem *addr = core->bus->mmio + offset; 849d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki if (core->bus->mapped_core != core) 859d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki bcma_host_pci_switch_core(core); 869d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki switch (reg_width) { 879d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u8): 889d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki ioread8_rep(addr, buffer, count); 899d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 909d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u16): 919d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(count & 1); 929d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki ioread16_rep(addr, buffer, count >> 1); 939d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 949d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u32): 959d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(count & 3); 969d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki ioread32_rep(addr, buffer, count >> 2); 979d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 989d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki default: 999d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(1); 1009d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki } 1019d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki} 1029d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki 1039d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłeckivoid bcma_host_pci_block_write(struct bcma_device *core, const void *buffer, 1049d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki size_t count, u16 offset, u8 reg_width) 1059d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki{ 1069d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki void __iomem *addr = core->bus->mmio + offset; 1079d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki if (core->bus->mapped_core != core) 1089d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki bcma_host_pci_switch_core(core); 1099d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki switch (reg_width) { 1109d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u8): 1119d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki iowrite8_rep(addr, buffer, count); 1129d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 1139d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u16): 1149d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(count & 1); 1159d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki iowrite16_rep(addr, buffer, count >> 1); 1169d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 1179d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki case sizeof(u32): 1189d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(count & 3); 1199d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki iowrite32_rep(addr, buffer, count >> 2); 1209d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki break; 1219d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki default: 1229d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki WARN_ON(1); 1239d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki } 1249d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki} 1259d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki#endif 1269d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki 1278369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) 1288369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 1298369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (core->bus->mapped_core != core) 1308369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bcma_host_pci_switch_core(core); 1318369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); 1328369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 1338369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1348369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset, 1358369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki u32 value) 1368369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 1378369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (core->bus->mapped_core != core) 1388369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bcma_host_pci_switch_core(core); 1398369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset); 1408369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 1418369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1428369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckiconst struct bcma_host_ops bcma_host_pci_ops = { 1438369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .read8 = bcma_host_pci_read8, 1448369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .read16 = bcma_host_pci_read16, 1458369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .read32 = bcma_host_pci_read32, 1468369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .write8 = bcma_host_pci_write8, 1478369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .write16 = bcma_host_pci_write16, 1488369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .write32 = bcma_host_pci_write32, 1499d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki#ifdef CONFIG_BCMA_BLOCKIO 1509d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki .block_read = bcma_host_pci_block_read, 1519d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki .block_write = bcma_host_pci_block_write, 1529d75ef0f8f6d2e31ed940b3057a42a25f07076fbRafał Miłecki#endif 1538369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .aread32 = bcma_host_pci_aread32, 1548369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .awrite32 = bcma_host_pci_awrite32, 1558369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki}; 1568369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1578369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic int bcma_host_pci_probe(struct pci_dev *dev, 1588369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki const struct pci_device_id *id) 1598369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 1608369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki struct bcma_bus *bus; 1618369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki int err = -ENOMEM; 1628369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki const char *name; 1638369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki u32 val; 1648369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1658369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Alloc */ 1668369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bus = kzalloc(sizeof(*bus), GFP_KERNEL); 1678369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (!bus) 1688369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki goto out; 1698369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1708369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Basic PCI configuration */ 1718369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki err = pci_enable_device(dev); 1728369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (err) 1738369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki goto err_kfree_bus; 1748369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1758369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki name = dev_name(&dev->dev); 1768369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (dev->driver && dev->driver->name) 1778369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki name = dev->driver->name; 1788369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki err = pci_request_regions(dev, name); 1798369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (err) 1808369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki goto err_pci_disable; 1818369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_set_master(dev); 1828369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1838369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Disable the RETRY_TIMEOUT register (0x41) to keep 1848369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki * PCI Tx retries from interfering with C3 CPU state */ 1858369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_read_config_dword(dev, 0x40, &val); 1868369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if ((val & 0x0000ff00) != 0) 1878369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_write_config_dword(dev, 0x40, val & 0xffff00ff); 1888369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1898369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* SSB needed additional powering up, do we have any AMBA PCI cards? */ 1908369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (!pci_is_pcie(dev)) 1918369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pr_err("PCI card detected, report problems.\n"); 1928369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1938369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Map MMIO */ 1948369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki err = -ENOMEM; 1958369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bus->mmio = pci_iomap(dev, 0, ~0UL); 1968369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (!bus->mmio) 1978369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki goto err_pci_release_regions; 1988369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 1998369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Host specific */ 2008369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bus->host_pci = dev; 2018369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bus->hosttype = BCMA_HOSTTYPE_PCI; 2028369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bus->ops = &bcma_host_pci_ops; 2038369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2048369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki /* Register */ 2058369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki err = bcma_bus_register(bus); 2068369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki if (err) 2078369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki goto err_pci_unmap_mmio; 2088369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2098369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_set_drvdata(dev, bus); 2108369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2118369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckiout: 2128369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return err; 2138369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2148369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckierr_pci_unmap_mmio: 2158369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_iounmap(dev, bus->mmio); 2168369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckierr_pci_release_regions: 2178369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_release_regions(dev); 2188369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckierr_pci_disable: 2198369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_disable_device(dev); 2208369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckierr_kfree_bus: 2218369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki kfree(bus); 2228369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return err; 2238369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 2248369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2258369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic void bcma_host_pci_remove(struct pci_dev *dev) 2268369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 2278369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki struct bcma_bus *bus = pci_get_drvdata(dev); 2288369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2298369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki bcma_bus_unregister(bus); 2308369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_iounmap(dev, bus->mmio); 2318369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_release_regions(dev); 2328369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_disable_device(dev); 2338369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki kfree(bus); 2348369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_set_drvdata(dev, NULL); 2358369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 2368369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 237775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki#ifdef CONFIG_PM 238775ab52142b02237a54184238e922251c59a2b5cRafał Miłeckistatic int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state) 239775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki{ 24028e7d218da975f6ae1751e293aed938952c55c98Rafał Miłecki struct bcma_bus *bus = pci_get_drvdata(dev); 24128e7d218da975f6ae1751e293aed938952c55c98Rafał Miłecki 242775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki /* Host specific */ 243775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki pci_save_state(dev); 244775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki pci_disable_device(dev); 245775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki pci_set_power_state(dev, pci_choose_state(dev, state)); 246775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 24728e7d218da975f6ae1751e293aed938952c55c98Rafał Miłecki bus->mapped_core = NULL; 248775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki return 0; 249775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki} 250775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 251775ab52142b02237a54184238e922251c59a2b5cRafał Miłeckistatic int bcma_host_pci_resume(struct pci_dev *dev) 252775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki{ 253775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki struct bcma_bus *bus = pci_get_drvdata(dev); 254775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki int err; 255775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 256775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki /* Host specific */ 257775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki pci_set_power_state(dev, 0); 258775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki err = pci_enable_device(dev); 259775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki if (err) 260775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki return err; 261775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki pci_restore_state(dev); 262775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 263775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki /* Bus specific */ 264775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki err = bcma_bus_resume(bus); 265775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki if (err) 266775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki return err; 267775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 268775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki return 0; 269775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki} 270775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki#else /* CONFIG_PM */ 271775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki# define bcma_host_pci_suspend NULL 272775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki# define bcma_host_pci_resume NULL 273775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki#endif /* CONFIG_PM */ 274775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki 2758369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { 2769594b56dbed8cecc4694ed2ab7cf36c66623910eRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, 2778369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, 2788369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, 27991fa4b0a6b92ebef3d5e26b709faf62a3b44beb0Rafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, 2808369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, 2818369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki { 0, }, 2828369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki}; 2838369ae33b705222aa05ab53c7d6b4458f4ed161bRafał MiłeckiMODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl); 2848369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2858369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic struct pci_driver bcma_pci_bridge_driver = { 2868369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .name = "bcma-pci-bridge", 2878369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .id_table = bcma_pci_bridge_tbl, 2888369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .probe = bcma_host_pci_probe, 2898369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki .remove = bcma_host_pci_remove, 290775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki .suspend = bcma_host_pci_suspend, 291775ab52142b02237a54184238e922251c59a2b5cRafał Miłecki .resume = bcma_host_pci_resume, 2928369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki}; 2938369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2948369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckiint __init bcma_host_pci_init(void) 2958369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 2968369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki return pci_register_driver(&bcma_pci_bridge_driver); 2978369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 2988369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki 2998369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckivoid __exit bcma_host_pci_exit(void) 3008369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{ 3018369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki pci_unregister_driver(&bcma_pci_bridge_driver); 3028369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki} 303