diff options
| -rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 77fae5f64f2e..5558d932b4d5 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
| @@ -204,6 +204,23 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, | |||
| 204 | { | 204 | { |
| 205 | u32 ma, pcila, pciha; | 205 | u32 ma, pcila, pciha; |
| 206 | 206 | ||
| 207 | /* Hack warning ! The "old" PCI 2.x cell only let us configure the low | ||
| 208 | * 32-bit of incoming PLB addresses. The top 4 bits of the 36-bit | ||
| 209 | * address are actually hard wired to a value that appears to depend | ||
| 210 | * on the specific SoC. For example, it's 0 on 440EP and 1 on 440EPx. | ||
| 211 | * | ||
| 212 | * The trick here is we just crop those top bits and ignore them when | ||
| 213 | * programming the chip. That means the device-tree has to be right | ||
| 214 | * for the specific part used (we don't print a warning if it's wrong | ||
| 215 | * but on the other hand, you'll crash quickly enough), but at least | ||
| 216 | * this code should work whatever the hard coded value is | ||
| 217 | */ | ||
| 218 | plb_addr &= 0xffffffffull; | ||
| 219 | |||
| 220 | /* Note: Due to the above hack, the test below doesn't actually test | ||
| 221 | * if you address is above 4G, but it tests that address and | ||
| 222 | * (address + size) are both contained in the same 4G | ||
| 223 | */ | ||
| 207 | if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || | 224 | if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || |
| 208 | size < 0x1000 || (plb_addr & (size - 1)) != 0) { | 225 | size < 0x1000 || (plb_addr & (size - 1)) != 0) { |
| 209 | printk(KERN_WARNING "%s: Resource out of range\n", | 226 | printk(KERN_WARNING "%s: Resource out of range\n", |
