svn commit: r352470 - in stable/12/sys: arm/arm dev/acpica
Jayachandran C.
jchandra at FreeBSD.org
Wed Sep 18 07:09:18 UTC 2019
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,
More information about the svn-src-stable-12
mailing list