[PATCH] acpi: pci: don't ignore function ID of bridge device in _PRT

Ard Biesheuvel ard.biesheuvel at linaro.org
Fri Apr 7 09:22:22 EDT 2017


We currently derive legacy interrupt routing by matching _PRT
entries on the PCI device only, presumably under the assumption
that PRT entries always have a value of 0xffff in the function
field, meaning 'match all functions'.

This no longer holds for modern PCIe topologies, where the
legacy interrupts for different slots may be wired to different
functions on the same bridge device. For instance, on AMD Seattle,
we may have something like

-[0000:00]-+-00.0  Advanced Micro Devices, Inc. [AMD] Device 1a00
           +-02.0  Advanced Micro Devices, Inc. [AMD] Device 1a01
           +-02.2-[01]----00.0  Renesas uPD720202 USB 3.0 Host Controller
           \-02.3-[02]----00.0  Realtek RTL8169 PCIe Gigabit Ethernet

where the _PRT describes the legacy interrupt routing as

    Name (_PRT, Package ()  // _PRT: PCI Routing Table
    {
        // slot 1: dev 2 fn 1
        Package () { 0x20001, 0x0, 0x0, 0x140 },
        Package () { 0x20001, 0x1, 0x0, 0x141 },
        Package () { 0x20001, 0x2, 0x0, 0x142 },
        Package () { 0x20001, 0x3, 0x0, 0x143 },

        // slot 1: dev 2 fn 2
        Package () { 0x20002, 0x0, 0x0, 0x144 },
        Package () { 0x20002, 0x1, 0x0, 0x145 },
        Package () { 0x20002, 0x2, 0x0, 0x146 },
        Package () { 0x20002, 0x3, 0x0, 0x147 },

        // slot 1: dev 2 fn 3
        Package () { 0x20003, 0x0, 0x0, 0x148 },
        Package () { 0x20003, 0x1, 0x0, 0x149 },
        Package () { 0x20003, 0x2, 0x0, 0x14a },
        Package () { 0x20003, 0x3, 0x0, 0x14b }
    }) // _PRT

The current code always matches on the first entry when trying to
derive the legacy interrupt routing for the USB and Ethernet controllers
behind bridges 02.2 and 02.3, which results in the wrong entry to
be selected.

So fix this by matching the function ID to the value in the _PRT entry
if the _PRT entries are not using 0xffff in the lower word to match
all functions.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 drivers/acpi/pci_irq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index c576a6fe4ebb..caac4ac94418 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -160,6 +160,8 @@ static int acpi_pci_irq_check_entry(acpi_handle handle, struct pci_dev *dev,
 	struct acpi_prt_entry *entry;
 
 	if (((prt->address >> 16) & 0xffff) != device ||
+	    ((prt->address & 0xffff) != 0xffff &&
+	     (prt->address & 0xffff) != PCI_FUNC(dev->devfn)) ||
 	    prt->pin + 1 != pin)
 		return -ENODEV;
 
-- 
2.9.3




More information about the linux-arm-kernel mailing list