diff options
author | Greg Ungerer <gerg@linux-m68k.org> | 2018-04-11 13:39:44 +1000 |
---|---|---|
committer | Greg Ungerer <gerg@linux-m68k.org> | 2018-05-28 09:45:27 +1000 |
commit | 082f55c459845088c3fee99c3a88ee117c148218 (patch) | |
tree | 8c321b25d043797a12cef6ac7407c5b43c274947 /arch/m68k/coldfire | |
parent | 48074d2615add385e6357fc1333959fc778557f9 (diff) |
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 <gerg@linux-m68k.org>
Reviewed-by: Angelo Dureghello <angelo@sysam.it>
Tested-by: Angelo Dureghello <angelo@sysam.it>
Diffstat (limited to 'arch/m68k/coldfire')
-rw-r--r-- | arch/m68k/coldfire/pci.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index db709ad30f88..62b0eb6cf69a 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; } |