1187500Simp/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
2187500Simp
3187500Simp/*-
4187500Simp * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
5187500Simp * All rights reserved.
6187500Simp *
7187500Simp * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8187500Simp *
9187500Simp * Redistribution and use in source and binary forms, with or without
10187500Simp * modification, are permitted provided that the following conditions
11187500Simp * are met:
12187500Simp * 1. Redistributions of source code must retain the above copyright
13187500Simp *    notice, this list of conditions and the following disclaimer.
14187500Simp * 2. Redistributions in binary form must reproduce the above copyright
15187500Simp *    notice, this list of conditions and the following disclaimer in the
16187500Simp *    documentation and/or other materials provided with the distribution.
17187500Simp * 3. All advertising materials mentioning features or use of this software
18187500Simp *    must display the following acknowledgement:
19187500Simp *	This product includes software developed for the NetBSD Project by
20187500Simp *	Wasabi Systems, Inc.
21187500Simp * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22187500Simp *    or promote products derived from this software without specific prior
23187500Simp *    written permission.
24187500Simp *
25187500Simp * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26187500Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27187500Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28187500Simp * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29187500Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30187500Simp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31187500Simp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32187500Simp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33187500Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34187500Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35187500Simp * POSSIBILITY OF SUCH DAMAGE.
36187500Simp */
37187500Simp
38187500Simp#include <sys/cdefs.h>
39187500Simp__FBSDID("$FreeBSD$");
40187500Simp
41187500Simp#include <sys/param.h>
42187500Simp#include <sys/systm.h>
43187500Simp#include <sys/bus.h>
44187500Simp#include <sys/interrupt.h>
45187500Simp#include <sys/kernel.h>
46187500Simp#include <sys/module.h>
47187500Simp#include <sys/rman.h>
48187500Simp#include <sys/malloc.h>
49187500Simp
50187500Simp#include <machine/bus.h>
51187500Simp
52187500Simp#include <mips/adm5120/adm5120reg.h>
53187500Simp#include <mips/adm5120/obiovar.h>
54187500Simp
55187500Simp/* MIPS HW interrupts of IRQ/FIQ respectively */
56187500Simp#define ADM5120_INTR		0
57187500Simp#define ADM5120_FAST_INTR	1
58187500Simp
59187500Simp/* Interrupt levels */
60187500Simp#define INTR_IRQ 0
61187500Simp#define INTR_FIQ 1
62187500Simp
63187500Simpint irq_priorities[NIRQS] = {
64187500Simp	INTR_IRQ,	/* flash */
65187500Simp	INTR_FIQ,	/* uart0 */
66187500Simp	INTR_FIQ,	/* uart1 */
67187500Simp	INTR_IRQ,	/* ahci  */
68187500Simp	INTR_IRQ,	/* unknown */
69187500Simp	INTR_IRQ,	/* unknown */
70187500Simp	INTR_IRQ,	/* unknown */
71187500Simp	INTR_IRQ,	/* unknown */
72187500Simp	INTR_IRQ,	/* unknown */
73187500Simp	INTR_IRQ,	/* admsw */
74187500Simp	INTR_IRQ,	/* unknown */
75187500Simp	INTR_IRQ,	/* unknown */
76187500Simp	INTR_IRQ,	/* unknown */
77187500Simp	INTR_IRQ,	/* unknown */
78187500Simp	INTR_IRQ,	/* unknown */
79187500Simp	INTR_IRQ,	/* unknown */
80187500Simp	INTR_IRQ,	/* unknown */
81187500Simp	INTR_IRQ,	/* unknown */
82187500Simp	INTR_IRQ,	/* unknown */
83187500Simp	INTR_IRQ,	/* unknown */
84187500Simp	INTR_IRQ,	/* unknown */
85187500Simp	INTR_IRQ,	/* unknown */
86187500Simp	INTR_IRQ,	/* unknown */
87187500Simp	INTR_IRQ,	/* unknown */
88187500Simp	INTR_IRQ,	/* unknown */
89187500Simp	INTR_IRQ,	/* unknown */
90187500Simp	INTR_IRQ,	/* unknown */
91187500Simp	INTR_IRQ,	/* unknown */
92187500Simp	INTR_IRQ,	/* unknown */
93187500Simp	INTR_IRQ,	/* unknown */
94187500Simp	INTR_IRQ,	/* unknown */
95187500Simp	INTR_IRQ,	/* unknown */
96187500Simp};
97187500Simp
98187500Simp
99187500Simp#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(ADM5120_BASE_ICU + (o)))
100187500Simp#define REG_WRITE(o,v) (REG_READ(o)) = (v)
101187500Simp
102187500Simpstatic int	obio_activate_resource(device_t, device_t, int, int,
103187500Simp		    struct resource *);
104212413Savgstatic device_t	obio_add_child(device_t, u_int, const char *, int);
105187500Simpstatic struct resource *
106187500Simp		obio_alloc_resource(device_t, device_t, int, int *, u_long,
107187500Simp		    u_long, u_long, u_int);
108187500Simpstatic int	obio_attach(device_t);
109187500Simpstatic int	obio_deactivate_resource(device_t, device_t, int, int,
110187500Simp		    struct resource *);
111187500Simpstatic struct resource_list *
112187500Simp		obio_get_resource_list(device_t, device_t);
113187500Simpstatic void	obio_hinted_child(device_t, const char *, int);
114187500Simpstatic int	obio_intr(void *);
115187500Simpstatic int	obio_probe(device_t);
116187500Simpstatic int	obio_release_resource(device_t, device_t, int, int,
117187500Simp		    struct resource *);
118187500Simpstatic int	obio_setup_intr(device_t, device_t, struct resource *, int,
119187500Simp		    driver_filter_t *, driver_intr_t *, void *, void **);
120187500Simpstatic int	obio_teardown_intr(device_t, device_t, struct resource *,
121187500Simp		    void *);
122187500Simp
123204056Simpstatic void
124204056Simpobio_mask_irq(void *arg)
125204056Simp{
126204056Simp  /* XXX need to write */
127204056Simp#if 0
128204056Simp	unsigned int irq = (unsigned int)arg;
129204056Simp	int ip_bit, mask, mask_register;
130204056Simp
131204056Simp	/* mask IRQ */
132204056Simp	mask_register = ICU_IRQ_MASK_REG(irq);
133204056Simp	ip_bit = ICU_IP_BIT(irq);
134204056Simp
135204056Simp	mask = ICU_REG_READ(mask_register);
136204056Simp	ICU_REG_WRITE(mask_register, mask | ip_bit);
137204056Simp#endif
138204056Simp}
139204056Simp
140204056Simpstatic void
141204056Simpobio_unmask_irq(void *arg)
142204056Simp{
143204056Simp  /* XXX need to write */
144204056Simp#if 0
145204056Simp	unsigned int irq = (unsigned int)arg;
146204056Simp	int ip_bit, mask, mask_register;
147204056Simp
148204056Simp	/* unmask IRQ */
149204056Simp	mask_register = ICU_IRQ_MASK_REG(irq);
150204056Simp	ip_bit = ICU_IP_BIT(irq);
151204056Simp
152204056Simp	mask = ICU_REG_READ(mask_register);
153204056Simp	ICU_REG_WRITE(mask_register, mask & ~ip_bit);
154204056Simp#endif
155204056Simp}
156204056Simp
157187500Simpstatic int
158187500Simpobio_probe(device_t dev)
159187500Simp{
160187500Simp
161265999Sian	return (BUS_PROBE_NOWILDCARD);
162187500Simp}
163187500Simp
164187500Simpstatic int
165187500Simpobio_attach(device_t dev)
166187500Simp{
167187500Simp	struct obio_softc *sc = device_get_softc(dev);
168187500Simp	int rid;
169187500Simp
170187500Simp	sc->oba_mem_rman.rm_type = RMAN_ARRAY;
171187500Simp	sc->oba_mem_rman.rm_descr = "OBIO memeory";
172187500Simp	if (rman_init(&sc->oba_mem_rman) != 0 ||
173187500Simp	    rman_manage_region(&sc->oba_mem_rman, OBIO_MEM_START,
174187500Simp	        OBIO_MEM_START + OBIO_MEM_SIZE) != 0)
175187500Simp		panic("obio_attach: failed to set up I/O rman");
176187500Simp
177187500Simp	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
178187500Simp	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
179187500Simp
180187500Simp	if (rman_init(&sc->oba_irq_rman) != 0 ||
181187500Simp	    rman_manage_region(&sc->oba_irq_rman, 0, NIRQS-1) != 0)
182187500Simp		panic("obio_attach: failed to set up IRQ rman");
183187500Simp
184187500Simp	/* Hook up our interrupt handler. */
185187500Simp	if ((sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
186187500Simp	    ADM5120_INTR, ADM5120_INTR, 1,
187187500Simp	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
188187500Simp		device_printf(dev, "unable to allocate IRQ resource\n");
189187500Simp		return (ENXIO);
190187500Simp	}
191187500Simp
192187500Simp	if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, obio_intr, NULL,
193187500Simp	    sc, &sc->sc_ih))) {
194187500Simp		device_printf(dev,
195187500Simp		    "WARNING: unable to register interrupt handler\n");
196187500Simp		return (ENXIO);
197187500Simp	}
198187500Simp
199187500Simp	/* Hook up our FAST interrupt handler. */
200187500Simp	if ((sc->sc_fast_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
201187500Simp	    ADM5120_FAST_INTR, ADM5120_FAST_INTR, 1,
202187500Simp	    RF_SHAREABLE | RF_ACTIVE)) == NULL) {
203187500Simp		device_printf(dev, "unable to allocate IRQ resource\n");
204187500Simp		return (ENXIO);
205187500Simp	}
206187500Simp
207187500Simp	if ((bus_setup_intr(dev, sc->sc_fast_irq, INTR_TYPE_MISC, obio_intr,
208187500Simp	    NULL, sc, &sc->sc_fast_ih))) {
209187500Simp		device_printf(dev,
210187500Simp		    "WARNING: unable to register interrupt handler\n");
211187500Simp		return (ENXIO);
212187500Simp	}
213187500Simp
214187500Simp	/* disable all interrupts */
215187500Simp	REG_WRITE(ICU_ENABLE_REG, ICU_INT_MASK);
216187500Simp
217187500Simp	bus_generic_probe(dev);
218187500Simp	bus_enumerate_hinted_children(dev);
219187500Simp	bus_generic_attach(dev);
220187500Simp
221187500Simp	return (0);
222187500Simp}
223187500Simp
224187500Simpstatic struct resource *
225187500Simpobio_alloc_resource(device_t bus, device_t child, int type, int *rid,
226187500Simp    u_long start, u_long end, u_long count, u_int flags)
227187500Simp{
228187500Simp	struct obio_softc		*sc = device_get_softc(bus);
229187500Simp	struct obio_ivar		*ivar = device_get_ivars(child);
230187500Simp	struct resource			*rv;
231187500Simp	struct resource_list_entry	*rle;
232187500Simp	struct rman			*rm;
233187500Simp	int				 isdefault, needactivate, passthrough;
234187500Simp
235187500Simp	isdefault = (start == 0UL && end == ~0UL && count == 1);
236187500Simp	needactivate = flags & RF_ACTIVE;
237187500Simp	passthrough = (device_get_parent(child) != bus);
238187500Simp	rle = NULL;
239187500Simp
240187500Simp	if (passthrough)
241187500Simp		return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type,
242187500Simp		    rid, start, end, count, flags));
243187500Simp
244187500Simp	/*
245187500Simp	 * If this is an allocation of the "default" range for a given RID,
246187500Simp	 * and we know what the resources for this device are (ie. they aren't
247187500Simp	 * maintained by a child bus), then work out the start/end values.
248187500Simp	 */
249187500Simp	if (isdefault) {
250187500Simp		rle = resource_list_find(&ivar->resources, type, *rid);
251187500Simp		if (rle == NULL)
252187500Simp			return (NULL);
253187500Simp		if (rle->res != NULL) {
254187500Simp			panic("%s: resource entry is busy", __func__);
255187500Simp		}
256187500Simp		start = rle->start;
257187500Simp		end = rle->end;
258187500Simp		count = rle->count;
259187500Simp	}
260187500Simp
261187500Simp	switch (type) {
262187500Simp	case SYS_RES_IRQ:
263187500Simp		rm = &sc->oba_irq_rman;
264187500Simp		break;
265187500Simp	case SYS_RES_MEMORY:
266187500Simp		rm = &sc->oba_mem_rman;
267187500Simp		break;
268187500Simp	default:
269187500Simp		printf("%s: unknown resource type %d\n", __func__, type);
270187500Simp		return (0);
271187500Simp	}
272187500Simp
273187500Simp	rv = rman_reserve_resource(rm, start, end, count, flags, child);
274187500Simp	if (rv == 0) {
275187500Simp		printf("%s: could not reserve resource\n", __func__);
276187500Simp		return (0);
277187500Simp	}
278187500Simp
279187500Simp	rman_set_rid(rv, *rid);
280187500Simp
281187500Simp	if (needactivate) {
282187500Simp		if (bus_activate_resource(child, type, *rid, rv)) {
283187500Simp			printf("%s: could not activate resource\n", __func__);
284187500Simp			rman_release_resource(rv);
285187500Simp			return (0);
286187500Simp		}
287187500Simp	}
288187500Simp
289187500Simp	return (rv);
290187500Simp}
291187500Simp
292187500Simpstatic int
293187500Simpobio_activate_resource(device_t bus, device_t child, int type, int rid,
294187500Simp    struct resource *r)
295187500Simp{
296187500Simp
297187500Simp	/*
298187500Simp	 * If this is a memory resource, track the direct mapping
299187500Simp	 * in the uncached MIPS KSEG1 segment.
300187500Simp	 */
301187500Simp	if (type == SYS_RES_MEMORY) {
302187500Simp		void *vaddr;
303187500Simp
304187500Simp		vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r));
305187500Simp		rman_set_virtual(r, vaddr);
306191282Sgonzo		rman_set_bustag(r, mips_bus_space_generic);
307187500Simp		rman_set_bushandle(r, (bus_space_handle_t)vaddr);
308187500Simp	}
309187500Simp
310187500Simp	return (rman_activate_resource(r));
311187500Simp}
312187500Simp
313187500Simpstatic int
314187500Simpobio_deactivate_resource(device_t bus, device_t child, int type, int rid,
315187500Simp    struct resource *r)
316187500Simp{
317187500Simp
318187500Simp	return (rman_deactivate_resource(r));
319187500Simp}
320187500Simp
321187500Simpstatic int
322187500Simpobio_release_resource(device_t dev, device_t child, int type,
323187500Simp    int rid, struct resource *r)
324187500Simp{
325187500Simp	struct resource_list *rl;
326187500Simp	struct resource_list_entry *rle;
327187500Simp
328187500Simp	rl = obio_get_resource_list(dev, child);
329187500Simp	if (rl == NULL)
330187500Simp		return (EINVAL);
331187500Simp	rle = resource_list_find(rl, type, rid);
332187500Simp	if (rle == NULL)
333187500Simp		return (EINVAL);
334187500Simp	rman_release_resource(r);
335187500Simp	rle->res = NULL;
336187500Simp
337187500Simp	return (0);
338187500Simp}
339187500Simp
340187500Simpstatic int
341187500Simpobio_setup_intr(device_t dev, device_t child, struct resource *ires,
342187500Simp		int flags, driver_filter_t *filt, driver_intr_t *handler,
343187500Simp		void *arg, void **cookiep)
344187500Simp{
345187500Simp	struct obio_softc *sc = device_get_softc(dev);
346187500Simp	struct intr_event *event;
347187500Simp	int irq, error, priority;
348187500Simp	uint32_t irqmask;
349187500Simp
350187500Simp	irq = rman_get_start(ires);
351187500Simp
352187500Simp	if (irq >= NIRQS)
353187500Simp		panic("%s: bad irq %d", __func__, irq);
354187500Simp
355187500Simp	event = sc->sc_eventstab[irq];
356187500Simp	if (event == NULL) {
357204056Simp		error = intr_event_create(&event, (void *)irq, 0, irq,
358204056Simp		    obio_mask_irq, obio_unmask_irq,
359204056Simp		    NULL, NULL,
360204056Simp		    "obio intr%d:", irq);
361187500Simp
362187500Simp		sc->sc_eventstab[irq] = event;
363187500Simp	}
364187500Simp	else
365187500Simp		panic("obio: Can't share IRQs");
366187500Simp
367187500Simp	intr_event_add_handler(event, device_get_nameunit(child), filt,
368187500Simp	    handler, arg, intr_priority(flags), flags, cookiep);
369187500Simp
370187500Simp	irqmask = 1 << irq;
371187500Simp	priority = irq_priorities[irq];
372187500Simp
373187500Simp	if (priority == INTR_FIQ)
374187500Simp		REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) | irqmask);
375187500Simp	else
376187500Simp		REG_WRITE(ICU_MODE_REG, REG_READ(ICU_MODE_REG) & ~irqmask);
377187500Simp
378187500Simp	/* enable */
379187500Simp	REG_WRITE(ICU_ENABLE_REG, irqmask);
380187500Simp
381187500Simp	return (0);
382187500Simp}
383187500Simp
384187500Simpstatic int
385187500Simpobio_teardown_intr(device_t dev, device_t child, struct resource *ires,
386187500Simp    void *cookie)
387187500Simp{
388187500Simp	struct obio_softc *sc = device_get_softc(dev);
389187500Simp	int irq, result;
390187500Simp	uint32_t irqmask;
391187500Simp
392187500Simp	irq = rman_get_start(ires);
393187500Simp	if (irq >= NIRQS)
394187500Simp		panic("%s: bad irq %d", __func__, irq);
395187500Simp
396187500Simp	if (sc->sc_eventstab[irq] == NULL)
397187500Simp		panic("Trying to teardown unoccupied IRQ");
398187500Simp
399187500Simp	irqmask = 1 << irq;     /* only used as a mask from here on */
400187500Simp
401187500Simp	/* disable this irq in HW */
402187500Simp	REG_WRITE(ICU_DISABLE_REG, irqmask);
403187500Simp
404187500Simp	result = intr_event_remove_handler(cookie);
405187500Simp	if (!result) {
406187500Simp		sc->sc_eventstab[irq] = NULL;
407187500Simp	}
408187500Simp
409187500Simp	return (result);
410187500Simp}
411187500Simp
412187500Simpstatic int
413187500Simpobio_intr(void *arg)
414187500Simp{
415187500Simp	struct obio_softc *sc = arg;
416187500Simp	struct intr_event *event;
417187500Simp	uint32_t irqstat;
418187500Simp	int irq;
419187500Simp
420187500Simp	irqstat = REG_READ(ICU_FIQ_STATUS_REG);
421187500Simp	irqstat |= REG_READ(ICU_STATUS_REG);
422187500Simp
423187500Simp	irq = 0;
424187500Simp	while (irqstat != 0) {
425187500Simp		if ((irqstat & 1) == 1) {
426187500Simp			event = sc->sc_eventstab[irq];
427187500Simp			if (!event || TAILQ_EMPTY(&event->ie_handlers))
428187500Simp				continue;
429187500Simp
430187500Simp			/* TODO: pass frame as an argument*/
431187500Simp			/* TODO: log stray interrupt */
432187500Simp			intr_event_handle(event, NULL);
433187500Simp		}
434187500Simp
435187500Simp		irq++;
436187500Simp		irqstat >>= 1;
437187500Simp	}
438187500Simp
439187500Simp	return (FILTER_HANDLED);
440187500Simp}
441187500Simp
442187500Simpstatic void
443187500Simpobio_hinted_child(device_t bus, const char *dname, int dunit)
444187500Simp{
445187500Simp	device_t		child;
446187500Simp	long			maddr;
447187500Simp	int			msize;
448187500Simp	int			irq;
449187500Simp	int			result;
450187500Simp
451187500Simp	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
452187500Simp
453187500Simp	/*
454187500Simp	 * Set hard-wired resources for hinted child using
455187500Simp	 * specific RIDs.
456187500Simp	 */
457187500Simp	resource_long_value(dname, dunit, "maddr", &maddr);
458187500Simp	resource_int_value(dname, dunit, "msize", &msize);
459187500Simp
460187500Simp
461187500Simp	result = bus_set_resource(child, SYS_RES_MEMORY, 0,
462187500Simp	    maddr, msize);
463187500Simp	if (result != 0)
464187500Simp		device_printf(bus, "warning: bus_set_resource() failed\n");
465187500Simp
466187500Simp	if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
467187500Simp		result = bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
468187500Simp		if (result != 0)
469187500Simp			device_printf(bus,
470187500Simp			    "warning: bus_set_resource() failed\n");
471187500Simp	}
472187500Simp}
473187500Simp
474187500Simpstatic device_t
475212413Savgobio_add_child(device_t bus, u_int order, const char *name, int unit)
476187500Simp{
477187500Simp	device_t		child;
478187500Simp	struct obio_ivar	*ivar;
479187500Simp
480187500Simp	ivar = malloc(sizeof(struct obio_ivar), M_DEVBUF, M_WAITOK | M_ZERO);
481187500Simp	if (ivar == NULL) {
482187500Simp		printf("Failed to allocate ivar\n");
483187500Simp		return (0);
484187500Simp	}
485187500Simp	resource_list_init(&ivar->resources);
486187500Simp
487187500Simp	child = device_add_child_ordered(bus, order, name, unit);
488187500Simp	if (child == NULL) {
489187500Simp		printf("Can't add child %s%d ordered\n", name, unit);
490187500Simp		return (0);
491187500Simp	}
492187500Simp
493187500Simp	device_set_ivars(child, ivar);
494187500Simp
495187500Simp	return (child);
496187500Simp}
497187500Simp
498187500Simp/*
499187500Simp * Helper routine for bus_generic_rl_get_resource/bus_generic_rl_set_resource
500187500Simp * Provides pointer to resource_list for these routines
501187500Simp */
502187500Simpstatic struct resource_list *
503187500Simpobio_get_resource_list(device_t dev, device_t child)
504187500Simp{
505187500Simp	struct obio_ivar *ivar;
506187500Simp
507187500Simp	ivar = device_get_ivars(child);
508187500Simp	return (&(ivar->resources));
509187500Simp}
510187500Simp
511187500Simpstatic device_method_t obio_methods[] = {
512187500Simp	DEVMETHOD(bus_activate_resource,	obio_activate_resource),
513187500Simp	DEVMETHOD(bus_add_child,		obio_add_child),
514187500Simp	DEVMETHOD(bus_alloc_resource,		obio_alloc_resource),
515187500Simp	DEVMETHOD(bus_deactivate_resource,	obio_deactivate_resource),
516187500Simp	DEVMETHOD(bus_get_resource_list,	obio_get_resource_list),
517187500Simp	DEVMETHOD(bus_hinted_child,		obio_hinted_child),
518187500Simp	DEVMETHOD(bus_release_resource,		obio_release_resource),
519187500Simp	DEVMETHOD(bus_setup_intr,		obio_setup_intr),
520187500Simp	DEVMETHOD(bus_teardown_intr,		obio_teardown_intr),
521187500Simp	DEVMETHOD(device_attach,		obio_attach),
522187500Simp	DEVMETHOD(device_probe,			obio_probe),
523187500Simp        DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
524187500Simp        DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
525187500Simp
526187500Simp	{0, 0},
527187500Simp};
528187500Simp
529187500Simpstatic driver_t obio_driver = {
530187500Simp	"obio",
531187500Simp	obio_methods,
532187500Simp	sizeof(struct obio_softc),
533187500Simp};
534187500Simpstatic devclass_t obio_devclass;
535187500Simp
536187500SimpDRIVER_MODULE(obio, nexus, obio_driver, obio_devclass, 0, 0);
537