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-all mailing list