Lines Matching +full:irq +full:- +full:device
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (C) 2008-2010 Nathan Whitehorn
65 * IBM CPC9X5 Hypertransport Device interface.
85 int *irq);
87 int irq);
89 int irq, uint64_t *addr, uint32_t *data);
95 /* Device interface */
163 if (strcmp(compatible, "u3-ht") != 0) in cpcht_probe()
185 sc->pci_sc.sc_quirks = OFW_PCI_QUIRK_RANGES_ON_CHILDREN; in cpcht_attach()
186 sc->sc_populated_slots = 0; in cpcht_attach()
187 sc->sc_data = (vm_offset_t)pmap_mapdev(reg[1], reg[2]); in cpcht_attach()
190 * Set up the resource manager and the HT->MPIC mapping. For cpcht, in cpcht_attach()
196 /* I/O port mappings are usually not in the device tree */ in cpcht_attach()
197 rman_manage_region(&sc->pci_sc.sc_io_rman, 0, CPCHT_IOPORT_SIZE - 1); in cpcht_attach()
200 bzero(sc->htirq_map, sizeof(sc->htirq_map)); in cpcht_attach()
201 mtx_init(&sc->htirq_mtx, "cpcht irq", NULL, MTX_DEF); in cpcht_attach()
203 sc->htirq_map[i].irq_type = IRQ_INTERNAL; in cpcht_attach()
208 cpcht_irqmap = sc->htirq_map; in cpcht_attach()
220 int i, nirq, irq; in cpcht_configure_htbridge() local
224 if (OF_getencprop(child, "reg", (pcell_t *)&pcir, sizeof(pcir)) == -1) in cpcht_configure_htbridge()
235 sc->sc_populated_slots |= (1 << s); in cpcht_configure_htbridge()
238 * Next build up any HT->MPIC mappings for this sub-bus. One would in cpcht_configure_htbridge()
260 /* Find the HT IRQ capabilities */ in cpcht_configure_htbridge()
269 /* Ask for the IRQ count */ in cpcht_configure_htbridge()
274 device_printf(dev, "%d HT IRQs on device %d.%d\n", nirq, s, f); in cpcht_configure_htbridge()
279 irq = PCIB_READ_CONFIG(dev, b, s, f, ptr + 4, 4); in cpcht_configure_htbridge()
285 irq | HTAPIC_MASK, 4); in cpcht_configure_htbridge()
286 irq = (irq >> 16) & 0xff; in cpcht_configure_htbridge()
288 sc->htirq_map[irq].irq_type = IRQ_HT; in cpcht_configure_htbridge()
289 sc->htirq_map[irq].ht_source = i; in cpcht_configure_htbridge()
290 sc->htirq_map[irq].ht_base = sc->sc_data + in cpcht_configure_htbridge()
295 sc->htirq_map[irq].eoi_data = in cpcht_configure_htbridge()
300 * Apple uses a non-compliant IO/APIC that differs in cpcht_configure_htbridge()
301 * in how we signal EOIs. Check if this device was in cpcht_configure_htbridge()
307 sc->htirq_map[irq].apple_eoi = in cpcht_configure_htbridge()
308 (sc->htirq_map[irq].ht_base - ptr) + 0x60; in cpcht_configure_htbridge()
321 caoff = sc->sc_data + in cpcht_read_config()
324 if (bus == 0 && (!(sc->sc_populated_slots & (1 << slot)) || func > 0)) in cpcht_read_config()
353 caoff = sc->sc_data + in cpcht_write_config()
356 if (bus == 0 && (!(sc->sc_populated_slots & (1 << slot)) || func > 0)) in cpcht_write_config()
395 mtx_lock(&sc->htirq_mtx); in cpcht_alloc_msi()
396 for (i = 8; i < 124 - count; i++) { in cpcht_alloc_msi()
398 if (sc->htirq_map[i+j].irq_type != IRQ_NONE) in cpcht_alloc_msi()
408 mtx_unlock(&sc->htirq_mtx); in cpcht_alloc_msi()
414 sc->htirq_map[i+j].irq_type = IRQ_MSI; in cpcht_alloc_msi()
416 mtx_unlock(&sc->htirq_mtx); in cpcht_alloc_msi()
429 mtx_lock(&sc->htirq_mtx); in cpcht_release_msi()
431 sc->htirq_map[irqs[i] & 0xff].irq_type = IRQ_NONE; in cpcht_release_msi()
432 mtx_unlock(&sc->htirq_mtx); in cpcht_release_msi()
438 cpcht_alloc_msix(device_t dev, device_t child, int *irq) in cpcht_alloc_msix() argument
449 mtx_lock(&sc->htirq_mtx); in cpcht_alloc_msix()
451 if (sc->htirq_map[i].irq_type == IRQ_NONE) { in cpcht_alloc_msix()
452 sc->htirq_map[i].irq_type = IRQ_MSI; in cpcht_alloc_msix()
453 *irq = MAP_IRQ(cpcht_msipic, i); in cpcht_alloc_msix()
455 mtx_unlock(&sc->htirq_mtx); in cpcht_alloc_msix()
459 mtx_unlock(&sc->htirq_mtx); in cpcht_alloc_msix()
465 cpcht_release_msix(device_t dev, device_t child, int irq) in cpcht_release_msix() argument
471 mtx_lock(&sc->htirq_mtx); in cpcht_release_msix()
472 sc->htirq_map[irq & 0xff].irq_type = IRQ_NONE; in cpcht_release_msix()
473 mtx_unlock(&sc->htirq_mtx); in cpcht_release_msix()
479 cpcht_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, in cpcht_map_msi() argument
489 ht = &dinfo->cfg.ht; in cpcht_map_msi()
498 *addr = ht->ht_msiaddr; in cpcht_map_msi()
499 *data = irq & 0xff; in cpcht_map_msi()
510 static void openpic_cpcht_config(device_t, u_int irq,
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);
518 /* Device interface */
555 if (strcmp(type, "open-pic") != 0) in openpic_cpcht_probe()
567 int err, irq; in openpic_cpcht_attach() local
575 * The HT APIC stuff is not thread-safe, so we need a mutex to in openpic_cpcht_attach()
579 mtx_init(&sc->sc_ht_mtx, "htpic", NULL, MTX_SPIN); in openpic_cpcht_attach()
582 * Interrupts 0-3 are internally sourced and are level triggered in openpic_cpcht_attach()
583 * active low. Interrupts 4-123 are connected to a pulse generator in openpic_cpcht_attach()
584 * and should be programmed as edge triggered low-to-high. in openpic_cpcht_attach()
589 for (irq = 0; irq < 4; irq++) in openpic_cpcht_attach()
590 openpic_config(dev, irq, INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW); in openpic_cpcht_attach()
591 for (irq = 4; irq < 124; irq++) in openpic_cpcht_attach()
592 openpic_config(dev, irq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); in openpic_cpcht_attach()
606 openpic_cpcht_config(device_t dev, u_int irq, enum intr_trigger trig, in openpic_cpcht_config() argument
615 * settings need to be negotiated with the remote IO-APIC on the HT in openpic_cpcht_config()
621 if (cpcht_irqmap != NULL && irq < 128 && in openpic_cpcht_config()
622 cpcht_irqmap[irq].ht_base > 0 && !cpcht_irqmap[irq].edge) { in openpic_cpcht_config()
623 mtx_lock_spin(&sc->sc_ht_mtx); in openpic_cpcht_config()
626 out8rb(cpcht_irqmap[irq].ht_base + PCIR_HT_COMMAND, in openpic_cpcht_config()
627 0x10 + (cpcht_irqmap[irq].ht_source << 1)); in openpic_cpcht_config()
629 /* Grab the IRQ config register */ in openpic_cpcht_config()
630 ht_irq = in32rb(cpcht_irqmap[irq].ht_base + 4); in openpic_cpcht_config()
632 /* Mask the IRQ while we fiddle settings */ in openpic_cpcht_config()
633 out32rb(cpcht_irqmap[irq].ht_base + 4, ht_irq | HTAPIC_MASK); in openpic_cpcht_config()
638 cpcht_irqmap[irq].edge = 1; in openpic_cpcht_config()
640 cpcht_irqmap[irq].edge = 0; in openpic_cpcht_config()
643 out32rb(cpcht_irqmap[irq].ht_base + 4, ht_irq); in openpic_cpcht_config()
645 mtx_unlock_spin(&sc->sc_ht_mtx); in openpic_cpcht_config()
650 openpic_cpcht_enable(device_t dev, u_int irq, u_int vec, void **priv) in openpic_cpcht_enable() argument
655 openpic_enable(dev, irq, vec, priv); in openpic_cpcht_enable()
659 if (cpcht_irqmap != NULL && irq < 128 && in openpic_cpcht_enable()
660 cpcht_irqmap[irq].ht_base > 0) { in openpic_cpcht_enable()
661 mtx_lock_spin(&sc->sc_ht_mtx); in openpic_cpcht_enable()
664 out8rb(cpcht_irqmap[irq].ht_base + PCIR_HT_COMMAND, in openpic_cpcht_enable()
665 0x10 + (cpcht_irqmap[irq].ht_source << 1)); in openpic_cpcht_enable()
668 ht_irq = in32rb(cpcht_irqmap[irq].ht_base + 4); in openpic_cpcht_enable()
670 out32rb(cpcht_irqmap[irq].ht_base + 4, ht_irq); in openpic_cpcht_enable()
672 mtx_unlock_spin(&sc->sc_ht_mtx); in openpic_cpcht_enable()
675 openpic_cpcht_eoi(dev, irq, *priv); in openpic_cpcht_enable()
679 openpic_cpcht_unmask(device_t dev, u_int irq, void *priv) in openpic_cpcht_unmask() argument
684 openpic_unmask(dev, irq, priv); in openpic_cpcht_unmask()
688 if (cpcht_irqmap != NULL && irq < 128 && in openpic_cpcht_unmask()
689 cpcht_irqmap[irq].ht_base > 0) { in openpic_cpcht_unmask()
690 mtx_lock_spin(&sc->sc_ht_mtx); in openpic_cpcht_unmask()
693 out8rb(cpcht_irqmap[irq].ht_base + PCIR_HT_COMMAND, in openpic_cpcht_unmask()
694 0x10 + (cpcht_irqmap[irq].ht_source << 1)); in openpic_cpcht_unmask()
697 ht_irq = in32rb(cpcht_irqmap[irq].ht_base + 4); in openpic_cpcht_unmask()
699 out32rb(cpcht_irqmap[irq].ht_base + 4, ht_irq); in openpic_cpcht_unmask()
701 mtx_unlock_spin(&sc->sc_ht_mtx); in openpic_cpcht_unmask()
704 openpic_cpcht_eoi(dev, irq, priv); in openpic_cpcht_unmask()
708 openpic_cpcht_eoi(device_t dev, u_int irq, void *priv) in openpic_cpcht_eoi() argument
713 if (irq == 255) in openpic_cpcht_eoi()
718 if (cpcht_irqmap != NULL && irq < 128 && in openpic_cpcht_eoi()
719 cpcht_irqmap[irq].ht_base > 0 && !cpcht_irqmap[irq].edge) { in openpic_cpcht_eoi()
720 /* If this is an HT IRQ, acknowledge it at the remote APIC */ in openpic_cpcht_eoi()
722 if (cpcht_irqmap[irq].apple_eoi) { in openpic_cpcht_eoi()
723 off = (cpcht_irqmap[irq].ht_source >> 3) & ~3; in openpic_cpcht_eoi()
724 mask = 1 << (cpcht_irqmap[irq].ht_source & 0x1f); in openpic_cpcht_eoi()
725 out32rb(cpcht_irqmap[irq].apple_eoi + off, mask); in openpic_cpcht_eoi()
727 mtx_lock_spin(&sc->sc_ht_mtx); in openpic_cpcht_eoi()
729 out8rb(cpcht_irqmap[irq].ht_base + PCIR_HT_COMMAND, in openpic_cpcht_eoi()
730 0x11 + (cpcht_irqmap[irq].ht_source << 1)); in openpic_cpcht_eoi()
731 out32rb(cpcht_irqmap[irq].ht_base + 4, in openpic_cpcht_eoi()
732 cpcht_irqmap[irq].eoi_data); in openpic_cpcht_eoi()
734 mtx_unlock_spin(&sc->sc_ht_mtx); in openpic_cpcht_eoi()
738 openpic_eoi(dev, irq, priv); in openpic_cpcht_eoi()