From 082f55c459845088c3fee99c3a88ee117c148218 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 11 Apr 2018 13:39:44 +1000 Subject: [PATCH] m68k: fix ColdFire PCI config reads and writes The ColdFire PCI configuration space access functions swap addressing regions to do their work. Just letting the read/write cycles exit the CPU core (via the ColdFire "nop" instruction) is not enough to guarantee that the address region remapping has actually completed. Insert a read back of the mapping register to be absolutely sure that the remapping has completed. This fixes an occasional boot hang during the ColdFire PCI initialization phase. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/coldfire/pci.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index db709ad..62b0eb6 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -46,13 +46,6 @@ static unsigned char mcf_host_irq[] = { 0, 69, 69, 71, 71, }; - -static inline void syncio(void) -{ - /* The ColdFire "nop" instruction waits for all bus IO to complete */ - __asm__ __volatile__ ("nop"); -} - /* * Configuration space access functions. Configuration space access is * through the IO mapping window, enabling it via the PCICAR register. @@ -74,9 +67,9 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } - syncio(); addr = mcf_mk_pcicar(bus->number, devfn, where); __raw_writel(PCICAR_E | addr, PCICAR); + __raw_readl(PCICAR); addr = iospace + (where & 0x3); switch (size) { @@ -91,8 +84,8 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, break; } - syncio(); __raw_writel(0, PCICAR); + __raw_readl(PCICAR); return PCIBIOS_SUCCESSFUL; } @@ -106,9 +99,9 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } - syncio(); addr = mcf_mk_pcicar(bus->number, devfn, where); __raw_writel(PCICAR_E | addr, PCICAR); + __raw_readl(PCICAR); addr = iospace + (where & 0x3); switch (size) { @@ -123,8 +116,8 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, break; } - syncio(); __raw_writel(0, PCICAR); + __raw_readl(PCICAR); return PCIBIOS_SUCCESSFUL; } -- 2.7.4