xref: /freebsd/sys/dev/bhnd/bhnd.c (revision a5ff72cb0e51a7675d4e2b5810a2b6dad5b91960)
1 /*-
2  * Copyright (c) 2015 Landon Fuller <landon@landonf.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, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 /*
34  * Broadcom Home Networking Division (HND) Bus Driver.
35  *
36  * The Broadcom HND family of devices consists of both SoCs and host-connected
37  * networking chipsets containing a common family of Broadcom IP cores,
38  * including an integrated MIPS and/or ARM cores.
39  *
40  * HND devices expose a nearly identical interface whether accessible over a
41  * native SoC interconnect, or when connected via a host interface such as
42  * PCIe. As a result, the majority of hardware support code should be re-usable
43  * across host drivers for HND networking chipsets, as well as FreeBSD support
44  * for Broadcom MIPS/ARM HND SoCs.
45  *
46  * Earlier HND models used the siba(4) on-chip interconnect, while later models
47  * use bcma(4); the programming model is almost entirely independent
48  * of the actual underlying interconect.
49  */
50 
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/bus.h>
54 #include <sys/module.h>
55 #include <sys/systm.h>
56 
57 #include <machine/bus.h>
58 #include <sys/rman.h>
59 #include <machine/resource.h>
60 
61 #include "bhnd.h"
62 #include "bhndvar.h"
63 
64 #include "bhnd_nvram_if.h"
65 
66 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
67 
68 /**
69  * bhnd_generic_probe_nomatch() reporting configuration.
70  */
71 static const struct bhnd_nomatch {
72 	uint16_t	vendor;		/**< core designer */
73 	uint16_t	device;		/**< core id */
74 	bool		if_verbose;	/**< print when bootverbose is set. */
75 } bhnd_nomatch_table[] = {
76 	{ BHND_MFGID_ARM,	BHND_COREID_OOB_ROUTER,		true	},
77 	{ BHND_MFGID_ARM,	BHND_COREID_EROM,		true	},
78 	{ BHND_MFGID_ARM,	BHND_COREID_PL301,		true	},
79 	{ BHND_MFGID_ARM,	BHND_COREID_APB_BRIDGE,		true	},
80 	{ BHND_MFGID_ARM,	BHND_COREID_AXI_UNMAPPED,	false	},
81 
82 	{ BHND_MFGID_INVALID,	BHND_COREID_INVALID,		false	}
83 };
84 
85 static device_t	find_nvram_child(device_t dev);
86 
87 static int	compare_ascending_probe_order(const void *lhs,
88 		    const void *rhs);
89 static int	compare_descending_probe_order(const void *lhs,
90 		    const void *rhs);
91 
92 /**
93  * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
94  *
95  * This implementation calls device_probe_and_attach() for each of the device's
96  * children, in bhnd probe order.
97  */
98 int
99 bhnd_generic_attach(device_t dev)
100 {
101 	device_t	*devs;
102 	int		 ndevs;
103 	int		 error;
104 
105 	if (device_is_attached(dev))
106 		return (EBUSY);
107 
108 	if ((error = device_get_children(dev, &devs, &ndevs)))
109 		return (error);
110 
111 	qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order);
112 	for (int i = 0; i < ndevs; i++) {
113 		device_t child = devs[i];
114 		device_probe_and_attach(child);
115 	}
116 
117 	free(devs, M_TEMP);
118 	return (0);
119 }
120 
121 /**
122  * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
123  *
124  * This implementation calls device_detach() for each of the the device's
125  * children, in reverse bhnd probe order, terminating if any call to
126  * device_detach() fails.
127  */
128 int
129 bhnd_generic_detach(device_t dev)
130 {
131 	device_t	*devs;
132 	int		 ndevs;
133 	int		 error;
134 
135 	if (!device_is_attached(dev))
136 		return (EBUSY);
137 
138 	if ((error = device_get_children(dev, &devs, &ndevs)))
139 		return (error);
140 
141 	/* Detach in the reverse of attach order */
142 	qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
143 	for (int i = 0; i < ndevs; i++) {
144 		device_t child = devs[i];
145 
146 		/* Terminate on first error */
147 		if ((error = device_detach(child)))
148 			goto cleanup;
149 	}
150 
151 cleanup:
152 	free(devs, M_TEMP);
153 	return (error);
154 }
155 
156 /**
157  * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
158  *
159  * This implementation calls device_shutdown() for each of the device's
160  * children, in reverse bhnd probe order, terminating if any call to
161  * device_shutdown() fails.
162  */
163 int
164 bhnd_generic_shutdown(device_t dev)
165 {
166 	device_t	*devs;
167 	int		 ndevs;
168 	int		 error;
169 
170 	if (!device_is_attached(dev))
171 		return (EBUSY);
172 
173 	if ((error = device_get_children(dev, &devs, &ndevs)))
174 		return (error);
175 
176 	/* Shutdown in the reverse of attach order */
177 	qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
178 	for (int i = 0; i < ndevs; i++) {
179 		device_t child = devs[i];
180 
181 		/* Terminate on first error */
182 		if ((error = device_shutdown(child)))
183 			goto cleanup;
184 	}
185 
186 cleanup:
187 	free(devs, M_TEMP);
188 	return (error);
189 }
190 
191 /**
192  * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
193  *
194  * This implementation calls BUS_RESUME_CHILD() for each of the device's
195  * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
196  * fails.
197  */
198 int
199 bhnd_generic_resume(device_t dev)
200 {
201 	device_t	*devs;
202 	int		 ndevs;
203 	int		 error;
204 
205 	if (!device_is_attached(dev))
206 		return (EBUSY);
207 
208 	if ((error = device_get_children(dev, &devs, &ndevs)))
209 		return (error);
210 
211 	qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order);
212 	for (int i = 0; i < ndevs; i++) {
213 		device_t child = devs[i];
214 
215 		/* Terminate on first error */
216 		if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
217 			goto cleanup;
218 	}
219 
220 cleanup:
221 	free(devs, M_TEMP);
222 	return (error);
223 }
224 
225 /**
226  * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
227  *
228  * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
229  * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
230  * fails, the suspend operation is terminated and any devices that were
231  * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
232  * methods.
233  */
234 int
235 bhnd_generic_suspend(device_t dev)
236 {
237 	device_t	*devs;
238 	int		 ndevs;
239 	int		 error;
240 
241 	if (!device_is_attached(dev))
242 		return (EBUSY);
243 
244 	if ((error = device_get_children(dev, &devs, &ndevs)))
245 		return (error);
246 
247 	/* Suspend in the reverse of attach order */
248 	qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
249 	for (int i = 0; i < ndevs; i++) {
250 		device_t child = devs[i];
251 		error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
252 
253 		/* On error, resume suspended devices and then terminate */
254 		if (error) {
255 			for (int j = 0; j < i; j++) {
256 				BUS_RESUME_CHILD(device_get_parent(devs[j]),
257 				    devs[j]);
258 			}
259 
260 			goto cleanup;
261 		}
262 	}
263 
264 cleanup:
265 	free(devs, M_TEMP);
266 	return (error);
267 }
268 
269 /*
270  * Ascending comparison of bhnd device's probe order.
271  */
272 static int
273 compare_ascending_probe_order(const void *lhs, const void *rhs)
274 {
275 	device_t	ldev, rdev;
276 	int		lorder, rorder;
277 
278 	ldev = (*(const device_t *) lhs);
279 	rdev = (*(const device_t *) rhs);
280 
281 	lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev);
282 	rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev);
283 
284 	if (lorder < rorder) {
285 		return (-1);
286 	} else if (lorder > rorder) {
287 		return (1);
288 	} else {
289 		return (0);
290 	}
291 }
292 
293 /*
294  * Descending comparison of bhnd device's probe order.
295  */
296 static int
297 compare_descending_probe_order(const void *lhs, const void *rhs)
298 {
299 	return (compare_ascending_probe_order(rhs, lhs));
300 }
301 
302 /**
303  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
304  *
305  * This implementation determines probe ordering based on the device's class
306  * and other properties, including whether the device is serving as a host
307  * bridge.
308  */
309 int
310 bhnd_generic_get_probe_order(device_t dev, device_t child)
311 {
312 	switch (bhnd_get_class(child)) {
313 	case BHND_DEVCLASS_CC:
314 		return (BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST);
315 
316 	case BHND_DEVCLASS_CC_B:
317 		/* fall through */
318 	case BHND_DEVCLASS_PMU:
319 		return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
320 
321 	case BHND_DEVCLASS_SOC_ROUTER:
322 		return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
323 
324 	case BHND_DEVCLASS_SOC_BRIDGE:
325 		return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
326 
327 	case BHND_DEVCLASS_CPU:
328 		return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
329 
330 	case BHND_DEVCLASS_RAM:
331 		/* fall through */
332 	case BHND_DEVCLASS_MEMC:
333 		return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
334 
335 	case BHND_DEVCLASS_NVRAM:
336 		return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
337 
338 	case BHND_DEVCLASS_PCI:
339 	case BHND_DEVCLASS_PCIE:
340 	case BHND_DEVCLASS_PCCARD:
341 	case BHND_DEVCLASS_ENET:
342 	case BHND_DEVCLASS_ENET_MAC:
343 	case BHND_DEVCLASS_ENET_PHY:
344 	case BHND_DEVCLASS_WLAN:
345 	case BHND_DEVCLASS_WLAN_MAC:
346 	case BHND_DEVCLASS_WLAN_PHY:
347 	case BHND_DEVCLASS_EROM:
348 	case BHND_DEVCLASS_OTHER:
349 	case BHND_DEVCLASS_INVALID:
350 		if (bhnd_is_hostb_device(child))
351 			return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
352 
353 		return (BHND_PROBE_DEFAULT);
354 	}
355 }
356 
357 /**
358  * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
359  *
360  * This implementation assumes that port and region numbers are 0-indexed and
361  * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
362  * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
363  * within the defined range.
364  */
365 static bool
366 bhnd_generic_is_region_valid(device_t dev, device_t child,
367     bhnd_port_type type, u_int port, u_int region)
368 {
369 	if (port >= bhnd_get_port_count(child, type))
370 		return (false);
371 
372 	if (region >= bhnd_get_region_count(child, type, port))
373 		return (false);
374 
375 	return (true);
376 }
377 
378 /**
379  * Find an NVRAM child device on @p dev, if any.
380  *
381  * @retval device_t An NVRAM device.
382  * @retval NULL If no NVRAM device is found.
383  */
384 static device_t
385 find_nvram_child(device_t dev)
386 {
387 	device_t chipc, nvram;
388 
389 	/* Look for a directly-attached NVRAM child */
390 	nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
391 	    -1);
392 	if (nvram == NULL)
393 		return (NULL);
394 
395 	/* Further checks require a bhnd(4) bus */
396 	if (device_get_devclass(dev) != bhnd_devclass)
397 		return (NULL);
398 
399 	/* Look for a ChipCommon-attached OTP device */
400 	if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
401 		/* Recursively search the ChipCommon device */
402 		if ((nvram = find_nvram_child(chipc)) != NULL)
403 			return (nvram);
404 	}
405 
406 	/* Not found */
407 	return (NULL);
408 }
409 
410 /**
411  * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR().
412  *
413  * This implementation searches @p dev for a valid NVRAM device. If no NVRAM
414  * child device is found on @p dev, the request is delegated to the
415  * BHND_BUS_READ_NVRAM_VAR() method on the parent
416  * of @p dev.
417  */
418 static int
419 bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
420     void *buf, size_t *size)
421 {
422 	device_t nvram;
423 
424 	/* Try to find an NVRAM device applicable to @p child */
425 	if ((nvram = find_nvram_child(dev)) == NULL)
426 		return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child,
427 		    name, buf, size));
428 
429 	return BHND_NVRAM_GETVAR(nvram, name, buf, size);
430 }
431 
432 /**
433  * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
434  *
435  * This implementation requests the device's struct resource_list via
436  * BUS_GET_RESOURCE_LIST.
437  */
438 int
439 bhnd_generic_print_child(device_t dev, device_t child)
440 {
441 	struct resource_list	*rl;
442 	int			retval = 0;
443 
444 	retval += bus_print_child_header(dev, child);
445 
446 	rl = BUS_GET_RESOURCE_LIST(dev, child);
447 	if (rl != NULL) {
448 		retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
449 		    "%#jx");
450 	}
451 
452 	retval += printf(" at core %u", bhnd_get_core_index(child));
453 
454 	retval += bus_print_child_domain(dev, child);
455 	retval += bus_print_child_footer(dev, child);
456 
457 	return (retval);
458 }
459 
460 /**
461  * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
462  *
463  * This implementation requests the device's struct resource_list via
464  * BUS_GET_RESOURCE_LIST.
465  */
466 void
467 bhnd_generic_probe_nomatch(device_t dev, device_t child)
468 {
469 	struct resource_list		*rl;
470 	const struct bhnd_nomatch	*nm;
471 	bool				 report;
472 
473 	/* Fetch reporting configuration for this device */
474 	report = true;
475 	for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
476 		if (nm->vendor != bhnd_get_vendor(child))
477 			continue;
478 
479 		if (nm->device != bhnd_get_device(child))
480 			continue;
481 
482 		report = false;
483 		if (bootverbose && nm->if_verbose)
484 			report = true;
485 		break;
486 	}
487 
488 	if (!report)
489 		return;
490 
491 	/* Print the non-matched device info */
492 	device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child),
493 		bhnd_get_device_name(child));
494 
495 	rl = BUS_GET_RESOURCE_LIST(dev, child);
496 	if (rl != NULL)
497 		resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
498 
499 	printf(" at core %u (no driver attached)\n",
500 	    bhnd_get_core_index(child));
501 }
502 
503 /**
504  * Default implementation of BUS_CHILD_PNPINFO_STR().
505  */
506 static int
507 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
508     size_t buflen)
509 {
510 	if (device_get_parent(child) != dev) {
511 		return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
512 		    buf, buflen));
513 	}
514 
515 	snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
516 	    bhnd_get_vendor(child), bhnd_get_device(child),
517 	    bhnd_get_hwrev(child));
518 
519 	return (0);
520 }
521 
522 /**
523  * Default implementation of BUS_CHILD_LOCATION_STR().
524  */
525 static int
526 bhnd_child_location_str(device_t dev, device_t child, char *buf,
527     size_t buflen)
528 {
529 	bhnd_addr_t	addr;
530 	bhnd_size_t	size;
531 
532 	if (device_get_parent(child) != dev) {
533 		return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
534 		    buf, buflen));
535 	}
536 
537 
538 	if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
539 		/* No device default port/region */
540 		if (buflen > 0)
541 			*buf = '\0';
542 		return (0);
543 	}
544 
545 	snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
546 	return (0);
547 }
548 
549 /**
550  * Helper function for implementing BUS_SUSPEND_CHILD().
551  *
552  * TODO: Power management
553  *
554  * If @p child is not a direct child of @p dev, suspension is delegated to
555  * the @p dev parent.
556  */
557 int
558 bhnd_generic_suspend_child(device_t dev, device_t child)
559 {
560 	if (device_get_parent(child) != dev)
561 		BUS_SUSPEND_CHILD(device_get_parent(dev), child);
562 
563 	return bus_generic_suspend_child(dev, child);
564 }
565 
566 /**
567  * Helper function for implementing BUS_RESUME_CHILD().
568  *
569  * TODO: Power management
570  *
571  * If @p child is not a direct child of @p dev, suspension is delegated to
572  * the @p dev parent.
573  */
574 int
575 bhnd_generic_resume_child(device_t dev, device_t child)
576 {
577 	if (device_get_parent(child) != dev)
578 		BUS_RESUME_CHILD(device_get_parent(dev), child);
579 
580 	return bus_generic_resume_child(dev, child);
581 }
582 
583 /*
584  * Delegate all indirect I/O to the parent device. When inherited by
585  * non-bridged bus implementations, resources will never be marked as
586  * indirect, and these methods should never be called.
587  */
588 
589 static uint8_t
590 bhnd_read_1(device_t dev, device_t child, struct bhnd_resource *r,
591     bus_size_t offset)
592 {
593 	return (BHND_BUS_READ_1(device_get_parent(dev), child, r, offset));
594 }
595 
596 static uint16_t
597 bhnd_read_2(device_t dev, device_t child, struct bhnd_resource *r,
598     bus_size_t offset)
599 {
600 	return (BHND_BUS_READ_2(device_get_parent(dev), child, r, offset));
601 }
602 
603 static uint32_t
604 bhnd_read_4(device_t dev, device_t child, struct bhnd_resource *r,
605     bus_size_t offset)
606 {
607 	return (BHND_BUS_READ_4(device_get_parent(dev), child, r, offset));
608 }
609 
610 static void
611 bhnd_write_1(device_t dev, device_t child, struct bhnd_resource *r,
612     bus_size_t offset, uint8_t value)
613 {
614 	BHND_BUS_WRITE_1(device_get_parent(dev), child, r, offset, value);
615 }
616 
617 static void
618 bhnd_write_2(device_t dev, device_t child, struct bhnd_resource *r,
619     bus_size_t offset, uint16_t value)
620 {
621 	BHND_BUS_WRITE_2(device_get_parent(dev), child, r, offset, value);
622 }
623 
624 static void
625 bhnd_write_4(device_t dev, device_t child, struct bhnd_resource *r,
626     bus_size_t offset, uint32_t value)
627 {
628 	BHND_BUS_WRITE_4(device_get_parent(dev), child, r, offset, value);
629 }
630 
631 static void
632 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
633     bus_size_t offset, bus_size_t length, int flags)
634 {
635 	BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
636 	    flags);
637 }
638 
639 static device_method_t bhnd_methods[] = {
640 	/* Device interface */ \
641 	DEVMETHOD(device_attach,		bhnd_generic_attach),
642 	DEVMETHOD(device_detach,		bhnd_generic_detach),
643 	DEVMETHOD(device_shutdown,		bhnd_generic_shutdown),
644 	DEVMETHOD(device_suspend,		bhnd_generic_suspend),
645 	DEVMETHOD(device_resume,		bhnd_generic_resume),
646 
647 	/* Bus interface */
648 	DEVMETHOD(bus_probe_nomatch,		bhnd_generic_probe_nomatch),
649 	DEVMETHOD(bus_print_child,		bhnd_generic_print_child),
650 	DEVMETHOD(bus_child_pnpinfo_str,	bhnd_child_pnpinfo_str),
651 	DEVMETHOD(bus_child_location_str,	bhnd_child_location_str),
652 
653 	DEVMETHOD(bus_suspend_child,		bhnd_generic_suspend_child),
654 	DEVMETHOD(bus_resume_child,		bhnd_generic_resume_child),
655 
656 	DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
657 	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
658 	DEVMETHOD(bus_delete_resource,		bus_generic_rl_delete_resource),
659 	DEVMETHOD(bus_alloc_resource,		bus_generic_rl_alloc_resource),
660 	DEVMETHOD(bus_adjust_resource,		bus_generic_adjust_resource),
661 	DEVMETHOD(bus_release_resource,		bus_generic_rl_release_resource),
662 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
663 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
664 
665 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
666 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
667 	DEVMETHOD(bus_config_intr,		bus_generic_config_intr),
668 	DEVMETHOD(bus_bind_intr,		bus_generic_bind_intr),
669 	DEVMETHOD(bus_describe_intr,		bus_generic_describe_intr),
670 
671 	DEVMETHOD(bus_get_dma_tag,		bus_generic_get_dma_tag),
672 
673 	/* BHND interface */
674 	DEVMETHOD(bhnd_bus_get_chipid,		bhnd_bus_generic_get_chipid),
675 	DEVMETHOD(bhnd_bus_get_probe_order,	bhnd_generic_get_probe_order),
676 	DEVMETHOD(bhnd_bus_is_region_valid,	bhnd_generic_is_region_valid),
677 	DEVMETHOD(bhnd_bus_is_hostb_device,	bhnd_bus_generic_is_hostb_device),
678 	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhnd_bus_generic_is_hw_disabled),
679 	DEVMETHOD(bhnd_bus_read_nvram_var,	bhnd_generic_read_nvram_var),
680 	DEVMETHOD(bhnd_bus_read_1,		bhnd_read_1),
681 	DEVMETHOD(bhnd_bus_read_2,		bhnd_read_2),
682 	DEVMETHOD(bhnd_bus_read_4,		bhnd_read_4),
683 	DEVMETHOD(bhnd_bus_write_1,		bhnd_write_1),
684 	DEVMETHOD(bhnd_bus_write_2,		bhnd_write_2),
685 	DEVMETHOD(bhnd_bus_write_4,		bhnd_write_4),
686 	DEVMETHOD(bhnd_bus_barrier,		bhnd_barrier),
687 
688 	DEVMETHOD_END
689 };
690 
691 devclass_t bhnd_devclass;	/**< bhnd bus. */
692 devclass_t bhnd_hostb_devclass;	/**< bhnd bus host bridge. */
693 devclass_t bhnd_nvram_devclass;	/**< bhnd NVRAM device */
694 
695 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
696 MODULE_VERSION(bhnd, 1);
697