2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (C) 2008-2010 Nathan Whitehorn
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/module.h>
33 #include <sys/kernel.h>
35 #include <sys/mutex.h>
36 #include <sys/pciio.h>
39 #include <dev/ofw/openfirm.h>
40 #include <dev/ofw/ofw_pci.h>
42 #include <dev/pci/pcivar.h>
43 #include <dev/pci/pcireg.h>
45 #include <machine/bus.h>
46 #include <machine/intr_machdep.h>
47 #include <machine/md_var.h>
48 #include <machine/openpicreg.h>
49 #include <machine/openpicvar.h>
50 #include <machine/pio.h>
51 #include <machine/resource.h>
53 #include <dev/ofw/ofw_bus.h>
54 #include <dev/ofw/ofw_bus_subr.h>
55 #include <dev/ofw/ofwpci.h>
61 #include <dev/pci/pcib_private.h>
65 * IBM CPC9X5 Hypertransport Device interface.
67 static int cpcht_probe(device_t
);
68 static int cpcht_attach(device_t
);
70 static void cpcht_configure_htbridge(device_t
, phandle_t
);
75 static u_int32_t
cpcht_read_config(device_t
, u_int
, u_int
, u_int
,
77 static void cpcht_write_config(device_t
, u_int
, u_int
, u_int
,
78 u_int
, u_int32_t
, int);
79 static int cpcht_route_interrupt(device_t
, device_t
, int);
80 static int cpcht_alloc_msi(device_t dev
, device_t child
,
81 int count
, int maxcount
, int *irqs
);
82 static int cpcht_release_msi(device_t dev
, device_t child
,
83 int count
, int *irqs
);
84 static int cpcht_alloc_msix(device_t dev
, device_t child
,
86 static int cpcht_release_msix(device_t dev
, device_t child
,
88 static int cpcht_map_msi(device_t dev
, device_t child
,
89 int irq
, uint64_t *addr
, uint32_t *data
);
94 static device_method_t cpcht_methods
[] = {
95 /* Device interface */
96 DEVMETHOD(device_probe
, cpcht_probe
),
97 DEVMETHOD(device_attach
, cpcht_attach
),
100 DEVMETHOD(pcib_read_config
, cpcht_read_config
),
101 DEVMETHOD(pcib_write_config
, cpcht_write_config
),
102 DEVMETHOD(pcib_route_interrupt
, cpcht_route_interrupt
),
103 DEVMETHOD(pcib_alloc_msi
, cpcht_alloc_msi
),
104 DEVMETHOD(pcib_release_msi
, cpcht_release_msi
),
105 DEVMETHOD(pcib_alloc_msix
, cpcht_alloc_msix
),
106 DEVMETHOD(pcib_release_msix
, cpcht_release_msix
),
107 DEVMETHOD(pcib_map_msi
, cpcht_map_msi
),
108 DEVMETHOD(pcib_request_feature
, pcib_request_feature_allow
),
115 IRQ_NONE
, IRQ_HT
, IRQ_MSI
, IRQ_INTERNAL
121 vm_offset_t apple_eoi
;
126 static struct cpcht_irq
*cpcht_irqmap
= NULL
;
127 uint32_t cpcht_msipic
= 0;
130 struct ofw_pci_softc pci_sc
;
132 uint64_t sc_populated_slots
;
134 struct cpcht_irq htirq_map
[128];
135 struct mtx htirq_mtx
;
138 DEFINE_CLASS_1(pcib
, cpcht_driver
, cpcht_methods
, sizeof(struct cpcht_softc
),
140 EARLY_DRIVER_MODULE(cpcht
, ofwbus
, cpcht_driver
, 0, 0, BUS_PASS_BUS
);
142 #define CPCHT_IOPORT_BASE 0xf4000000UL /* Hardwired */
143 #define CPCHT_IOPORT_SIZE 0x00400000UL
145 #define HTAPIC_REQUEST_EOI 0x20
146 #define HTAPIC_TRIGGER_LEVEL 0x02
147 #define HTAPIC_MASK 0x01
150 cpcht_probe(device_t dev
)
152 const char *type
, *compatible
;
154 type
= ofw_bus_get_type(dev
);
155 compatible
= ofw_bus_get_compat(dev
);
157 if (type
== NULL
|| compatible
== NULL
)
160 if (strcmp(type
, "ht") != 0)
163 if (strcmp(compatible
, "u3-ht") != 0)
166 device_set_desc(dev
, "IBM CPC9X5 HyperTransport Tunnel");
171 cpcht_attach(device_t dev
)
173 struct cpcht_softc
*sc
;
174 phandle_t node
, child
;
178 node
= ofw_bus_get_node(dev
);
179 sc
= device_get_softc(dev
);
181 if (OF_getencprop(node
, "reg", reg
, sizeof(reg
)) < 12)
184 if (OF_getproplen(node
, "ranges") <= 0)
185 sc
->pci_sc
.sc_quirks
= OFW_PCI_QUIRK_RANGES_ON_CHILDREN
;
186 sc
->sc_populated_slots
= 0;
187 sc
->sc_data
= (vm_offset_t
)pmap_mapdev(reg
[1], reg
[2]);
190 * Set up the resource manager and the HT->MPIC mapping. For cpcht,
191 * the ranges are properties of the child bridges, and this is also
192 * where we get the HT interrupts properties.
196 /* I/O port mappings are usually not in the device tree */
197 rman_manage_region(&sc
->pci_sc
.sc_io_rman
, 0, CPCHT_IOPORT_SIZE
- 1);
200 bzero(sc
->htirq_map
, sizeof(sc
->htirq_map
));
201 mtx_init(&sc
->htirq_mtx
, "cpcht irq", NULL
, MTX_DEF
);
202 for (i
= 0; i
< 8; i
++)
203 sc
->htirq_map
[i
].irq_type
= IRQ_INTERNAL
;
204 for (child
= OF_child(node
); child
!= 0; child
= OF_peer(child
))
205 cpcht_configure_htbridge(dev
, child
);
207 /* Now make the mapping table available to the MPIC */
208 cpcht_irqmap
= sc
->htirq_map
;
210 return (ofw_pcib_attach(dev
));
214 cpcht_configure_htbridge(device_t dev
, phandle_t child
)
216 struct cpcht_softc
*sc
;
217 struct ofw_pci_register pcir
;
223 sc
= device_get_softc(dev
);
224 if (OF_getencprop(child
, "reg", (pcell_t
*)&pcir
, sizeof(pcir
)) == -1)
227 b
= OFW_PCI_PHYS_HI_BUS(pcir
.phys_hi
);
228 s
= OFW_PCI_PHYS_HI_DEVICE(pcir
.phys_hi
);
229 f
= OFW_PCI_PHYS_HI_FUNCTION(pcir
.phys_hi
);
232 * Mark this slot is populated. The remote south bridge does
233 * not like us talking to unpopulated slots on the root bus.
235 sc
->sc_populated_slots
|= (1 << s
);
238 * Next build up any HT->MPIC mappings for this sub-bus. One would
239 * naively hope that enabling, disabling, and EOIing interrupts would
240 * cause the appropriate HT bus transactions to that effect. This is
243 * Instead, we have to muck about on the HT peer's root PCI bridges,
244 * figure out what interrupts they send, enable them, and cache
245 * the location of their WaitForEOI registers so that we can
249 /* All the devices we are interested in have caps */
250 if (!(PCIB_READ_CONFIG(dev
, b
, s
, f
, PCIR_STATUS
, 2)
251 & PCIM_STATUS_CAPPRESENT
))
254 nextptr
= PCIB_READ_CONFIG(dev
, b
, s
, f
, PCIR_CAP_PTR
, 1);
255 while (nextptr
!= 0) {
257 nextptr
= PCIB_READ_CONFIG(dev
, b
, s
, f
,
258 ptr
+ PCICAP_NEXTPTR
, 1);
260 /* Find the HT IRQ capabilities */
261 if (PCIB_READ_CONFIG(dev
, b
, s
, f
,
262 ptr
+ PCICAP_ID
, 1) != PCIY_HT
)
265 val
= PCIB_READ_CONFIG(dev
, b
, s
, f
, ptr
+ PCIR_HT_COMMAND
, 2);
266 if ((val
& PCIM_HTCMD_CAP_MASK
) != PCIM_HTCAP_INTERRUPT
)
269 /* Ask for the IRQ count */
270 PCIB_WRITE_CONFIG(dev
, b
, s
, f
, ptr
+ PCIR_HT_COMMAND
, 0x1, 1);
271 nirq
= PCIB_READ_CONFIG(dev
, b
, s
, f
, ptr
+ 4, 4);
272 nirq
= ((nirq
>> 16) & 0xff) + 1;
274 device_printf(dev
, "%d HT IRQs on device %d.%d\n", nirq
, s
, f
);
276 for (i
= 0; i
< nirq
; i
++) {
277 PCIB_WRITE_CONFIG(dev
, b
, s
, f
,
278 ptr
+ PCIR_HT_COMMAND
, 0x10 + (i
<< 1), 1);
279 irq
= PCIB_READ_CONFIG(dev
, b
, s
, f
, ptr
+ 4, 4);
282 * Mask this interrupt for now.
284 PCIB_WRITE_CONFIG(dev
, b
, s
, f
, ptr
+ 4,
285 irq
| HTAPIC_MASK
, 4);
286 irq
= (irq
>> 16) & 0xff;
288 sc
->htirq_map
[irq
].irq_type
= IRQ_HT
;
289 sc
->htirq_map
[irq
].ht_source
= i
;
290 sc
->htirq_map
[irq
].ht_base
= sc
->sc_data
+
291 (((((s
& 0x1f) << 3) | (f
& 0x07)) << 8) | (ptr
));
293 PCIB_WRITE_CONFIG(dev
, b
, s
, f
,
294 ptr
+ PCIR_HT_COMMAND
, 0x11 + (i
<< 1), 1);
295 sc
->htirq_map
[irq
].eoi_data
=
296 PCIB_READ_CONFIG(dev
, b
, s
, f
, ptr
+ 4, 4) |
300 * Apple uses a non-compliant IO/APIC that differs
301 * in how we signal EOIs. Check if this device was
302 * made by Apple, and act accordingly.
304 vend
= PCIB_READ_CONFIG(dev
, b
, s
, f
,
306 if ((vend
& 0xffff) == 0x106b)
307 sc
->htirq_map
[irq
].apple_eoi
=
308 (sc
->htirq_map
[irq
].ht_base
- ptr
) + 0x60;
314 cpcht_read_config(device_t dev
, u_int bus
, u_int slot
, u_int func
, u_int reg
,
317 struct cpcht_softc
*sc
;
320 sc
= device_get_softc(dev
);
321 caoff
= sc
->sc_data
+
322 (((((slot
& 0x1f) << 3) | (func
& 0x07)) << 8) | reg
);
324 if (bus
== 0 && (!(sc
->sc_populated_slots
& (1 << slot
)) || func
> 0))
328 caoff
+= 0x01000000UL
+ (bus
<< 16);
332 return (in8rb(caoff
));
335 return (in16rb(caoff
));
338 return (in32rb(caoff
));
346 cpcht_write_config(device_t dev
, u_int bus
, u_int slot
, u_int func
,
347 u_int reg
, u_int32_t val
, int width
)
349 struct cpcht_softc
*sc
;
352 sc
= device_get_softc(dev
);
353 caoff
= sc
->sc_data
+
354 (((((slot
& 0x1f) << 3) | (func
& 0x07)) << 8) | reg
);
356 if (bus
== 0 && (!(sc
->sc_populated_slots
& (1 << slot
)) || func
> 0))
360 caoff
+= 0x01000000UL
+ (bus
<< 16);
376 cpcht_route_interrupt(device_t bus
, device_t dev
, int pin
)
382 cpcht_alloc_msi(device_t dev
, device_t child
, int count
, int maxcount
,
385 struct cpcht_softc
*sc
;
388 sc
= device_get_softc(dev
);
391 /* Bail if no MSI PIC yet */
392 if (cpcht_msipic
== 0)
395 mtx_lock(&sc
->htirq_mtx
);
396 for (i
= 8; i
< 124 - count
; i
++) {
397 for (j
= 0; j
< count
; j
++) {
398 if (sc
->htirq_map
[i
+j
].irq_type
!= IRQ_NONE
)
404 i
+= j
; /* We know there isn't a large enough run */
408 mtx_unlock(&sc
->htirq_mtx
);
412 for (j
= 0; j
< count
; j
++) {
413 irqs
[j
] = MAP_IRQ(cpcht_msipic
, i
+j
);
414 sc
->htirq_map
[i
+j
].irq_type
= IRQ_MSI
;
416 mtx_unlock(&sc
->htirq_mtx
);
422 cpcht_release_msi(device_t dev
, device_t child
, int count
, int *irqs
)
424 struct cpcht_softc
*sc
;
427 sc
= device_get_softc(dev
);
429 mtx_lock(&sc
->htirq_mtx
);
430 for (i
= 0; i
< count
; i
++)
431 sc
->htirq_map
[irqs
[i
] & 0xff].irq_type
= IRQ_NONE
;
432 mtx_unlock(&sc
->htirq_mtx
);
438 cpcht_alloc_msix(device_t dev
, device_t child
, int *irq
)
440 struct cpcht_softc
*sc
;
443 sc
= device_get_softc(dev
);
445 /* Bail if no MSI PIC yet */
446 if (cpcht_msipic
== 0)
449 mtx_lock(&sc
->htirq_mtx
);
450 for (i
= 8; i
< 124; i
++) {
451 if (sc
->htirq_map
[i
].irq_type
== IRQ_NONE
) {
452 sc
->htirq_map
[i
].irq_type
= IRQ_MSI
;
453 *irq
= MAP_IRQ(cpcht_msipic
, i
);
455 mtx_unlock(&sc
->htirq_mtx
);
459 mtx_unlock(&sc
->htirq_mtx
);
465 cpcht_release_msix(device_t dev
, device_t child
, int irq
)
467 struct cpcht_softc
*sc
;
469 sc
= device_get_softc(dev
);
471 mtx_lock(&sc
->htirq_mtx
);
472 sc
->htirq_map
[irq
& 0xff].irq_type
= IRQ_NONE
;
473 mtx_unlock(&sc
->htirq_mtx
);
479 cpcht_map_msi(device_t dev
, device_t child
, int irq
, uint64_t *addr
,
483 struct pci_devinfo
*dinfo
;
484 struct pcicfg_ht
*ht
= NULL
;
486 for (pcib
= child
; pcib
!= dev
; pcib
=
487 device_get_parent(device_get_parent(pcib
))) {
488 dinfo
= device_get_ivars(pcib
);
498 *addr
= ht
->ht_msiaddr
;
505 * Driver for the integrated MPIC on U3/U4 (CPC925/CPC945)
508 static int openpic_cpcht_probe(device_t
);
509 static int openpic_cpcht_attach(device_t
);
510 static void openpic_cpcht_config(device_t
, u_int irq
,
511 enum intr_trigger trig
, enum intr_polarity pol
);
512 static void openpic_cpcht_enable(device_t
, u_int irq
, u_int vector
,
514 static void openpic_cpcht_unmask(device_t
, u_int irq
, void *priv
);
515 static void openpic_cpcht_eoi(device_t
, u_int irq
, void *priv
);
517 static device_method_t openpic_cpcht_methods
[] = {
518 /* Device interface */
519 DEVMETHOD(device_probe
, openpic_cpcht_probe
),
520 DEVMETHOD(device_attach
, openpic_cpcht_attach
),
523 DEVMETHOD(pic_bind
, openpic_bind
),
524 DEVMETHOD(pic_config
, openpic_cpcht_config
),
525 DEVMETHOD(pic_dispatch
, openpic_dispatch
),
526 DEVMETHOD(pic_enable
, openpic_cpcht_enable
),
527 DEVMETHOD(pic_eoi
, openpic_cpcht_eoi
),
528 DEVMETHOD(pic_ipi
, openpic_ipi
),
529 DEVMETHOD(pic_mask
, openpic_mask
),
530 DEVMETHOD(pic_unmask
, openpic_cpcht_unmask
),
535 struct openpic_cpcht_softc
{
536 struct openpic_softc sc_openpic
;
538 struct mtx sc_ht_mtx
;
541 static driver_t openpic_cpcht_driver
= {
543 openpic_cpcht_methods
,
544 sizeof(struct openpic_cpcht_softc
),
547 EARLY_DRIVER_MODULE(openpic
, unin
, openpic_cpcht_driver
, 0, 0,
551 openpic_cpcht_probe(device_t dev
)
553 const char *type
= ofw_bus_get_type(dev
);
555 if (strcmp(type
, "open-pic") != 0)
558 device_set_desc(dev
, OPENPIC_DEVSTR
);
563 openpic_cpcht_attach(device_t dev
)
565 struct openpic_cpcht_softc
*sc
;
569 node
= ofw_bus_get_node(dev
);
570 err
= openpic_common_attach(dev
, node
);
575 * The HT APIC stuff is not thread-safe, so we need a mutex to
578 sc
= device_get_softc(dev
);
579 mtx_init(&sc
->sc_ht_mtx
, "htpic", NULL
, MTX_SPIN
);
582 * Interrupts 0-3 are internally sourced and are level triggered
583 * active low. Interrupts 4-123 are connected to a pulse generator
584 * and should be programmed as edge triggered low-to-high.
586 * IBM CPC945 Manual, Section 9.3.
589 for (irq
= 0; irq
< 4; irq
++)
590 openpic_config(dev
, irq
, INTR_TRIGGER_LEVEL
, INTR_POLARITY_LOW
);
591 for (irq
= 4; irq
< 124; irq
++)
592 openpic_config(dev
, irq
, INTR_TRIGGER_EDGE
, INTR_POLARITY_LOW
);
595 * Use this PIC for MSI only if it is the root PIC. This may not
596 * be necessary, but Linux does it, and I cannot find any U3 machines
597 * with MSI devices to test.
606 openpic_cpcht_config(device_t dev
, u_int irq
, enum intr_trigger trig
,
607 enum intr_polarity pol
)
609 struct openpic_cpcht_softc
*sc
;
613 * The interrupt settings for the MPIC are completely determined
614 * by the internal wiring in the northbridge. Real changes to these
615 * settings need to be negotiated with the remote IO-APIC on the HT
619 sc
= device_get_softc(dev
);
621 if (cpcht_irqmap
!= NULL
&& irq
< 128 &&
622 cpcht_irqmap
[irq
].ht_base
> 0 && !cpcht_irqmap
[irq
].edge
) {
623 mtx_lock_spin(&sc
->sc_ht_mtx
);
625 /* Program the data port */
626 out8rb(cpcht_irqmap
[irq
].ht_base
+ PCIR_HT_COMMAND
,
627 0x10 + (cpcht_irqmap
[irq
].ht_source
<< 1));
629 /* Grab the IRQ config register */
630 ht_irq
= in32rb(cpcht_irqmap
[irq
].ht_base
+ 4);
632 /* Mask the IRQ while we fiddle settings */
633 out32rb(cpcht_irqmap
[irq
].ht_base
+ 4, ht_irq
| HTAPIC_MASK
);
635 /* Program the interrupt sense */
636 ht_irq
&= ~(HTAPIC_TRIGGER_LEVEL
| HTAPIC_REQUEST_EOI
);
637 if (trig
== INTR_TRIGGER_EDGE
) {
638 cpcht_irqmap
[irq
].edge
= 1;
640 cpcht_irqmap
[irq
].edge
= 0;
641 ht_irq
|= HTAPIC_TRIGGER_LEVEL
| HTAPIC_REQUEST_EOI
;
643 out32rb(cpcht_irqmap
[irq
].ht_base
+ 4, ht_irq
);
645 mtx_unlock_spin(&sc
->sc_ht_mtx
);
650 openpic_cpcht_enable(device_t dev
, u_int irq
, u_int vec
, void **priv
)
652 struct openpic_cpcht_softc
*sc
;
655 openpic_enable(dev
, irq
, vec
, priv
);
657 sc
= device_get_softc(dev
);
659 if (cpcht_irqmap
!= NULL
&& irq
< 128 &&
660 cpcht_irqmap
[irq
].ht_base
> 0) {
661 mtx_lock_spin(&sc
->sc_ht_mtx
);
663 /* Program the data port */
664 out8rb(cpcht_irqmap
[irq
].ht_base
+ PCIR_HT_COMMAND
,
665 0x10 + (cpcht_irqmap
[irq
].ht_source
<< 1));
667 /* Unmask the interrupt */
668 ht_irq
= in32rb(cpcht_irqmap
[irq
].ht_base
+ 4);
669 ht_irq
&= ~HTAPIC_MASK
;
670 out32rb(cpcht_irqmap
[irq
].ht_base
+ 4, ht_irq
);
672 mtx_unlock_spin(&sc
->sc_ht_mtx
);
675 openpic_cpcht_eoi(dev
, irq
, *priv
);
679 openpic_cpcht_unmask(device_t dev
, u_int irq
, void *priv
)
681 struct openpic_cpcht_softc
*sc
;
684 openpic_unmask(dev
, irq
, priv
);
686 sc
= device_get_softc(dev
);
688 if (cpcht_irqmap
!= NULL
&& irq
< 128 &&
689 cpcht_irqmap
[irq
].ht_base
> 0) {
690 mtx_lock_spin(&sc
->sc_ht_mtx
);
692 /* Program the data port */
693 out8rb(cpcht_irqmap
[irq
].ht_base
+ PCIR_HT_COMMAND
,
694 0x10 + (cpcht_irqmap
[irq
].ht_source
<< 1));
696 /* Unmask the interrupt */
697 ht_irq
= in32rb(cpcht_irqmap
[irq
].ht_base
+ 4);
698 ht_irq
&= ~HTAPIC_MASK
;
699 out32rb(cpcht_irqmap
[irq
].ht_base
+ 4, ht_irq
);
701 mtx_unlock_spin(&sc
->sc_ht_mtx
);
704 openpic_cpcht_eoi(dev
, irq
, priv
);
708 openpic_cpcht_eoi(device_t dev
, u_int irq
, void *priv
)
710 struct openpic_cpcht_softc
*sc
;
716 sc
= device_get_softc(dev
);
718 if (cpcht_irqmap
!= NULL
&& irq
< 128 &&
719 cpcht_irqmap
[irq
].ht_base
> 0 && !cpcht_irqmap
[irq
].edge
) {
720 /* If this is an HT IRQ, acknowledge it at the remote APIC */
722 if (cpcht_irqmap
[irq
].apple_eoi
) {
723 off
= (cpcht_irqmap
[irq
].ht_source
>> 3) & ~3;
724 mask
= 1 << (cpcht_irqmap
[irq
].ht_source
& 0x1f);
725 out32rb(cpcht_irqmap
[irq
].apple_eoi
+ off
, mask
);
727 mtx_lock_spin(&sc
->sc_ht_mtx
);
729 out8rb(cpcht_irqmap
[irq
].ht_base
+ PCIR_HT_COMMAND
,
730 0x11 + (cpcht_irqmap
[irq
].ht_source
<< 1));
731 out32rb(cpcht_irqmap
[irq
].ht_base
+ 4,
732 cpcht_irqmap
[irq
].eoi_data
);
734 mtx_unlock_spin(&sc
->sc_ht_mtx
);
738 openpic_eoi(dev
, irq
, priv
);