Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70882416 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/imx'

  - 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
parents a40c4b37 075af61c
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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