It appears that we wrongly calculate dev_base for type1 config cycles. The thing is: we shouldn't subtract hose->first_busno because PCI core sets PCI primary, secondary and subordinate bus numbers, and PCIe controller actually takes the registers into account. So we should use just bus->number.
Also, according to MPC8315 reference manual, primary bus number should always remain 0. We have PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS quirk in indirect_pci.c, but since 83xx is somewhat special, it doesn't use indirect_pci.c routines, so we have to implement the quirk specifically for 83xx PCIe controllers. Signed-off-by: Anton Vorontsov <avoront...@ru.mvista.com> --- This fixes the issue similar to http://www.pubbs.net/linuxppc/200908/22024/ i.e. lspci reports: 0000:00:00.0 Power PC: Freescale Semiconductor Inc Device 00b4 (rev 11) 0002:02:00.0 PCI bridge: Freescale Semiconductor Inc Device 00b4 (rev 11) 0002:03:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge (rev 03) 0002:04:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge (rev 03) 0002:04:01.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge (rev 03) 0002:04:02.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge (rev 03) ... While it should be: 0000:00:00.0 Power PC: Freescale Semiconductor Inc Device 00b4 (rev 11) 0002:02:00.0 PCI bridge: Freescale Semiconductor Inc Device 00b4 (rev 11) 0002:03:00.0 PCI bridge: Texas Instruments XIO2000(A)/XIO2200(A) PCI Express-to-PCI Bridge (rev 03) 0002:04:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G550 AGP (rev 01) arch/powerpc/sysdev/fsl_pci.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index ae88b14..0c11aa6 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -450,8 +450,7 @@ static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus, { struct pci_controller *hose = pci_bus_to_host(bus); struct mpc83xx_pcie_priv *pcie = hose->dn->data; - u8 bus_no = bus->number - hose->first_busno; - u32 dev_base = bus_no << 24 | devfn << 16; + u32 dev_base = bus->number << 24 | devfn << 16; int ret; ret = mpc83xx_pcie_exclude_device(bus, devfn); @@ -501,12 +500,17 @@ static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn, static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { + struct pci_controller *hose = pci_bus_to_host(bus); void __iomem *cfg_addr; cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); if (!cfg_addr) return PCIBIOS_DEVICE_NOT_FOUND; + /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ + if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) + val &= 0xffffff00; + switch (len) { case 1: out_8(cfg_addr, val); -- 1.6.3.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev