ar724x_pci.c revision 287882
1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 3 * Copyright (c) 2011, Luiz Otavio O Souza. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice unmodified, this list of conditions, and the following 11 * disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/sys/mips/atheros/ar724x_pci.c 287882 2015-09-16 23:34:51Z zbb $"); 31 32#include "opt_ar71xx.h" 33 34#include <sys/param.h> 35#include <sys/systm.h> 36 37#include <sys/bus.h> 38#include <sys/interrupt.h> 39#include <sys/malloc.h> 40#include <sys/kernel.h> 41#include <sys/module.h> 42#include <sys/rman.h> 43 44#include <vm/vm.h> 45#include <vm/pmap.h> 46#include <vm/vm_extern.h> 47 48#include <machine/bus.h> 49#include <machine/cpu.h> 50#include <machine/intr_machdep.h> 51#include <machine/pmap.h> 52 53#include <dev/pci/pcivar.h> 54#include <dev/pci/pcireg.h> 55 56#include <dev/pci/pcib_private.h> 57#include "pcib_if.h" 58 59#include <mips/atheros/ar71xxreg.h> 60#include <mips/atheros/ar724xreg.h> 61#include <mips/atheros/ar71xx_setup.h> 62#include <mips/atheros/ar71xx_pci_bus_space.h> 63 64#include <mips/atheros/ar71xx_cpudef.h> 65 66#ifdef AR71XX_ATH_EEPROM 67#include <mips/atheros/ar71xx_fixup.h> 68#endif /* AR71XX_ATH_EEPROM */ 69 70#undef AR724X_PCI_DEBUG 71#ifdef AR724X_PCI_DEBUG 72#define dprintf printf 73#else 74#define dprintf(x, arg...) 75#endif 76 77struct ar71xx_pci_softc { 78 device_t sc_dev; 79 80 int sc_busno; 81 struct rman sc_mem_rman; 82 struct rman sc_irq_rman; 83 84 struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; 85 mips_intrcnt_t sc_intr_counter[AR71XX_PCI_NIRQS]; 86 struct resource *sc_irq; 87 void *sc_ih; 88}; 89 90static int ar724x_pci_setup_intr(device_t, device_t, struct resource *, int, 91 driver_filter_t *, driver_intr_t *, void *, void **); 92static int ar724x_pci_teardown_intr(device_t, device_t, struct resource *, 93 void *); 94static int ar724x_pci_intr(void *); 95 96static void 97ar724x_pci_write(uint32_t reg, uint32_t offset, uint32_t data, int bytes) 98{ 99 uint32_t val, mask, shift; 100 101 /* Register access is 32-bit aligned */ 102 shift = (offset & 3) * 8; 103 if (bytes % 4) 104 mask = (1 << (bytes * 8)) - 1; 105 else 106 mask = 0xffffffff; 107 108 val = ATH_READ_REG(reg + (offset & ~3)); 109 val &= ~(mask << shift); 110 val |= ((data & mask) << shift); 111 ATH_WRITE_REG(reg + (offset & ~3), val); 112 113 dprintf("%s: %#x/%#x addr=%#x, data=%#x(%#x), bytes=%d\n", __func__, 114 reg, reg + (offset & ~3), offset, data, val, bytes); 115} 116 117static uint32_t 118ar724x_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 119 u_int reg, int bytes) 120{ 121 uint32_t data, shift, mask; 122 123 /* Register access is 32-bit aligned */ 124 shift = (reg & 3) * 8; 125 126 /* Create a mask based on the width, post-shift */ 127 if (bytes == 2) 128 mask = 0xffff; 129 else if (bytes == 1) 130 mask = 0xff; 131 else 132 mask = 0xffffffff; 133 134 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 135 func, reg, bytes); 136 137 if ((bus == 0) && (slot == 0) && (func == 0)) 138 data = ATH_READ_REG(AR724X_PCI_CFG_BASE + (reg & ~3)); 139 else 140 data = -1; 141 142 /* Get request bytes from 32-bit word */ 143 data = (data >> shift) & mask; 144 145 dprintf("%s: read 0x%x\n", __func__, data); 146 147 return (data); 148} 149 150static void 151ar724x_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 152 u_int reg, uint32_t data, int bytes) 153{ 154 155 dprintf("%s: tag (%x, %x, %x) reg %d(%d): %x\n", __func__, bus, slot, 156 func, reg, bytes, data); 157 158 if ((bus != 0) || (slot != 0) || (func != 0)) 159 return; 160 161 /* 162 * WAR for BAR issue on AR7240 - We are unable to access the PCI 163 * device space if we set the BAR with proper base address. 164 * 165 * However, we _do_ want to allow programming in the probe value 166 * (0xffffffff) so the PCI code can find out how big the memory 167 * map is for this device. Without it, it'll think the memory 168 * map is 32 bits wide, the PCI code will then end up thinking 169 * the register window is '0' and fail to allocate resources. 170 */ 171 if (reg == PCIR_BAR(0) && bytes == 4 172 && ar71xx_soc == AR71XX_SOC_AR7240 173 && data != 0xffffffff) 174 ar724x_pci_write(AR724X_PCI_CFG_BASE, reg, 0xffff, bytes); 175 else 176 ar724x_pci_write(AR724X_PCI_CFG_BASE, reg, data, bytes); 177} 178 179static void 180ar724x_pci_mask_irq(void *source) 181{ 182 uint32_t reg; 183 unsigned int irq = (unsigned int)source; 184 185 /* XXX - Only one interrupt ? Only one device ? */ 186 if (irq != AR71XX_PCI_IRQ_START) 187 return; 188 189 /* Update the interrupt mask reg */ 190 reg = ATH_READ_REG(AR724X_PCI_INTR_MASK); 191 ATH_WRITE_REG(AR724X_PCI_INTR_MASK, 192 reg & ~AR724X_PCI_INTR_DEV0); 193 194 /* Clear any pending interrupt */ 195 reg = ATH_READ_REG(AR724X_PCI_INTR_STATUS); 196 ATH_WRITE_REG(AR724X_PCI_INTR_STATUS, 197 reg | AR724X_PCI_INTR_DEV0); 198} 199 200static void 201ar724x_pci_unmask_irq(void *source) 202{ 203 uint32_t reg; 204 unsigned int irq = (unsigned int)source; 205 206 /* XXX */ 207 if (irq != AR71XX_PCI_IRQ_START) 208 return; 209 210 /* Update the interrupt mask reg */ 211 reg = ATH_READ_REG(AR724X_PCI_INTR_MASK); 212 ATH_WRITE_REG(AR724X_PCI_INTR_MASK, 213 reg | AR724X_PCI_INTR_DEV0); 214} 215 216static int 217ar724x_pci_setup(device_t dev) 218{ 219 uint32_t reg; 220 221 /* setup COMMAND register */ 222 reg = PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | PCIM_CMD_SERRESPEN | 223 PCIM_CMD_BACKTOBACK | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN; 224 225 ar724x_pci_write(AR724X_PCI_CRP_BASE, PCIR_COMMAND, reg, 2); 226 ar724x_pci_write(AR724X_PCI_CRP_BASE, 0x20, 0x1ff01000, 4); 227 ar724x_pci_write(AR724X_PCI_CRP_BASE, 0x24, 0x1ff01000, 4); 228 229 reg = ATH_READ_REG(AR724X_PCI_RESET); 230 if (reg != 0x7) { 231 DELAY(100000); 232 ATH_WRITE_REG(AR724X_PCI_RESET, 0); 233 DELAY(100); 234 ATH_WRITE_REG(AR724X_PCI_RESET, 4); 235 DELAY(100000); 236 } 237 238 if (ar71xx_soc == AR71XX_SOC_AR7240) 239 reg = AR724X_PCI_APP_LTSSM_ENABLE; 240 else 241 reg = 0x1ffc1; 242 ATH_WRITE_REG(AR724X_PCI_APP, reg); 243 /* Flush write */ 244 (void) ATH_READ_REG(AR724X_PCI_APP); 245 246 DELAY(1000); 247 248 reg = ATH_READ_REG(AR724X_PCI_RESET); 249 if ((reg & AR724X_PCI_RESET_LINK_UP) == 0) { 250 device_printf(dev, "no PCIe controller found\n"); 251 return (ENXIO); 252 } 253 254 if (ar71xx_soc == AR71XX_SOC_AR7241 || 255 ar71xx_soc == AR71XX_SOC_AR7242) { 256 reg = ATH_READ_REG(AR724X_PCI_APP); 257 reg |= (1 << 16); 258 ATH_WRITE_REG(AR724X_PCI_APP, reg); 259 } 260 261 return (0); 262} 263 264#ifdef AR71XX_ATH_EEPROM 265#define AR5416_EEPROM_MAGIC 0xa55a 266 267/* 268 * XXX - This should not be here ! And this looks like Atheros (if_ath) only. 269 */ 270static void 271ar724x_pci_fixup(device_t dev, long flash_addr, int len) 272{ 273 uint32_t bar0, reg, val; 274 uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr); 275 276#if 0 277 if (cal_data[0] != AR5416_EEPROM_MAGIC) { 278 device_printf(dev, "%s: Invalid calibration data from 0x%x\n", 279 __func__, (uintptr_t) flash_addr); 280 return; 281 } 282#endif 283 284 /* Save bar(0) address - just to flush bar(0) (SoC WAR) ? */ 285 bar0 = ar724x_pci_read_config(dev, 0, 0, 0, PCIR_BAR(0), 4); 286 287 /* Write temporary BAR0 to map the NIC into a fixed location */ 288 ar724x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), 289 AR71XX_PCI_MEM_BASE, 4); 290 291 val = ar724x_pci_read_config(dev, 0, 0, 0, PCIR_COMMAND, 2); 292 val |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); 293 ar724x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, val, 2); 294 295 /* set pointer to first reg address */ 296 cal_data += 3; 297 while (*cal_data != 0xffff) { 298 reg = *cal_data++; 299 val = *cal_data++; 300 val |= (*cal_data++) << 16; 301 302 if (bootverbose) 303 printf(" 0x%08x=0x%04x\n", reg, val); 304 305 /* Write eeprom fixup data to device memory */ 306 ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val); 307 DELAY(100); 308 } 309 310 val = ar724x_pci_read_config(dev, 0, 0, 0, PCIR_COMMAND, 2); 311 val &= ~(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN); 312 ar724x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, val, 2); 313 314 /* Write the saved bar(0) address */ 315 ar724x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), bar0, 4); 316} 317#undef AR5416_EEPROM_MAGIC 318 319/* 320 * XXX This is (mostly) duplicated with ar71xx_pci.c. 321 * It should at some point be fixed. 322 */ 323static void 324ar724x_pci_slot_fixup(device_t dev) 325{ 326 long int flash_addr; 327 char buf[64]; 328 int size; 329 330 /* 331 * Check whether the given slot has a hint to poke. 332 */ 333 if (bootverbose) 334 device_printf(dev, "%s: checking dev %s, %d/%d/%d\n", 335 __func__, device_get_nameunit(dev), 0, 0, 0); 336 337 snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr", 338 0, 0, 0); 339 340 if (resource_long_value(device_get_name(dev), device_get_unit(dev), 341 buf, &flash_addr) == 0) { 342 snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size", 343 0, 0, 0); 344 if (resource_int_value(device_get_name(dev), 345 device_get_unit(dev), buf, &size) != 0) { 346 device_printf(dev, 347 "%s: missing hint '%s', aborting EEPROM\n", 348 __func__, buf); 349 return; 350 } 351 352 device_printf(dev, "found EEPROM at 0x%lx on %d.%d.%d\n", 353 flash_addr, 0, 0, 0); 354 ar724x_pci_fixup(dev, flash_addr, size); 355 ar71xx_pci_slot_create_eeprom_firmware(dev, 0, 0, 0, 356 flash_addr, size); 357 } 358} 359#endif /* AR71XX_ATH_EEPROM */ 360 361static int 362ar724x_pci_probe(device_t dev) 363{ 364 365 return (BUS_PROBE_NOWILDCARD); 366} 367 368static int 369ar724x_pci_attach(device_t dev) 370{ 371 struct ar71xx_pci_softc *sc = device_get_softc(dev); 372 int busno = 0; 373 int rid = 0; 374 375 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 376 sc->sc_mem_rman.rm_descr = "ar724x PCI memory window"; 377 if (rman_init(&sc->sc_mem_rman) != 0 || 378 rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, 379 AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) { 380 panic("ar724x_pci_attach: failed to set up I/O rman"); 381 } 382 383 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 384 sc->sc_irq_rman.rm_descr = "ar724x PCI IRQs"; 385 if (rman_init(&sc->sc_irq_rman) != 0 || 386 rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, 387 AR71XX_PCI_IRQ_END) != 0) 388 panic("ar724x_pci_attach: failed to set up IRQ rman"); 389 390 /* Disable interrupts */ 391 ATH_WRITE_REG(AR724X_PCI_INTR_STATUS, 0); 392 ATH_WRITE_REG(AR724X_PCI_INTR_MASK, 0); 393 394 /* Hook up our interrupt handler. */ 395 if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 396 RF_SHAREABLE | RF_ACTIVE)) == NULL) { 397 device_printf(dev, "unable to allocate IRQ resource\n"); 398 return (ENXIO); 399 } 400 401 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, 402 ar724x_pci_intr, NULL, sc, &sc->sc_ih))) { 403 device_printf(dev, 404 "WARNING: unable to register interrupt handler\n"); 405 return (ENXIO); 406 } 407 408 /* Reset PCIe core and PCIe PHY */ 409 ar71xx_device_stop(AR724X_RESET_PCIE); 410 ar71xx_device_stop(AR724X_RESET_PCIE_PHY); 411 ar71xx_device_stop(AR724X_RESET_PCIE_PHY_SERIAL); 412 DELAY(100); 413 414 ar71xx_device_start(AR724X_RESET_PCIE_PHY_SERIAL); 415 DELAY(100); 416 ar71xx_device_start(AR724X_RESET_PCIE_PHY); 417 ar71xx_device_start(AR724X_RESET_PCIE); 418 419 if (ar724x_pci_setup(dev)) 420 return (ENXIO); 421 422#ifdef AR71XX_ATH_EEPROM 423 ar724x_pci_slot_fixup(dev); 424#endif /* AR71XX_ATH_EEPROM */ 425 426 /* Fixup internal PCI bridge */ 427 ar724x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, 428 PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN 429 | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK 430 | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2); 431 432 device_add_child(dev, "pci", -1); 433 return (bus_generic_attach(dev)); 434} 435 436static int 437ar724x_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 438{ 439 struct ar71xx_pci_softc *sc = device_get_softc(dev); 440 441 switch (which) { 442 case PCIB_IVAR_DOMAIN: 443 *result = 0; 444 return (0); 445 case PCIB_IVAR_BUS: 446 *result = sc->sc_busno; 447 return (0); 448 } 449 450 return (ENOENT); 451} 452 453static int 454ar724x_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 455{ 456 struct ar71xx_pci_softc * sc = device_get_softc(dev); 457 458 switch (which) { 459 case PCIB_IVAR_BUS: 460 sc->sc_busno = result; 461 return (0); 462 } 463 464 return (ENOENT); 465} 466 467static struct resource * 468ar724x_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 469 u_long start, u_long end, u_long count, u_int flags) 470{ 471 struct ar71xx_pci_softc *sc = device_get_softc(bus); 472 struct resource *rv; 473 struct rman *rm; 474 475 switch (type) { 476 case SYS_RES_IRQ: 477 rm = &sc->sc_irq_rman; 478 break; 479 case SYS_RES_MEMORY: 480 rm = &sc->sc_mem_rman; 481 break; 482 default: 483 return (NULL); 484 } 485 486 rv = rman_reserve_resource(rm, start, end, count, flags, child); 487 488 if (rv == NULL) 489 return (NULL); 490 491 rman_set_rid(rv, *rid); 492 493 if (flags & RF_ACTIVE) { 494 if (bus_activate_resource(child, type, *rid, rv)) { 495 rman_release_resource(rv); 496 return (NULL); 497 } 498 } 499 500 return (rv); 501} 502 503static int 504ar724x_pci_activate_resource(device_t bus, device_t child, int type, int rid, 505 struct resource *r) 506{ 507 int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), 508 child, type, rid, r)); 509 510 if (!res) { 511 switch(type) { 512 case SYS_RES_MEMORY: 513 case SYS_RES_IOPORT: 514 515 rman_set_bustag(r, ar71xx_bus_space_pcimem); 516 break; 517 } 518 } 519 520 return (res); 521} 522 523static int 524ar724x_pci_setup_intr(device_t bus, device_t child, struct resource *ires, 525 int flags, driver_filter_t *filt, driver_intr_t *handler, 526 void *arg, void **cookiep) 527{ 528 struct ar71xx_pci_softc *sc = device_get_softc(bus); 529 struct intr_event *event; 530 int irq, error; 531 532 irq = rman_get_start(ires); 533 if (irq > AR71XX_PCI_IRQ_END) 534 panic("%s: bad irq %d", __func__, irq); 535 536 event = sc->sc_eventstab[irq]; 537 if (event == NULL) { 538 error = intr_event_create(&event, (void *)irq, 0, irq, 539 ar724x_pci_mask_irq, ar724x_pci_unmask_irq, NULL, NULL, 540 "pci intr%d:", irq); 541 542 if (error == 0) { 543 sc->sc_eventstab[irq] = event; 544 sc->sc_intr_counter[irq] = 545 mips_intrcnt_create(event->ie_name); 546 } 547 else 548 return error; 549 } 550 551 intr_event_add_handler(event, device_get_nameunit(child), filt, 552 handler, arg, intr_priority(flags), flags, cookiep); 553 mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); 554 555 ar724x_pci_unmask_irq((void*)irq); 556 557 return (0); 558} 559 560static int 561ar724x_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, 562 void *cookie) 563{ 564 struct ar71xx_pci_softc *sc = device_get_softc(dev); 565 int irq, result; 566 567 irq = rman_get_start(ires); 568 if (irq > AR71XX_PCI_IRQ_END) 569 panic("%s: bad irq %d", __func__, irq); 570 571 if (sc->sc_eventstab[irq] == NULL) 572 panic("Trying to teardown unoccupied IRQ"); 573 574 ar724x_pci_mask_irq((void*)irq); 575 576 result = intr_event_remove_handler(cookie); 577 if (!result) 578 sc->sc_eventstab[irq] = NULL; 579 580 return (result); 581} 582 583static int 584ar724x_pci_intr(void *arg) 585{ 586 struct ar71xx_pci_softc *sc = arg; 587 struct intr_event *event; 588 uint32_t reg, irq, mask; 589 590 591 reg = ATH_READ_REG(AR724X_PCI_INTR_STATUS); 592 mask = ATH_READ_REG(AR724X_PCI_INTR_MASK); 593 /* 594 * Handle only unmasked interrupts 595 */ 596 reg &= mask; 597 if (reg & AR724X_PCI_INTR_DEV0) { 598 599 irq = AR71XX_PCI_IRQ_START; 600 event = sc->sc_eventstab[irq]; 601 if (!event || TAILQ_EMPTY(&event->ie_handlers)) { 602 printf("Stray IRQ %d\n", irq); 603 return (FILTER_STRAY); 604 } 605 606 /* Flush pending memory transactions */ 607 ar71xx_device_flush_ddr(AR71XX_CPU_DDR_FLUSH_PCIE); 608 609 /* TODO: frame instead of NULL? */ 610 intr_event_handle(event, NULL); 611 mips_intrcnt_inc(sc->sc_intr_counter[irq]); 612 } 613 614 return (FILTER_HANDLED); 615} 616 617static int 618ar724x_pci_maxslots(device_t dev) 619{ 620 621 return (PCI_SLOTMAX); 622} 623 624static int 625ar724x_pci_route_interrupt(device_t pcib, device_t device, int pin) 626{ 627 628 return (pci_get_slot(device)); 629} 630 631static device_method_t ar724x_pci_methods[] = { 632 /* Device interface */ 633 DEVMETHOD(device_probe, ar724x_pci_probe), 634 DEVMETHOD(device_attach, ar724x_pci_attach), 635 DEVMETHOD(device_shutdown, bus_generic_shutdown), 636 DEVMETHOD(device_suspend, bus_generic_suspend), 637 DEVMETHOD(device_resume, bus_generic_resume), 638 639 /* Bus interface */ 640 DEVMETHOD(bus_read_ivar, ar724x_pci_read_ivar), 641 DEVMETHOD(bus_write_ivar, ar724x_pci_write_ivar), 642 DEVMETHOD(bus_alloc_resource, ar724x_pci_alloc_resource), 643 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 644 DEVMETHOD(bus_activate_resource, ar724x_pci_activate_resource), 645 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 646 DEVMETHOD(bus_setup_intr, ar724x_pci_setup_intr), 647 DEVMETHOD(bus_teardown_intr, ar724x_pci_teardown_intr), 648 649 /* pcib interface */ 650 DEVMETHOD(pcib_maxslots, ar724x_pci_maxslots), 651 DEVMETHOD(pcib_read_config, ar724x_pci_read_config), 652 DEVMETHOD(pcib_write_config, ar724x_pci_write_config), 653 DEVMETHOD(pcib_route_interrupt, ar724x_pci_route_interrupt), 654 655 DEVMETHOD_END 656}; 657 658static driver_t ar724x_pci_driver = { 659 "pcib", 660 ar724x_pci_methods, 661 sizeof(struct ar71xx_pci_softc), 662}; 663 664static devclass_t ar724x_pci_devclass; 665 666DRIVER_MODULE(ar724x_pci, nexus, ar724x_pci_driver, ar724x_pci_devclass, 0, 0); 667