ar71xx_pci.c revision 234204
1/*-
2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_pci.c 234204 2012-04-13 06:11:24Z adrian $");
30
31#include "opt_ar71xx.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35
36#include <sys/bus.h>
37#include <sys/interrupt.h>
38#include <sys/malloc.h>
39#include <sys/kernel.h>
40#include <sys/module.h>
41#include <sys/rman.h>
42
43#include <vm/vm.h>
44#include <vm/pmap.h>
45#include <vm/vm_extern.h>
46
47#include <machine/bus.h>
48#include <machine/cpu.h>
49#include <machine/intr_machdep.h>
50#include <machine/pmap.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/ar71xx_pci_bus_space.h>
60
61#include <mips/atheros/ar71xx_cpudef.h>
62
63#undef AR71XX_PCI_DEBUG
64#ifdef AR71XX_PCI_DEBUG
65#define dprintf printf
66#else
67#define dprintf(x, arg...)
68#endif
69
70struct ar71xx_pci_softc {
71	device_t		sc_dev;
72
73	int			sc_busno;
74	struct rman		sc_mem_rman;
75	struct rman		sc_irq_rman;
76
77	struct intr_event	*sc_eventstab[AR71XX_PCI_NIRQS];
78	mips_intrcnt_t		sc_intr_counter[AR71XX_PCI_NIRQS];
79	struct resource		*sc_irq;
80	void			*sc_ih;
81};
82
83static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int,
84		    driver_filter_t *, driver_intr_t *, void *, void **);
85static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *,
86		    void *);
87static int ar71xx_pci_intr(void *);
88
89static void
90ar71xx_pci_mask_irq(void *source)
91{
92	uint32_t reg;
93	unsigned int irq = (unsigned int)source;
94
95	reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
96	/* flush */
97	reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
98	ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq));
99}
100
101static void
102ar71xx_pci_unmask_irq(void *source)
103{
104	uint32_t reg;
105	unsigned int irq = (unsigned int)source;
106
107	reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
108	ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq));
109	/* flush */
110	reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
111}
112
113/*
114 * get bitmask for bytes of interest:
115 *   0 - we want this byte, 1 - ignore it. e.g: we read 1 byte
116 *   from register 7. Bitmask would be: 0111
117 */
118static uint32_t
119ar71xx_get_bytes_to_read(int reg, int bytes)
120{
121	uint32_t bytes_to_read = 0;
122	if ((bytes % 4) == 0)
123		bytes_to_read = 0;
124	else if ((bytes % 4) == 1)
125		bytes_to_read = (~(1 << (reg % 4))) & 0xf;
126	else if ((bytes % 4) == 2)
127		bytes_to_read = (~(3 << (reg % 4))) & 0xf;
128	else
129		panic("%s: wrong combination", __func__);
130
131	return (bytes_to_read);
132}
133
134static int
135ar71xx_pci_check_bus_error(void)
136{
137	uint32_t error, addr, has_errors = 0;
138	error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3;
139	dprintf("%s: PCI error = %02x\n", __func__, error);
140	if (error) {
141		addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR);
142
143		/* Do not report it yet */
144#if 0
145		printf("PCI bus error %d at addr 0x%08x\n", error, addr);
146#endif
147		ATH_WRITE_REG(AR71XX_PCI_ERROR, error);
148		has_errors = 1;
149	}
150
151	error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1;
152	dprintf("%s: AHB error = %02x\n", __func__, error);
153	if (error) {
154		addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR);
155		/* Do not report it yet */
156#if 0
157		printf("AHB bus error %d at addr 0x%08x\n", error, addr);
158#endif
159		ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error);
160		has_errors = 1;
161	}
162
163	return (has_errors);
164}
165
166static uint32_t
167ar71xx_pci_make_addr(int bus, int slot, int func, int reg)
168{
169	if (bus == 0) {
170		return ((1 << slot) | (func << 8) | (reg & ~3));
171	} else {
172		return ((bus << 16) | (slot << 11) | (func << 8)
173		    | (reg  & ~3) | 1);
174	}
175}
176
177static int
178ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes,
179    uint32_t cmd)
180{
181	uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3));
182	cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4);
183
184	ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr);
185	ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd);
186
187	dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__,
188	    bus, slot, func, reg, bytes, addr, cmd);
189
190	return ar71xx_pci_check_bus_error();
191}
192
193static uint32_t
194ar71xx_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
195    u_int reg, int bytes)
196{
197	uint32_t data;
198	uint32_t cmd, shift, mask;
199
200	/* register access is 32-bit aligned */
201	shift = (reg & 3) * 8;
202	if (shift)
203		mask = (1 << shift) - 1;
204	else
205		mask = 0xffffffff;
206
207	dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot,
208	    func, reg, bytes);
209
210	 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes,
211	     PCI_CONF_CMD_READ) == 0)
212		 data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA);
213	 else
214		 data = -1;
215
216	/* get request bytes from 32-bit word */
217	data = (data >> shift) & mask;
218
219 	dprintf("%s: read 0x%x\n", __func__, data);
220
221	return (data);
222}
223
224static void
225ar71xx_pci_local_write(device_t dev, uint32_t reg, uint32_t data, int bytes)
226{
227	uint32_t cmd;
228
229	dprintf("%s: local write reg %d(%d)\n", __func__, reg, bytes);
230
231	data = data << (8*(reg % 4));
232
233	cmd = PCI_LCONF_CMD_WRITE | (reg & ~3);
234	cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 20);
235	ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd);
236	ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data);
237}
238
239static void
240ar71xx_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
241    u_int reg, uint32_t data, int bytes)
242{
243
244	dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot,
245	    func, reg, bytes);
246
247	data = data << (8*(reg % 4));
248
249	 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes,
250	     PCI_CONF_CMD_WRITE) == 0)
251		 ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data);
252}
253
254#ifdef	AR71XX_ATH_EEPROM
255/*
256 * Some embedded boards (eg AP94) have the MAC attached via PCI but they
257 * don't have the MAC-attached EEPROM.  The register initialisation
258 * values and calibration data are stored in the on-board flash.
259 * This routine initialises the NIC via the EEPROM register contents
260 * before the probe/attach routines get a go at things.
261 */
262static void
263ar71xx_pci_fixup(device_t dev, u_int bus, u_int slot, u_int func,
264    long flash_addr)
265{
266	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
267	uint32_t reg, val, bar0;
268
269	printf("%s: flash_addr=%lx, cal_data=%p\n",
270	    __func__, flash_addr, cal_data);
271
272	/* XXX check 0xa55a */
273	/* Save bar(0) address - just to flush bar(0) (SoC WAR) ? */
274	bar0 = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_BAR(0), 4);
275	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0),
276	    AR71XX_PCI_MEM_BASE, 4);
277
278	val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2);
279	val |= (PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
280	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2);
281
282	cal_data += 3;
283	while (*cal_data != 0xffff) {
284		reg = *cal_data++;
285		val = *cal_data++;
286		val |= (*cal_data++) << 16;
287		printf("  reg: %x, val=%x\n", reg, val);
288
289		/* Write eeprom fixup data to device memory */
290		ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val);
291		DELAY(100);
292	}
293
294	val = ar71xx_pci_read_config(dev, bus, slot, func, PCIR_COMMAND, 2);
295	val &= ~(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
296	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_COMMAND, val, 2);
297
298	/* Write the saved bar(0) address */
299	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0), bar0, 4);
300}
301
302static void
303ar71xx_pci_slot_fixup(device_t dev, u_int bus, u_int slot, u_int func)
304{
305	long int flash_addr;
306	char buf[32];
307
308	/*
309	 * Check whether the given slot has a hint to poke.
310	 */
311	printf("%s: checking dev %s, %d/%d/%d\n",
312	    __func__, device_get_nameunit(dev), bus, slot, func);
313	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr",
314	    bus, slot, func);
315
316	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
317	    buf, &flash_addr) == 0) {
318		printf("%s: found fixupaddr at %lx: updating\n",
319		    __func__, flash_addr);
320		ar71xx_pci_fixup(dev, bus, slot, func, flash_addr);
321	}
322}
323#endif	/* AR71XX_ATH_EEPROM */
324
325static int
326ar71xx_pci_probe(device_t dev)
327{
328
329	return (0);
330}
331
332static int
333ar71xx_pci_attach(device_t dev)
334{
335	int busno = 0;
336	int rid = 0;
337	struct ar71xx_pci_softc *sc = device_get_softc(dev);
338
339	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
340	sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window";
341	if (rman_init(&sc->sc_mem_rman) != 0 ||
342	    rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE,
343		AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) {
344		panic("ar71xx_pci_attach: failed to set up I/O rman");
345	}
346
347	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
348	sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs";
349	if (rman_init(&sc->sc_irq_rman) != 0 ||
350	    rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START,
351	        AR71XX_PCI_IRQ_END) != 0)
352		panic("ar71xx_pci_attach: failed to set up IRQ rman");
353
354
355	ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0);
356	ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0);
357
358	/* Hook up our interrupt handler. */
359	if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
360	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
361		device_printf(dev, "unable to allocate IRQ resource\n");
362		return ENXIO;
363	}
364
365	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
366			    ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) {
367		device_printf(dev,
368		    "WARNING: unable to register interrupt handler\n");
369		return ENXIO;
370	}
371
372	/* reset PCI core and PCI bus */
373	ar71xx_device_stop(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS);
374	DELAY(100000);
375
376	ar71xx_device_start(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS);
377	DELAY(100000);
378
379	/* Init PCI windows */
380	ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR);
381	ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR);
382	ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR);
383	ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR);
384	ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR);
385	ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR);
386	ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR);
387	ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR);
388	DELAY(100000);
389
390	ar71xx_pci_check_bus_error();
391
392	/* Fixup internal PCI bridge */
393	ar71xx_pci_local_write(dev, PCIR_COMMAND,
394            PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN
395	    | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK
396	    | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 4);
397
398#ifdef	AR71XX_ATH_EEPROM
399	/*
400	 * Hard-code a check for slot 17 and 18 - these are
401	 * the two PCI slots which may have a PCI device that
402	 * requires "fixing".
403	 */
404	ar71xx_pci_slot_fixup(dev, 0, 17, 0);
405	ar71xx_pci_slot_fixup(dev, 0, 18, 0);
406#endif	/* AR71XX_ATH_EEPROM */
407
408	device_add_child(dev, "pci", busno);
409	return (bus_generic_attach(dev));
410}
411
412static int
413ar71xx_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
414{
415	struct ar71xx_pci_softc *sc = device_get_softc(dev);
416
417	switch (which) {
418	case PCIB_IVAR_DOMAIN:
419		*result = 0;
420		return (0);
421	case PCIB_IVAR_BUS:
422		*result = sc->sc_busno;
423		return (0);
424	}
425
426	return (ENOENT);
427}
428
429static int
430ar71xx_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
431{
432	struct ar71xx_pci_softc * sc = device_get_softc(dev);
433
434	switch (which) {
435	case PCIB_IVAR_BUS:
436		sc->sc_busno = result;
437		return (0);
438	}
439
440	return (ENOENT);
441}
442
443static struct resource *
444ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
445    u_long start, u_long end, u_long count, u_int flags)
446{
447
448	struct ar71xx_pci_softc *sc = device_get_softc(bus);
449	struct resource *rv;
450	struct rman *rm;
451
452	switch (type) {
453	case SYS_RES_IRQ:
454		rm = &sc->sc_irq_rman;
455		break;
456	case SYS_RES_MEMORY:
457		rm = &sc->sc_mem_rman;
458		break;
459	default:
460		return (NULL);
461	}
462
463	rv = rman_reserve_resource(rm, start, end, count, flags, child);
464
465	if (rv == NULL)
466		return (NULL);
467
468	rman_set_rid(rv, *rid);
469
470	if (flags & RF_ACTIVE) {
471		if (bus_activate_resource(child, type, *rid, rv)) {
472			rman_release_resource(rv);
473			return (NULL);
474		}
475	}
476
477
478	return (rv);
479}
480
481
482static int
483ar71xx_pci_activate_resource(device_t bus, device_t child, int type, int rid,
484    struct resource *r)
485{
486	int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus),
487	    child, type, rid, r));
488
489	if (!res) {
490		switch(type) {
491		case SYS_RES_MEMORY:
492		case SYS_RES_IOPORT:
493			rman_set_bustag(r, ar71xx_bus_space_pcimem);
494			break;
495		}
496	}
497
498	return (res);
499}
500
501
502
503static int
504ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires,
505		int flags, driver_filter_t *filt, driver_intr_t *handler,
506		void *arg, void **cookiep)
507{
508	struct ar71xx_pci_softc *sc = device_get_softc(bus);
509	struct intr_event *event;
510	int irq, error;
511
512	irq = rman_get_start(ires);
513
514	if (irq > AR71XX_PCI_IRQ_END)
515		panic("%s: bad irq %d", __func__, irq);
516
517	event = sc->sc_eventstab[irq];
518	if (event == NULL) {
519		error = intr_event_create(&event, (void *)irq, 0, irq,
520		    ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL,
521		    "pci intr%d:", irq);
522
523		if (error == 0) {
524			sc->sc_eventstab[irq] = event;
525			sc->sc_intr_counter[irq] =
526			    mips_intrcnt_create(event->ie_name);
527		}
528		else
529			return error;
530	}
531
532	intr_event_add_handler(event, device_get_nameunit(child), filt,
533	    handler, arg, intr_priority(flags), flags, cookiep);
534	mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname);
535
536	ar71xx_pci_unmask_irq((void*)irq);
537
538	return (0);
539}
540
541static int
542ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires,
543    void *cookie)
544{
545	struct ar71xx_pci_softc *sc = device_get_softc(dev);
546	int irq, result;
547
548	irq = rman_get_start(ires);
549	if (irq > AR71XX_PCI_IRQ_END)
550		panic("%s: bad irq %d", __func__, irq);
551
552	if (sc->sc_eventstab[irq] == NULL)
553		panic("Trying to teardown unoccupied IRQ");
554
555	ar71xx_pci_mask_irq((void*)irq);
556
557	result = intr_event_remove_handler(cookie);
558	if (!result)
559		sc->sc_eventstab[irq] = NULL;
560
561	return (result);
562}
563
564static int
565ar71xx_pci_intr(void *arg)
566{
567	struct ar71xx_pci_softc *sc = arg;
568	struct intr_event *event;
569	uint32_t reg, irq, mask;
570
571	reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS);
572	mask = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
573	/*
574	 * Handle only unmasked interrupts
575	 */
576	reg &= mask;
577	for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) {
578		if (reg & (1 << irq)) {
579			event = sc->sc_eventstab[irq];
580			if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
581				/* Ignore timer interrupts */
582				if (irq != 0)
583					printf("Stray IRQ %d\n", irq);
584				continue;
585			}
586
587			/* Flush DDR FIFO for IP2 */
588			ar71xx_device_ddr_flush_ip2();
589
590			/* TODO: frame instead of NULL? */
591			intr_event_handle(event, NULL);
592			mips_intrcnt_inc(sc->sc_intr_counter[irq]);
593		}
594	}
595
596	return (FILTER_HANDLED);
597}
598
599static int
600ar71xx_pci_maxslots(device_t dev)
601{
602
603	return (PCI_SLOTMAX);
604}
605
606static int
607ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin)
608{
609	if (pci_get_slot(device) < AR71XX_PCI_BASE_SLOT)
610		panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT",
611		    __func__, pci_get_slot(device));
612
613	return (pci_get_slot(device) - AR71XX_PCI_BASE_SLOT);
614}
615
616static device_method_t ar71xx_pci_methods[] = {
617	/* Device interface */
618	DEVMETHOD(device_probe,		ar71xx_pci_probe),
619	DEVMETHOD(device_attach,	ar71xx_pci_attach),
620	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
621	DEVMETHOD(device_suspend,	bus_generic_suspend),
622	DEVMETHOD(device_resume,	bus_generic_resume),
623
624	/* Bus interface */
625	DEVMETHOD(bus_read_ivar,	ar71xx_pci_read_ivar),
626	DEVMETHOD(bus_write_ivar,	ar71xx_pci_write_ivar),
627	DEVMETHOD(bus_alloc_resource,	ar71xx_pci_alloc_resource),
628	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
629	DEVMETHOD(bus_activate_resource, ar71xx_pci_activate_resource),
630	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
631	DEVMETHOD(bus_setup_intr,	ar71xx_pci_setup_intr),
632	DEVMETHOD(bus_teardown_intr,	ar71xx_pci_teardown_intr),
633
634	/* pcib interface */
635	DEVMETHOD(pcib_maxslots,	ar71xx_pci_maxslots),
636	DEVMETHOD(pcib_read_config,	ar71xx_pci_read_config),
637	DEVMETHOD(pcib_write_config,	ar71xx_pci_write_config),
638	DEVMETHOD(pcib_route_interrupt,	ar71xx_pci_route_interrupt),
639
640	DEVMETHOD_END
641};
642
643static driver_t ar71xx_pci_driver = {
644	"pcib",
645	ar71xx_pci_methods,
646	sizeof(struct ar71xx_pci_softc),
647};
648
649static devclass_t ar71xx_pci_devclass;
650
651DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0);
652