1 /* 2 * Broadcom specific AMBA 3 * PCI Core in hostmode 4 * 5 * Copyright 2005 - 2011, Broadcom Corporation 6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 7 * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> 8 * 9 * Licensed under the GNU/GPL. See COPYING for details. 10 */ 11 12 #include "bcma_private.h" 13 #include <linux/pci.h> 14 #include <linux/export.h> 15 #include <linux/bcma/bcma.h> 16 #include <asm/paccess.h> 17 18 /* Probe a 32bit value on the bus and catch bus exceptions. 19 * Returns nonzero on a bus exception. 20 * This is MIPS specific */ 21 #define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr))) 22 23 /* Assume one-hot slot wiring */ 24 #define BCMA_PCI_SLOT_MAX 16 25 #define PCI_CONFIG_SPACE_SIZE 256 26 27 bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc) 28 { 29 struct bcma_bus *bus = pc->core->bus; 30 u16 chipid_top; 31 u32 tmp; 32 33 chipid_top = (bus->chipinfo.id & 0xFF00); 34 if (chipid_top != 0x4700 && 35 chipid_top != 0x5300) 36 return false; 37 38 bcma_core_enable(pc->core, 0); 39 40 return !mips_busprobe32(tmp, pc->core->io_addr); 41 } 42 43 static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address) 44 { 45 pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address); 46 pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR); 47 return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA); 48 } 49 50 static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address, 51 u32 data) 52 { 53 pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address); 54 pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR); 55 pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data); 56 } 57 58 static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev, 59 unsigned int func, unsigned int off) 60 { 61 u32 addr = 0; 62 63 /* Issue config commands only when the data link is up (atleast 64 * one external pcie device is present). 65 */ 66 if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG) 67 & BCMA_CORE_PCI_DLLP_LSREG_LINKUP)) 68 goto out; 69 70 /* Type 0 transaction */ 71 /* Slide the PCI window to the appropriate slot */ 72 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0); 73 /* Calculate the address */ 74 addr = pc->host_controller->host_cfg_addr; 75 addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT); 76 addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT); 77 addr |= (off & ~3); 78 79 out: 80 return addr; 81 } 82 83 static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev, 84 unsigned int func, unsigned int off, 85 void *buf, int len) 86 { 87 int err = -EINVAL; 88 u32 addr, val; 89 void __iomem *mmio = 0; 90 91 WARN_ON(!pc->hostmode); 92 if (unlikely(len != 1 && len != 2 && len != 4)) 93 goto out; 94 if (dev == 0) { 95 /* we support only two functions on device 0 */ 96 if (func > 1) 97 return -EINVAL; 98 99 /* accesses to config registers with offsets >= 256 100 * requires indirect access. 101 */ 102 if (off >= PCI_CONFIG_SPACE_SIZE) { 103 addr = (func << 12); 104 addr |= (off & 0x0FFF); 105 val = bcma_pcie_read_config(pc, addr); 106 } else { 107 addr = BCMA_CORE_PCI_PCICFG0; 108 addr |= (func << 8); 109 addr |= (off & 0xfc); 110 val = pcicore_read32(pc, addr); 111 } 112 } else { 113 addr = bcma_get_cfgspace_addr(pc, dev, func, off); 114 if (unlikely(!addr)) 115 goto out; 116 err = -ENOMEM; 117 mmio = ioremap_nocache(addr, sizeof(val)); 118 if (!mmio) 119 goto out; 120 121 if (mips_busprobe32(val, mmio)) { 122 val = 0xffffffff; 123 goto unmap; 124 } 125 126 val = readl(mmio); 127 } 128 val >>= (8 * (off & 3)); 129 130 switch (len) { 131 case 1: 132 *((u8 *)buf) = (u8)val; 133 break; 134 case 2: 135 *((u16 *)buf) = (u16)val; 136 break; 137 case 4: 138 *((u32 *)buf) = (u32)val; 139 break; 140 } 141 err = 0; 142 unmap: 143 if (mmio) 144 iounmap(mmio); 145 out: 146 return err; 147 } 148 149 static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev, 150 unsigned int func, unsigned int off, 151 const void *buf, int len) 152 { 153 int err = -EINVAL; 154 u32 addr = 0, val = 0; 155 void __iomem *mmio = 0; 156 u16 chipid = pc->core->bus->chipinfo.id; 157 158 WARN_ON(!pc->hostmode); 159 if (unlikely(len != 1 && len != 2 && len != 4)) 160 goto out; 161 if (dev == 0) { 162 /* accesses to config registers with offsets >= 256 163 * requires indirect access. 164 */ 165 if (off < PCI_CONFIG_SPACE_SIZE) { 166 addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0; 167 addr |= (func << 8); 168 addr |= (off & 0xfc); 169 mmio = ioremap_nocache(addr, sizeof(val)); 170 if (!mmio) 171 goto out; 172 } 173 } else { 174 addr = bcma_get_cfgspace_addr(pc, dev, func, off); 175 if (unlikely(!addr)) 176 goto out; 177 err = -ENOMEM; 178 mmio = ioremap_nocache(addr, sizeof(val)); 179 if (!mmio) 180 goto out; 181 182 if (mips_busprobe32(val, mmio)) { 183 val = 0xffffffff; 184 goto unmap; 185 } 186 } 187 188 switch (len) { 189 case 1: 190 val = readl(mmio); 191 val &= ~(0xFF << (8 * (off & 3))); 192 val |= *((const u8 *)buf) << (8 * (off & 3)); 193 break; 194 case 2: 195 val = readl(mmio); 196 val &= ~(0xFFFF << (8 * (off & 3))); 197 val |= *((const u16 *)buf) << (8 * (off & 3)); 198 break; 199 case 4: 200 val = *((const u32 *)buf); 201 break; 202 } 203 if (dev == 0 && !addr) { 204 /* accesses to config registers with offsets >= 256 205 * requires indirect access. 206 */ 207 addr = (func << 12); 208 addr |= (off & 0x0FFF); 209 bcma_pcie_write_config(pc, addr, val); 210 } else { 211 writel(val, mmio); 212 213 if (chipid == BCMA_CHIP_ID_BCM4716 || 214 chipid == BCMA_CHIP_ID_BCM4748) 215 readl(mmio); 216 } 217 218 err = 0; 219 unmap: 220 if (mmio) 221 iounmap(mmio); 222 out: 223 return err; 224 } 225 226 static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus, 227 unsigned int devfn, 228 int reg, int size, u32 *val) 229 { 230 unsigned long flags; 231 int err; 232 struct bcma_drv_pci *pc; 233 struct bcma_drv_pci_host *pc_host; 234 235 pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops); 236 pc = pc_host->pdev; 237 238 spin_lock_irqsave(&pc_host->cfgspace_lock, flags); 239 err = bcma_extpci_read_config(pc, PCI_SLOT(devfn), 240 PCI_FUNC(devfn), reg, val, size); 241 spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags); 242 243 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 244 } 245 246 static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus, 247 unsigned int devfn, 248 int reg, int size, u32 val) 249 { 250 unsigned long flags; 251 int err; 252 struct bcma_drv_pci *pc; 253 struct bcma_drv_pci_host *pc_host; 254 255 pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops); 256 pc = pc_host->pdev; 257 258 spin_lock_irqsave(&pc_host->cfgspace_lock, flags); 259 err = bcma_extpci_write_config(pc, PCI_SLOT(devfn), 260 PCI_FUNC(devfn), reg, &val, size); 261 spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags); 262 263 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 264 } 265 266 /* return cap_offset if requested capability exists in the PCI config space */ 267 static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc, 268 unsigned int dev, 269 unsigned int func, u8 req_cap_id, 270 unsigned char *buf, u32 *buflen) 271 { 272 u8 cap_id; 273 u8 cap_ptr = 0; 274 u32 bufsize; 275 u8 byte_val; 276 277 /* check for Header type 0 */ 278 bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val, 279 sizeof(u8)); 280 if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL) 281 return cap_ptr; 282 283 /* check if the capability pointer field exists */ 284 bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val, 285 sizeof(u8)); 286 if (!(byte_val & PCI_STATUS_CAP_LIST)) 287 return cap_ptr; 288 289 /* check if the capability pointer is 0x00 */ 290 bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr, 291 sizeof(u8)); 292 if (cap_ptr == 0x00) 293 return cap_ptr; 294 295 /* loop thr'u the capability list and see if the requested capabilty 296 * exists */ 297 bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8)); 298 while (cap_id != req_cap_id) { 299 bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr, 300 sizeof(u8)); 301 if (cap_ptr == 0x00) 302 return cap_ptr; 303 bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, 304 sizeof(u8)); 305 } 306 307 /* found the caller requested capability */ 308 if ((buf != NULL) && (buflen != NULL)) { 309 u8 cap_data; 310 311 bufsize = *buflen; 312 if (!bufsize) 313 return cap_ptr; 314 315 *buflen = 0; 316 317 /* copy the cpability data excluding cap ID and next ptr */ 318 cap_data = cap_ptr + 2; 319 if ((bufsize + cap_data) > PCI_CONFIG_SPACE_SIZE) 320 bufsize = PCI_CONFIG_SPACE_SIZE - cap_data; 321 *buflen = bufsize; 322 while (bufsize--) { 323 bcma_extpci_read_config(pc, dev, func, cap_data, buf, 324 sizeof(u8)); 325 cap_data++; 326 buf++; 327 } 328 } 329 330 return cap_ptr; 331 } 332 333 /* If the root port is capable of returning Config Request 334 * Retry Status (CRS) Completion Status to software then 335 * enable the feature. 336 */ 337 static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc) 338 { 339 struct bcma_bus *bus = pc->core->bus; 340 u8 cap_ptr, root_ctrl, root_cap, dev; 341 u16 val16; 342 int i; 343 344 cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL, 345 NULL); 346 root_cap = cap_ptr + PCI_EXP_RTCAP; 347 bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16)); 348 if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) { 349 /* Enable CRS software visibility */ 350 root_ctrl = cap_ptr + PCI_EXP_RTCTL; 351 val16 = PCI_EXP_RTCTL_CRSSVE; 352 bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16, 353 sizeof(u16)); 354 355 /* Initiate a configuration request to read the vendor id 356 * field of the device function's config space header after 357 * 100 ms wait time from the end of Reset. If the device is 358 * not done with its internal initialization, it must at 359 * least return a completion TLP, with a completion status 360 * of "Configuration Request Retry Status (CRS)". The root 361 * complex must complete the request to the host by returning 362 * a read-data value of 0001h for the Vendor ID field and 363 * all 1s for any additional bytes included in the request. 364 * Poll using the config reads for max wait time of 1 sec or 365 * until we receive the successful completion status. Repeat 366 * the procedure for all the devices. 367 */ 368 for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) { 369 for (i = 0; i < 100000; i++) { 370 bcma_extpci_read_config(pc, dev, 0, 371 PCI_VENDOR_ID, &val16, 372 sizeof(val16)); 373 if (val16 != 0x1) 374 break; 375 udelay(10); 376 } 377 if (val16 == 0x1) 378 bcma_err(bus, "PCI: Broken device in slot %d\n", 379 dev); 380 } 381 } 382 } 383 384 void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) 385 { 386 struct bcma_bus *bus = pc->core->bus; 387 struct bcma_drv_pci_host *pc_host; 388 u32 tmp; 389 u32 pci_membase_1G; 390 unsigned long io_map_base; 391 392 bcma_info(bus, "PCIEcore in host mode found\n"); 393 394 if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) { 395 bcma_info(bus, "This PCIE core is disabled and not working\n"); 396 return; 397 } 398 399 pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); 400 if (!pc_host) { 401 bcma_err(bus, "can not allocate memory"); 402 return; 403 } 404 405 pc->host_controller = pc_host; 406 pc_host->pci_controller.io_resource = &pc_host->io_resource; 407 pc_host->pci_controller.mem_resource = &pc_host->mem_resource; 408 pc_host->pci_controller.pci_ops = &pc_host->pci_ops; 409 pc_host->pdev = pc; 410 411 pci_membase_1G = BCMA_SOC_PCI_DMA; 412 pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG; 413 414 pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config; 415 pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config; 416 417 pc_host->mem_resource.name = "BCMA PCIcore external memory", 418 pc_host->mem_resource.start = BCMA_SOC_PCI_DMA; 419 pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1; 420 pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED; 421 422 pc_host->io_resource.name = "BCMA PCIcore external I/O", 423 pc_host->io_resource.start = 0x100; 424 pc_host->io_resource.end = 0x7FF; 425 pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED; 426 427 /* Reset RC */ 428 usleep_range(3000, 5000); 429 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE); 430 usleep_range(1000, 2000); 431 pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST | 432 BCMA_CORE_PCI_CTL_RST_OE); 433 434 /* 64 MB I/O access window. On 4716, use 435 * sbtopcie0 to access the device registers. We 436 * can't use address match 2 (1 GB window) region 437 * as mips can't generate 64-bit address on the 438 * backplane. 439 */ 440 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4716 || 441 bus->chipinfo.id == BCMA_CHIP_ID_BCM4748) { 442 pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; 443 pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + 444 BCMA_SOC_PCI_MEM_SZ - 1; 445 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, 446 BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM); 447 } else if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { 448 tmp = BCMA_CORE_PCI_SBTOPCI_MEM; 449 tmp |= BCMA_CORE_PCI_SBTOPCI_PREF; 450 tmp |= BCMA_CORE_PCI_SBTOPCI_BURST; 451 if (pc->core->core_unit == 0) { 452 pc_host->mem_resource.start = BCMA_SOC_PCI_MEM; 453 pc_host->mem_resource.end = BCMA_SOC_PCI_MEM + 454 BCMA_SOC_PCI_MEM_SZ - 1; 455 pc_host->io_resource.start = 0x100; 456 pc_host->io_resource.end = 0x47F; 457 pci_membase_1G = BCMA_SOC_PCIE_DMA_H32; 458 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, 459 tmp | BCMA_SOC_PCI_MEM); 460 } else if (pc->core->core_unit == 1) { 461 pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM; 462 pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM + 463 BCMA_SOC_PCI_MEM_SZ - 1; 464 pc_host->io_resource.start = 0x480; 465 pc_host->io_resource.end = 0x7FF; 466 pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32; 467 pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG; 468 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, 469 tmp | BCMA_SOC_PCI1_MEM); 470 } 471 } else 472 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0, 473 BCMA_CORE_PCI_SBTOPCI_IO); 474 475 /* 64 MB configuration access window */ 476 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0); 477 478 /* 1 GB memory access window */ 479 pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2, 480 BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G); 481 482 483 /* As per PCI Express Base Spec 1.1 we need to wait for 484 * at least 100 ms from the end of a reset (cold/warm/hot) 485 * before issuing configuration requests to PCI Express 486 * devices. 487 */ 488 msleep(100); 489 490 bcma_core_pci_enable_crs(pc); 491 492 /* Enable PCI bridge BAR0 memory & master access */ 493 tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; 494 bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp)); 495 496 /* Enable PCI interrupts */ 497 pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA); 498 499 /* Ok, ready to run, register it to the system. 500 * The following needs change, if we want to port hostmode 501 * to non-MIPS platform. */ 502 io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start, 503 resource_size(&pc_host->mem_resource)); 504 pc_host->pci_controller.io_map_base = io_map_base; 505 set_io_port_base(pc_host->pci_controller.io_map_base); 506 /* Give some time to the PCI controller to configure itself with the new 507 * values. Not waiting at this point causes crashes of the machine. */ 508 usleep_range(10000, 15000); 509 register_pci_controller(&pc_host->pci_controller); 510 return; 511 } 512 513 /* Early PCI fixup for a device on the PCI-core bridge. */ 514 static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev) 515 { 516 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { 517 /* This is not a device on the PCI-core bridge. */ 518 return; 519 } 520 if (PCI_SLOT(dev->devfn) != 0) 521 return; 522 523 pr_info("PCI: Fixing up bridge %s\n", pci_name(dev)); 524 525 /* Enable PCI bridge bus mastering and memory space */ 526 pci_set_master(dev); 527 if (pcibios_enable_device(dev, ~0) < 0) { 528 pr_err("PCI: BCMA bridge enable failed\n"); 529 return; 530 } 531 532 /* Enable PCI bridge BAR1 prefetch and burst */ 533 pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3); 534 } 535 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge); 536 537 /* Early PCI fixup for all PCI-cores to set the correct memory address. */ 538 static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) 539 { 540 struct resource *res; 541 int pos, err; 542 543 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { 544 /* This is not a device on the PCI-core bridge. */ 545 return; 546 } 547 if (PCI_SLOT(dev->devfn) == 0) 548 return; 549 550 pr_info("PCI: Fixing up addresses %s\n", pci_name(dev)); 551 552 for (pos = 0; pos < 6; pos++) { 553 res = &dev->resource[pos]; 554 if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) { 555 err = pci_assign_resource(dev, pos); 556 if (err) 557 pr_err("PCI: Problem fixing up the addresses on %s\n", 558 pci_name(dev)); 559 } 560 } 561 } 562 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); 563 564 /* This function is called when doing a pci_enable_device(). 565 * We must first check if the device is a device on the PCI-core bridge. */ 566 int bcma_core_pci_plat_dev_init(struct pci_dev *dev) 567 { 568 struct bcma_drv_pci_host *pc_host; 569 570 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { 571 /* This is not a device on the PCI-core bridge. */ 572 return -ENODEV; 573 } 574 pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, 575 pci_ops); 576 577 pr_info("PCI: Fixing up device %s\n", pci_name(dev)); 578 579 /* Fix up interrupt lines */ 580 dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2; 581 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 582 583 return 0; 584 } 585 EXPORT_SYMBOL(bcma_core_pci_plat_dev_init); 586 587 /* PCI device IRQ mapping. */ 588 int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev) 589 { 590 struct bcma_drv_pci_host *pc_host; 591 592 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { 593 /* This is not a device on the PCI-core bridge. */ 594 return -ENODEV; 595 } 596 597 pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host, 598 pci_ops); 599 return bcma_core_mips_irq(pc_host->pdev->core) + 2; 600 } 601 EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq); 602