Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/fsl_pci: Fix P2P bridge handling for MPC83xx PCIe controllers

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 <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>

authored by

Anton Vorontsov and committed by
Kumar Gala
f93611fa e090aa80

+6 -2
+6 -2
arch/powerpc/sysdev/fsl_pci.c
··· 464 464 { 465 465 struct pci_controller *hose = pci_bus_to_host(bus); 466 466 struct mpc83xx_pcie_priv *pcie = hose->dn->data; 467 - u8 bus_no = bus->number - hose->first_busno; 468 - u32 dev_base = bus_no << 24 | devfn << 16; 467 + u32 dev_base = bus->number << 24 | devfn << 16; 469 468 int ret; 470 469 471 470 ret = mpc83xx_pcie_exclude_device(bus, devfn); ··· 514 515 static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn, 515 516 int offset, int len, u32 val) 516 517 { 518 + struct pci_controller *hose = pci_bus_to_host(bus); 517 519 void __iomem *cfg_addr; 518 520 519 521 cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset); 520 522 if (!cfg_addr) 521 523 return PCIBIOS_DEVICE_NOT_FOUND; 524 + 525 + /* PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS */ 526 + if (offset == PCI_PRIMARY_BUS && bus->number == hose->first_busno) 527 + val &= 0xffffff00; 522 528 523 529 switch (len) { 524 530 case 1: