Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bhnd/bcma/bcma.c
39537 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2015-2016 Landon Fuller <[email protected]>
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/param.h>
37
#include <sys/bus.h>
38
#include <sys/kernel.h>
39
#include <sys/malloc.h>
40
#include <sys/module.h>
41
#include <sys/systm.h>
42
43
#include <machine/bus.h>
44
45
#include <dev/bhnd/cores/pmu/bhnd_pmu.h>
46
47
#include "bcma_dmp.h"
48
49
#include "bcma_eromreg.h"
50
#include "bcma_eromvar.h"
51
52
#include "bcmavar.h"
53
54
/* RID used when allocating EROM table */
55
#define BCMA_EROM_RID 0
56
57
static bhnd_erom_class_t *
58
bcma_get_erom_class(driver_t *driver)
59
{
60
return (&bcma_erom_parser);
61
}
62
63
int
64
bcma_probe(device_t dev)
65
{
66
device_set_desc(dev, "BCMA BHND bus");
67
return (BUS_PROBE_DEFAULT);
68
}
69
70
/**
71
* Default bcma(4) bus driver implementation of DEVICE_ATTACH().
72
*
73
* This implementation initializes internal bcma(4) state and performs
74
* bus enumeration, and must be called by subclassing drivers in
75
* DEVICE_ATTACH() before any other bus methods.
76
*/
77
int
78
bcma_attach(device_t dev)
79
{
80
int error;
81
82
/* Enumerate children */
83
if ((error = bcma_add_children(dev))) {
84
return (error);
85
}
86
87
return (0);
88
}
89
90
int
91
bcma_detach(device_t dev)
92
{
93
return (bhnd_generic_detach(dev));
94
}
95
96
static device_t
97
bcma_add_child(device_t dev, u_int order, const char *name, int unit)
98
{
99
struct bcma_devinfo *dinfo;
100
device_t child;
101
102
child = device_add_child_ordered(dev, order, name, unit);
103
if (child == NULL)
104
return (NULL);
105
106
if ((dinfo = bcma_alloc_dinfo(dev)) == NULL) {
107
device_delete_child(dev, child);
108
return (NULL);
109
}
110
111
device_set_ivars(child, dinfo);
112
113
return (child);
114
}
115
116
static void
117
bcma_child_deleted(device_t dev, device_t child)
118
{
119
struct bcma_devinfo *dinfo;
120
121
/* Call required bhnd(4) implementation */
122
bhnd_generic_child_deleted(dev, child);
123
124
/* Free bcma device info */
125
if ((dinfo = device_get_ivars(child)) != NULL)
126
bcma_free_dinfo(dev, child, dinfo);
127
128
device_set_ivars(child, NULL);
129
}
130
131
static int
132
bcma_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
133
{
134
const struct bcma_devinfo *dinfo;
135
const struct bhnd_core_info *ci;
136
137
dinfo = device_get_ivars(child);
138
ci = &dinfo->corecfg->core_info;
139
140
switch (index) {
141
case BHND_IVAR_VENDOR:
142
*result = ci->vendor;
143
return (0);
144
case BHND_IVAR_DEVICE:
145
*result = ci->device;
146
return (0);
147
case BHND_IVAR_HWREV:
148
*result = ci->hwrev;
149
return (0);
150
case BHND_IVAR_DEVICE_CLASS:
151
*result = bhnd_core_class(ci);
152
return (0);
153
case BHND_IVAR_VENDOR_NAME:
154
*result = (uintptr_t) bhnd_vendor_name(ci->vendor);
155
return (0);
156
case BHND_IVAR_DEVICE_NAME:
157
*result = (uintptr_t) bhnd_core_name(ci);
158
return (0);
159
case BHND_IVAR_CORE_INDEX:
160
*result = ci->core_idx;
161
return (0);
162
case BHND_IVAR_CORE_UNIT:
163
*result = ci->unit;
164
return (0);
165
case BHND_IVAR_PMU_INFO:
166
*result = (uintptr_t) dinfo->pmu_info;
167
return (0);
168
default:
169
return (ENOENT);
170
}
171
}
172
173
static int
174
bcma_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
175
{
176
struct bcma_devinfo *dinfo;
177
178
dinfo = device_get_ivars(child);
179
180
switch (index) {
181
case BHND_IVAR_VENDOR:
182
case BHND_IVAR_DEVICE:
183
case BHND_IVAR_HWREV:
184
case BHND_IVAR_DEVICE_CLASS:
185
case BHND_IVAR_VENDOR_NAME:
186
case BHND_IVAR_DEVICE_NAME:
187
case BHND_IVAR_CORE_INDEX:
188
case BHND_IVAR_CORE_UNIT:
189
return (EINVAL);
190
case BHND_IVAR_PMU_INFO:
191
dinfo->pmu_info = (void *)value;
192
return (0);
193
default:
194
return (ENOENT);
195
}
196
}
197
198
static struct resource_list *
199
bcma_get_resource_list(device_t dev, device_t child)
200
{
201
struct bcma_devinfo *dinfo = device_get_ivars(child);
202
return (&dinfo->resources);
203
}
204
205
static int
206
bcma_read_iost(device_t dev, device_t child, uint16_t *iost)
207
{
208
uint32_t value;
209
int error;
210
211
if ((error = bhnd_read_config(child, BCMA_DMP_IOSTATUS, &value, 4)))
212
return (error);
213
214
/* Return only the bottom 16 bits */
215
*iost = (value & BCMA_DMP_IOST_MASK);
216
return (0);
217
}
218
219
static int
220
bcma_read_ioctl(device_t dev, device_t child, uint16_t *ioctl)
221
{
222
uint32_t value;
223
int error;
224
225
if ((error = bhnd_read_config(child, BCMA_DMP_IOCTRL, &value, 4)))
226
return (error);
227
228
/* Return only the bottom 16 bits */
229
*ioctl = (value & BCMA_DMP_IOCTRL_MASK);
230
return (0);
231
}
232
233
static int
234
bcma_write_ioctl(device_t dev, device_t child, uint16_t value, uint16_t mask)
235
{
236
struct bcma_devinfo *dinfo;
237
struct bhnd_resource *r;
238
uint32_t ioctl;
239
240
if (device_get_parent(child) != dev)
241
return (EINVAL);
242
243
dinfo = device_get_ivars(child);
244
if ((r = dinfo->res_agent) == NULL)
245
return (ENODEV);
246
247
/* Write new value */
248
ioctl = bhnd_bus_read_4(r, BCMA_DMP_IOCTRL);
249
ioctl &= ~(BCMA_DMP_IOCTRL_MASK & mask);
250
ioctl |= (value & mask);
251
252
bhnd_bus_write_4(r, BCMA_DMP_IOCTRL, ioctl);
253
254
/* Perform read-back and wait for completion */
255
bhnd_bus_read_4(r, BCMA_DMP_IOCTRL);
256
DELAY(10);
257
258
return (0);
259
}
260
261
static bool
262
bcma_is_hw_suspended(device_t dev, device_t child)
263
{
264
uint32_t rst;
265
uint16_t ioctl;
266
int error;
267
268
/* Is core held in RESET? */
269
error = bhnd_read_config(child, BCMA_DMP_RESETCTRL, &rst, 4);
270
if (error) {
271
device_printf(child, "error reading HW reset state: %d\n",
272
error);
273
return (true);
274
}
275
276
if (rst & BCMA_DMP_RC_RESET)
277
return (true);
278
279
/* Is core clocked? */
280
error = bhnd_read_ioctl(child, &ioctl);
281
if (error) {
282
device_printf(child, "error reading HW ioctl register: %d\n",
283
error);
284
return (true);
285
}
286
287
if (!(ioctl & BHND_IOCTL_CLK_EN))
288
return (true);
289
290
return (false);
291
}
292
293
static int
294
bcma_reset_hw(device_t dev, device_t child, uint16_t ioctl,
295
uint16_t reset_ioctl)
296
{
297
struct bcma_devinfo *dinfo;
298
struct bhnd_resource *r;
299
uint16_t clkflags;
300
int error;
301
302
if (device_get_parent(child) != dev)
303
return (EINVAL);
304
305
dinfo = device_get_ivars(child);
306
307
/* We require exclusive control over BHND_IOCTL_CLK_(EN|FORCE) */
308
clkflags = BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE;
309
if (ioctl & clkflags)
310
return (EINVAL);
311
312
/* Can't suspend the core without access to the agent registers */
313
if ((r = dinfo->res_agent) == NULL)
314
return (ENODEV);
315
316
/* Place core into known RESET state */
317
if ((error = bhnd_suspend_hw(child, reset_ioctl)))
318
return (error);
319
320
/*
321
* Leaving the core in reset:
322
* - Set the caller's IOCTL flags
323
* - Enable clocks
324
* - Force clock distribution to ensure propagation throughout the
325
* core.
326
*/
327
if ((error = bhnd_write_ioctl(child, ioctl | clkflags, UINT16_MAX)))
328
return (error);
329
330
/* Bring the core out of reset */
331
if ((error = bcma_dmp_write_reset(child, dinfo, 0x0)))
332
return (error);
333
334
/* Disable forced clock gating (leaving clock enabled) */
335
error = bhnd_write_ioctl(child, 0x0, BHND_IOCTL_CLK_FORCE);
336
if (error)
337
return (error);
338
339
return (0);
340
}
341
342
static int
343
bcma_suspend_hw(device_t dev, device_t child, uint16_t ioctl)
344
{
345
struct bcma_devinfo *dinfo;
346
struct bhnd_resource *r;
347
uint16_t clkflags;
348
int error;
349
350
if (device_get_parent(child) != dev)
351
return (EINVAL);
352
353
dinfo = device_get_ivars(child);
354
355
/* We require exclusive control over BHND_IOCTL_CLK_(EN|FORCE) */
356
clkflags = BHND_IOCTL_CLK_EN | BHND_IOCTL_CLK_FORCE;
357
if (ioctl & clkflags)
358
return (EINVAL);
359
360
/* Can't suspend the core without access to the agent registers */
361
if ((r = dinfo->res_agent) == NULL)
362
return (ENODEV);
363
364
/* Wait for any pending reset operations to clear */
365
if ((error = bcma_dmp_wait_reset(child, dinfo)))
366
return (error);
367
368
/* Put core into reset (if not already in reset) */
369
if ((error = bcma_dmp_write_reset(child, dinfo, BCMA_DMP_RC_RESET)))
370
return (error);
371
372
/* Write core flags (and clear CLK_EN/CLK_FORCE) */
373
if ((error = bhnd_write_ioctl(child, ioctl, ~clkflags)))
374
return (error);
375
376
return (0);
377
}
378
379
static int
380
bcma_read_config(device_t dev, device_t child, bus_size_t offset, void *value,
381
u_int width)
382
{
383
struct bcma_devinfo *dinfo;
384
struct bhnd_resource *r;
385
386
/* Must be a directly attached child core */
387
if (device_get_parent(child) != dev)
388
return (EINVAL);
389
390
/* Fetch the agent registers */
391
dinfo = device_get_ivars(child);
392
if ((r = dinfo->res_agent) == NULL)
393
return (ENODEV);
394
395
/* Verify bounds */
396
if (offset > rman_get_size(r->res))
397
return (EFAULT);
398
399
if (rman_get_size(r->res) - offset < width)
400
return (EFAULT);
401
402
switch (width) {
403
case 1:
404
*((uint8_t *)value) = bhnd_bus_read_1(r, offset);
405
return (0);
406
case 2:
407
*((uint16_t *)value) = bhnd_bus_read_2(r, offset);
408
return (0);
409
case 4:
410
*((uint32_t *)value) = bhnd_bus_read_4(r, offset);
411
return (0);
412
default:
413
return (EINVAL);
414
}
415
}
416
417
static int
418
bcma_write_config(device_t dev, device_t child, bus_size_t offset,
419
const void *value, u_int width)
420
{
421
struct bcma_devinfo *dinfo;
422
struct bhnd_resource *r;
423
424
/* Must be a directly attached child core */
425
if (device_get_parent(child) != dev)
426
return (EINVAL);
427
428
/* Fetch the agent registers */
429
dinfo = device_get_ivars(child);
430
if ((r = dinfo->res_agent) == NULL)
431
return (ENODEV);
432
433
/* Verify bounds */
434
if (offset > rman_get_size(r->res))
435
return (EFAULT);
436
437
if (rman_get_size(r->res) - offset < width)
438
return (EFAULT);
439
440
switch (width) {
441
case 1:
442
bhnd_bus_write_1(r, offset, *(const uint8_t *)value);
443
return (0);
444
case 2:
445
bhnd_bus_write_2(r, offset, *(const uint16_t *)value);
446
return (0);
447
case 4:
448
bhnd_bus_write_4(r, offset, *(const uint32_t *)value);
449
return (0);
450
default:
451
return (EINVAL);
452
}
453
}
454
455
static u_int
456
bcma_get_port_count(device_t dev, device_t child, bhnd_port_type type)
457
{
458
struct bcma_devinfo *dinfo;
459
460
/* delegate non-bus-attached devices to our parent */
461
if (device_get_parent(child) != dev)
462
return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child,
463
type));
464
465
dinfo = device_get_ivars(child);
466
switch (type) {
467
case BHND_PORT_DEVICE:
468
return (dinfo->corecfg->num_dev_ports);
469
case BHND_PORT_BRIDGE:
470
return (dinfo->corecfg->num_bridge_ports);
471
case BHND_PORT_AGENT:
472
return (dinfo->corecfg->num_wrapper_ports);
473
default:
474
device_printf(dev, "%s: unknown type (%d)\n",
475
__func__,
476
type);
477
return (0);
478
}
479
}
480
481
static u_int
482
bcma_get_region_count(device_t dev, device_t child, bhnd_port_type type,
483
u_int port_num)
484
{
485
struct bcma_devinfo *dinfo;
486
struct bcma_sport_list *ports;
487
struct bcma_sport *port;
488
489
/* delegate non-bus-attached devices to our parent */
490
if (device_get_parent(child) != dev)
491
return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child,
492
type, port_num));
493
494
dinfo = device_get_ivars(child);
495
ports = bcma_corecfg_get_port_list(dinfo->corecfg, type);
496
497
STAILQ_FOREACH(port, ports, sp_link) {
498
if (port->sp_num == port_num)
499
return (port->sp_num_maps);
500
}
501
502
/* not found */
503
return (0);
504
}
505
506
static int
507
bcma_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type,
508
u_int port_num, u_int region_num)
509
{
510
struct bcma_devinfo *dinfo;
511
struct bcma_map *map;
512
struct bcma_sport_list *ports;
513
struct bcma_sport *port;
514
515
dinfo = device_get_ivars(child);
516
ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type);
517
518
STAILQ_FOREACH(port, ports, sp_link) {
519
if (port->sp_num != port_num)
520
continue;
521
522
STAILQ_FOREACH(map, &port->sp_maps, m_link)
523
if (map->m_region_num == region_num)
524
return map->m_rid;
525
}
526
527
return -1;
528
}
529
530
static int
531
bcma_decode_port_rid(device_t dev, device_t child, int type, int rid,
532
bhnd_port_type *port_type, u_int *port_num, u_int *region_num)
533
{
534
struct bcma_devinfo *dinfo;
535
struct bcma_map *map;
536
struct bcma_sport_list *ports;
537
struct bcma_sport *port;
538
539
dinfo = device_get_ivars(child);
540
541
/* Ports are always memory mapped */
542
if (type != SYS_RES_MEMORY)
543
return (EINVAL);
544
545
/* Starting with the most likely device list, search all three port
546
* lists */
547
bhnd_port_type types[] = {
548
BHND_PORT_DEVICE,
549
BHND_PORT_AGENT,
550
BHND_PORT_BRIDGE
551
};
552
553
for (int i = 0; i < nitems(types); i++) {
554
ports = bcma_corecfg_get_port_list(dinfo->corecfg, types[i]);
555
556
STAILQ_FOREACH(port, ports, sp_link) {
557
STAILQ_FOREACH(map, &port->sp_maps, m_link) {
558
if (map->m_rid != rid)
559
continue;
560
561
*port_type = port->sp_type;
562
*port_num = port->sp_num;
563
*region_num = map->m_region_num;
564
return (0);
565
}
566
}
567
}
568
569
return (ENOENT);
570
}
571
572
static int
573
bcma_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type,
574
u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size)
575
{
576
struct bcma_devinfo *dinfo;
577
struct bcma_map *map;
578
struct bcma_sport_list *ports;
579
struct bcma_sport *port;
580
581
dinfo = device_get_ivars(child);
582
ports = bcma_corecfg_get_port_list(dinfo->corecfg, port_type);
583
584
/* Search the port list */
585
STAILQ_FOREACH(port, ports, sp_link) {
586
if (port->sp_num != port_num)
587
continue;
588
589
STAILQ_FOREACH(map, &port->sp_maps, m_link) {
590
if (map->m_region_num != region_num)
591
continue;
592
593
/* Found! */
594
*addr = map->m_base;
595
*size = map->m_size;
596
return (0);
597
}
598
}
599
600
return (ENOENT);
601
}
602
603
/**
604
* Default bcma(4) bus driver implementation of BHND_BUS_GET_INTR_COUNT().
605
*/
606
u_int
607
bcma_get_intr_count(device_t dev, device_t child)
608
{
609
struct bcma_devinfo *dinfo;
610
611
/* delegate non-bus-attached devices to our parent */
612
if (device_get_parent(child) != dev)
613
return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), child));
614
615
dinfo = device_get_ivars(child);
616
return (dinfo->num_intrs);
617
}
618
619
/**
620
* Default bcma(4) bus driver implementation of BHND_BUS_GET_INTR_IVEC().
621
*/
622
int
623
bcma_get_intr_ivec(device_t dev, device_t child, u_int intr, u_int *ivec)
624
{
625
struct bcma_devinfo *dinfo;
626
struct bcma_intr *desc;
627
628
/* delegate non-bus-attached devices to our parent */
629
if (device_get_parent(child) != dev) {
630
return (BHND_BUS_GET_INTR_IVEC(device_get_parent(dev), child,
631
intr, ivec));
632
}
633
634
dinfo = device_get_ivars(child);
635
636
STAILQ_FOREACH(desc, &dinfo->intrs, i_link) {
637
if (desc->i_sel == intr) {
638
*ivec = desc->i_busline;
639
return (0);
640
}
641
}
642
643
/* Not found */
644
return (ENXIO);
645
}
646
647
/**
648
* Scan the device enumeration ROM table, adding all valid discovered cores to
649
* the bus.
650
*
651
* @param bus The bcma bus.
652
*/
653
int
654
bcma_add_children(device_t bus)
655
{
656
bhnd_erom_t *erom;
657
struct bcma_erom *bcma_erom;
658
struct bhnd_erom_io *eio;
659
const struct bhnd_chipid *cid;
660
struct bcma_corecfg *corecfg;
661
struct bcma_devinfo *dinfo;
662
device_t child;
663
int error;
664
665
cid = BHND_BUS_GET_CHIPID(bus, bus);
666
corecfg = NULL;
667
668
/* Allocate our EROM parser */
669
eio = bhnd_erom_iores_new(bus, BCMA_EROM_RID);
670
erom = bhnd_erom_alloc(&bcma_erom_parser, cid, eio);
671
if (erom == NULL) {
672
bhnd_erom_io_fini(eio);
673
return (ENODEV);
674
}
675
676
/* Add all cores. */
677
bcma_erom = (struct bcma_erom *)erom;
678
while ((error = bcma_erom_next_corecfg(bcma_erom, &corecfg)) == 0) {
679
/* Add the child device */
680
child = BUS_ADD_CHILD(bus, 0, NULL, DEVICE_UNIT_ANY);
681
if (child == NULL) {
682
error = ENXIO;
683
goto cleanup;
684
}
685
686
/* Initialize device ivars */
687
dinfo = device_get_ivars(child);
688
if ((error = bcma_init_dinfo(bus, child, dinfo, corecfg)))
689
goto cleanup;
690
691
/* The dinfo instance now owns the corecfg value */
692
corecfg = NULL;
693
694
/* If pins are floating or the hardware is otherwise
695
* unpopulated, the device shouldn't be used. */
696
if (bhnd_is_hw_disabled(child))
697
device_disable(child);
698
699
/* Issue bus callback for fully initialized child. */
700
BHND_BUS_CHILD_ADDED(bus, child);
701
}
702
703
/* EOF while parsing cores is expected */
704
if (error == ENOENT)
705
error = 0;
706
707
cleanup:
708
bhnd_erom_free(erom);
709
710
if (corecfg != NULL)
711
bcma_free_corecfg(corecfg);
712
713
if (error)
714
device_delete_children(bus);
715
716
return (error);
717
}
718
719
static device_method_t bcma_methods[] = {
720
/* Device interface */
721
DEVMETHOD(device_probe, bcma_probe),
722
DEVMETHOD(device_attach, bcma_attach),
723
DEVMETHOD(device_detach, bcma_detach),
724
725
/* Bus interface */
726
DEVMETHOD(bus_add_child, bcma_add_child),
727
DEVMETHOD(bus_child_deleted, bcma_child_deleted),
728
DEVMETHOD(bus_read_ivar, bcma_read_ivar),
729
DEVMETHOD(bus_write_ivar, bcma_write_ivar),
730
DEVMETHOD(bus_get_resource_list, bcma_get_resource_list),
731
732
/* BHND interface */
733
DEVMETHOD(bhnd_bus_get_erom_class, bcma_get_erom_class),
734
DEVMETHOD(bhnd_bus_read_ioctl, bcma_read_ioctl),
735
DEVMETHOD(bhnd_bus_write_ioctl, bcma_write_ioctl),
736
DEVMETHOD(bhnd_bus_read_iost, bcma_read_iost),
737
DEVMETHOD(bhnd_bus_is_hw_suspended, bcma_is_hw_suspended),
738
DEVMETHOD(bhnd_bus_reset_hw, bcma_reset_hw),
739
DEVMETHOD(bhnd_bus_suspend_hw, bcma_suspend_hw),
740
DEVMETHOD(bhnd_bus_read_config, bcma_read_config),
741
DEVMETHOD(bhnd_bus_write_config, bcma_write_config),
742
DEVMETHOD(bhnd_bus_get_port_count, bcma_get_port_count),
743
DEVMETHOD(bhnd_bus_get_region_count, bcma_get_region_count),
744
DEVMETHOD(bhnd_bus_get_port_rid, bcma_get_port_rid),
745
DEVMETHOD(bhnd_bus_decode_port_rid, bcma_decode_port_rid),
746
DEVMETHOD(bhnd_bus_get_region_addr, bcma_get_region_addr),
747
DEVMETHOD(bhnd_bus_get_intr_count, bcma_get_intr_count),
748
DEVMETHOD(bhnd_bus_get_intr_ivec, bcma_get_intr_ivec),
749
750
DEVMETHOD_END
751
};
752
753
DEFINE_CLASS_1(bhnd, bcma_driver, bcma_methods, sizeof(struct bcma_softc), bhnd_driver);
754
MODULE_VERSION(bcma, 1);
755
MODULE_DEPEND(bcma, bhnd, 1, 1, 1);
756
757