summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuacai Chen <chenhuacai@loongson.cn>2024-06-12 09:53:15 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-08-03 09:54:21 +0300
commite22b88f234a1f306b8a7bf04af375ddf1758dba2 (patch)
tree032b12ddffee5a058c09d34e0d403492b440c6ce
parenta5b1cce14a49ffc9aa2d8479b9b59c2e9e1f03c6 (diff)
downloadlinux-e22b88f234a1f306b8a7bf04af375ddf1758dba2.tar.xz
PCI: loongson: Enable MSI in LS7A Root Complex
commit a4bbcac11d3cea85822af8b40daed7e96bca5068 upstream. The LS7A chipset can be used as part of a PCIe Root Complex with Loongson-3C6000 and similar CPUs. In this case, DEV_LS7A_PCIE_PORT5 has a PCI_CLASS_BRIDGE_HOST class code, and it is a Type 0 Function whose config space provides access to Root Complex registers. The DEV_LS7A_PCIE_PORT5 has an MSI Capability, and its MSI Enable bit must be set before other devices below the Root Complex can use MSI. This is not the standard PCI behavior of MSI Enable, so the normal PCI MSI code does not set it. Set the DEV_LS7A_PCIE_PORT5 MSI Enable bit via a quirk so other devices below the Root Complex can use MSI. [kwilczynski: exit early to reduce indentation; commit log] Link: https://lore.kernel.org/linux-pci/20240612065315.2048110-1-chenhuacai@loongson.cn Signed-off-by: Sheng Wu <wusheng@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Signed-off-by: Krzysztof WilczyƄski <kwilczynski@kernel.org> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/pci/controller/pci-loongson.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c
index 8b34ccff073a..bc630ab8a283 100644
--- a/drivers/pci/controller/pci-loongson.c
+++ b/drivers/pci/controller/pci-loongson.c
@@ -163,6 +163,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON,
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON,
DEV_LS7A_HDMI, loongson_pci_pin_quirk);
+static void loongson_pci_msi_quirk(struct pci_dev *dev)
+{
+ u16 val, class = dev->class >> 8;
+
+ if (class != PCI_CLASS_BRIDGE_HOST)
+ return;
+
+ pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &val);
+ val |= PCI_MSI_FLAGS_ENABLE;
+ pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, val);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk);
+
static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus)
{
struct pci_config_window *cfg;