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

Reply via email to