From d1f0ae412e88d33d772dc85e773b70abc6655138 Mon Sep 17 00:00:00 2001 From: mmel Date: Sat, 5 Nov 2016 10:23:02 +0000 Subject: MFC r304459,r305527: r304459: INTRNG: Rework handling with resources. Partially revert r301453. - Read interrupt properties at bus enumeration time and store it into global mapping table. - At bus_activate_resource() time, given mapping entry is resolved and connected to real interrupt source. A copy of mapping entry is attached to given resource. - At bus_setup_intr() time, mapping entry stored in resource is used for delivery of requested interrupt configuration. - For MSI/MSIX interrupts, mapping entry is created within pci_alloc_msi()/pci_alloc_msix() call. - For legacy PCI interrupts, mapping entry must be created within pcib_route_interrupt() by pcib driver itself. r305527: Fix MIPS INTRNG (both FDT and non-FDT) behaviour broken by r304459 --- sys/arm64/arm64/nexus.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'sys/arm64') diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 2cd36ad..26e1c6c 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef FDT +#include #include #include "ofw_bus_if.h" #endif @@ -344,6 +345,8 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, rman_set_bustag(r, &memmap_bus); rman_set_virtual(r, (void *)vaddr); rman_set_bushandle(r, vaddr); + } else if (type == SYS_RES_IRQ) { + intr_activate_irq(child, r); } return (0); } @@ -377,13 +380,17 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, bus_size_t psize; bus_space_handle_t vaddr; - psize = (bus_size_t)rman_get_size(r); - vaddr = rman_get_bushandle(r); + if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { + psize = (bus_size_t)rman_get_size(r); + vaddr = rman_get_bushandle(r); - if (vaddr != 0) { - bus_space_unmap(&memmap_bus, vaddr, psize); - rman_set_virtual(r, NULL); - rman_set_bushandle(r, 0); + if (vaddr != 0) { + bus_space_unmap(&memmap_bus, vaddr, psize); + rman_set_virtual(r, NULL); + rman_set_bushandle(r, 0); + } + } else if (type == SYS_RES_IRQ) { + intr_deactivate_irq(child, r); } return (rman_deactivate_resource(r)); @@ -430,8 +437,18 @@ static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, pcell_t *intr) { - - return (INTR_IRQ_INVALID); + u_int irq; + struct intr_map_data_fdt *fdt_data; + size_t len; + + len = sizeof(*fdt_data) + icells * sizeof(pcell_t); + fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data( + INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO); + fdt_data->iparent = iparent; + fdt_data->ncells = icells; + memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t)); + irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data); + return (irq); } #endif -- cgit v1.1