Date: Wed, 18 Sep 2019 07:09:16 +0000 (UTC) From: "Jayachandran C." <jchandra@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r352470 - in stable/12/sys: arm/arm dev/acpica Message-ID: <201909180709.x8I79Gc2094359@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jchandra Date: Wed Sep 18 07:09:16 2019 New Revision: 352470 URL: https://svnweb.freebsd.org/changeset/base/352470 Log: MFC r340598: acpica: rework INTRNG interrupts On arm64 (where INTRNG is enabled), the interrupts have to be mapped with ACPI_BUS_MAP_INTR() before adding them as resources to devices. The earlier code did the mapping before calling acpi_set_resource(), which bypassed code that checked for PCI link interrupts. To fix this, move the call to map interrupts into acpi_set_resource() and that requires additional work to lookup interrupt properties. The changes here are to: * extend acpi_lookup_irq_handler() to lookup an irq in the ACPI resources * create a helper function acpi_map_intr() which uses the updated acpi_lookup_irq_handler() to look up an irq, and then map it with ACPI_BUS_MAP_INTR() * use acpi_map_intr() in acpi_pcib_route_interrupt() to map pci link interrupts. With these changes, we can drop the ifdefs in acpi_resource.c, and we can also drop the call for mapping interrupts in generic_timer.c Reviewed by: andrew Differential Revision: https://reviews.freebsd.org/D17790 Modified: stable/12/sys/arm/arm/generic_timer.c stable/12/sys/dev/acpica/acpi.c stable/12/sys/dev/acpica/acpi_pcib.c stable/12/sys/dev/acpica/acpi_resource.c stable/12/sys/dev/acpica/acpivar.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/arm/arm/generic_timer.c ============================================================================== --- stable/12/sys/arm/arm/generic_timer.c Wed Sep 18 07:01:01 2019 (r352469) +++ stable/12/sys/arm/arm/generic_timer.c Wed Sep 18 07:09:16 2019 (r352470) @@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$"); #ifdef DEV_ACPI #include <contrib/dev/acpica/include/acpi.h> #include <dev/acpica/acpivar.h> -#include "acpi_bus_if.h" #endif #define GT_CTRL_ENABLE (1 << 0) @@ -340,8 +339,6 @@ static void arm_tmr_acpi_add_irq(device_t parent, device_t dev, int rid, u_int irq) { - irq = ACPI_BUS_MAP_INTR(parent, dev, irq, - INTR_TRIGGER_LEVEL, INTR_POLARITY_HIGH); BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, rid, irq, 1); } Modified: stable/12/sys/dev/acpica/acpi.c ============================================================================== --- stable/12/sys/dev/acpica/acpi.c Wed Sep 18 07:01:01 2019 (r352469) +++ stable/12/sys/dev/acpica/acpi.c Wed Sep 18 07:09:16 2019 (r352470) @@ -1318,6 +1318,13 @@ acpi_set_resource(device_t dev, device_t child, int ty } #endif +#ifdef INTRNG + /* map with default for now */ + if (type == SYS_RES_IRQ) + start = (rman_res_t)acpi_map_intr(child, (u_int)start, + acpi_get_handle(child)); +#endif + /* If the resource is already allocated, fail. */ if (resource_list_busy(rl, type, rid)) return (EBUSY); Modified: stable/12/sys/dev/acpica/acpi_pcib.c ============================================================================== --- stable/12/sys/dev/acpica/acpi_pcib.c Wed Sep 18 07:01:01 2019 (r352469) +++ stable/12/sys/dev/acpica/acpi_pcib.c Wed Sep 18 07:09:16 2019 (r352470) @@ -188,6 +188,7 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + lnkdev = NULL; interrupt = PCI_INVALID_IRQ; /* ACPI numbers pins 0-3, not 1-4 like the BIOS. */ @@ -252,7 +253,12 @@ acpi_pcib_route_interrupt(device_t pcib, device_t dev, out: ACPI_SERIAL_END(pcib); - +#ifdef INTRNG + if (PCI_INTERRUPT_VALID(interrupt)) { + interrupt = acpi_map_intr(dev, interrupt, lnkdev); + KASSERT(PCI_INTERRUPT_VALID(interrupt), ("mapping fail")); + } +#endif return_VALUE(interrupt); } Modified: stable/12/sys/dev/acpica/acpi_resource.c ============================================================================== --- stable/12/sys/dev/acpica/acpi_resource.c Wed Sep 18 07:01:01 2019 (r352469) +++ stable/12/sys/dev/acpica/acpi_resource.c Wed Sep 18 07:09:16 2019 (r352470) @@ -55,10 +55,13 @@ ACPI_MODULE_NAME("RESOURCE") struct lookup_irq_request { ACPI_RESOURCE *acpi_res; - struct resource *res; + u_int irq; int counter; int rid; int found; + int checkrid; + int trig; + int pol; }; static ACPI_STATUS @@ -66,18 +69,22 @@ acpi_lookup_irq_handler(ACPI_RESOURCE *res, void *cont { struct lookup_irq_request *req; size_t len; - u_int irqnum, irq; + u_int irqnum, irq, trig, pol; switch (res->Type) { case ACPI_RESOURCE_TYPE_IRQ: irqnum = res->Data.Irq.InterruptCount; irq = res->Data.Irq.Interrupts[0]; len = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ); + trig = res->Data.Irq.Triggering; + pol = res->Data.Irq.Polarity; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: irqnum = res->Data.ExtendedIrq.InterruptCount; irq = res->Data.ExtendedIrq.Interrupts[0]; len = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ); + trig = res->Data.ExtendedIrq.Triggering; + pol = res->Data.ExtendedIrq.Polarity; break; default: return (AE_OK); @@ -85,14 +92,21 @@ acpi_lookup_irq_handler(ACPI_RESOURCE *res, void *cont if (irqnum != 1) return (AE_OK); req = (struct lookup_irq_request *)context; - if (req->counter != req->rid) { - req->counter++; - return (AE_OK); + if (req->checkrid) { + if (req->counter != req->rid) { + req->counter++; + return (AE_OK); + } + KASSERT(irq == req->irq, ("IRQ resources do not match")); + } else { + if (req->irq != irq) + return (AE_OK); } req->found = 1; - KASSERT(irq == rman_get_start(req->res), - ("IRQ resources do not match")); - bcopy(res, req->acpi_res, len); + req->pol = pol; + req->trig = trig; + if (req->acpi_res != NULL) + bcopy(res, req->acpi_res, len); return (AE_CTRL_TERMINATE); } @@ -104,10 +118,11 @@ acpi_lookup_irq_resource(device_t dev, int rid, struct ACPI_STATUS status; req.acpi_res = acpi_res; - req.res = res; + req.irq = rman_get_start(res); req.counter = 0; req.rid = rid; req.found = 0; + req.checkrid = 1; status = AcpiWalkResources(acpi_get_handle(dev), "_CRS", acpi_lookup_irq_handler, &req); if (ACPI_SUCCESS(status) && req.found == 0) @@ -155,6 +170,34 @@ acpi_config_intr(device_t dev, ACPI_RESOURCE *res) INTR_POLARITY_HIGH : INTR_POLARITY_LOW); } +#ifdef INTRNG +int +acpi_map_intr(device_t dev, u_int irq, ACPI_HANDLE handle) +{ + struct lookup_irq_request req; + int trig, pol; + + trig = ACPI_LEVEL_SENSITIVE; + pol = ACPI_ACTIVE_HIGH; + if (handle != NULL) { + req.found = 0; + req.acpi_res = NULL; + req.irq = irq; + req.counter = 0; + req.rid = 0; + req.checkrid = 0; + AcpiWalkResources(handle, "_CRS", acpi_lookup_irq_handler, &req); + if (req.found != 0) { + trig = req.trig; + pol = req.pol; + } + } + return ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, irq, + (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, + (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); +} +#endif + struct acpi_resource_context { struct acpi_parse_resource_set *set; device_t dev; @@ -601,13 +644,7 @@ acpi_res_set_irq(device_t dev, void *context, uint8_t if (count != 1) return; -#ifdef INTRNG - intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq, - (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, - (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); -#else intr = *irq; -#endif bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); } @@ -625,13 +662,7 @@ acpi_res_set_ext_irq(device_t dev, void *context, uint if (count != 1) return; -#ifdef INTRNG - intr = ACPI_BUS_MAP_INTR(device_get_parent(dev), dev, *irq, - (trig == ACPI_EDGE_SENSITIVE) ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL, - (pol == ACPI_ACTIVE_HIGH) ? INTR_POLARITY_HIGH : INTR_POLARITY_LOW); -#else intr = *irq; -#endif bus_set_resource(dev, SYS_RES_IRQ, cp->ar_nirq++, intr, 1); } Modified: stable/12/sys/dev/acpica/acpivar.h ============================================================================== --- stable/12/sys/dev/acpica/acpivar.h Wed Sep 18 07:01:01 2019 (r352469) +++ stable/12/sys/dev/acpica/acpivar.h Wed Sep 18 07:09:16 2019 (r352470) @@ -399,6 +399,9 @@ extern struct acpi_parse_resource_set acpi_res_parse_s int acpi_identify(void); void acpi_config_intr(device_t dev, ACPI_RESOURCE *res); +#ifdef INTRNG +int acpi_map_intr(device_t dev, u_int irq, ACPI_HANDLE handle); +#endif ACPI_STATUS acpi_lookup_irq_resource(device_t dev, int rid, struct resource *res, ACPI_RESOURCE *acpi_res); ACPI_STATUS acpi_parse_resources(device_t dev, ACPI_HANDLE handle,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909180709.x8I79Gc2094359>