summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@linux-m68k.org>2018-04-11 13:39:44 +1000
committerGreg Ungerer <gerg@linux-m68k.org>2018-05-28 09:45:27 +1000
commit082f55c459845088c3fee99c3a88ee117c148218 (patch)
tree8c321b25d043797a12cef6ac7407c5b43c274947 /arch
parent48074d2615add385e6357fc1333959fc778557f9 (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')
-rw-r--r--arch/m68k/coldfire/pci.c15
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;
}