xref: /freebsd/sys/dev/bhnd/bhnd_bus_if.m (revision 74d9553e43cfafc29448d0bb836916aa21dea0de)
1#-
2# Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8# 1. Redistributions of source code must retain the above copyright
9#    notice, this list of conditions and the following disclaimer.
10# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17# IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24#
25# $FreeBSD$
26
27#include <sys/types.h>
28#include <sys/bus.h>
29#include <sys/rman.h>
30
31#include <dev/bhnd/bhnd_types.h>
32#include <dev/bhnd/bhnd_erom_types.h>
33
34INTERFACE bhnd_bus;
35
36#
37# bhnd(4) bus interface
38#
39
40HEADER {
41	/* forward declarations */
42	struct bhnd_board_info;
43	struct bhnd_core_info;
44	struct bhnd_chipid;
45	struct bhnd_devinfo;
46	struct bhnd_resource;
47}
48
49CODE {
50	#include <sys/systm.h>
51
52	#include <dev/bhnd/bhndvar.h>
53
54	static bhnd_erom_class_t *
55	bhnd_bus_null_get_erom_class(driver_t *driver)
56	{
57		return (NULL);
58	}
59
60	static struct bhnd_chipid *
61	bhnd_bus_null_get_chipid(device_t dev, device_t child)
62	{
63		panic("bhnd_bus_get_chipid unimplemented");
64	}
65
66	static int
67	bhnd_bus_null_read_ioctl(device_t dev, device_t child, uint16_t *ioctl)
68	{
69		panic("bhnd_bus_read_ioctl unimplemented");
70	}
71
72
73	static int
74	bhnd_bus_null_write_ioctl(device_t dev, device_t child, uint16_t value,
75	    uint16_t mask)
76	{
77		panic("bhnd_bus_write_ioctl unimplemented");
78	}
79
80
81	static int
82	bhnd_bus_null_read_iost(device_t dev, device_t child, uint16_t *iost)
83	{
84		panic("bhnd_bus_read_iost unimplemented");
85	}
86
87	static bool
88	bhnd_bus_null_is_hw_suspended(device_t dev, device_t child)
89	{
90		panic("bhnd_bus_is_hw_suspended unimplemented");
91	}
92
93	static int
94	bhnd_bus_null_reset_hw(device_t dev, device_t child, uint16_t ioctl)
95	{
96		panic("bhnd_bus_reset_hw unimplemented");
97	}
98
99
100	static int
101	bhnd_bus_null_suspend_hw(device_t dev, device_t child)
102	{
103		panic("bhnd_bus_suspend_hw unimplemented");
104	}
105
106	static bhnd_attach_type
107	bhnd_bus_null_get_attach_type(device_t dev, device_t child)
108	{
109		panic("bhnd_bus_get_attach_type unimplemented");
110	}
111
112	static bhnd_clksrc
113	bhnd_bus_null_pwrctl_get_clksrc(device_t dev, device_t child,
114	    bhnd_clock clock)
115	{
116		return (BHND_CLKSRC_UNKNOWN);
117	}
118
119	static int
120	bhnd_bus_null_pwrctl_gate_clock(device_t dev, device_t child,
121	    bhnd_clock clock)
122	{
123		return (ENODEV);
124	}
125
126	static int
127	bhnd_bus_null_pwrctl_ungate_clock(device_t dev, device_t child,
128	    bhnd_clock clock)
129	{
130		return (ENODEV);
131	}
132
133	static int
134	bhnd_bus_null_read_board_info(device_t dev, device_t child,
135	    struct bhnd_board_info *info)
136	{
137		panic("bhnd_bus_read_boardinfo unimplemented");
138	}
139
140	static int
141	bhnd_bus_null_get_intr_count(device_t dev, device_t child)
142	{
143		panic("bhnd_bus_get_intr_count unimplemented");
144	}
145
146	static int
147	bhnd_bus_null_assign_intr(device_t dev, device_t child, int rid)
148	{
149		panic("bhnd_bus_assign_intr unimplemented");
150	}
151
152	static int
153	bhnd_bus_null_get_core_ivec(device_t dev, device_t child, u_int intr,
154	    uint32_t *ivec)
155	{
156		panic("bhnd_bus_get_core_ivec unimplemented");
157	}
158
159	static void
160	bhnd_bus_null_child_added(device_t dev, device_t child)
161	{
162	}
163
164	static int
165	bhnd_bus_null_alloc_pmu(device_t dev, device_t child)
166	{
167		panic("bhnd_bus_alloc_pmu unimplemented");
168	}
169
170	static int
171	bhnd_bus_null_release_pmu(device_t dev, device_t child)
172	{
173		panic("bhnd_bus_release_pmu unimplemented");
174	}
175
176	static int
177	bhnd_bus_null_request_clock(device_t dev, device_t child,
178	    bhnd_clock clock)
179	{
180		panic("bhnd_bus_request_clock unimplemented");
181	}
182
183	static int
184	bhnd_bus_null_enable_clocks(device_t dev, device_t child,
185	    uint32_t clocks)
186	{
187		panic("bhnd_bus_enable_clocks unimplemented");
188	}
189
190	static int
191	bhnd_bus_null_request_ext_rsrc(device_t dev, device_t child,
192	    u_int rsrc)
193	{
194		panic("bhnd_bus_request_ext_rsrc unimplemented");
195	}
196
197	static int
198	bhnd_bus_null_release_ext_rsrc(device_t dev, device_t child,
199	    u_int rsrc)
200	{
201		panic("bhnd_bus_release_ext_rsrc unimplemented");
202	}
203
204	static int
205	bhnd_bus_null_read_config(device_t dev, device_t child,
206	    bus_size_t offset, void *value, u_int width)
207	{
208		panic("bhnd_bus_null_read_config unimplemented");
209	}
210
211	static void
212	bhnd_bus_null_write_config(device_t dev, device_t child,
213	    bus_size_t offset, void *value, u_int width)
214	{
215		panic("bhnd_bus_null_write_config unimplemented");
216	}
217
218	static device_t
219	bhnd_bus_null_find_hostb_device(device_t dev)
220	{
221		return (NULL);
222	}
223
224	static bool
225	bhnd_bus_null_is_hw_disabled(device_t dev, device_t child)
226	{
227		panic("bhnd_bus_is_hw_disabled unimplemented");
228	}
229
230	static int
231	bhnd_bus_null_get_probe_order(device_t dev, device_t child)
232	{
233		panic("bhnd_bus_get_probe_order unimplemented");
234	}
235
236	static int
237	bhnd_bus_null_get_port_rid(device_t dev, device_t child,
238	    bhnd_port_type port_type, u_int port, u_int region)
239	{
240		return (-1);
241	}
242
243	static int
244	bhnd_bus_null_decode_port_rid(device_t dev, device_t child, int type,
245	    int rid, bhnd_port_type *port_type, u_int *port, u_int *region)
246	{
247		return (ENOENT);
248	}
249
250	static int
251	bhnd_bus_null_get_region_addr(device_t dev, device_t child,
252	    bhnd_port_type type, u_int port, u_int region, bhnd_addr_t *addr,
253	    bhnd_size_t *size)
254	{
255		return (ENOENT);
256	}
257
258	static int
259	bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
260	    const char *name, void *buf, size_t *size, bhnd_nvram_type type)
261	{
262		return (ENODEV);
263	}
264
265}
266
267/**
268 * Return the bhnd(4) bus driver's device enumeration parser class.
269 *
270 * @param driver	The bhnd bus driver instance.
271 */
272STATICMETHOD bhnd_erom_class_t * get_erom_class {
273	driver_t			*driver;
274} DEFAULT bhnd_bus_null_get_erom_class;
275
276/**
277 * Return the active host bridge core for the bhnd bus, if any.
278 *
279 * @param dev The bhnd bus device.
280 *
281 * @retval device_t if a hostb device exists
282 * @retval NULL if no hostb device is found.
283 */
284METHOD device_t find_hostb_device {
285	device_t dev;
286} DEFAULT bhnd_bus_null_find_hostb_device;
287
288/**
289 * Return true if the hardware components required by @p child are unpopulated
290 * or otherwise unusable.
291 *
292 * In some cases, enumerated devices may have pins that are left floating, or
293 * the hardware may otherwise be non-functional; this method allows a parent
294 * device to explicitly specify if a successfully enumerated @p child should
295 * be disabled.
296 *
297 * @param dev The device whose child is being examined.
298 * @param child The child device.
299 */
300METHOD bool is_hw_disabled {
301	device_t dev;
302	device_t child;
303} DEFAULT bhnd_bus_null_is_hw_disabled;
304
305/**
306 * Return the probe (and attach) order for @p child.
307 *
308 * All devices on the bhnd(4) bus will be probed, attached, or resumed in
309 * ascending order; they will be suspended, shutdown, and detached in
310 * descending order.
311 *
312 * The following device methods will be dispatched in ascending probe order
313 * by the bus:
314 *
315 * - DEVICE_PROBE()
316 * - DEVICE_ATTACH()
317 * - DEVICE_RESUME()
318 *
319 * The following device methods will be dispatched in descending probe order
320 * by the bus:
321 *
322 * - DEVICE_SHUTDOWN()
323 * - DEVICE_DETACH()
324 * - DEVICE_SUSPEND()
325 *
326 * @param dev The device whose child is being examined.
327 * @param child The child device.
328 *
329 * Refer to BHND_PROBE_* and BHND_PROBE_ORDER_* for the standard set of
330 * priorities.
331 */
332METHOD int get_probe_order {
333	device_t dev;
334	device_t child;
335} DEFAULT bhnd_bus_null_get_probe_order;
336
337/**
338 * Return the BHND chip identification for the parent bus.
339 *
340 * @param dev The device whose child is being examined.
341 * @param child The child device.
342 */
343METHOD const struct bhnd_chipid * get_chipid {
344	device_t dev;
345	device_t child;
346} DEFAULT bhnd_bus_null_get_chipid;
347
348/**
349 * Return the BHND attachment type of the parent bus.
350 *
351 * @param dev The device whose child is being examined.
352 * @param child The child device.
353 *
354 * @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter,
355 * such as a WiFi chipset.
356 * @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock,
357 * CPU, etc) to a directly attached native host.
358 */
359METHOD bhnd_attach_type get_attach_type {
360	device_t dev;
361	device_t child;
362} DEFAULT bhnd_bus_null_get_attach_type;
363
364/**
365 * Attempt to read the BHND board identification from the parent bus.
366 *
367 * This relies on NVRAM access, and will fail if a valid NVRAM device cannot
368 * be found, or is not yet attached.
369 *
370 * @param dev The parent of @p child.
371 * @param child The bhnd device requesting board info.
372 * @param[out] info On success, will be populated with the bhnd(4) device's
373 * board information.
374 *
375 * @retval 0 success
376 * @retval ENODEV	No valid NVRAM source could be found.
377 * @retval non-zero	If reading @p name otherwise fails, a regular unix
378 *			error code will be returned.
379 */
380METHOD int read_board_info {
381	device_t dev;
382	device_t child;
383	struct bhnd_board_info *info;
384} DEFAULT bhnd_bus_null_read_board_info;
385
386/**
387 * Return the number of interrupts to be assigned to @p child via
388 * BHND_BUS_ASSIGN_INTR().
389 *
390 * @param dev The bhnd bus parent of @p child.
391 * @param child The bhnd device for which a count should be returned.
392 *
393 * @retval 0		If no interrupts should be assigned.
394 * @retval non-zero	The count of interrupt resource IDs to be
395 *			assigned, starting at rid 0.
396 */
397METHOD int get_intr_count {
398	device_t dev;
399	device_t child;
400} DEFAULT bhnd_bus_null_get_intr_count;
401
402/**
403 * Assign an interrupt to @p child via bus_set_resource().
404 *
405 * The default bus implementation of this method should assign backplane
406 * interrupt values to @p child.
407 *
408 * Bridge-attached bus implementations may instead override standard
409 * interconnect IRQ assignment, providing IRQs inherited from the parent bus.
410 *
411 * TODO: Once we can depend on INTRNG, investigate replacing this with a
412 * bridge-level interrupt controller.
413 *
414 * @param dev The bhnd bus parent of @p child.
415 * @param child The bhnd device to which an interrupt should be assigned.
416 * @param rid The interrupt resource ID to be assigned.
417 *
418 * @retval 0		If an interrupt was assigned.
419 * @retval non-zero	If assigning an interrupt otherwise fails, a regular
420 *			unix error code will be returned.
421 */
422METHOD int assign_intr {
423	device_t dev;
424	device_t child;
425	int rid;
426} DEFAULT bhnd_bus_null_assign_intr;
427
428/**
429 * Return the backplane interrupt vector corresponding to @p child's given
430 * @p intr number.
431 *
432 * @param dev The bhnd bus parent of @p child.
433 * @param child The bhnd device for which the assigned interrupt vector should
434 * be queried.
435 * @param intr The interrupt number being queried. This is equivalent to the
436 * bus resource ID for the interrupt.
437 * @param[out] ivec On success, the assigned hardware interrupt vector be
438 * written to this pointer.
439 *
440 * On bcma(4) devices, this returns the OOB bus line assigned to the
441 * interrupt.
442 *
443 * On siba(4) devices, this returns the target OCP slave flag number assigned
444 * to the interrupt.
445 *
446 * @retval 0		success
447 * @retval ENXIO	If @p intr exceeds the number of interrupts available
448 *			to @p child.
449 */
450METHOD int get_core_ivec {
451	device_t dev;
452	device_t child;
453	u_int intr;
454	uint32_t *ivec;
455} DEFAULT bhnd_bus_null_get_core_ivec;
456
457/**
458 * Notify a bhnd bus that a child was added.
459 *
460 * This method must be called by concrete bhnd(4) driver impementations
461 * after @p child's bus state is fully initialized.
462 *
463 * @param dev The bhnd bus whose child is being added.
464 * @param child The child added to @p dev.
465 */
466METHOD void child_added {
467	device_t dev;
468	device_t child;
469} DEFAULT bhnd_bus_null_child_added;
470
471/**
472 * Read the current value of @p child's I/O control register.
473 *
474 * @param dev The bhnd bus parent of @p child.
475 * @param child The bhnd device for which the I/O control register should be
476 * read.
477 * @param[out] ioctl On success, the I/O control register value.
478 *
479 * @retval 0 success
480 * @retval EINVAL If @p child is not a direct child of @p dev.
481 * @retval ENODEV If agent/config space for @p child is unavailable.
482 * @retval non-zero If reading the IOCTL register otherwise fails, a regular
483 * unix error code will be returned.
484 */
485METHOD int read_ioctl {
486	device_t dev;
487	device_t child;
488	uint16_t *ioctl;
489} DEFAULT bhnd_bus_null_read_ioctl;
490
491/**
492 * Write @p value with @p mask to @p child's I/O control register.
493 *
494 * @param dev The bhnd bus parent of @p child.
495 * @param child The bhnd device for which the I/O control register should
496 * be updated.
497 * @param value The value to be written (see also BHND_IOCTL_*).
498 * @param mask Only the bits defined by @p mask will be updated from @p value.
499 *
500 * @retval 0 success
501 * @retval EINVAL If @p child is not a direct child of @p dev.
502 * @retval ENODEV If agent/config space for @p child is unavailable.
503 * @retval non-zero If writing the IOCTL register otherwise fails, a regular
504 * unix error code will be returned.
505 */
506METHOD int write_ioctl {
507	device_t dev;
508	device_t child;
509	uint16_t value;
510	uint16_t mask;
511} DEFAULT bhnd_bus_null_write_ioctl;
512
513/**
514 * Read the current value of @p child's I/O status register.
515 *
516 * @param dev The bhnd bus parent of @p child.
517 * @param child The bhnd device for which the I/O status register should be
518 * read.
519 * @param[out] iost On success, the I/O status register value.
520 *
521 * @retval 0 success
522 * @retval EINVAL If @p child is not a direct child of @p dev.
523 * @retval ENODEV If agent/config space for @p child is unavailable.
524 * @retval non-zero If reading the IOST register otherwise fails, a regular
525 * unix error code will be returned.
526 */
527METHOD int read_iost {
528	device_t dev;
529	device_t child;
530	uint16_t *iost;
531} DEFAULT bhnd_bus_null_read_iost;
532
533
534/**
535 * Return true if the given bhnd device's hardware is currently held
536 * in a RESET state or otherwise not clocked (BHND_IOCTL_CLK_EN).
537 *
538 * @param dev The bhnd bus parent of @p child.
539 * @param child The device to query.
540 *
541 * @retval true If @p child is held in RESET or not clocked (BHND_IOCTL_CLK_EN),
542 * or an error occured determining @p child's hardware state.
543 * @retval false If @p child is clocked and is not held in RESET.
544 */
545METHOD bool is_hw_suspended {
546	device_t dev;
547	device_t child;
548} DEFAULT bhnd_bus_null_is_hw_suspended;
549
550/**
551 * Place the bhnd(4) device's hardware into a reset state, and then bring the
552 * hardware out of reset with BHND_IOCTL_CLK_EN and @p ioctl flags set.
553 *
554 * Any clock or resource PMU requests previously made by @p child will be
555 * invalidated.
556 *
557 * @param dev The bhnd bus parent of @p child.
558 * @param child The device to be reset.
559 * @param ioctl Device-specific core ioctl flags to be supplied on reset
560 * (see BHND_IOCTL_*).
561 *
562 * @retval 0 success
563 * @retval non-zero error
564 */
565METHOD int reset_hw {
566	device_t dev;
567	device_t child;
568	uint16_t ioctl;
569} DEFAULT bhnd_bus_null_reset_hw;
570
571/**
572 * Suspend @p child's hardware in a low-power reset state.
573 *
574 * Any clock or resource PMU requests previously made by @p dev will be
575 * invalidated.
576 *
577 * The hardware may be brought out of reset via bhnd_reset_hw().
578 *
579 * @param dev The bhnd bus parent of @P child.
580 * @param dev The device to be suspended.
581 *
582 * @retval 0 success
583 * @retval non-zero error
584 */
585METHOD int suspend_hw {
586	device_t dev;
587	device_t child;
588} DEFAULT bhnd_bus_null_suspend_hw;
589
590/**
591 * If supported by the chipset, return the clock source for the given clock.
592 *
593 * This function is only supported on early PWRCTL-equipped chipsets
594 * that expose clock management via their host bridge interface. Currently,
595 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
596 *
597 * @param dev The parent of @p child.
598 * @param child The bhnd device requesting a clock source.
599 * @param clock The clock for which a clock source will be returned.
600 *
601 * @retval	bhnd_clksrc		The clock source for @p clock.
602 * @retval	BHND_CLKSRC_UNKNOWN	If @p clock is unsupported, or its
603 *					clock source is not known to the bus.
604 */
605METHOD bhnd_clksrc pwrctl_get_clksrc {
606	device_t dev;
607	device_t child;
608	bhnd_clock clock;
609} DEFAULT bhnd_bus_null_pwrctl_get_clksrc;
610
611/**
612 * If supported by the chipset, gate the clock source for @p clock
613 *
614 * This function is only supported on early PWRCTL-equipped chipsets
615 * that expose clock management via their host bridge interface. Currently,
616 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
617 *
618 * @param dev The parent of @p child.
619 * @param child The bhnd device requesting clock gating.
620 * @param clock The clock to be disabled.
621 *
622 * @retval 0 success
623 * @retval ENODEV If bus-level clock source management is not supported.
624 * @retval ENXIO If bus-level management of @p clock is not supported.
625 */
626METHOD int pwrctl_gate_clock {
627	device_t dev;
628	device_t child;
629	bhnd_clock clock;
630} DEFAULT bhnd_bus_null_pwrctl_gate_clock;
631
632/**
633 * If supported by the chipset, ungate the clock source for @p clock
634 *
635 * This function is only supported on early PWRCTL-equipped chipsets
636 * that expose clock management via their host bridge interface. Currently,
637 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
638 *
639 * @param dev The parent of @p child.
640 * @param child The bhnd device requesting clock gating.
641 * @param clock The clock to be enabled.
642 *
643 * @retval 0 success
644 * @retval ENODEV If bus-level clock source management is not supported.
645 * @retval ENXIO If bus-level management of @p clock is not supported.
646 */
647METHOD int pwrctl_ungate_clock {
648	device_t dev;
649	device_t child;
650	bhnd_clock clock;
651} DEFAULT bhnd_bus_null_pwrctl_ungate_clock;
652
653/**
654 * Allocate and enable per-core PMU request handling for @p child.
655 *
656 * The region containing the core's PMU register block (if any) must be
657 * allocated via bus_alloc_resource(9) (or bhnd_alloc_resource) before
658 * calling BHND_BUS_ALLOC_PMU(), and must not be released until after
659 * calling BHND_BUS_RELEASE_PMU().
660 *
661 * @param dev The parent of @p child.
662 * @param child The requesting bhnd device.
663 */
664METHOD int alloc_pmu {
665	device_t dev;
666	device_t child;
667} DEFAULT bhnd_bus_null_alloc_pmu;
668
669/**
670 * Release per-core PMU resources allocated for @p child. Any
671 * outstanding PMU requests are discarded.
672 *
673 * @param dev The parent of @p child.
674 * @param child The requesting bhnd device.
675 */
676METHOD int release_pmu {
677	device_t dev;
678	device_t child;
679} DEFAULT bhnd_bus_null_release_pmu;
680
681/**
682 * Request that @p clock (or faster) be routed to @p child.
683 *
684 * @note A driver must ask the bhnd bus to allocate PMU request state
685 * via BHND_BUS_ALLOC_PMU() before it can request clock resources.
686 *
687 * @note Any outstanding PMU clock requests will be discarded upon calling
688 * BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().
689 *
690 * @param dev The parent of @p child.
691 * @param child The bhnd device requesting @p clock.
692 * @param clock The requested clock source.
693 *
694 * @retval 0 success
695 * @retval ENODEV If an unsupported clock was requested.
696 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
697 */
698METHOD int request_clock {
699	device_t dev;
700	device_t child;
701	bhnd_clock clock;
702} DEFAULT bhnd_bus_null_request_clock;
703
704/**
705 * Request that @p clocks be powered on behalf of @p child.
706 *
707 * This will power on clock sources (e.g. XTAL, PLL, etc) required for
708 * @p clocks and wait until they are ready, discarding any previous
709 * requests by @p child.
710 *
711 * @note A driver must ask the bhnd bus to allocate PMU request state
712 * via BHND_BUS_ALLOC_PMU() before it can request clock resources.
713 *
714 * @note Any outstanding PMU clock requests will be discarded upon calling
715 * BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().
716 *
717 * @param dev The parent of @p child.
718 * @param child The bhnd device requesting @p clock.
719 * @param clock The requested clock source.
720 *
721 * @retval 0 success
722 * @retval ENODEV If an unsupported clock was requested.
723 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
724 */
725METHOD int enable_clocks {
726	device_t dev;
727	device_t child;
728	uint32_t clocks;
729} DEFAULT bhnd_bus_null_enable_clocks;
730
731/**
732 * Power up an external PMU-managed resource assigned to @p child.
733 *
734 * @note A driver must ask the bhnd bus to allocate PMU request state
735 * via BHND_BUS_ALLOC_PMU() before it can request PMU resources.
736 *
737 * @note Any outstanding PMU resource requests will be released upon calling
738 * BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().
739 *
740 * @param dev The parent of @p child.
741 * @param child The bhnd device requesting @p rsrc.
742 * @param rsrc The core-specific external resource identifier.
743 *
744 * @retval 0 success
745 * @retval ENODEV If the PMU does not support @p rsrc.
746 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
747 */
748METHOD int request_ext_rsrc {
749	device_t dev;
750	device_t child;
751	u_int rsrc;
752} DEFAULT bhnd_bus_null_request_ext_rsrc;
753
754/**
755 * Power down an external PMU-managed resource assigned to @p child.
756 *
757 * @note A driver must ask the bhnd bus to allocate PMU request state
758 * via BHND_BUS_ALLOC_PMU() before it can request PMU resources.
759 *
760 * @param dev The parent of @p child.
761 * @param child The bhnd device requesting @p rsrc.
762 * @param rsrc The core-specific external resource number.
763 *
764 * @retval 0 success
765 * @retval ENODEV If the PMU does not support @p rsrc.
766 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
767 */
768METHOD int release_ext_rsrc {
769	device_t dev;
770	device_t child;
771	u_int rsrc;
772} DEFAULT bhnd_bus_null_release_ext_rsrc;
773
774/**
775 * Read @p width bytes at @p offset from the bus-specific agent/config
776 * space of @p child.
777 *
778 * @param dev The parent of @p child.
779 * @param child The bhnd device for which @p offset should be read.
780 * @param offset The offset to be read.
781 * @param[out] value On success, the bytes read at @p offset.
782 * @param width The size of the access. Must be 1, 2 or 4 bytes.
783 *
784 * The exact behavior of this method is bus-specific. On a bcma(4) bus, this
785 * method provides access to the first agent port of @p child; on a siba(4) bus,
786 * this method provides access to the core's CFG0 register block.
787 *
788 * @note Device drivers should only use this API for functionality
789 * that is not available via another bhnd(4) function.
790 *
791 * @retval 0 success
792 * @retval EINVAL If @p child is not a direct child of @p dev.
793 * @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.
794 * @retval ENODEV If accessing agent/config space for @p child is unsupported.
795 * @retval EFAULT If reading @p width at @p offset exceeds the bounds of
796 * the mapped agent/config space  for @p child.
797 */
798METHOD int read_config {
799	device_t dev;
800	device_t child;
801	bus_size_t offset;
802	void *value;
803	u_int width;
804} DEFAULT bhnd_bus_null_read_config;
805
806/**
807 * Read @p width bytes at @p offset from the bus-specific agent/config
808 * space of @p child.
809 *
810 * @param dev The parent of @p child.
811 * @param child The bhnd device for which @p offset should be read.
812 * @param offset The offset to be written.
813 * @param value A pointer to the value to be written.
814 * @param width The size of @p value. Must be 1, 2 or 4 bytes.
815 *
816 * The exact behavior of this method is bus-specific. In the case of
817 * bcma(4), this method provides access to the first agent port of @p child.
818 *
819 * @note Device drivers should only use this API for functionality
820 * that is not available via another bhnd(4) function.
821 *
822 * @retval 0 success
823 * @retval EINVAL If @p child is not a direct child of @p dev.
824 * @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.
825 * @retval ENODEV If accessing agent/config space for @p child is unsupported.
826 * @retval EFAULT If reading @p width at @p offset exceeds the bounds of
827 * the mapped agent/config space  for @p child.
828 */
829METHOD int write_config {
830	device_t dev;
831	device_t child;
832	bus_size_t offset;
833	const void *value;
834	u_int width;
835} DEFAULT bhnd_bus_null_write_config;
836
837/**
838 * Allocate a bhnd resource.
839 *
840 * This method's semantics are functionally identical to the bus API of the same
841 * name; refer to BUS_ALLOC_RESOURCE for complete documentation.
842 */
843METHOD struct bhnd_resource * alloc_resource {
844	device_t dev;
845	device_t child;
846	int type;
847	int *rid;
848	rman_res_t start;
849	rman_res_t end;
850	rman_res_t count;
851	u_int flags;
852} DEFAULT bhnd_bus_generic_alloc_resource;
853
854/**
855 * Release a bhnd resource.
856 *
857 * This method's semantics are functionally identical to the bus API of the same
858 * name; refer to BUS_RELEASE_RESOURCE for complete documentation.
859 */
860METHOD int release_resource {
861	device_t dev;
862	device_t child;
863	int type;
864	int rid;
865	struct bhnd_resource *res;
866} DEFAULT bhnd_bus_generic_release_resource;
867
868/**
869 * Activate a bhnd resource.
870 *
871 * This method's semantics are functionally identical to the bus API of the same
872 * name; refer to BUS_ACTIVATE_RESOURCE for complete documentation.
873 */
874METHOD int activate_resource {
875	device_t dev;
876        device_t child;
877	int type;
878        int rid;
879        struct bhnd_resource *r;
880} DEFAULT bhnd_bus_generic_activate_resource;
881
882/**
883 * Deactivate a bhnd resource.
884 *
885 * This method's semantics are functionally identical to the bus API of the same
886 * name; refer to BUS_DEACTIVATE_RESOURCE for complete documentation.
887 */
888METHOD int deactivate_resource {
889        device_t dev;
890        device_t child;
891        int type;
892	int rid;
893        struct bhnd_resource *r;
894} DEFAULT bhnd_bus_generic_deactivate_resource;
895
896/**
897 * Return true if @p region_num is a valid region on @p port_num of
898 * @p type attached to @p child.
899 *
900 * @param dev The device whose child is being examined.
901 * @param child The child device.
902 * @param type The port type being queried.
903 * @param port_num The port number being queried.
904 * @param region_num The region number being queried.
905 */
906METHOD bool is_region_valid {
907	device_t dev;
908	device_t child;
909	bhnd_port_type type;
910	u_int port_num;
911	u_int region_num;
912};
913
914/**
915 * Return the number of ports of type @p type attached to @p child.
916 *
917 * @param dev The device whose child is being examined.
918 * @param child The child device.
919 * @param type The port type being queried.
920 */
921METHOD u_int get_port_count {
922	device_t dev;
923	device_t child;
924	bhnd_port_type type;
925};
926
927/**
928 * Return the number of memory regions mapped to @p child @p port of
929 * type @p type.
930 *
931 * @param dev The device whose child is being examined.
932 * @param child The child device.
933 * @param port The port number being queried.
934 * @param type The port type being queried.
935 */
936METHOD u_int get_region_count {
937	device_t dev;
938	device_t child;
939	bhnd_port_type type;
940	u_int port;
941};
942
943/**
944 * Return the SYS_RES_MEMORY resource-ID for a port/region pair attached to
945 * @p child.
946 *
947 * @param dev The bus device.
948 * @param child The bhnd child.
949 * @param port_type The port type.
950 * @param port_num The index of the child interconnect port.
951 * @param region_num The index of the port-mapped address region.
952 *
953 * @retval -1 No such port/region found.
954 */
955METHOD int get_port_rid {
956	device_t dev;
957	device_t child;
958	bhnd_port_type port_type;
959	u_int port_num;
960	u_int region_num;
961} DEFAULT bhnd_bus_null_get_port_rid;
962
963
964/**
965 * Decode a port / region pair on @p child defined by @p type and @p rid.
966 *
967 * @param dev The bus device.
968 * @param child The bhnd child.
969 * @param type The resource type.
970 * @param rid The resource ID.
971 * @param[out] port_type The port's type.
972 * @param[out] port The port identifier.
973 * @param[out] region The identifier of the memory region on @p port.
974 *
975 * @retval 0 success
976 * @retval non-zero No matching type/rid found.
977 */
978METHOD int decode_port_rid {
979	device_t dev;
980	device_t child;
981	int type;
982	int rid;
983	bhnd_port_type *port_type;
984	u_int *port;
985	u_int *region;
986} DEFAULT bhnd_bus_null_decode_port_rid;
987
988/**
989 * Get the address and size of @p region on @p port.
990 *
991 * @param dev The bus device.
992 * @param child The bhnd child.
993 * @param port_type The port type.
994 * @param port The port identifier.
995 * @param region The identifier of the memory region on @p port.
996 * @param[out] region_addr The region's base address.
997 * @param[out] region_size The region's size.
998 *
999 * @retval 0 success
1000 * @retval non-zero No matching port/region found.
1001 */
1002METHOD int get_region_addr {
1003	device_t dev;
1004	device_t child;
1005	bhnd_port_type port_type;
1006	u_int port;
1007	u_int region;
1008	bhnd_addr_t *region_addr;
1009	bhnd_size_t *region_size;
1010} DEFAULT bhnd_bus_null_get_region_addr;
1011
1012/**
1013 * Read an NVRAM variable.
1014 *
1015 * It is the responsibility of the bus to delegate this request to
1016 * the appropriate NVRAM child device, or to a parent bus implementation.
1017 *
1018 * @param		dev	The bus device.
1019 * @param		child	The requesting device.
1020 * @param		name	The NVRAM variable name.
1021 * @param[out]		buf	On success, the requested value will be written
1022 *				to this buffer. This argment may be NULL if
1023 *				the value is not desired.
1024 * @param[in,out]	size	The capacity of @p buf. On success, will be set
1025 *				to the actual size of the requested value.
1026 * @param		type	The data type to be written to @p buf.
1027 *
1028 * @retval 0		success
1029 * @retval ENOENT	The requested variable was not found.
1030 * @retval ENOMEM	If @p buf is non-NULL and a buffer of @p size is too
1031 *			small to hold the requested value.
1032 * @retval ENODEV	No valid NVRAM source could be found.
1033 * @retval EFTYPE	If the @p name's data type cannot be coerced to @p type.
1034 * @retval ERANGE	If value coercion would overflow @p type.
1035 * @retval non-zero	If reading @p name otherwise fails, a regular unix
1036 *			error code will be returned.
1037 */
1038METHOD int get_nvram_var {
1039	device_t	 dev;
1040	device_t	 child;
1041	const char	*name;
1042	void		*buf;
1043	size_t		*size;
1044	bhnd_nvram_type	 type;
1045} DEFAULT bhnd_bus_null_get_nvram_var;
1046
1047
1048/** An implementation of bus_read_1() compatible with bhnd_resource */
1049METHOD uint8_t read_1 {
1050	device_t dev;
1051	device_t child;
1052	struct bhnd_resource *r;
1053	bus_size_t offset;
1054}
1055
1056/** An implementation of bus_read_2() compatible with bhnd_resource */
1057METHOD uint16_t read_2 {
1058	device_t dev;
1059	device_t child;
1060	struct bhnd_resource *r;
1061	bus_size_t offset;
1062}
1063
1064/** An implementation of bus_read_4() compatible with bhnd_resource */
1065METHOD uint32_t read_4 {
1066	device_t dev;
1067	device_t child;
1068	struct bhnd_resource *r;
1069	bus_size_t offset;
1070}
1071
1072/** An implementation of bus_write_1() compatible with bhnd_resource */
1073METHOD void write_1 {
1074	device_t dev;
1075	device_t child;
1076	struct bhnd_resource *r;
1077	bus_size_t offset;
1078	uint8_t value;
1079}
1080
1081/** An implementation of bus_write_2() compatible with bhnd_resource */
1082METHOD void write_2 {
1083	device_t dev;
1084	device_t child;
1085	struct bhnd_resource *r;
1086	bus_size_t offset;
1087	uint16_t value;
1088}
1089
1090/** An implementation of bus_write_4() compatible with bhnd_resource */
1091METHOD void write_4 {
1092	device_t dev;
1093	device_t child;
1094	struct bhnd_resource *r;
1095	bus_size_t offset;
1096	uint32_t value;
1097}
1098
1099/** An implementation of bus_read_stream_1() compatible with bhnd_resource */
1100METHOD uint8_t read_stream_1 {
1101	device_t dev;
1102	device_t child;
1103	struct bhnd_resource *r;
1104	bus_size_t offset;
1105}
1106
1107/** An implementation of bus_read_stream_2() compatible with bhnd_resource */
1108METHOD uint16_t read_stream_2 {
1109	device_t dev;
1110	device_t child;
1111	struct bhnd_resource *r;
1112	bus_size_t offset;
1113}
1114
1115/** An implementation of bus_read_stream_4() compatible with bhnd_resource */
1116METHOD uint32_t read_stream_4 {
1117	device_t dev;
1118	device_t child;
1119	struct bhnd_resource *r;
1120	bus_size_t offset;
1121}
1122
1123/** An implementation of bus_write_stream_1() compatible with bhnd_resource */
1124METHOD void write_stream_1 {
1125	device_t dev;
1126	device_t child;
1127	struct bhnd_resource *r;
1128	bus_size_t offset;
1129	uint8_t value;
1130}
1131
1132/** An implementation of bus_write_stream_2() compatible with bhnd_resource */
1133METHOD void write_stream_2 {
1134	device_t dev;
1135	device_t child;
1136	struct bhnd_resource *r;
1137	bus_size_t offset;
1138	uint16_t value;
1139}
1140
1141/** An implementation of bus_write_stream_4() compatible with bhnd_resource */
1142METHOD void write_stream_4 {
1143	device_t dev;
1144	device_t child;
1145	struct bhnd_resource *r;
1146	bus_size_t offset;
1147	uint32_t value;
1148}
1149
1150/** An implementation of bus_read_multi_1() compatible with bhnd_resource */
1151METHOD void read_multi_1 {
1152	device_t dev;
1153	device_t child;
1154	struct bhnd_resource *r;
1155	bus_size_t offset;
1156	uint8_t *datap;
1157	bus_size_t count;
1158}
1159
1160/** An implementation of bus_read_multi_2() compatible with bhnd_resource */
1161METHOD void read_multi_2 {
1162	device_t dev;
1163	device_t child;
1164	struct bhnd_resource *r;
1165	bus_size_t offset;
1166	uint16_t *datap;
1167	bus_size_t count;
1168}
1169
1170/** An implementation of bus_read_multi_4() compatible with bhnd_resource */
1171METHOD void read_multi_4 {
1172	device_t dev;
1173	device_t child;
1174	struct bhnd_resource *r;
1175	bus_size_t offset;
1176	uint32_t *datap;
1177	bus_size_t count;
1178}
1179
1180/** An implementation of bus_write_multi_1() compatible with bhnd_resource */
1181METHOD void write_multi_1 {
1182	device_t dev;
1183	device_t child;
1184	struct bhnd_resource *r;
1185	bus_size_t offset;
1186	uint8_t *datap;
1187	bus_size_t count;
1188}
1189
1190/** An implementation of bus_write_multi_2() compatible with bhnd_resource */
1191METHOD void write_multi_2 {
1192	device_t dev;
1193	device_t child;
1194	struct bhnd_resource *r;
1195	bus_size_t offset;
1196	uint16_t *datap;
1197	bus_size_t count;
1198}
1199
1200/** An implementation of bus_write_multi_4() compatible with bhnd_resource */
1201METHOD void write_multi_4 {
1202	device_t dev;
1203	device_t child;
1204	struct bhnd_resource *r;
1205	bus_size_t offset;
1206	uint32_t *datap;
1207	bus_size_t count;
1208}
1209
1210/** An implementation of bus_read_multi_stream_1() compatible
1211 *  bhnd_resource */
1212METHOD void read_multi_stream_1 {
1213	device_t dev;
1214	device_t child;
1215	struct bhnd_resource *r;
1216	bus_size_t offset;
1217	uint8_t *datap;
1218	bus_size_t count;
1219}
1220
1221/** An implementation of bus_read_multi_stream_2() compatible
1222 *  bhnd_resource */
1223METHOD void read_multi_stream_2 {
1224	device_t dev;
1225	device_t child;
1226	struct bhnd_resource *r;
1227	bus_size_t offset;
1228	uint16_t *datap;
1229	bus_size_t count;
1230}
1231
1232/** An implementation of bus_read_multi_stream_4() compatible
1233 *  bhnd_resource */
1234METHOD void read_multi_stream_4 {
1235	device_t dev;
1236	device_t child;
1237	struct bhnd_resource *r;
1238	bus_size_t offset;
1239	uint32_t *datap;
1240	bus_size_t count;
1241}
1242
1243/** An implementation of bus_write_multi_stream_1() compatible
1244 *  bhnd_resource */
1245METHOD void write_multi_stream_1 {
1246	device_t dev;
1247	device_t child;
1248	struct bhnd_resource *r;
1249	bus_size_t offset;
1250	uint8_t *datap;
1251	bus_size_t count;
1252}
1253
1254/** An implementation of bus_write_multi_stream_2() compatible with
1255 *  bhnd_resource */
1256METHOD void write_multi_stream_2 {
1257	device_t dev;
1258	device_t child;
1259	struct bhnd_resource *r;
1260	bus_size_t offset;
1261	uint16_t *datap;
1262	bus_size_t count;
1263}
1264
1265/** An implementation of bus_write_multi_stream_4() compatible with
1266 *  bhnd_resource */
1267METHOD void write_multi_stream_4 {
1268	device_t dev;
1269	device_t child;
1270	struct bhnd_resource *r;
1271	bus_size_t offset;
1272	uint32_t *datap;
1273	bus_size_t count;
1274}
1275
1276/** An implementation of bus_set_multi_1() compatible with bhnd_resource */
1277METHOD void set_multi_1 {
1278	device_t dev;
1279	device_t child;
1280	struct bhnd_resource *r;
1281	bus_size_t offset;
1282	uint8_t value;
1283	bus_size_t count;
1284}
1285
1286/** An implementation of bus_set_multi_2() compatible with bhnd_resource */
1287METHOD void set_multi_2 {
1288	device_t dev;
1289	device_t child;
1290	struct bhnd_resource *r;
1291	bus_size_t offset;
1292	uint16_t value;
1293	bus_size_t count;
1294}
1295
1296/** An implementation of bus_set_multi_4() compatible with bhnd_resource */
1297METHOD void set_multi_4 {
1298	device_t dev;
1299	device_t child;
1300	struct bhnd_resource *r;
1301	bus_size_t offset;
1302	uint32_t value;
1303	bus_size_t count;
1304}
1305
1306/** An implementation of bus_set_region_1() compatible with bhnd_resource */
1307METHOD void set_region_1 {
1308	device_t dev;
1309	device_t child;
1310	struct bhnd_resource *r;
1311	bus_size_t offset;
1312	uint8_t value;
1313	bus_size_t count;
1314}
1315
1316/** An implementation of bus_set_region_2() compatible with bhnd_resource */
1317METHOD void set_region_2 {
1318	device_t dev;
1319	device_t child;
1320	struct bhnd_resource *r;
1321	bus_size_t offset;
1322	uint16_t value;
1323	bus_size_t count;
1324}
1325
1326/** An implementation of bus_set_region_4() compatible with bhnd_resource */
1327METHOD void set_region_4 {
1328	device_t dev;
1329	device_t child;
1330	struct bhnd_resource *r;
1331	bus_size_t offset;
1332	uint32_t value;
1333	bus_size_t count;
1334}
1335
1336/** An implementation of bus_read_region_1() compatible with bhnd_resource */
1337METHOD void read_region_1 {
1338	device_t dev;
1339	device_t child;
1340	struct bhnd_resource *r;
1341	bus_size_t offset;
1342	uint8_t *datap;
1343	bus_size_t count;
1344}
1345
1346/** An implementation of bus_read_region_2() compatible with bhnd_resource */
1347METHOD void read_region_2 {
1348	device_t dev;
1349	device_t child;
1350	struct bhnd_resource *r;
1351	bus_size_t offset;
1352	uint16_t *datap;
1353	bus_size_t count;
1354}
1355
1356/** An implementation of bus_read_region_4() compatible with bhnd_resource */
1357METHOD void read_region_4 {
1358	device_t dev;
1359	device_t child;
1360	struct bhnd_resource *r;
1361	bus_size_t offset;
1362	uint32_t *datap;
1363	bus_size_t count;
1364}
1365
1366/** An implementation of bus_read_region_stream_1() compatible with
1367  * bhnd_resource */
1368METHOD void read_region_stream_1 {
1369	device_t dev;
1370	device_t child;
1371	struct bhnd_resource *r;
1372	bus_size_t offset;
1373	uint8_t *datap;
1374	bus_size_t count;
1375}
1376
1377/** An implementation of bus_read_region_stream_2() compatible with
1378  * bhnd_resource */
1379METHOD void read_region_stream_2 {
1380	device_t dev;
1381	device_t child;
1382	struct bhnd_resource *r;
1383	bus_size_t offset;
1384	uint16_t *datap;
1385	bus_size_t count;
1386}
1387
1388/** An implementation of bus_read_region_stream_4() compatible with
1389  * bhnd_resource */
1390METHOD void read_region_stream_4 {
1391	device_t dev;
1392	device_t child;
1393	struct bhnd_resource *r;
1394	bus_size_t offset;
1395	uint32_t *datap;
1396	bus_size_t count;
1397}
1398
1399/** An implementation of bus_write_region_1() compatible with bhnd_resource */
1400METHOD void write_region_1 {
1401	device_t dev;
1402	device_t child;
1403	struct bhnd_resource *r;
1404	bus_size_t offset;
1405	uint8_t *datap;
1406	bus_size_t count;
1407}
1408
1409/** An implementation of bus_write_region_2() compatible with bhnd_resource */
1410METHOD void write_region_2 {
1411	device_t dev;
1412	device_t child;
1413	struct bhnd_resource *r;
1414	bus_size_t offset;
1415	uint16_t *datap;
1416	bus_size_t count;
1417}
1418
1419/** An implementation of bus_write_region_4() compatible with bhnd_resource */
1420METHOD void write_region_4 {
1421	device_t dev;
1422	device_t child;
1423	struct bhnd_resource *r;
1424	bus_size_t offset;
1425	uint32_t *datap;
1426	bus_size_t count;
1427}
1428
1429/** An implementation of bus_write_region_stream_1() compatible with
1430  * bhnd_resource */
1431METHOD void write_region_stream_1 {
1432	device_t dev;
1433	device_t child;
1434	struct bhnd_resource *r;
1435	bus_size_t offset;
1436	uint8_t *datap;
1437	bus_size_t count;
1438}
1439
1440/** An implementation of bus_write_region_stream_2() compatible with
1441  * bhnd_resource */
1442METHOD void write_region_stream_2 {
1443	device_t dev;
1444	device_t child;
1445	struct bhnd_resource *r;
1446	bus_size_t offset;
1447	uint16_t *datap;
1448	bus_size_t count;
1449}
1450
1451/** An implementation of bus_write_region_stream_4() compatible with
1452  * bhnd_resource */
1453METHOD void write_region_stream_4 {
1454	device_t dev;
1455	device_t child;
1456	struct bhnd_resource *r;
1457	bus_size_t offset;
1458	uint32_t *datap;
1459	bus_size_t count;
1460}
1461
1462/** An implementation of bus_barrier() compatible with bhnd_resource */
1463METHOD void barrier {
1464	device_t dev;
1465	device_t child;
1466	struct bhnd_resource *r;
1467	bus_size_t offset;
1468	bus_size_t length;
1469	int flags;
1470}
1471