Commit 082f55c4 authored by Greg Ungerer's avatar Greg Ungerer

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: default avatarGreg Ungerer <gerg@linux-m68k.org>
Reviewed-by: default avatarAngelo Dureghello <angelo@sysam.it>
Tested-by: default avatarAngelo Dureghello <angelo@sysam.it>
parent 48074d26
...@@ -46,13 +46,6 @@ static unsigned char mcf_host_irq[] = { ...@@ -46,13 +46,6 @@ static unsigned char mcf_host_irq[] = {
0, 69, 69, 71, 71, 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 * Configuration space access functions. Configuration space access is
* through the IO mapping window, enabling it via the PCICAR register. * 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, ...@@ -74,9 +67,9 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
syncio();
addr = mcf_mk_pcicar(bus->number, devfn, where); addr = mcf_mk_pcicar(bus->number, devfn, where);
__raw_writel(PCICAR_E | addr, PCICAR); __raw_writel(PCICAR_E | addr, PCICAR);
__raw_readl(PCICAR);
addr = iospace + (where & 0x3); addr = iospace + (where & 0x3);
switch (size) { switch (size) {
...@@ -91,8 +84,8 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, ...@@ -91,8 +84,8 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn,
break; break;
} }
syncio();
__raw_writel(0, PCICAR); __raw_writel(0, PCICAR);
__raw_readl(PCICAR);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
...@@ -106,9 +99,9 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, ...@@ -106,9 +99,9 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
syncio();
addr = mcf_mk_pcicar(bus->number, devfn, where); addr = mcf_mk_pcicar(bus->number, devfn, where);
__raw_writel(PCICAR_E | addr, PCICAR); __raw_writel(PCICAR_E | addr, PCICAR);
__raw_readl(PCICAR);
addr = iospace + (where & 0x3); addr = iospace + (where & 0x3);
switch (size) { switch (size) {
...@@ -123,8 +116,8 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, ...@@ -123,8 +116,8 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn,
break; break;
} }
syncio();
__raw_writel(0, PCICAR); __raw_writel(0, PCICAR);
__raw_readl(PCICAR);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment