summaryrefslogtreecommitdiff
path: root/arch/x86/pci/i386.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 22:26:33 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-25 22:26:33 +0400
commitec73adba51b4dae11134f7e6ffc84feade9f15fa (patch)
tree59b1d2c90f960d69fd247289fcd59fc213484a70 /arch/x86/pci/i386.c
parentcc556c5c92a45763e23015a31efb27005a6132fa (diff)
parent2a61812af2e564cba2c8170cf96e1c823210f619 (diff)
downloadlinux-ec73adba51b4dae11134f7e6ffc84feade9f15fa.tar.xz
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: x86: add X86_FEATURE_XMM4_2 definitions x86: fix cpufreq + sched_clock() regression x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet against BAR, v3 x86: do not enable TSC notifier if we don't need it x86 MCE: Fix CPU hotplug problem with multiple multicore AMD CPUs x86: fix: make PCI ECS for AMD CPUs hotplug capable x86: fix: do not run code in amd_bus.c on non-AMD CPUs
Diffstat (limited to 'arch/x86/pci/i386.c')
-rw-r--r--arch/x86/pci/i386.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 5807d1bc73f7..d765da913842 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -31,8 +31,11 @@
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/bootmem.h>
+#include <linux/acpi.h>
#include <asm/pat.h>
+#include <asm/hpet.h>
+#include <asm/io_apic.h>
#include "pci.h"
@@ -77,6 +80,77 @@ pcibios_align_resource(void *data, struct resource *res,
}
EXPORT_SYMBOL(pcibios_align_resource);
+static int check_res_with_valid(struct pci_dev *dev, struct resource *res)
+{
+ unsigned long base;
+ unsigned long size;
+ int i;
+
+ base = res->start;
+ size = (res->start == 0 && res->end == res->start) ? 0 :
+ (res->end - res->start + 1);
+
+ if (!base || !size)
+ return 0;
+
+#ifdef CONFIG_HPET_TIMER
+ /* for hpet */
+ if (base == hpet_address && (res->flags & IORESOURCE_MEM)) {
+ dev_info(&dev->dev, "BAR has HPET at %08lx-%08lx\n",
+ base, base + size - 1);
+ return 1;
+ }
+#endif
+
+#ifdef CONFIG_X86_IO_APIC
+ for (i = 0; i < nr_ioapics; i++) {
+ unsigned long ioapic_phys = mp_ioapics[i].mp_apicaddr;
+
+ if (base == ioapic_phys && (res->flags & IORESOURCE_MEM)) {
+ dev_info(&dev->dev, "BAR has ioapic at %08lx-%08lx\n",
+ base, base + size - 1);
+ return 1;
+ }
+ }
+#endif
+
+#ifdef CONFIG_PCI_MMCONFIG
+ for (i = 0; i < pci_mmcfg_config_num; i++) {
+ unsigned long addr;
+
+ addr = pci_mmcfg_config[i].address;
+ if (base == addr && (res->flags & IORESOURCE_MEM)) {
+ dev_info(&dev->dev, "BAR has MMCONFIG at %08lx-%08lx\n",
+ base, base + size - 1);
+ return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+static int check_platform(struct pci_dev *dev, struct resource *res)
+{
+ struct resource *root = NULL;
+
+ /*
+ * forcibly insert it into the
+ * resource tree
+ */
+ if (res->flags & IORESOURCE_MEM)
+ root = &iomem_resource;
+ else if (res->flags & IORESOURCE_IO)
+ root = &ioport_resource;
+
+ if (root && check_res_with_valid(dev, res)) {
+ insert_resource(root, res);
+
+ return 1;
+ }
+
+ return 0;
+}
/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
@@ -128,6 +202,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
pr = pci_find_parent_resource(dev, r);
if (!r->start || !pr ||
request_resource(pr, r) < 0) {
+ if (check_platform(dev, r))
+ continue;
dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx);
/*
@@ -171,6 +247,8 @@ static void __init pcibios_allocate_resources(int pass)
r->flags, disabled, pass);
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) {
+ if (check_platform(dev, r))
+ continue;
dev_err(&dev->dev, "BAR %d: can't "
"allocate resource\n", idx);
/* We'll assign a new address later */