The current quirk is a header quirk which runs after pci_setup_device(). This means that we can warnings from the later due to an unrecognized class code, and some parts of pci_dev aren't setup properly.
On the other hand, we somewhat rely on that later on as this causes "pci_read_bases" to not be called, thus not bringing in the bogus BAR 0 of the root complex. This breaks up the quirk in two. One is an early quirk and fixes up the class code. The other one remains a header quirk and removes the bogus resource. Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org> --- arch/powerpc/sysdev/fsl_pci.c | 34 +++++++++++++++++++++++++++++----- 1 files changed, 29 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index b392144..a1da340 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -36,23 +36,48 @@ static int fsl_pcie_bus_fixup, is_mpc83xx_pci; -static void __init quirk_fsl_pcie_header(struct pci_dev *dev) +static int __devinit __quirk_is_fsl_pcie_host(struct pci_dev *dev) { u8 progif; + /* We aren't a root complex, don't bother */ + if (dev->bus->self) + return 0; + /* if we aren't a PCIe don't bother */ if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) - return; + return 0; /* if we aren't in host mode don't bother */ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if (progif & 0x1) + return 0; + + return 1; +} + +static void __devinit quirk_fsl_pcie_early(struct pci_dev *dev) +{ + + if (!__quirk_is_fsl_pcie_host(dev)) return; + /* Fix incorrect class code */ dev->class = PCI_CLASS_BRIDGE_PCI << 8; fsl_pcie_bus_fixup = 1; - return; } +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_early); + +static void __devinit quirk_fsl_pcie_header(struct pci_dev *dev) +{ + if (!__quirk_is_fsl_pcie_host(dev)) + return; + + /* Hide resource 0 */ + dev->resource[0].start = dev->resource[0].end = 0; + dev->resource[0].flags = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header); static int __init fsl_pcie_check_link(struct pci_controller *hose) { @@ -81,6 +106,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask) */ if ((dev->bus == &pci_bus_type) && dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) { + dev_info(dev, "Switching PCI device to direct DMA ops\n"); set_dma_ops(dev, &dma_direct_ops); set_dma_offset(dev, pci64_dma_offset); } @@ -496,8 +522,6 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) } #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */ -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header); - #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x) struct mpc83xx_pcie_priv { void __iomem *cfg_type0; -- 1.7.7.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev