Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/acpi arm: acpi: Improve legacy INTx support.
details: https://anonhg.NetBSD.org/src/rev/2f3e895eff0a
branches: trunk
changeset: 368939:2f3e895eff0a
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Aug 13 20:07:13 2022 +0000
description:
arm: acpi: Improve legacy INTx support.
For devices on a bus with no direct _PRT, use the raw intr pin with the
parent bridge's slot number to derive a pin number that can be used to
lookup the pin -> irq mapping in the parent bus's _PRT.
diffstat:
sys/arch/arm/acpi/acpi_pci_machdep.c | 37 ++++++++++++++++++++++++++++++-----
1 files changed, 31 insertions(+), 6 deletions(-)
diffs (103 lines):
diff -r d7972e573168 -r 2f3e895eff0a sys/arch/arm/acpi/acpi_pci_machdep.c
--- a/sys/arch/arm/acpi/acpi_pci_machdep.c Sat Aug 13 17:46:26 2022 +0000
+++ b/sys/arch/arm/acpi/acpi_pci_machdep.c Sat Aug 13 20:07:13 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_pci_machdep.c,v 1.21 2021/12/21 11:02:38 skrll Exp $ */
+/* $NetBSD: acpi_pci_machdep.c,v 1.22 2022/08/13 20:07:13 jmcneill Exp $ */
/*-
* Copyright (c) 2018, 2020 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#define _INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.21 2021/12/21 11:02:38 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_pci_machdep.c,v 1.22 2022/08/13 20:07:13 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -71,6 +71,8 @@
struct acpi_pci_prt {
u_int prt_segment;
u_int prt_bus;
+ u_int prt_bridge_dev;
+ bool prt_derived;
ACPI_HANDLE prt_handle;
TAILQ_ENTRY(acpi_pci_prt) prt_list;
};
@@ -210,6 +212,8 @@
struct acpi_devnode *ad;
ACPI_HANDLE handle;
int seg, bus, dev, func;
+ u_int bridge_dev = 0;
+ bool derived = false;
seg = ap->ap_seg;
handle = NULL;
@@ -225,10 +229,13 @@
if (ad != NULL) {
handle = ad->ad_handle;
} else {
- /* No routes defined for this bus, copy from parent */
+ /* No routes defined for this bus, derive from parent */
TAILQ_FOREACH(prtp, &acpi_pci_irq_routes, prt_list)
- if (prtp->prt_bus == bus) {
+ if (prtp->prt_bus == bus &&
+ prtp->prt_segment == seg) {
handle = prtp->prt_handle;
+ bridge_dev = dev;
+ derived = true;
break;
}
}
@@ -244,8 +251,10 @@
if (handle != NULL) {
prt = kmem_alloc(sizeof(*prt), KM_SLEEP);
prt->prt_bus = pba->pba_bus;
- prt->prt_segment = ap->ap_seg;
+ prt->prt_segment = seg;
prt->prt_handle = handle;
+ prt->prt_bridge_dev = bridge_dev;
+ prt->prt_derived = derived;
TAILQ_INSERT_TAIL(&acpi_pci_irq_routes, prt, prt_list);
}
@@ -375,6 +384,7 @@
ACPI_HANDLE linksrc;
ACPI_BUFFER buf;
void *linkdev;
+ u_int pin;
if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
return EINVAL;
@@ -386,6 +396,21 @@
if (ACPI_FAILURE(acpi_get(prt->prt_handle, &buf, AcpiGetIrqRoutingTable)))
return EIO;
+ /*
+ * For busses with no direct _PRT entry, derive the pin from the
+ * parent bridge.
+ */
+ if (prt->prt_derived) {
+ pin = (((pa->pa_rawintrpin + prt->prt_bridge_dev) - 1) % 4) + 1;
+ } else {
+ pin = pa->pa_intrpin;
+ }
+
+ aprint_debug("%s: bus=%u pin=%u pa_rawintrpin=%u pa_intrpin=%u "
+ "pa_intrswiz=%u prt_bridge_dev=%u\n",
+ __func__, pa->pa_bus, pin, pa->pa_rawintrpin,
+ pa->pa_intrpin, pa->pa_intrswiz, prt->prt_bridge_dev);
+
error = ENOENT;
for (char *p = buf.Pointer; ; p += tab->Length) {
tab = (ACPI_PCI_ROUTING_TABLE *)p;
@@ -393,7 +418,7 @@
break;
if (pa->pa_device == ACPI_HIWORD(tab->Address) &&
- (pa->pa_intrpin - 1) == (tab->Pin & 3)) {
+ (pin - 1) == (tab->Pin & 3)) {
if (tab->Source[0] != 0) {
if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, tab->Source, &linksrc)))
goto done;
Home |
Main Index |
Thread Index |
Old Index