2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
3 * Copyright (c) 2017 The FreeBSD Foundation
6 * Portions of this software were developed by Landon Fuller
7 * under sponsorship from the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
17 * redistribution must be conditioned upon including a substantially
18 * similar Disclaimer requirement for further binary redistribution.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGES.
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
38 * Broadcom Home Networking Division (HND) Bus Driver.
40 * The Broadcom HND family of devices consists of both SoCs and host-connected
41 * networking chipsets containing a common family of Broadcom IP cores,
42 * including an integrated MIPS and/or ARM cores.
44 * HND devices expose a nearly identical interface whether accessible over a
45 * native SoC interconnect, or when connected via a host interface such as
46 * PCIe. As a result, the majority of hardware support code should be re-usable
47 * across host drivers for HND networking chipsets, as well as FreeBSD support
48 * for Broadcom MIPS/ARM HND SoCs.
50 * Earlier HND models used the siba(4) on-chip interconnect, while later models
51 * use bcma(4); the programming model is almost entirely independent
52 * of the actual underlying interconect.
55 #include <sys/param.h>
56 #include <sys/kernel.h>
58 #include <sys/module.h>
59 #include <sys/systm.h>
61 #include <machine/bus.h>
63 #include <machine/resource.h>
65 #include <dev/bhnd/cores/chipc/chipcvar.h>
67 #include <dev/bhnd/cores/pmu/bhnd_pmu.h>
68 #include <dev/bhnd/cores/pmu/bhnd_pmureg.h>
70 #include "bhnd_chipc_if.h"
71 #include "bhnd_nvram_if.h"
76 #include "bhnd_private.h"
78 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
81 * bhnd_generic_probe_nomatch() reporting configuration.
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 },
94 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false }
97 static int bhnd_delete_children(struct bhnd_softc *sc);
100 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
102 * This implementation calls device_probe_and_attach() for each of the device's
103 * children, in bhnd probe order.
106 bhnd_generic_attach(device_t dev)
108 struct bhnd_softc *sc;
111 if (device_is_attached(dev))
114 sc = device_get_softc(dev);
117 /* Probe and attach all children */
118 if ((error = bhnd_bus_probe_children(dev))) {
119 bhnd_delete_children(sc);
127 * Detach and delete all children, in reverse of their attach order.
130 bhnd_delete_children(struct bhnd_softc *sc)
136 /* Fetch children in detach order */
137 error = bhnd_bus_get_children(sc->dev, &devs, &ndevs,
138 BHND_DEVICE_ORDER_DETACH);
143 for (int i = 0; i < ndevs; i++) {
144 device_t child = devs[i];
146 /* Terminate on first error */
147 if ((error = device_delete_child(sc->dev, child)))
152 bhnd_bus_free_children(devs);
157 * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
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.
164 bhnd_generic_detach(device_t dev)
166 struct bhnd_softc *sc;
169 if (!device_is_attached(dev))
172 sc = device_get_softc(dev);
174 if ((error = bhnd_delete_children(sc)))
181 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
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.
188 bhnd_generic_shutdown(device_t dev)
194 if (!device_is_attached(dev))
197 /* Fetch children in detach order */
198 error = bhnd_bus_get_children(dev, &devs, &ndevs,
199 BHND_DEVICE_ORDER_DETACH);
203 /* Perform shutdown */
204 for (int i = 0; i < ndevs; i++) {
205 device_t child = devs[i];
207 /* Terminate on first error */
208 if ((error = device_shutdown(child)))
213 bhnd_bus_free_children(devs);
218 * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
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()
225 bhnd_generic_resume(device_t dev)
231 if (!device_is_attached(dev))
234 /* Fetch children in attach order */
235 error = bhnd_bus_get_children(dev, &devs, &ndevs,
236 BHND_DEVICE_ORDER_ATTACH);
241 for (int i = 0; i < ndevs; i++) {
242 device_t child = devs[i];
244 /* Terminate on first error */
245 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
250 bhnd_bus_free_children(devs);
255 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
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()
264 bhnd_generic_suspend(device_t dev)
270 if (!device_is_attached(dev))
273 /* Fetch children in detach order */
274 error = bhnd_bus_get_children(dev, &devs, &ndevs,
275 BHND_DEVICE_ORDER_DETACH);
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);
284 /* On error, resume suspended devices and then terminate */
286 for (int j = 0; j < i; j++) {
287 BUS_RESUME_CHILD(device_get_parent(devs[j]),
296 bhnd_bus_free_children(devs);
301 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
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
308 bhnd_generic_get_probe_order(device_t dev, device_t child)
310 switch (bhnd_get_class(child)) {
311 case BHND_DEVCLASS_CC:
312 /* Must be early enough to provide NVRAM access to the
314 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
316 case BHND_DEVCLASS_CC_B:
318 case BHND_DEVCLASS_PMU:
319 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
321 case BHND_DEVCLASS_SOC_ROUTER:
322 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
324 case BHND_DEVCLASS_SOC_BRIDGE:
325 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
327 case BHND_DEVCLASS_CPU:
328 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
330 case BHND_DEVCLASS_RAM:
332 case BHND_DEVCLASS_MEMC:
333 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
335 case BHND_DEVCLASS_NVRAM:
336 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
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);
353 return (BHND_PROBE_DEFAULT);
355 return (BHND_PROBE_DEFAULT);
360 * Default bhnd(4) bus driver implementation of BHND_BUS_ALLOC_PMU().
363 bhnd_generic_alloc_pmu(device_t dev, device_t child)
365 struct bhnd_softc *sc;
366 struct bhnd_resource *br;
367 struct bhnd_core_pmu_info *pm;
368 struct resource_list *rl;
369 struct resource_list_entry *rle;
376 GIANT_REQUIRED; /* for newbus */
378 sc = device_get_softc(dev);
379 pm = bhnd_get_pmu_info(child);
380 pmu_regs = BHND_CLK_CTL_ST;
382 /* already allocated? */
384 panic("duplicate PMU allocation for %s",
385 device_get_nameunit(child));
388 /* Determine address+size of the core's PMU register block */
389 error = bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &r_addr,
392 device_printf(sc->dev, "error fetching register block info for "
393 "%s: %d\n", device_get_nameunit(child), error);
397 if (r_size < (pmu_regs + sizeof(uint32_t))) {
398 device_printf(sc->dev, "pmu offset %#jx would overrun %s "
399 "register block\n", (uintmax_t)pmu_regs,
400 device_get_nameunit(child));
404 /* Locate actual resource containing the core's register block */
405 if ((rl = BUS_GET_RESOURCE_LIST(dev, child)) == NULL) {
406 device_printf(dev, "NULL resource list returned for %s\n",
407 device_get_nameunit(child));
411 if ((rle = resource_list_find(rl, SYS_RES_MEMORY, 0)) == NULL) {
412 device_printf(dev, "cannot locate core register resource "
413 "for %s\n", device_get_nameunit(child));
417 if (rle->res == NULL) {
418 device_printf(dev, "core register resource unallocated for "
419 "%s\n", device_get_nameunit(child));
423 if (r_addr+pmu_regs < rman_get_start(rle->res) ||
424 r_addr+pmu_regs >= rman_get_end(rle->res))
426 device_printf(dev, "core register resource does not map PMU "
427 "registers at %#jx\n for %s\n", r_addr+pmu_regs,
428 device_get_nameunit(child));
432 /* Adjust PMU register offset relative to the actual start address
433 * of the core's register block allocation.
435 * XXX: The saved offset will be invalid if bus_adjust_resource is
436 * used to modify the resource's start address.
438 if (rman_get_start(rle->res) > r_addr)
439 pmu_regs -= rman_get_start(rle->res) - r_addr;
441 pmu_regs -= r_addr - rman_get_start(rle->res);
443 /* Retain PMU reference on behalf of our caller */
444 pmu_dev = bhnd_retain_provider(child, BHND_SERVICE_PMU);
445 if (pmu_dev == NULL) {
446 device_printf(sc->dev,
447 "pmu unavailable; cannot allocate request state\n");
451 /* Allocate and initialize PMU info */
452 br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
454 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
459 br->direct = ((rman_get_flags(rle->res) & RF_ACTIVE) != 0);
461 pm = malloc(sizeof(*pm), M_BHND, M_NOWAIT);
463 bhnd_release_provider(child, pmu_dev, BHND_SERVICE_PMU);
469 pm->pm_regs = pmu_regs;
470 pm->pm_pmu = pmu_dev;
472 bhnd_set_pmu_info(child, pm);
477 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_PMU().
480 bhnd_generic_release_pmu(device_t dev, device_t child)
482 struct bhnd_softc *sc;
483 struct bhnd_core_pmu_info *pm;
486 GIANT_REQUIRED; /* for newbus */
488 sc = device_get_softc(dev);
490 /* dispatch release request */
491 pm = bhnd_get_pmu_info(child);
493 panic("pmu over-release for %s", device_get_nameunit(child));
495 if ((error = BHND_PMU_CORE_RELEASE(pm->pm_pmu, pm)))
499 bhnd_set_pmu_info(child, NULL);
501 bhnd_release_provider(pm->pm_dev, pm->pm_pmu, BHND_SERVICE_PMU);
502 free(pm->pm_res, M_BHND);
509 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_CLOCK().
512 bhnd_generic_request_clock(device_t dev, device_t child, bhnd_clock clock)
514 struct bhnd_softc *sc;
515 struct bhnd_core_pmu_info *pm;
517 sc = device_get_softc(dev);
519 if ((pm = bhnd_get_pmu_info(child)) == NULL)
520 panic("no active PMU request state");
522 /* dispatch request to PMU */
523 return (BHND_PMU_CORE_REQ_CLOCK(pm->pm_pmu, pm, clock));
527 * Default bhnd(4) bus driver implementation of BHND_BUS_ENABLE_CLOCKS().
530 bhnd_generic_enable_clocks(device_t dev, device_t child, uint32_t clocks)
532 struct bhnd_softc *sc;
533 struct bhnd_core_pmu_info *pm;
535 sc = device_get_softc(dev);
537 if ((pm = bhnd_get_pmu_info(child)) == NULL)
538 panic("no active PMU request state");
540 /* dispatch request to PMU */
541 return (BHND_PMU_CORE_EN_CLOCKS(pm->pm_pmu, pm, clocks));
545 * Default bhnd(4) bus driver implementation of BHND_BUS_REQUEST_EXT_RSRC().
548 bhnd_generic_request_ext_rsrc(device_t dev, device_t child, u_int rsrc)
550 struct bhnd_softc *sc;
551 struct bhnd_core_pmu_info *pm;
553 sc = device_get_softc(dev);
555 if ((pm = bhnd_get_pmu_info(child)) == NULL)
556 panic("no active PMU request state");
558 /* dispatch request to PMU */
559 return (BHND_PMU_CORE_REQ_EXT_RSRC(pm->pm_pmu, pm, rsrc));
563 * Default bhnd(4) bus driver implementation of BHND_BUS_RELEASE_EXT_RSRC().
566 bhnd_generic_release_ext_rsrc(device_t dev, device_t child, u_int rsrc)
568 struct bhnd_softc *sc;
569 struct bhnd_core_pmu_info *pm;
571 sc = device_get_softc(dev);
573 if ((pm = bhnd_get_pmu_info(child)) == NULL)
574 panic("no active PMU request state");
576 /* dispatch request to PMU */
577 return (BHND_PMU_CORE_RELEASE_EXT_RSRC(pm->pm_pmu, pm, rsrc));
582 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
584 * This implementation assumes that port and region numbers are 0-indexed and
585 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
586 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
587 * within the defined range.
590 bhnd_generic_is_region_valid(device_t dev, device_t child,
591 bhnd_port_type type, u_int port, u_int region)
593 if (port >= bhnd_get_port_count(child, type))
596 if (region >= bhnd_get_region_count(child, type, port))
603 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
605 * This implementation searches @p dev for a registered NVRAM child device.
607 * If no NVRAM device is registered with @p dev, the request is delegated to
608 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
611 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
612 void *buf, size_t *size, bhnd_nvram_type type)
614 struct bhnd_softc *sc;
615 device_t nvram, parent;
618 sc = device_get_softc(dev);
620 /* If a NVRAM device is available, consult it first */
621 nvram = bhnd_retain_provider(child, BHND_SERVICE_NVRAM);
623 error = BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
624 bhnd_release_provider(child, nvram, BHND_SERVICE_NVRAM);
628 /* Otherwise, try to delegate to parent */
629 if ((parent = device_get_parent(dev)) == NULL)
632 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
633 name, buf, size, type));
637 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
639 * This implementation requests the device's struct resource_list via
640 * BUS_GET_RESOURCE_LIST.
643 bhnd_generic_print_child(device_t dev, device_t child)
645 struct resource_list *rl;
648 retval += bus_print_child_header(dev, child);
650 rl = BUS_GET_RESOURCE_LIST(dev, child);
654 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
657 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
661 retval += printf(" at core %u", bhnd_get_core_index(child));
663 retval += bus_print_child_domain(dev, child);
664 retval += bus_print_child_footer(dev, child);
670 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
672 * This implementation requests the device's struct resource_list via
673 * BUS_GET_RESOURCE_LIST.
676 bhnd_generic_probe_nomatch(device_t dev, device_t child)
678 struct resource_list *rl;
679 const struct bhnd_nomatch *nm;
682 /* Fetch reporting configuration for this device */
684 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
685 if (nm->vendor != bhnd_get_vendor(child))
688 if (nm->device != bhnd_get_device(child))
692 if (bootverbose && nm->if_verbose)
700 /* Print the non-matched device info */
701 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child),
702 bhnd_get_device_name(child));
704 rl = BUS_GET_RESOURCE_LIST(dev, child);
706 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
707 resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%#jd");
710 printf(" at core %u (no driver attached)\n",
711 bhnd_get_core_index(child));
715 * Default implementation of BUS_CHILD_PNPINFO_STR().
718 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
721 if (device_get_parent(child) != dev) {
722 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
726 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
727 bhnd_get_vendor(child), bhnd_get_device(child),
728 bhnd_get_hwrev(child));
734 * Default implementation of BUS_CHILD_LOCATION_STR().
737 bhnd_child_location_str(device_t dev, device_t child, char *buf,
743 if (device_get_parent(child) != dev) {
744 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
749 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
750 /* No device default port/region */
756 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
761 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
763 * This implementation manages internal bhnd(4) state, and must be called
764 * by subclassing drivers.
767 bhnd_generic_child_deleted(device_t dev, device_t child)
769 struct bhnd_softc *sc;
771 sc = device_get_softc(dev);
773 /* Free device info */
774 if (bhnd_get_pmu_info(child) != NULL) {
775 /* Releasing PMU requests automatically would be nice,
776 * but we can't reference per-core PMU register
777 * resource after driver detach */
778 panic("%s leaked device pmu state\n",
779 device_get_nameunit(child));
784 * Helper function for implementing BUS_SUSPEND_CHILD().
786 * TODO: Power management
788 * If @p child is not a direct child of @p dev, suspension is delegated to
792 bhnd_generic_suspend_child(device_t dev, device_t child)
794 if (device_get_parent(child) != dev)
795 BUS_SUSPEND_CHILD(device_get_parent(dev), child);
797 return bus_generic_suspend_child(dev, child);
801 * Helper function for implementing BUS_RESUME_CHILD().
803 * TODO: Power management
805 * If @p child is not a direct child of @p dev, suspension is delegated to
809 bhnd_generic_resume_child(device_t dev, device_t child)
811 if (device_get_parent(child) != dev)
812 BUS_RESUME_CHILD(device_get_parent(dev), child);
814 return bus_generic_resume_child(dev, child);
818 * Delegate all indirect I/O to the parent device. When inherited by
819 * non-bridged bus implementations, resources will never be marked as
820 * indirect, and these methods will never be called.
822 #define BHND_IO_READ(_type, _name, _method) \
824 bhnd_read_ ## _name (device_t dev, device_t child, \
825 struct bhnd_resource *r, bus_size_t offset) \
827 return (BHND_BUS_READ_ ## _method( \
828 device_get_parent(dev), child, r, offset)); \
831 #define BHND_IO_WRITE(_type, _name, _method) \
833 bhnd_write_ ## _name (device_t dev, device_t child, \
834 struct bhnd_resource *r, bus_size_t offset, _type value) \
836 return (BHND_BUS_WRITE_ ## _method( \
837 device_get_parent(dev), child, r, offset, \
841 #define BHND_IO_MISC(_type, _op, _method) \
843 bhnd_ ## _op (device_t dev, device_t child, \
844 struct bhnd_resource *r, bus_size_t offset, _type datap, \
847 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \
848 offset, datap, count); \
851 #define BHND_IO_METHODS(_type, _size) \
852 BHND_IO_READ(_type, _size, _size) \
853 BHND_IO_WRITE(_type, _size, _size) \
855 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \
856 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \
858 BHND_IO_MISC(_type*, read_multi_ ## _size, \
859 READ_MULTI_ ## _size) \
860 BHND_IO_MISC(_type*, write_multi_ ## _size, \
861 WRITE_MULTI_ ## _size) \
863 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \
864 READ_MULTI_STREAM_ ## _size) \
865 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \
866 WRITE_MULTI_STREAM_ ## _size) \
868 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \
869 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \
871 BHND_IO_MISC(_type*, read_region_ ## _size, \
872 READ_REGION_ ## _size) \
873 BHND_IO_MISC(_type*, write_region_ ## _size, \
874 WRITE_REGION_ ## _size) \
876 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \
877 READ_REGION_STREAM_ ## _size) \
878 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \
879 WRITE_REGION_STREAM_ ## _size) \
881 BHND_IO_METHODS(uint8_t, 1);
882 BHND_IO_METHODS(uint16_t, 2);
883 BHND_IO_METHODS(uint32_t, 4);
886 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
887 bus_size_t offset, bus_size_t length, int flags)
889 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
893 static device_method_t bhnd_methods[] = {
894 /* Device interface */ \
895 DEVMETHOD(device_attach, bhnd_generic_attach),
896 DEVMETHOD(device_detach, bhnd_generic_detach),
897 DEVMETHOD(device_shutdown, bhnd_generic_shutdown),
898 DEVMETHOD(device_suspend, bhnd_generic_suspend),
899 DEVMETHOD(device_resume, bhnd_generic_resume),
902 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted),
903 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch),
904 DEVMETHOD(bus_print_child, bhnd_generic_print_child),
905 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str),
906 DEVMETHOD(bus_child_location_str, bhnd_child_location_str),
908 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child),
909 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child),
911 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
912 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
913 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
914 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
915 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
916 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
917 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
918 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
920 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
921 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
922 DEVMETHOD(bus_config_intr, bus_generic_config_intr),
923 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr),
924 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr),
926 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag),
929 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid),
930 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
931 DEVMETHOD(bhnd_bus_read_board_info, bhnd_bus_generic_read_board_info),
933 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
935 DEVMETHOD(bhnd_bus_alloc_pmu, bhnd_generic_alloc_pmu),
936 DEVMETHOD(bhnd_bus_release_pmu, bhnd_generic_release_pmu),
937 DEVMETHOD(bhnd_bus_request_clock, bhnd_generic_request_clock),
938 DEVMETHOD(bhnd_bus_enable_clocks, bhnd_generic_enable_clocks),
939 DEVMETHOD(bhnd_bus_request_ext_rsrc, bhnd_generic_request_ext_rsrc),
940 DEVMETHOD(bhnd_bus_release_ext_rsrc, bhnd_generic_release_ext_rsrc),
942 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
943 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
945 /* BHND interface (bus I/O) */
946 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
947 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
948 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
949 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1),
950 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2),
951 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4),
953 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1),
954 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2),
955 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4),
956 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1),
957 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2),
958 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4),
960 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1),
961 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2),
962 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4),
963 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1),
964 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2),
965 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4),
967 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
968 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
969 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
970 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
971 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
972 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
974 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1),
975 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2),
976 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4),
978 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1),
979 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2),
980 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4),
982 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1),
983 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2),
984 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4),
985 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1),
986 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2),
987 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4),
989 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
990 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
991 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
992 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
993 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
994 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
996 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier),
1001 devclass_t bhnd_devclass; /**< bhnd bus. */
1002 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */
1003 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */
1005 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
1006 MODULE_VERSION(bhnd, 1);