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