From 930c6074d7dd579f3d4e8b04548dd8cb0341de1d Mon Sep 17 00:00:00 2001 From: Jianmin Lv Date: Thu, 14 Jul 2022 20:42:16 +0800 Subject: PCI: loongson: Work around LS7A incorrect Interrupt Pin registers Several devices integrated into LS7A report 1 (which means they use INTA) in their Interrupt Pin registers, but they actually use a different interrupt. Add a quirk to override the incorrect Interrupt Pin values. This is only needed by ACPI-based systems. For DT-based systems, pci_assign_irq() ignores the Interrupt Pin register except to learn that the device uses INTx and the host bridge .map_irq() function (loongson_map_irq()) learns the IRQ mapping via DT and of_irq_parse_pci(). [bhelgaas: drop PCIE_PORT_x, OHCI, GPU since they are function 0 and don't need the quirk, squash in updates from https://lore.kernel.org/r/CAAhV-H40_o+9KS1t67O98GusM38pDaiB4bssxd3KQZpAByfnLg@mail.gmail.com] Link: https://lore.kernel.org/r/20220714124216.1489304-8-chenhuacai@loongson.cn Signed-off-by: Jianmin Lv Signed-off-by: Huacai Chen Signed-off-by: Bjorn Helgaas --- drivers/pci/controller/pci-loongson.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'drivers/pci/controller/pci-loongson.c') diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 6ed125c7d86a..05c50408f13b 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -20,8 +20,15 @@ #define DEV_PCIE_PORT_2 0x7a29 #define DEV_LS2K_APB 0x7a02 -#define DEV_LS7A_CONF 0x7a10 +#define DEV_LS7A_GMAC 0x7a03 +#define DEV_LS7A_DC1 0x7a06 #define DEV_LS7A_LPC 0x7a0c +#define DEV_LS7A_AHCI 0x7a08 +#define DEV_LS7A_CONF 0x7a10 +#define DEV_LS7A_GNET 0x7a13 +#define DEV_LS7A_EHCI 0x7a14 +#define DEV_LS7A_DC2 0x7a36 +#define DEV_LS7A_HDMI 0x7a37 #define FLAG_CFG0 BIT(0) #define FLAG_CFG1 BIT(1) @@ -100,6 +107,25 @@ static void loongson_mrrs_quirk(struct pci_dev *dev) } DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_mrrs_quirk); +static void loongson_pci_pin_quirk(struct pci_dev *pdev) +{ + pdev->pin = 1 + (PCI_FUNC(pdev->devfn) & 3); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_DC1, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_DC2, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_GMAC, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_AHCI, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_EHCI, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_GNET, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_HDMI, loongson_pci_pin_quirk); + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) { struct pci_config_window *cfg; -- cgit v1.2.3