xref: /freebsd/sys/dev/bhnd/bhnd.c (revision edca4938f74db18d091868237592abbf7e718669)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
5  * Copyright (c) 2017 The FreeBSD Foundation
6  * All rights reserved.
7  *
8  * Portions of this software were developed by Landon Fuller
9  * under sponsorship from the FreeBSD Foundation.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
19  *    redistribution must be conditioned upon including a substantially
20  *    similar Disclaimer requirement for further binary redistribution.
21  *
22  * NO WARRANTY
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
26  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
28  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
31  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33  * THE POSSIBILITY OF SUCH DAMAGES.
34  */
35 
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38 
39 /*
40  * Broadcom Home Networking Division (HND) Bus Driver.
41  *
42  * The Broadcom HND family of devices consists of both SoCs and host-connected
43  * networking chipsets containing a common family of Broadcom IP cores,
44  * including an integrated MIPS and/or ARM cores.
45  *
46  * HND devices expose a nearly identical interface whether accessible over a
47  * native SoC interconnect, or when connected via a host interface such as
48  * PCIe. As a result, the majority of hardware support code should be re-usable
49  * across host drivers for HND networking chipsets, as well as FreeBSD support
50  * for Broadcom MIPS/ARM HND SoCs.
51  *
52  * Earlier HND models used the siba(4) on-chip interconnect, while later models
53  * use bcma(4); the programming model is almost entirely independent
54  * of the actual underlying interconect.
55  */
56 
57 #include <sys/param.h>
58 #include <sys/kernel.h>
59 #include <sys/bus.h>
60 #include <sys/module.h>
61 #include <sys/systm.h>
62 
63 #include <machine/bus.h>
64 #include <sys/rman.h>
65 #include <machine/resource.h>
66 
67 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
68 
69 #include "bhnd_chipc_if.h"
70 #include "bhnd_nvram_if.h"
71 
72 #include "bhnd.h"
73 #include "bhndreg.h"
74 #include "bhndvar.h"
75 
76 #include "bhnd_private.h"
77 
78 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
79 
80 /**
81  * bhnd_generic_probe_nomatch() reporting configuration.
82  */
83 static const struct bhnd_nomatch {
84 	uint16_t	vendor;		/**< core designer */
85 	uint16_t	device;		/**< core id */
86 	bool		if_verbose;	/**< print when bootverbose is set. */
87 } bhnd_nomatch_table[] = {
88 	{ BHND_MFGID_ARM,	BHND_COREID_OOB_ROUTER,		true	},
89 	{ BHND_MFGID_ARM,	BHND_COREID_EROM,		true	},
90 	{ BHND_MFGID_ARM,	BHND_COREID_PL301,		true	},
91 	{ BHND_MFGID_ARM,	BHND_COREID_APB_BRIDGE,		true	},
92 	{ BHND_MFGID_ARM,	BHND_COREID_AXI_UNMAPPED,	false	},
93 
94 	{ BHND_MFGID_INVALID,	BHND_COREID_INVALID,		false	}
95 };
96 
97 static int			 bhnd_delete_children(struct bhnd_softc *sc);
98 
99 /**
100  * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
101  *
102  * This implementation calls device_probe_and_attach() for each of the device's
103  * children, in bhnd probe order.
104  */
105 int
106 bhnd_generic_attach(device_t dev)
107 {
108 	struct bhnd_softc	*sc;
109 	int			 error;
110 
111 	if (device_is_attached(dev))
112 		return (EBUSY);
113 
114 	sc = device_get_softc(dev);
115 	sc->dev = dev;
116 
117 	/* Probe and attach all children */
118 	if ((error = bhnd_bus_probe_children(dev))) {
119 		bhnd_delete_children(sc);
120 		return (error);
121 	}
122 
123 	return (0);
124 }
125 
126 /**
127  * Detach and delete all children, in reverse of their attach order.
128  */
129 static int
130 bhnd_delete_children(struct bhnd_softc *sc)
131 {
132 	device_t		*devs;
133 	int			 ndevs;
134 	int			 error;
135 
136 	/* Fetch children in detach order */
137 	error = bhnd_bus_get_children(sc->dev, &devs, &ndevs,
138 	    BHND_DEVICE_ORDER_DETACH);
139 	if (error)
140 		return (error);
141 
142 	/* Perform detach */
143 	for (int i = 0; i < ndevs; i++) {
144 		device_t child = devs[i];
145 
146 		/* Terminate on first error */
147 		if ((error = device_delete_child(sc->dev, child)))
148 			goto cleanup;
149 	}
150 
151 cleanup:
152 	bhnd_bus_free_children(devs);
153 	return (error);
154 }
155 
156 /**
157  * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
158  *
159  * This implementation calls device_detach() for each of the device's
160  * children, in reverse bhnd probe order, terminating if any call to
161  * device_detach() fails.
162  */
163 int
164 bhnd_generic_detach(device_t dev)
165 {
166 	struct bhnd_softc	*sc;
167 	int			 error;
168 
169 	if (!device_is_attached(dev))
170 		return (EBUSY);
171 
172 	sc = device_get_softc(dev);
173 
174 	if ((error = bhnd_delete_children(sc)))
175 		return (error);
176 
177 	return (0);
178 }
179 
180 /**
181  * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
182  *
183  * This implementation calls device_shutdown() for each of the device's
184  * children, in reverse bhnd probe order, terminating if any call to
185  * device_shutdown() fails.
186  */
187 int
188 bhnd_generic_shutdown(device_t dev)
189 {
190 	device_t	*devs;
191 	int		 ndevs;
192 	int		 error;
193 
194 	if (!device_is_attached(dev))
195 		return (EBUSY);
196 
197 	/* Fetch children in detach order */
198 	error = bhnd_bus_get_children(dev, &devs, &ndevs,
199 	    BHND_DEVICE_ORDER_DETACH);
200 	if (error)
201 		return (error);
202 
203 	/* Perform shutdown */
204 	for (int i = 0; i < ndevs; i++) {
205 		device_t child = devs[i];
206 
207 		/* Terminate on first error */
208 		if ((error = device_shutdown(child)))
209 			goto cleanup;
210 	}
211 
212 cleanup:
213 	bhnd_bus_free_children(devs);
214 	return (error);
215 }
216 
217 /**
218  * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
219  *
220  * This implementation calls BUS_RESUME_CHILD() for each of the device's
221  * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
222  * fails.
223  */
224 int
225 bhnd_generic_resume(device_t dev)
226 {
227 	device_t	*devs;
228 	int		 ndevs;
229 	int		 error;
230 
231 	if (!device_is_attached(dev))
232 		return (EBUSY);
233 
234 	/* Fetch children in attach order */
235 	error = bhnd_bus_get_children(dev, &devs, &ndevs,
236 	    BHND_DEVICE_ORDER_ATTACH);
237 	if (error)
238 		return (error);
239 
240 	/* Perform resume */
241 	for (int i = 0; i < ndevs; i++) {
242 		device_t child = devs[i];
243 
244 		/* Terminate on first error */
245 		if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
246 			goto cleanup;
247 	}
248 
249 cleanup:
250 	bhnd_bus_free_children(devs);
251 	return (error);
252 }
253 
254 /**
255  * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
256  *
257  * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
258  * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
259  * fails, the suspend operation is terminated and any devices that were
260  * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
261  * methods.
262  */
263 int
264 bhnd_generic_suspend(device_t dev)
265 {
266 	device_t	*devs;
267 	int		 ndevs;
268 	int		 error;
269 
270 	if (!device_is_attached(dev))
271 		return (EBUSY);
272 
273 	/* Fetch children in detach order */
274 	error = bhnd_bus_get_children(dev, &devs, &ndevs,
275 	    BHND_DEVICE_ORDER_DETACH);
276 	if (error)
277 		return (error);
278 
279 	/* Perform suspend */
280 	for (int i = 0; i < ndevs; i++) {
281 		device_t child = devs[i];
282 		error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
283 
284 		/* On error, resume suspended devices and then terminate */
285 		if (error) {
286 			for (int j = 0; j < i; j++) {
287 				BUS_RESUME_CHILD(device_get_parent(devs[j]),
288 				    devs[j]);
289 			}
290 
291 			goto cleanup;
292 		}
293 	}
294 
295 cleanup:
296 	bhnd_bus_free_children(devs);
297 	return (error);
298 }
299 
300 /**
301  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
302  *
303  * This implementation determines probe ordering based on the device's class
304  * and other properties, including whether the device is serving as a host
305  * bridge.
306  */
307 int
308 bhnd_generic_get_probe_order(device_t dev, device_t child)
309 {
310 	switch (bhnd_get_class(child)) {
311 	case BHND_DEVCLASS_CC:
312 		/* Must be early enough to provide NVRAM access to the
313 		 * host bridge */
314 		return (BHND_PROBE_ROOT + 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_bus_find_hostb_device(dev) == child)
351 			return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
352 
353 		return (BHND_PROBE_DEFAULT);
354 	default:
355 		return (BHND_PROBE_DEFAULT);
356 	}
357 }
358 
359 /**
360  * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU().
361  */
362 int
363 bhnd_generic_alloc_pmu(device_t dev, device_t child)
364 {
365 	struct bhnd_softc		*sc;
366 	struct bhnd_resource		*r;
367 	struct bhnd_core_clkctl		*clkctl;
368 	struct resource_list		*rl;
369 	struct resource_list_entry	*rle;
370 	device_t			 pmu_dev;
371 	bhnd_addr_t			 r_addr;
372 	bhnd_size_t			 r_size;
373 	bus_size_t			 pmu_regs;
374 	u_int				 max_latency;
375 	int				 error;
376 
377 	GIANT_REQUIRED;	/* for newbus */
378 
379 	if (device_get_parent(child) != dev)
380 		return (EINVAL);
381 
382 	sc = device_get_softc(dev);
383 	clkctl = bhnd_get_pmu_info(child);
384 	pmu_regs = BHND_CLK_CTL_ST;
385 
386 	/* already allocated? */
387 	if (clkctl != NULL) {
388 		panic("duplicate PMU allocation for %s",
389 		    device_get_nameunit(child));
390 	}
391 
392 	/* Determine address+size of the core's PMU register block */
393 	error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr,
394 	    &r_size);
395 	if (error) {
396 		device_printf(sc->dev, "error fetching register block info for "
397 		    "%s: %d\n", device_get_nameunit(child), error);
398 		return (error);
399 	}
400 
401 	if (r_size < (pmu_regs + sizeof(uint32_t))) {
402 		device_printf(sc->dev, "pmu offset %#jx would overrun %s "
403 		    "register block\n", (uintmax_t)pmu_regs,
404 		    device_get_nameunit(child));
405 		return (ENODEV);
406 	}
407 
408 	/* Locate actual resource containing the core's register block */
409 	if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) {
410 		device_printf(dev, "NULL resource list returned for %s\n",
411 		    device_get_nameunit(child));
412 		return (ENXIO);
413 	}
414 
415 	if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) {
416 		device_printf(dev, "cannot locate core register resource "
417 		    "for %s\n", device_get_nameunit(child));
418 		return (ENXIO);
419 	}
420 
421 	if (rle->res == NULL) {
422 		device_printf(dev, "core register resource unallocated for "
423 		    "%s\n", device_get_nameunit(child));
424 		return (ENXIO);
425 	}
426 
427 	if (r_addr+pmu_regs < rman_get_start(rle->res) ||
428 	    r_addr+pmu_regs >= rman_get_end(rle->res))
429 	{
430 		device_printf(dev, "core register resource does not map PMU "
431 		    "registers at %#jx\n for %s\n", r_addr+pmu_regs,
432 		    device_get_nameunit(child));
433 		return (ENXIO);
434 	}
435 
436 	/* Adjust PMU register offset relative to the actual start address
437 	 * of the core's register block allocation.
438 	 *
439 	 * XXX: The saved offset will be invalid if bus_adjust_resource is
440 	 * used to modify the resource's start address.
441 	 */
442 	if (rman_get_start(rle->res) > r_addr)
443 		pmu_regs -= rman_get_start(rle->res) - r_addr;
444 	else
445 		pmu_regs -= r_addr - rman_get_start(rle->res);
446 
447 	/* Retain a PMU reference for the clkctl instance state */
448 	pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU);
449 	if (pmu_dev == NULL) {
450 		device_printf(sc->dev, "PMU not found\n");
451 		return (ENXIO);
452 	}
453 
454 	/* Fetch the maximum transition latency from our PMU */
455 	max_latency = bhnd_pmu_get_max_transition_latency(pmu_dev);
456 
457 	/* Allocate a new bhnd_resource wrapping the standard resource we
458 	 * fetched from the resource list; we'll free this in
459 	 * bhnd_generic_release_pmu() */
460 	r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
461 	if (r == NULL) {
462 		bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
463 		return (ENOMEM);
464 	}
465 
466 	r->res = rle->res;
467 	r->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0);
468 
469 	/* Allocate the clkctl instance */
470 	clkctl = bhnd_alloc_core_clkctl(child, pmu_dev, r, pmu_regs,
471 	    max_latency);
472 	if (clkctl == NULL) {
473 		free(r, M_BHND);
474 		bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
475 		return (ENOMEM);
476 	}
477 
478 	bhnd_set_pmu_info(child, clkctl);
479 	return (0);
480 }
481 
482 /**
483  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU().
484  */
485 int
486 bhnd_generic_release_pmu(device_t dev, device_t child)
487 {
488 	struct bhnd_softc	*sc;
489 	struct bhnd_core_clkctl	*clkctl;
490 	struct bhnd_resource	*r;
491 	device_t		 pmu_dev;
492 
493 	GIANT_REQUIRED;	/* for newbus */
494 
495 	sc = device_get_softc(dev);
496 
497 	if (device_get_parent(child) != dev)
498 		return (EINVAL);
499 
500 	clkctl = bhnd_get_pmu_info(child);
501 	if (clkctl == NULL)
502 		panic("pmu over-release for %s", device_get_nameunit(child));
503 
504 	/* Clear all FORCE, AREQ, and ERSRC flags, unless we're already in
505 	 * RESET. Suspending a core clears clkctl automatically (and attempting
506 	 * to access the PMU registers in a suspended core will trigger a
507 	 * system livelock). */
508 	if (!bhnd_is_hw_suspended(clkctl->cc_dev)) {
509 		BHND_CLKCTL_LOCK(clkctl);
510 
511 		/* Clear all FORCE, AREQ, and ERSRC flags */
512 		BHND_CLKCTL_SET_4(clkctl, 0x0, BHND_CCS_FORCE_MASK |
513 		    BHND_CCS_AREQ_MASK | BHND_CCS_ERSRC_REQ_MASK);
514 
515 		BHND_CLKCTL_UNLOCK(clkctl);
516 	}
517 
518 	/* Clear child's PMU info reference */
519 	bhnd_set_pmu_info(child, NULL);
520 
521 	/* Before freeing the clkctl instance, save a pointer to resources we
522 	 * need to clean up manually */
523 	r = clkctl->cc_res;
524 	pmu_dev = clkctl->cc_pmu_dev;
525 
526 	/* Free the clkctl instance */
527 	bhnd_free_core_clkctl(clkctl);
528 
529 	/* Free the child's bhnd resource wrapper */
530 	free(r, M_BHND);
531 
532 	/* Release the child's PMU provider reference */
533 	bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
534 
535 	return (0);
536 }
537 
538 /**
539  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_LATENCY().
540  */
541 int
542 bhnd_generic_get_clock_latency(device_t dev, device_t child, bhnd_clock clock,
543     u_int *latency)
544 {
545 	struct bhnd_core_clkctl *clkctl;
546 
547 	if (device_get_parent(child) != dev)
548 		return (EINVAL);
549 
550 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
551 		panic("no active PMU allocation");
552 
553 	return (bhnd_pmu_get_clock_latency(clkctl->cc_pmu_dev, clock, latency));
554 }
555 
556 /**
557  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_CLOCK_FREQ().
558  */
559 int
560 bhnd_generic_get_clock_freq(device_t dev, device_t child, bhnd_clock clock,
561     u_int *freq)
562 {
563 	struct bhnd_core_clkctl *clkctl;
564 
565 	if (device_get_parent(child) != dev)
566 		return (EINVAL);
567 
568 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
569 		panic("no active PMU allocation");
570 
571 	return (bhnd_pmu_get_clock_freq(clkctl->cc_pmu_dev, clock, freq));
572 }
573 
574 /**
575  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK().
576  */
577 int
578 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock)
579 {
580 	struct bhnd_softc	*sc;
581 	struct bhnd_core_clkctl	*clkctl;
582 	uint32_t		 avail;
583 	uint32_t		 req;
584 	int			 error;
585 
586 	sc = device_get_softc(dev);
587 
588 	if (device_get_parent(child) != dev)
589 		return (EINVAL);
590 
591 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
592 		panic("no active PMU allocation");
593 
594 	BHND_ASSERT_CLKCTL_AVAIL(clkctl);
595 
596 	avail = 0x0;
597 	req = 0x0;
598 
599 	switch (clock) {
600 	case BHND_CLOCK_DYN:
601 		break;
602 	case BHND_CLOCK_ILP:
603 		req |= BHND_CCS_FORCEILP;
604 		break;
605 	case BHND_CLOCK_ALP:
606 		req |= BHND_CCS_FORCEALP;
607 		avail |= BHND_CCS_ALPAVAIL;
608 		break;
609 	case BHND_CLOCK_HT:
610 		req |= BHND_CCS_FORCEHT;
611 		avail |= BHND_CCS_HTAVAIL;
612 		break;
613 	default:
614 		device_printf(dev, "%s requested unknown clock: %#x\n",
615 		    device_get_nameunit(clkctl->cc_dev), clock);
616 		return (ENODEV);
617 	}
618 
619 	BHND_CLKCTL_LOCK(clkctl);
620 
621 	/* Issue request */
622 	BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_FORCE_MASK);
623 
624 	/* Wait for clock availability */
625 	error = bhnd_core_clkctl_wait(clkctl, avail, avail);
626 
627 	BHND_CLKCTL_UNLOCK(clkctl);
628 
629 	return (error);
630 }
631 
632 /**
633  * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS().
634  */
635 int
636 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks)
637 {
638 	struct bhnd_softc	*sc;
639 	struct bhnd_core_clkctl	*clkctl;
640 	uint32_t		 avail;
641 	uint32_t		 req;
642 	int			 error;
643 
644 	sc = device_get_softc(dev);
645 
646 	if (device_get_parent(child) != dev)
647 		return (EINVAL);
648 
649 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
650 		panic("no active PMU allocation");
651 
652 	BHND_ASSERT_CLKCTL_AVAIL(clkctl);
653 
654 	sc = device_get_softc(dev);
655 
656 	avail = 0x0;
657 	req = 0x0;
658 
659 	/* Build clock request flags */
660 	if (clocks & BHND_CLOCK_DYN)		/* nothing to enable */
661 		clocks &= ~BHND_CLOCK_DYN;
662 
663 	if (clocks & BHND_CLOCK_ILP)		/* nothing to enable */
664 		clocks &= ~BHND_CLOCK_ILP;
665 
666 	if (clocks & BHND_CLOCK_ALP) {
667 		req |= BHND_CCS_ALPAREQ;
668 		avail |= BHND_CCS_ALPAVAIL;
669 		clocks &= ~BHND_CLOCK_ALP;
670 	}
671 
672 	if (clocks & BHND_CLOCK_HT) {
673 		req |= BHND_CCS_HTAREQ;
674 		avail |= BHND_CCS_HTAVAIL;
675 		clocks &= ~BHND_CLOCK_HT;
676 	}
677 
678 	/* Check for unknown clock values */
679 	if (clocks != 0x0) {
680 		device_printf(dev, "%s requested unknown clocks: %#x\n",
681 		    device_get_nameunit(clkctl->cc_dev), clocks);
682 		return (ENODEV);
683 	}
684 
685 	BHND_CLKCTL_LOCK(clkctl);
686 
687 	/* Issue request */
688 	BHND_CLKCTL_SET_4(clkctl, req, BHND_CCS_AREQ_MASK);
689 
690 	/* Wait for clock availability */
691 	error = bhnd_core_clkctl_wait(clkctl, avail, avail);
692 
693 	BHND_CLKCTL_UNLOCK(clkctl);
694 
695 	return (error);
696 }
697 
698 /**
699  * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC().
700  */
701 int
702 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc)
703 {
704 	struct bhnd_softc	*sc;
705 	struct bhnd_core_clkctl	*clkctl;
706 	uint32_t		 req;
707 	uint32_t		 avail;
708 	int			 error;
709 
710 	sc = device_get_softc(dev);
711 
712 	if (device_get_parent(child) != dev)
713 		return (EINVAL);
714 
715 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
716 		panic("no active PMU allocation");
717 
718 	BHND_ASSERT_CLKCTL_AVAIL(clkctl);
719 
720 	sc = device_get_softc(dev);
721 
722 	if (rsrc > BHND_CCS_ERSRC_MAX)
723 		return (EINVAL);
724 
725 	req = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
726 	avail = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_STS);
727 
728 	BHND_CLKCTL_LOCK(clkctl);
729 
730 	/* Write request */
731 	BHND_CLKCTL_SET_4(clkctl, req, req);
732 
733 	/* Wait for resource availability */
734 	error = bhnd_core_clkctl_wait(clkctl, avail, avail);
735 
736 	BHND_CLKCTL_UNLOCK(clkctl);
737 
738 	return (error);
739 }
740 
741 /**
742  * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC().
743  */
744 int
745 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc)
746 {
747 	struct bhnd_softc	*sc;
748 	struct bhnd_core_clkctl	*clkctl;
749 	uint32_t		 mask;
750 
751 	sc = device_get_softc(dev);
752 
753 	if (device_get_parent(child) != dev)
754 		return (EINVAL);
755 
756 	if ((clkctl = bhnd_get_pmu_info(child)) == NULL)
757 		panic("no active PMU allocation");
758 
759 
760 	BHND_ASSERT_CLKCTL_AVAIL(clkctl);
761 
762 	sc = device_get_softc(dev);
763 
764 	if (rsrc > BHND_CCS_ERSRC_MAX)
765 		return (EINVAL);
766 
767 	mask = BHND_CCS_SET_BITS((1<<rsrc), BHND_CCS_ERSRC_REQ);
768 
769 	/* Clear request */
770 	BHND_CLKCTL_LOCK(clkctl);
771 	BHND_CLKCTL_SET_4(clkctl, 0x0, mask);
772 	BHND_CLKCTL_UNLOCK(clkctl);
773 
774 	return (0);
775 }
776 
777 /**
778  * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
779  *
780  * This implementation assumes that port and region numbers are 0-indexed and
781  * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
782  * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
783  * within the defined range.
784  */
785 static bool
786 bhnd_generic_is_region_valid(device_t dev, device_t child,
787     bhnd_port_type type, u_int port, u_int region)
788 {
789 	if (port >= bhnd_get_port_count(child, type))
790 		return (false);
791 
792 	if (region >= bhnd_get_region_count(child, type, port))
793 		return (false);
794 
795 	return (true);
796 }
797 
798 /**
799  * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
800  *
801  * This implementation searches @p dev for a registered NVRAM child device.
802  *
803  * If no NVRAM device is registered with @p dev, the request is delegated to
804  * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
805  */
806 int
807 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
808     void *buf, size_t *size, bhnd_nvram_type type)
809 {
810 	struct bhnd_softc	*sc;
811 	device_t		 nvram, parent;
812 	int			 error;
813 
814 	sc = device_get_softc(dev);
815 
816 	/* If a NVRAM device is available, consult it first */
817 	nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM);
818 	if (nvram != NULL) {
819 		error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
820 		bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM);
821 		return (error);
822 	}
823 
824 	/* Otherwise, try to delegate to parent */
825 	if ((parent = device_get_parent(dev)) == NULL)
826 		return (ENODEV);
827 
828 	return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
829 	    name, buf, size, type));
830 }
831 
832 /**
833  * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
834  *
835  * This implementation requests the device's struct resource_list via
836  * BUS_GET_RESOURCE_LIST.
837  */
838 int
839 bhnd_generic_print_child(device_t dev, device_t child)
840 {
841 	struct resource_list	*rl;
842 	int			retval = 0;
843 
844 	retval += bus_print_child_header(dev, child);
845 
846 	rl = BUS_GET_RESOURCE_LIST(dev, child);
847 
848 
849 	if (rl != NULL) {
850 		retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
851 		    "%#jx");
852 
853 		retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
854 		    "%#jd");
855 	}
856 
857 	retval += printf(" at core %u", bhnd_get_core_index(child));
858 
859 	retval += bus_print_child_domain(dev, child);
860 	retval += bus_print_child_footer(dev, child);
861 
862 	return (retval);
863 }
864 
865 /**
866  * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
867  *
868  * This implementation requests the device's struct resource_list via
869  * BUS_GET_RESOURCE_LIST.
870  */
871 void
872 bhnd_generic_probe_nomatch(device_t dev, device_t child)
873 {
874 	struct resource_list		*rl;
875 	const struct bhnd_nomatch	*nm;
876 	bool				 report;
877 
878 	/* Fetch reporting configuration for this device */
879 	report = true;
880 	for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
881 		if (nm->vendor != bhnd_get_vendor(child))
882 			continue;
883 
884 		if (nm->device != bhnd_get_device(child))
885 			continue;
886 
887 		report = false;
888 		if (bootverbose && nm->if_verbose)
889 			report = true;
890 		break;
891 	}
892 
893 	if (!report)
894 		return;
895 
896 	/* Print the non-matched device info */
897 	device_printf(dev, "<%s %s, rev %hhu>", bhnd_get_vendor_name(child),
898 		bhnd_get_device_name(child), bhnd_get_hwrev(child));
899 
900 	rl = BUS_GET_RESOURCE_LIST(dev, child);
901 	if (rl != NULL) {
902 		resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
903 		resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd");
904 	}
905 
906 	printf(" at core %u (no driver attached)\n",
907 	    bhnd_get_core_index(child));
908 }
909 
910 /**
911  * Default implementation of BUS_CHILD_PNPINFO_STR().
912  */
913 static int
914 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
915     size_t buflen)
916 {
917 	if (device_get_parent(child) != dev) {
918 		return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
919 		    buf, buflen));
920 	}
921 
922 	snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
923 	    bhnd_get_vendor(child), bhnd_get_device(child),
924 	    bhnd_get_hwrev(child));
925 
926 	return (0);
927 }
928 
929 /**
930  * Default implementation of BUS_CHILD_LOCATION_STR().
931  */
932 static int
933 bhnd_child_location_str(device_t dev, device_t child, char *buf,
934     size_t buflen)
935 {
936 	bhnd_addr_t	addr;
937 	bhnd_size_t	size;
938 
939 	if (device_get_parent(child) != dev) {
940 		return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
941 		    buf, buflen));
942 	}
943 
944 
945 	if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
946 		/* No device default port/region */
947 		if (buflen > 0)
948 			*buf = '\0';
949 		return (0);
950 	}
951 
952 	snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
953 	return (0);
954 }
955 
956 /**
957  * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
958  *
959  * This implementation manages internal bhnd(4) state, and must be called
960  * by subclassing drivers.
961  */
962 void
963 bhnd_generic_child_deleted(device_t dev, device_t child)
964 {
965 	struct bhnd_softc	*sc;
966 
967 	sc = device_get_softc(dev);
968 
969 	/* Free device info */
970 	if (bhnd_get_pmu_info(child) != NULL) {
971 		/* Releasing PMU requests automatically would be nice,
972 		 * but we can't reference per-core PMU register
973 		 * resource after driver detach */
974 		panic("%s leaked device pmu state\n",
975 		    device_get_nameunit(child));
976 	}
977 }
978 
979 /**
980  * Helper function for implementing BUS_SUSPEND_CHILD().
981  *
982  * TODO: Power management
983  *
984  * If @p child is not a direct child of @p dev, suspension is delegated to
985  * the @p dev parent.
986  */
987 int
988 bhnd_generic_suspend_child(device_t dev, device_t child)
989 {
990 	if (device_get_parent(child) != dev)
991 		BUS_SUSPEND_CHILD(device_get_parent(dev), child);
992 
993 	return bus_generic_suspend_child(dev, child);
994 }
995 
996 /**
997  * Helper function for implementing BUS_RESUME_CHILD().
998  *
999  * TODO: Power management
1000  *
1001  * If @p child is not a direct child of @p dev, suspension is delegated to
1002  * the @p dev parent.
1003  */
1004 int
1005 bhnd_generic_resume_child(device_t dev, device_t child)
1006 {
1007 	if (device_get_parent(child) != dev)
1008 		BUS_RESUME_CHILD(device_get_parent(dev), child);
1009 
1010 	return bus_generic_resume_child(dev, child);
1011 }
1012 
1013 
1014 /**
1015  * Default bhnd(4) bus driver implementation of BUS_SETUP_INTR().
1016  *
1017  * This implementation of BUS_SETUP_INTR() will delegate interrupt setup
1018  * to the parent of @p dev, if any.
1019  */
1020 int
1021 bhnd_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1022     int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
1023     void **cookiep)
1024 {
1025 	return (bus_generic_setup_intr(dev, child, irq, flags, filter, intr,
1026 	    arg, cookiep));
1027 }
1028 
1029 /*
1030  * Delegate all indirect I/O to the parent device. When inherited by
1031  * non-bridged bus implementations, resources will never be marked as
1032  * indirect, and these methods will never be called.
1033  */
1034 #define	BHND_IO_READ(_type, _name, _method)				\
1035 static _type								\
1036 bhnd_read_ ## _name (device_t dev, device_t child,			\
1037     struct bhnd_resource *r, bus_size_t offset)				\
1038 {									\
1039 	return (BHND_BUS_READ_ ## _method(				\
1040 		    device_get_parent(dev), child, r, offset));		\
1041 }
1042 
1043 #define	BHND_IO_WRITE(_type, _name, _method)				\
1044 static void								\
1045 bhnd_write_ ## _name (device_t dev, device_t child,			\
1046     struct bhnd_resource *r, bus_size_t offset, _type value)		\
1047 {									\
1048 	return (BHND_BUS_WRITE_ ## _method(				\
1049 		    device_get_parent(dev), child, r, offset,		\
1050 		    value));	\
1051 }
1052 
1053 #define	BHND_IO_MISC(_type, _op, _method)				\
1054 static void								\
1055 bhnd_ ## _op (device_t dev, device_t child,				\
1056     struct bhnd_resource *r, bus_size_t offset, _type datap,		\
1057     bus_size_t count)							\
1058 {									\
1059 	BHND_BUS_ ## _method(device_get_parent(dev), child, r,		\
1060 	    offset, datap, count);					\
1061 }
1062 
1063 #define	BHND_IO_METHODS(_type, _size)					\
1064 	BHND_IO_READ(_type, _size, _size)				\
1065 	BHND_IO_WRITE(_type, _size, _size)				\
1066 									\
1067 	BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size)		\
1068 	BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size)	\
1069 									\
1070 	BHND_IO_MISC(_type*, read_multi_ ## _size,			\
1071 	    READ_MULTI_ ## _size)					\
1072 	BHND_IO_MISC(_type*, write_multi_ ## _size,			\
1073 	    WRITE_MULTI_ ## _size)					\
1074 									\
1075 	BHND_IO_MISC(_type*, read_multi_stream_ ## _size,		\
1076 	   READ_MULTI_STREAM_ ## _size)					\
1077 	BHND_IO_MISC(_type*, write_multi_stream_ ## _size,		\
1078 	   WRITE_MULTI_STREAM_ ## _size)				\
1079 									\
1080 	BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size)	\
1081 	BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size)	\
1082 									\
1083 	BHND_IO_MISC(_type*, read_region_ ## _size,			\
1084 	    READ_REGION_ ## _size)					\
1085 	BHND_IO_MISC(_type*, write_region_ ## _size,			\
1086 	    WRITE_REGION_ ## _size)					\
1087 									\
1088 	BHND_IO_MISC(_type*, read_region_stream_ ## _size,		\
1089 	    READ_REGION_STREAM_ ## _size)				\
1090 	BHND_IO_MISC(_type*, write_region_stream_ ## _size,		\
1091 	    WRITE_REGION_STREAM_ ## _size)				\
1092 
1093 BHND_IO_METHODS(uint8_t, 1);
1094 BHND_IO_METHODS(uint16_t, 2);
1095 BHND_IO_METHODS(uint32_t, 4);
1096 
1097 static void
1098 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
1099     bus_size_t offset, bus_size_t length, int flags)
1100 {
1101 	BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
1102 	    flags);
1103 }
1104 
1105 static device_method_t bhnd_methods[] = {
1106 	/* Device interface */ \
1107 	DEVMETHOD(device_attach,		bhnd_generic_attach),
1108 	DEVMETHOD(device_detach,		bhnd_generic_detach),
1109 	DEVMETHOD(device_shutdown,		bhnd_generic_shutdown),
1110 	DEVMETHOD(device_suspend,		bhnd_generic_suspend),
1111 	DEVMETHOD(device_resume,		bhnd_generic_resume),
1112 
1113 	/* Bus interface */
1114 	DEVMETHOD(bus_child_deleted,		bhnd_generic_child_deleted),
1115 	DEVMETHOD(bus_probe_nomatch,		bhnd_generic_probe_nomatch),
1116 	DEVMETHOD(bus_print_child,		bhnd_generic_print_child),
1117 	DEVMETHOD(bus_child_pnpinfo_str,	bhnd_child_pnpinfo_str),
1118 	DEVMETHOD(bus_child_location_str,	bhnd_child_location_str),
1119 
1120 	DEVMETHOD(bus_suspend_child,		bhnd_generic_suspend_child),
1121 	DEVMETHOD(bus_resume_child,		bhnd_generic_resume_child),
1122 
1123 	DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
1124 	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
1125 	DEVMETHOD(bus_delete_resource,		bus_generic_rl_delete_resource),
1126 	DEVMETHOD(bus_alloc_resource,		bus_generic_rl_alloc_resource),
1127 	DEVMETHOD(bus_adjust_resource,		bus_generic_adjust_resource),
1128 	DEVMETHOD(bus_release_resource,		bus_generic_rl_release_resource),
1129 	DEVMETHOD(bus_activate_resource,	bus_generic_activate_resource),
1130 	DEVMETHOD(bus_deactivate_resource,	bus_generic_deactivate_resource),
1131 
1132 	DEVMETHOD(bus_setup_intr,		bhnd_generic_setup_intr),
1133 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
1134 	DEVMETHOD(bus_config_intr,		bus_generic_config_intr),
1135 	DEVMETHOD(bus_bind_intr,		bus_generic_bind_intr),
1136 	DEVMETHOD(bus_describe_intr,		bus_generic_describe_intr),
1137 
1138 	DEVMETHOD(bus_get_dma_tag,		bus_generic_get_dma_tag),
1139 
1140 	/* BHND interface */
1141 	DEVMETHOD(bhnd_bus_get_chipid,		bhnd_bus_generic_get_chipid),
1142 	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhnd_bus_generic_is_hw_disabled),
1143 
1144 	DEVMETHOD(bhnd_bus_get_probe_order,	bhnd_generic_get_probe_order),
1145 
1146 	DEVMETHOD(bhnd_bus_alloc_pmu,		bhnd_generic_alloc_pmu),
1147 	DEVMETHOD(bhnd_bus_release_pmu,		bhnd_generic_release_pmu),
1148 	DEVMETHOD(bhnd_bus_request_clock,	bhnd_generic_request_clock),
1149 	DEVMETHOD(bhnd_bus_enable_clocks,	bhnd_generic_enable_clocks),
1150 	DEVMETHOD(bhnd_bus_request_ext_rsrc,	bhnd_generic_request_ext_rsrc),
1151 	DEVMETHOD(bhnd_bus_release_ext_rsrc,	bhnd_generic_release_ext_rsrc),
1152 	DEVMETHOD(bhnd_bus_get_clock_latency,	bhnd_generic_get_clock_latency),
1153 	DEVMETHOD(bhnd_bus_get_clock_freq,	bhnd_generic_get_clock_freq),
1154 
1155 	DEVMETHOD(bhnd_bus_is_region_valid,	bhnd_generic_is_region_valid),
1156 	DEVMETHOD(bhnd_bus_get_nvram_var,	bhnd_generic_get_nvram_var),
1157 
1158 	/* BHND interface (bus I/O) */
1159 	DEVMETHOD(bhnd_bus_read_1,		bhnd_read_1),
1160 	DEVMETHOD(bhnd_bus_read_2,		bhnd_read_2),
1161 	DEVMETHOD(bhnd_bus_read_4,		bhnd_read_4),
1162 	DEVMETHOD(bhnd_bus_write_1,		bhnd_write_1),
1163 	DEVMETHOD(bhnd_bus_write_2,		bhnd_write_2),
1164 	DEVMETHOD(bhnd_bus_write_4,		bhnd_write_4),
1165 
1166 	DEVMETHOD(bhnd_bus_read_stream_1,	bhnd_read_stream_1),
1167 	DEVMETHOD(bhnd_bus_read_stream_2,	bhnd_read_stream_2),
1168 	DEVMETHOD(bhnd_bus_read_stream_4,	bhnd_read_stream_4),
1169 	DEVMETHOD(bhnd_bus_write_stream_1,	bhnd_write_stream_1),
1170 	DEVMETHOD(bhnd_bus_write_stream_2,	bhnd_write_stream_2),
1171 	DEVMETHOD(bhnd_bus_write_stream_4,	bhnd_write_stream_4),
1172 
1173 	DEVMETHOD(bhnd_bus_read_multi_1,	bhnd_read_multi_1),
1174 	DEVMETHOD(bhnd_bus_read_multi_2,	bhnd_read_multi_2),
1175 	DEVMETHOD(bhnd_bus_read_multi_4,	bhnd_read_multi_4),
1176 	DEVMETHOD(bhnd_bus_write_multi_1,	bhnd_write_multi_1),
1177 	DEVMETHOD(bhnd_bus_write_multi_2,	bhnd_write_multi_2),
1178 	DEVMETHOD(bhnd_bus_write_multi_4,	bhnd_write_multi_4),
1179 
1180 	DEVMETHOD(bhnd_bus_read_multi_stream_1,	bhnd_read_multi_stream_1),
1181 	DEVMETHOD(bhnd_bus_read_multi_stream_2,	bhnd_read_multi_stream_2),
1182 	DEVMETHOD(bhnd_bus_read_multi_stream_4,	bhnd_read_multi_stream_4),
1183 	DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
1184 	DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
1185 	DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
1186 
1187 	DEVMETHOD(bhnd_bus_set_multi_1,		bhnd_set_multi_1),
1188 	DEVMETHOD(bhnd_bus_set_multi_2,		bhnd_set_multi_2),
1189 	DEVMETHOD(bhnd_bus_set_multi_4,		bhnd_set_multi_4),
1190 
1191 	DEVMETHOD(bhnd_bus_set_region_1,	bhnd_set_region_1),
1192 	DEVMETHOD(bhnd_bus_set_region_2,	bhnd_set_region_2),
1193 	DEVMETHOD(bhnd_bus_set_region_4,	bhnd_set_region_4),
1194 
1195 	DEVMETHOD(bhnd_bus_read_region_1,	bhnd_read_region_1),
1196 	DEVMETHOD(bhnd_bus_read_region_2,	bhnd_read_region_2),
1197 	DEVMETHOD(bhnd_bus_read_region_4,	bhnd_read_region_4),
1198 	DEVMETHOD(bhnd_bus_write_region_1,	bhnd_write_region_1),
1199 	DEVMETHOD(bhnd_bus_write_region_2,	bhnd_write_region_2),
1200 	DEVMETHOD(bhnd_bus_write_region_4,	bhnd_write_region_4),
1201 
1202 	DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
1203 	DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
1204 	DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
1205 	DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
1206 	DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
1207 	DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
1208 
1209 	DEVMETHOD(bhnd_bus_barrier,			bhnd_barrier),
1210 
1211 	DEVMETHOD_END
1212 };
1213 
1214 devclass_t bhnd_devclass;	/**< bhnd bus. */
1215 devclass_t bhnd_hostb_devclass;	/**< bhnd bus host bridge. */
1216 devclass_t bhnd_nvram_devclass;	/**< bhnd NVRAM device */
1217 
1218 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
1219 MODULE_VERSION(bhnd, 1);
1220