]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
Merge branch 'remotes/lorenzo/pci/imx'
authorBjorn Helgaas <bhelgaas@google.com>
Mon, 23 Sep 2019 21:10:21 +0000 (16:10 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 23 Sep 2019 21:10:21 +0000 (16:10 -0500)
  - Reduce i.MX 6Quad DBI register length to avoid aborts from accessing
    invalid registers (Stefan Agner)

* remotes/lorenzo/pci/imx:
  PCI: imx6: Limit DBI register length

drivers/pci/controller/dwc/pci-imx6.c

index 9b5cb5b703890f3e6e2d17fe06d1ae29b8be11bb..8b8efa3063f520b2ec7238c2e6f3e55beebfaa83 100644 (file)
@@ -57,6 +57,7 @@ enum imx6_pcie_variants {
 struct imx6_pcie_drvdata {
        enum imx6_pcie_variants variant;
        u32 flags;
+       int dbi_length;
 };
 
 struct imx6_pcie {
@@ -1212,6 +1213,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
                .variant = IMX6Q,
                .flags = IMX6_PCIE_FLAG_IMX6_PHY |
                         IMX6_PCIE_FLAG_IMX6_SPEED_CHANGE,
+               .dbi_length = 0x200,
        },
        [IMX6SX] = {
                .variant = IMX6SX,
@@ -1254,6 +1256,37 @@ static struct platform_driver imx6_pcie_driver = {
        .shutdown = imx6_pcie_shutdown,
 };
 
+static void imx6_pcie_quirk(struct pci_dev *dev)
+{
+       struct pci_bus *bus = dev->bus;
+       struct pcie_port *pp = bus->sysdata;
+
+       /* Bus parent is the PCI bridge, its parent is this platform driver */
+       if (!bus->dev.parent || !bus->dev.parent->parent)
+               return;
+
+       /* Make sure we only quirk devices associated with this driver */
+       if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver)
+               return;
+
+       if (bus->number == pp->root_bus_nr) {
+               struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+               struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+               /*
+                * Limit config length to avoid the kernel reading beyond
+                * the register set and causing an abort on i.MX 6Quad
+                */
+               if (imx6_pcie->drvdata->dbi_length) {
+                       dev->cfg_size = imx6_pcie->drvdata->dbi_length;
+                       dev_info(&dev->dev, "Limiting cfg_size to %d\n",
+                                       dev->cfg_size);
+               }
+       }
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_SYNOPSYS, 0xabcd,
+                       PCI_CLASS_BRIDGE_PCI, 8, imx6_pcie_quirk);
+
 static int __init imx6_pcie_init(void)
 {
 #ifdef CONFIG_ARM