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/cdefs.h>
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/lock.h>
40 #include <sys/bus.h>
41 #include <sys/malloc.h>
42 #include <sys/module.h>
43 #include <sys/mutex.h>
44 #include <sys/sysctl.h>
45 #include <sys/systm.h>
46
47 #include <machine/bus.h>
48 #include <machine/resource.h>
49
50 #include <dev/bhnd/bhndreg.h>
51 #include <dev/bhnd/bhndvar.h>
52 #include <dev/bhnd/cores/chipc/chipc.h>
53
54 #include "bhnd_nvram_map.h"
55
56 #include "bhnd_pmureg.h"
57 #include "bhnd_pmuvar.h"
58
59 #include "bhnd_pmu_private.h"
60
61 /*
62 * Broadcom PMU driver.
63 *
64 * On modern BHND chipsets, the PMU, GCI, and SRENG (Save/Restore Engine?)
65 * register blocks are found within a dedicated PMU core (attached via
66 * the AHB 'always on bus').
67 *
68 * On earlier chipsets, these register blocks are found at the same
69 * offsets within the ChipCommon core.
70 */
71
72 static int bhnd_pmu_sysctl_bus_freq(SYSCTL_HANDLER_ARGS);
73 static int bhnd_pmu_sysctl_cpu_freq(SYSCTL_HANDLER_ARGS);
74 static int bhnd_pmu_sysctl_mem_freq(SYSCTL_HANDLER_ARGS);
75
76 static uint32_t bhnd_pmu_read_4(bus_size_t reg, void *ctx);
77 static void bhnd_pmu_write_4(bus_size_t reg, uint32_t val, void *ctx);
78 static uint32_t bhnd_pmu_read_chipst(void *ctx);
79
80 static const struct bhnd_pmu_io bhnd_pmu_res_io = {
81 .rd4 = bhnd_pmu_read_4,
82 .wr4 = bhnd_pmu_write_4,
83 .rd_chipst = bhnd_pmu_read_chipst
84 };
85
86 /**
87 * Default bhnd_pmu driver implementation of DEVICE_PROBE().
88 */
89 int
bhnd_pmu_probe(device_t dev)90 bhnd_pmu_probe(device_t dev)
91 {
92 return (BUS_PROBE_DEFAULT);
93 }
94
95 /**
96 * Default bhnd_pmu driver implementation of DEVICE_ATTACH().
97 *
98 * @param dev PMU device.
99 * @param res The PMU device registers. The driver will maintain a borrowed
100 * reference to this resource for the lifetime of the device.
101 */
102 int
bhnd_pmu_attach(device_t dev,struct bhnd_resource * res)103 bhnd_pmu_attach(device_t dev, struct bhnd_resource *res)
104 {
105 struct bhnd_pmu_softc *sc;
106 struct sysctl_ctx_list *ctx;
107 struct sysctl_oid *tree;
108 devclass_t bhnd_class;
109 device_t core, bus;
110 int error;
111
112 sc = device_get_softc(dev);
113 sc->dev = dev;
114 sc->res = res;
115
116 /* Fetch capability flags */
117 sc->caps = bhnd_bus_read_4(sc->res, BHND_PMU_CAP);
118
119 /* Find the bus and bus-attached core */
120 bhnd_class = devclass_find("bhnd");
121 core = sc->dev;
122 while ((bus = device_get_parent(core)) != NULL) {
123 if (device_get_devclass(bus) == bhnd_class)
124 break;
125
126 core = bus;
127 }
128
129 if (core == NULL) {
130 device_printf(sc->dev, "bhnd bus not found\n");
131 return (ENXIO);
132 }
133
134 /* Fetch chip and board info */
135 sc->cid = *bhnd_get_chipid(core);
136 if ((error = bhnd_read_board_info(core, &sc->board))) {
137 device_printf(sc->dev, "error fetching board info: %d\n",
138 error);
139 return (ENXIO);
140 }
141
142 /* Initialize query state */
143 error = bhnd_pmu_query_init(&sc->query, dev, sc->cid, &bhnd_pmu_res_io,
144 sc);
145 if (error)
146 return (error);
147 sc->io = sc->query.io;
148 sc->io_ctx = sc->query.io_ctx;
149
150 BPMU_LOCK_INIT(sc);
151
152 /* Allocate our own core clkctl state directly; we use this to wait on
153 * PMU state transitions, avoiding a cyclic dependency between bhnd(4)'s
154 * clkctl handling and registration of this device as a PMU */
155 sc->clkctl = bhnd_alloc_core_clkctl(core, dev, sc->res, BHND_CLK_CTL_ST,
156 BHND_PMU_MAX_TRANSITION_DLY);
157 if (sc->clkctl == NULL) {
158 device_printf(sc->dev, "failed to allocate clkctl for %s\n",
159 device_get_nameunit(core));
160 error = ENOMEM;
161 goto failed;
162 }
163
164 /* Locate ChipCommon device */
165 sc->chipc_dev = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC);
166 if (sc->chipc_dev == NULL) {
167 device_printf(sc->dev, "chipcommon device not found\n");
168 error = ENXIO;
169 goto failed;
170 }
171
172 /* Initialize PMU */
173 if ((error = bhnd_pmu_init(sc))) {
174 device_printf(sc->dev, "PMU init failed: %d\n", error);
175 goto failed;
176 }
177
178 /* Register ourselves with the bus */
179 if ((error = bhnd_register_provider(dev, BHND_SERVICE_PMU))) {
180 device_printf(sc->dev, "failed to register PMU with bus : %d\n",
181 error);
182 goto failed;
183 }
184
185 /* Set up sysctl nodes */
186 ctx = device_get_sysctl_ctx(dev);
187 tree = device_get_sysctl_tree(dev);
188
189 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
190 "bus_freq", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0,
191 bhnd_pmu_sysctl_bus_freq, "IU", "Bus clock frequency");
192
193 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
194 "cpu_freq", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0,
195 bhnd_pmu_sysctl_cpu_freq, "IU", "CPU clock frequency");
196
197 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
198 "mem_freq", CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, sc, 0,
199 bhnd_pmu_sysctl_mem_freq, "IU", "Memory clock frequency");
200
201 return (0);
202
203 failed:
204 BPMU_LOCK_DESTROY(sc);
205 bhnd_pmu_query_fini(&sc->query);
206
207 if (sc->clkctl != NULL)
208 bhnd_free_core_clkctl(sc->clkctl);
209
210 if (sc->chipc_dev != NULL) {
211 bhnd_release_provider(sc->dev, sc->chipc_dev,
212 BHND_SERVICE_CHIPC);
213 }
214
215 return (error);
216 }
217
218 /**
219 * Default bhnd_pmu driver implementation of DEVICE_DETACH().
220 */
221 int
bhnd_pmu_detach(device_t dev)222 bhnd_pmu_detach(device_t dev)
223 {
224 struct bhnd_pmu_softc *sc;
225 int error;
226
227 sc = device_get_softc(dev);
228
229 if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY)))
230 return (error);
231
232 BPMU_LOCK_DESTROY(sc);
233 bhnd_pmu_query_fini(&sc->query);
234 bhnd_free_core_clkctl(sc->clkctl);
235 bhnd_release_provider(sc->dev, sc->chipc_dev, BHND_SERVICE_CHIPC);
236
237 return (0);
238 }
239
240 /**
241 * Default bhnd_pmu driver implementation of DEVICE_SUSPEND().
242 */
243 int
bhnd_pmu_suspend(device_t dev)244 bhnd_pmu_suspend(device_t dev)
245 {
246 return (0);
247 }
248
249 /**
250 * Default bhnd_pmu driver implementation of DEVICE_RESUME().
251 */
252 int
bhnd_pmu_resume(device_t dev)253 bhnd_pmu_resume(device_t dev)
254 {
255 struct bhnd_pmu_softc *sc;
256 int error;
257
258 sc = device_get_softc(dev);
259
260 /* Re-initialize PMU */
261 if ((error = bhnd_pmu_init(sc))) {
262 device_printf(sc->dev, "PMU init failed: %d\n", error);
263 return (error);
264 }
265
266 return (0);
267 }
268
269 static int
bhnd_pmu_sysctl_bus_freq(SYSCTL_HANDLER_ARGS)270 bhnd_pmu_sysctl_bus_freq(SYSCTL_HANDLER_ARGS)
271 {
272 struct bhnd_pmu_softc *sc;
273 uint32_t freq;
274
275 sc = arg1;
276
277 BPMU_LOCK(sc);
278 freq = bhnd_pmu_si_clock(&sc->query);
279 BPMU_UNLOCK(sc);
280
281 return (sysctl_handle_32(oidp, NULL, freq, req));
282 }
283
284 static int
bhnd_pmu_sysctl_cpu_freq(SYSCTL_HANDLER_ARGS)285 bhnd_pmu_sysctl_cpu_freq(SYSCTL_HANDLER_ARGS)
286 {
287 struct bhnd_pmu_softc *sc;
288 uint32_t freq;
289
290 sc = arg1;
291
292 BPMU_LOCK(sc);
293 freq = bhnd_pmu_cpu_clock(&sc->query);
294 BPMU_UNLOCK(sc);
295
296 return (sysctl_handle_32(oidp, NULL, freq, req));
297 }
298
299 static int
bhnd_pmu_sysctl_mem_freq(SYSCTL_HANDLER_ARGS)300 bhnd_pmu_sysctl_mem_freq(SYSCTL_HANDLER_ARGS)
301 {
302 struct bhnd_pmu_softc *sc;
303 uint32_t freq;
304
305 sc = arg1;
306
307 BPMU_LOCK(sc);
308 freq = bhnd_pmu_mem_clock(&sc->query);
309 BPMU_UNLOCK(sc);
310
311 return (sysctl_handle_32(oidp, NULL, freq, req));
312 }
313
314 /**
315 * Default bhnd_pmu driver implementation of BHND_PMU_READ_CHIPCTRL().
316 */
317 static uint32_t
bhnd_pmu_read_chipctrl_method(device_t dev,uint32_t reg)318 bhnd_pmu_read_chipctrl_method(device_t dev, uint32_t reg)
319 {
320 struct bhnd_pmu_softc *sc;
321 uint32_t rval;
322
323 sc = device_get_softc(dev);
324
325 BPMU_LOCK(sc);
326 rval = BHND_PMU_CCTRL_READ(sc, reg);
327 BPMU_UNLOCK(sc);
328
329 return (rval);
330 }
331
332 /**
333 * Default bhnd_pmu driver implementation of BHND_PMU_WRITE_CHIPCTRL().
334 */
335 static void
bhnd_pmu_write_chipctrl_method(device_t dev,uint32_t reg,uint32_t value,uint32_t mask)336 bhnd_pmu_write_chipctrl_method(device_t dev, uint32_t reg, uint32_t value,
337 uint32_t mask)
338 {
339 struct bhnd_pmu_softc *sc = device_get_softc(dev);
340
341 BPMU_LOCK(sc);
342 BHND_PMU_CCTRL_WRITE(sc, reg, value, mask);
343 BPMU_UNLOCK(sc);
344 }
345
346 /**
347 * Default bhnd_pmu driver implementation of BHND_PMU_READ_REGCTRL().
348 */
349 static uint32_t
bhnd_pmu_read_regctrl_method(device_t dev,uint32_t reg)350 bhnd_pmu_read_regctrl_method(device_t dev, uint32_t reg)
351 {
352 struct bhnd_pmu_softc *sc;
353 uint32_t rval;
354
355 sc = device_get_softc(dev);
356
357 BPMU_LOCK(sc);
358 rval = BHND_PMU_REGCTRL_READ(sc, reg);
359 BPMU_UNLOCK(sc);
360
361 return (rval);
362 }
363
364 /**
365 * Default bhnd_pmu driver implementation of BHND_PMU_WRITE_REGCTRL().
366 */
367 static void
bhnd_pmu_write_regctrl_method(device_t dev,uint32_t reg,uint32_t value,uint32_t mask)368 bhnd_pmu_write_regctrl_method(device_t dev, uint32_t reg, uint32_t value,
369 uint32_t mask)
370 {
371 struct bhnd_pmu_softc *sc = device_get_softc(dev);
372
373 BPMU_LOCK(sc);
374 BHND_PMU_REGCTRL_WRITE(sc, reg, value, mask);
375 BPMU_UNLOCK(sc);
376 }
377
378 /**
379 * Default bhnd_pmu driver implementation of BHND_PMU_READ_PLLCTRL().
380 */
381 static uint32_t
bhnd_pmu_read_pllctrl_method(device_t dev,uint32_t reg)382 bhnd_pmu_read_pllctrl_method(device_t dev, uint32_t reg)
383 {
384 struct bhnd_pmu_softc *sc;
385 uint32_t rval;
386
387 sc = device_get_softc(dev);
388
389 BPMU_LOCK(sc);
390 rval = BHND_PMU_PLL_READ(sc, reg);
391 BPMU_UNLOCK(sc);
392
393 return (rval);
394 }
395
396 /**
397 * Default bhnd_pmu driver implementation of BHND_PMU_WRITE_PLLCTRL().
398 */
399 static void
bhnd_pmu_write_pllctrl_method(device_t dev,uint32_t reg,uint32_t value,uint32_t mask)400 bhnd_pmu_write_pllctrl_method(device_t dev, uint32_t reg, uint32_t value,
401 uint32_t mask)
402 {
403 struct bhnd_pmu_softc *sc = device_get_softc(dev);
404
405 BPMU_LOCK(sc);
406 BHND_PMU_PLL_WRITE(sc, reg, value, mask);
407 BPMU_UNLOCK(sc);
408 }
409
410 /**
411 * Default bhnd_pmu driver implementation of BHND_PMU_SET_VOLTAGE_RAW().
412 */
413 static int
bhnd_pmu_set_voltage_raw_method(device_t dev,bhnd_pmu_regulator regulator,uint32_t value)414 bhnd_pmu_set_voltage_raw_method(device_t dev, bhnd_pmu_regulator regulator,
415 uint32_t value)
416 {
417 struct bhnd_pmu_softc *sc;
418 int error;
419
420 sc = device_get_softc(dev);
421
422 switch (regulator) {
423 case BHND_REGULATOR_PAREF_LDO:
424 if (value > UINT8_MAX)
425 return (EINVAL);
426
427 BPMU_LOCK(sc);
428 error = bhnd_pmu_set_ldo_voltage(sc, SET_LDO_VOLTAGE_PAREF,
429 value);
430 BPMU_UNLOCK(sc);
431
432 return (error);
433
434 default:
435 return (ENODEV);
436 }
437 }
438
439 /**
440 * Default bhnd_pmu driver implementation of BHND_PMU_ENABLE_REGULATOR().
441 */
442 static int
bhnd_pmu_enable_regulator_method(device_t dev,bhnd_pmu_regulator regulator)443 bhnd_pmu_enable_regulator_method(device_t dev, bhnd_pmu_regulator regulator)
444 {
445 struct bhnd_pmu_softc *sc;
446 int error;
447
448 sc = device_get_softc(dev);
449
450 switch (regulator) {
451 case BHND_REGULATOR_PAREF_LDO:
452 BPMU_LOCK(sc);
453 error = bhnd_pmu_paref_ldo_enable(sc, true);
454 BPMU_UNLOCK(sc);
455
456 return (error);
457
458 default:
459 return (ENODEV);
460 }
461 }
462
463 /**
464 * Default bhnd_pmu driver implementation of BHND_PMU_DISABLE_REGULATOR().
465 */
466 static int
bhnd_pmu_disable_regulator_method(device_t dev,bhnd_pmu_regulator regulator)467 bhnd_pmu_disable_regulator_method(device_t dev, bhnd_pmu_regulator regulator)
468 {
469 struct bhnd_pmu_softc *sc;
470 int error;
471
472 sc = device_get_softc(dev);
473
474 switch (regulator) {
475 case BHND_REGULATOR_PAREF_LDO:
476 BPMU_LOCK(sc);
477 error = bhnd_pmu_paref_ldo_enable(sc, false);
478 BPMU_UNLOCK(sc);
479
480 return (error);
481
482 default:
483 return (ENODEV);
484 }
485 }
486
487 /**
488 * Default bhnd_pmu driver implementation of BHND_PMU_GET_CLOCK_LATENCY().
489 */
490 static int
bhnd_pmu_get_clock_latency_method(device_t dev,bhnd_clock clock,u_int * latency)491 bhnd_pmu_get_clock_latency_method(device_t dev, bhnd_clock clock,
492 u_int *latency)
493 {
494 struct bhnd_pmu_softc *sc;
495 u_int pwrup_delay;
496 int error;
497
498 sc = device_get_softc(dev);
499
500 switch (clock) {
501 case BHND_CLOCK_HT:
502 BPMU_LOCK(sc);
503 error = bhnd_pmu_fast_pwrup_delay(sc, &pwrup_delay);
504 BPMU_UNLOCK(sc);
505
506 if (error)
507 return (error);
508
509 *latency = pwrup_delay;
510 return (0);
511
512 default:
513 return (ENODEV);
514 }
515 }
516
517 /**
518 * Default bhnd_pmu driver implementation of BHND_PMU_GET_CLOCK_FREQ().
519 */
520 static int
bhnd_pmu_get_clock_freq_method(device_t dev,bhnd_clock clock,uint32_t * freq)521 bhnd_pmu_get_clock_freq_method(device_t dev, bhnd_clock clock, uint32_t *freq)
522 {
523 struct bhnd_pmu_softc *sc = device_get_softc(dev);
524
525 BPMU_LOCK(sc);
526 switch (clock) {
527 case BHND_CLOCK_HT:
528 *freq = bhnd_pmu_si_clock(&sc->query);
529 break;
530
531 case BHND_CLOCK_ALP:
532 *freq = bhnd_pmu_alp_clock(&sc->query);
533 break;
534
535 case BHND_CLOCK_ILP:
536 *freq = bhnd_pmu_ilp_clock(&sc->query);
537 break;
538
539 case BHND_CLOCK_DYN:
540 default:
541 BPMU_UNLOCK(sc);
542 return (ENODEV);
543 }
544
545 BPMU_UNLOCK(sc);
546 return (0);
547 }
548
549 /**
550 * Default bhnd_pmu driver implementation of BHND_PMU_REQUEST_SPURAVOID().
551 */
552 static int
bhnd_pmu_request_spuravoid_method(device_t dev,bhnd_pmu_spuravoid spuravoid)553 bhnd_pmu_request_spuravoid_method(device_t dev, bhnd_pmu_spuravoid spuravoid)
554 {
555 struct bhnd_pmu_softc *sc;
556 int error;
557
558 sc = device_get_softc(dev);
559
560 BPMU_LOCK(sc);
561 error = bhnd_pmu_set_spuravoid(sc, spuravoid);
562 BPMU_UNLOCK(sc);
563
564 return (error);
565 }
566
567 /**
568 * Default bhnd_pmu driver implementation of BHND_PMU_GET_TRANSITION_LATENCY().
569 */
570 static u_int
bhnd_pmu_get_max_transition_latency_method(device_t dev)571 bhnd_pmu_get_max_transition_latency_method(device_t dev)
572 {
573 return (BHND_PMU_MAX_TRANSITION_DLY);
574 }
575
576 /* bhnd_pmu_query read_4 callback */
577 static uint32_t
bhnd_pmu_read_4(bus_size_t reg,void * ctx)578 bhnd_pmu_read_4(bus_size_t reg, void *ctx)
579 {
580 struct bhnd_pmu_softc *sc = ctx;
581 return (bhnd_bus_read_4(sc->res, reg));
582 }
583
584 /* bhnd_pmu_query write_4 callback */
585 static void
bhnd_pmu_write_4(bus_size_t reg,uint32_t val,void * ctx)586 bhnd_pmu_write_4(bus_size_t reg, uint32_t val, void *ctx)
587 {
588 struct bhnd_pmu_softc *sc = ctx;
589 return (bhnd_bus_write_4(sc->res, reg, val));
590 }
591
592 /* bhnd_pmu_query read_chipst callback */
593 static uint32_t
bhnd_pmu_read_chipst(void * ctx)594 bhnd_pmu_read_chipst(void *ctx)
595 {
596 struct bhnd_pmu_softc *sc = ctx;
597 return (BHND_CHIPC_READ_CHIPST(sc->chipc_dev));
598 }
599
600 static device_method_t bhnd_pmu_methods[] = {
601 /* Device interface */
602 DEVMETHOD(device_probe, bhnd_pmu_probe),
603 DEVMETHOD(device_detach, bhnd_pmu_detach),
604 DEVMETHOD(device_suspend, bhnd_pmu_suspend),
605 DEVMETHOD(device_resume, bhnd_pmu_resume),
606
607 /* BHND PMU interface */
608 DEVMETHOD(bhnd_pmu_read_chipctrl, bhnd_pmu_read_chipctrl_method),
609 DEVMETHOD(bhnd_pmu_write_chipctrl, bhnd_pmu_write_chipctrl_method),
610 DEVMETHOD(bhnd_pmu_read_regctrl, bhnd_pmu_read_regctrl_method),
611 DEVMETHOD(bhnd_pmu_write_regctrl, bhnd_pmu_write_regctrl_method),
612 DEVMETHOD(bhnd_pmu_read_pllctrl, bhnd_pmu_read_pllctrl_method),
613 DEVMETHOD(bhnd_pmu_write_pllctrl, bhnd_pmu_write_pllctrl_method),
614 DEVMETHOD(bhnd_pmu_set_voltage_raw, bhnd_pmu_set_voltage_raw_method),
615 DEVMETHOD(bhnd_pmu_enable_regulator, bhnd_pmu_enable_regulator_method),
616 DEVMETHOD(bhnd_pmu_disable_regulator, bhnd_pmu_disable_regulator_method),
617
618 DEVMETHOD(bhnd_pmu_get_clock_latency, bhnd_pmu_get_clock_latency_method),
619 DEVMETHOD(bhnd_pmu_get_clock_freq, bhnd_pmu_get_clock_freq_method),
620
621 DEVMETHOD(bhnd_pmu_get_max_transition_latency, bhnd_pmu_get_max_transition_latency_method),
622 DEVMETHOD(bhnd_pmu_request_spuravoid, bhnd_pmu_request_spuravoid_method),
623
624 DEVMETHOD_END
625 };
626
627 DEFINE_CLASS_0(bhnd_pmu, bhnd_pmu_driver, bhnd_pmu_methods, sizeof(struct bhnd_pmu_softc));
628 MODULE_VERSION(bhnd_pmu, 1);
629