diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-03-20 04:55:35 +0100 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-03-20 19:40:22 +0100 |
commit | 068258bc15439c11a966e873f931cc8e513dca61 (patch) | |
tree | 956f247105e770adffc1fca68820668a73b484a9 /arch/x86/pci/mmconfig_64.c | |
parent | PCI MSI: Add example request loop to MSI-HOWTO.txt (diff) | |
download | linux-068258bc15439c11a966e873f931cc8e513dca61.tar.xz linux-068258bc15439c11a966e873f931cc8e513dca61.zip |
x86/PCI: host mmconfig detect clean up
Fix mmconfig detection to not assume a single mmconfig space in the
northbridge, paving the way for AMD fam10h + mcp55 CPUs. On those, the
MSR has some range, but the mcp55 pci config will have another one.
Also helps the mcp55 + io55 case, where every one will have one range.
If it is mcp55, exclude the range that is used by CPU MSR, in other
words , if the CPU claims busses 0-255, the range in mcp55 is dropped,
because CPU HW will not route those ranges to mcp55 mmconfig to handle
it.
Signed-off-by: Yinghai Lu <yinghai.lu@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86/pci/mmconfig_64.c')
-rw-r--r-- | arch/x86/pci/mmconfig_64.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 30007ffc8e11..94349f8b2f96 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c @@ -112,13 +112,18 @@ static struct pci_raw_ops pci_mmcfg = { static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) { void __iomem *addr; - u32 size; - - size = (cfg->end_bus_number + 1) << 20; - addr = ioremap_nocache(cfg->address, size); + u64 start, size; + + start = cfg->start_bus_number; + start <<= 20; + start += cfg->address; + size = cfg->end_bus_number + 1 - cfg->start_bus_number; + size <<= 20; + addr = ioremap_nocache(start, size); if (addr) { printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", - cfg->address, cfg->address + size - 1); + start, start + size - 1); + addr -= cfg->start_bus_number << 20; } return addr; } @@ -157,7 +162,7 @@ void __init pci_mmcfg_arch_free(void) for (i = 0; i < pci_mmcfg_config_num; ++i) { if (pci_mmcfg_virt[i].virt) { - iounmap(pci_mmcfg_virt[i].virt); + iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); pci_mmcfg_virt[i].virt = NULL; pci_mmcfg_virt[i].cfg = NULL; } |