diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /arch/x86/pci | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'arch/x86/pci')
-rw-r--r-- | arch/x86/pci/Makefile | 12 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 5 | ||||
-rw-r--r-- | arch/x86/pci/amd_bus.c | 52 | ||||
-rw-r--r-- | arch/x86/pci/early.c | 16 | ||||
-rw-r--r-- | arch/x86/pci/fixup.c | 31 | ||||
-rw-r--r-- | arch/x86/pci/i386.c | 27 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 176 | ||||
-rw-r--r-- | arch/x86/pci/legacy.c | 11 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 79 | ||||
-rw-r--r-- | arch/x86/pci/numaq_32.c (renamed from arch/x86/pci/numa.c) | 9 | ||||
-rw-r--r-- | arch/x86/pci/pci.h | 3 | ||||
-rw-r--r-- | arch/x86/pci/visws.c | 23 |
12 files changed, 268 insertions, 176 deletions
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index e515e8db842a..d49202e740ea 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -5,13 +5,13 @@ obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o | |||
5 | obj-$(CONFIG_PCI_DIRECT) += direct.o | 5 | obj-$(CONFIG_PCI_DIRECT) += direct.o |
6 | obj-$(CONFIG_PCI_OLPC) += olpc.o | 6 | obj-$(CONFIG_PCI_OLPC) += olpc.o |
7 | 7 | ||
8 | pci-y := fixup.o | 8 | obj-y += fixup.o |
9 | pci-$(CONFIG_ACPI) += acpi.o | 9 | obj-$(CONFIG_ACPI) += acpi.o |
10 | pci-y += legacy.o irq.o | 10 | obj-y += legacy.o irq.o |
11 | 11 | ||
12 | pci-$(CONFIG_X86_VISWS) += visws.o | 12 | obj-$(CONFIG_X86_VISWS) += visws.o |
13 | 13 | ||
14 | pci-$(CONFIG_X86_NUMAQ) += numa.o | 14 | obj-$(CONFIG_X86_NUMAQ) += numaq_32.o |
15 | 15 | ||
16 | obj-y += $(pci-y) common.o early.o | 16 | obj-y += common.o early.o |
17 | obj-y += amd_bus.o | 17 | obj-y += amd_bus.o |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 19af06927fbc..1d88d2b39771 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -250,10 +250,5 @@ int __init pci_acpi_init(void) | |||
250 | acpi_pci_irq_enable(dev); | 250 | acpi_pci_irq_enable(dev); |
251 | } | 251 | } |
252 | 252 | ||
253 | #ifdef CONFIG_X86_IO_APIC | ||
254 | if (acpi_ioapic) | ||
255 | print_IO_APIC(); | ||
256 | #endif | ||
257 | |||
258 | return 0; | 253 | return 0; |
259 | } | 254 | } |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index dbf532369711..22e057665e55 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
3 | #include <linux/topology.h> | 3 | #include <linux/topology.h> |
4 | #include <linux/cpu.h> | ||
4 | #include "pci.h" | 5 | #include "pci.h" |
5 | 6 | ||
6 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
@@ -555,15 +556,17 @@ static int __init early_fill_mp_bus_info(void) | |||
555 | return 0; | 556 | return 0; |
556 | } | 557 | } |
557 | 558 | ||
558 | postcore_initcall(early_fill_mp_bus_info); | 559 | #else /* !CONFIG_X86_64 */ |
559 | 560 | ||
560 | #endif | 561 | static int __init early_fill_mp_bus_info(void) { return 0; } |
562 | |||
563 | #endif /* !CONFIG_X86_64 */ | ||
561 | 564 | ||
562 | /* common 32/64 bit code */ | 565 | /* common 32/64 bit code */ |
563 | 566 | ||
564 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) | 567 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) |
565 | 568 | ||
566 | static void enable_pci_io_ecs_per_cpu(void *unused) | 569 | static void enable_pci_io_ecs(void *unused) |
567 | { | 570 | { |
568 | u64 reg; | 571 | u64 reg; |
569 | rdmsrl(MSR_AMD64_NB_CFG, reg); | 572 | rdmsrl(MSR_AMD64_NB_CFG, reg); |
@@ -573,14 +576,51 @@ static void enable_pci_io_ecs_per_cpu(void *unused) | |||
573 | } | 576 | } |
574 | } | 577 | } |
575 | 578 | ||
576 | static int __init enable_pci_io_ecs(void) | 579 | static int __cpuinit amd_cpu_notify(struct notifier_block *self, |
580 | unsigned long action, void *hcpu) | ||
577 | { | 581 | { |
582 | int cpu = (long)hcpu; | ||
583 | switch (action) { | ||
584 | case CPU_ONLINE: | ||
585 | case CPU_ONLINE_FROZEN: | ||
586 | smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0); | ||
587 | break; | ||
588 | default: | ||
589 | break; | ||
590 | } | ||
591 | return NOTIFY_OK; | ||
592 | } | ||
593 | |||
594 | static struct notifier_block __cpuinitdata amd_cpu_notifier = { | ||
595 | .notifier_call = amd_cpu_notify, | ||
596 | }; | ||
597 | |||
598 | static int __init pci_io_ecs_init(void) | ||
599 | { | ||
600 | int cpu; | ||
601 | |||
578 | /* assume all cpus from fam10h have IO ECS */ | 602 | /* assume all cpus from fam10h have IO ECS */ |
579 | if (boot_cpu_data.x86 < 0x10) | 603 | if (boot_cpu_data.x86 < 0x10) |
580 | return 0; | 604 | return 0; |
581 | on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1); | 605 | |
606 | register_cpu_notifier(&amd_cpu_notifier); | ||
607 | for_each_online_cpu(cpu) | ||
608 | amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE, | ||
609 | (void *)(long)cpu); | ||
582 | pci_probe |= PCI_HAS_IO_ECS; | 610 | pci_probe |= PCI_HAS_IO_ECS; |
611 | |||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int __init amd_postcore_init(void) | ||
616 | { | ||
617 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | ||
618 | return 0; | ||
619 | |||
620 | early_fill_mp_bus_info(); | ||
621 | pci_io_ecs_init(); | ||
622 | |||
583 | return 0; | 623 | return 0; |
584 | } | 624 | } |
585 | 625 | ||
586 | postcore_initcall(enable_pci_io_ecs); | 626 | postcore_initcall(amd_postcore_init); |
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index 858dbe3399f9..86631ccbc25a 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c | |||
@@ -7,15 +7,13 @@ | |||
7 | /* Direct PCI access. This is used for PCI accesses in early boot before | 7 | /* Direct PCI access. This is used for PCI accesses in early boot before |
8 | the PCI subsystem works. */ | 8 | the PCI subsystem works. */ |
9 | 9 | ||
10 | #define PDprintk(x...) | ||
11 | |||
12 | u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) | 10 | u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) |
13 | { | 11 | { |
14 | u32 v; | 12 | u32 v; |
15 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 13 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
16 | v = inl(0xcfc); | 14 | v = inl(0xcfc); |
17 | if (v != 0xffffffff) | 15 | if (v != 0xffffffff) |
18 | PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); | 16 | pr_debug("%x reading 4 from %x: %x\n", slot, offset, v); |
19 | return v; | 17 | return v; |
20 | } | 18 | } |
21 | 19 | ||
@@ -24,7 +22,7 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) | |||
24 | u8 v; | 22 | u8 v; |
25 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 23 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
26 | v = inb(0xcfc + (offset&3)); | 24 | v = inb(0xcfc + (offset&3)); |
27 | PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); | 25 | pr_debug("%x reading 1 from %x: %x\n", slot, offset, v); |
28 | return v; | 26 | return v; |
29 | } | 27 | } |
30 | 28 | ||
@@ -33,28 +31,28 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) | |||
33 | u16 v; | 31 | u16 v; |
34 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 32 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
35 | v = inw(0xcfc + (offset&2)); | 33 | v = inw(0xcfc + (offset&2)); |
36 | PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); | 34 | pr_debug("%x reading 2 from %x: %x\n", slot, offset, v); |
37 | return v; | 35 | return v; |
38 | } | 36 | } |
39 | 37 | ||
40 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, | 38 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, |
41 | u32 val) | 39 | u32 val) |
42 | { | 40 | { |
43 | PDprintk("%x writing to %x: %x\n", slot, offset, val); | 41 | pr_debug("%x writing to %x: %x\n", slot, offset, val); |
44 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 42 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
45 | outl(val, 0xcfc); | 43 | outl(val, 0xcfc); |
46 | } | 44 | } |
47 | 45 | ||
48 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) | 46 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) |
49 | { | 47 | { |
50 | PDprintk("%x writing to %x: %x\n", slot, offset, val); | 48 | pr_debug("%x writing to %x: %x\n", slot, offset, val); |
51 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 49 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
52 | outb(val, 0xcfc + (offset&3)); | 50 | outb(val, 0xcfc + (offset&3)); |
53 | } | 51 | } |
54 | 52 | ||
55 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) | 53 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) |
56 | { | 54 | { |
57 | PDprintk("%x writing to %x: %x\n", slot, offset, val); | 55 | pr_debug("%x writing to %x: %x\n", slot, offset, val); |
58 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 56 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
59 | outw(val, 0xcfc + (offset&2)); | 57 | outw(val, 0xcfc + (offset&2)); |
60 | } | 58 | } |
@@ -71,7 +69,7 @@ void early_dump_pci_device(u8 bus, u8 slot, u8 func) | |||
71 | int j; | 69 | int j; |
72 | u32 val; | 70 | u32 val; |
73 | 71 | ||
74 | printk("PCI: %02x:%02x:%02x", bus, slot, func); | 72 | printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func); |
75 | 73 | ||
76 | for (i = 0; i < 256; i += 4) { | 74 | for (i = 0; i < 256; i += 4) { |
77 | if (!(i & 0x0f)) | 75 | if (!(i & 0x0f)) |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index ff3a6a336342..3c27a809393b 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -23,7 +23,8 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
23 | pci_read_config_byte(d, reg++, &busno); | 23 | pci_read_config_byte(d, reg++, &busno); |
24 | pci_read_config_byte(d, reg++, &suba); | 24 | pci_read_config_byte(d, reg++, &suba); |
25 | pci_read_config_byte(d, reg++, &subb); | 25 | pci_read_config_byte(d, reg++, &subb); |
26 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); | 26 | dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, |
27 | suba, subb); | ||
27 | if (busno) | 28 | if (busno) |
28 | pci_scan_bus_with_sysdata(busno); /* Bus A */ | 29 | pci_scan_bus_with_sysdata(busno); /* Bus A */ |
29 | if (suba < subb) | 30 | if (suba < subb) |
@@ -510,3 +511,31 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, fam10h_pci_cfg_space_size); | |||
510 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size); | 511 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size); |
511 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size); | 512 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size); |
512 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size); | 513 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size); |
514 | |||
515 | /* | ||
516 | * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from | ||
517 | * confusing the PCI engine: | ||
518 | */ | ||
519 | static void sb600_disable_hpet_bar(struct pci_dev *dev) | ||
520 | { | ||
521 | u8 val; | ||
522 | |||
523 | /* | ||
524 | * The SB600 and SB700 both share the same device | ||
525 | * ID, but the PM register 0x55 does something different | ||
526 | * for the SB700, so make sure we are dealing with the | ||
527 | * SB600 before touching the bit: | ||
528 | */ | ||
529 | |||
530 | pci_read_config_byte(dev, 0x08, &val); | ||
531 | |||
532 | if (val < 0x2F) { | ||
533 | outb(0x55, 0xCD6); | ||
534 | val = inb(0xCD7); | ||
535 | |||
536 | /* Set bit 7 in PM register 0x55 */ | ||
537 | outb(0x55, 0xCD6); | ||
538 | outb(val | 0x80, 0xCD7); | ||
539 | } | ||
540 | } | ||
541 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x4385, sb600_disable_hpet_bar); | ||
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 2aafb67dc5f1..844df0cbbd3e 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
34 | 34 | ||
35 | #include <asm/pat.h> | 35 | #include <asm/pat.h> |
36 | #include <asm/e820.h> | ||
36 | 37 | ||
37 | #include "pci.h" | 38 | #include "pci.h" |
38 | 39 | ||
@@ -128,10 +129,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
128 | pr = pci_find_parent_resource(dev, r); | 129 | pr = pci_find_parent_resource(dev, r); |
129 | if (!r->start || !pr || | 130 | if (!r->start || !pr || |
130 | request_resource(pr, r) < 0) { | 131 | request_resource(pr, r) < 0) { |
131 | printk(KERN_ERR "PCI: Cannot allocate " | 132 | dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); |
132 | "resource region %d " | ||
133 | "of bridge %s\n", | ||
134 | idx, pci_name(dev)); | ||
135 | /* | 133 | /* |
136 | * Something is wrong with the region. | 134 | * Something is wrong with the region. |
137 | * Invalidate the resource to prevent | 135 | * Invalidate the resource to prevent |
@@ -166,15 +164,13 @@ static void __init pcibios_allocate_resources(int pass) | |||
166 | else | 164 | else |
167 | disabled = !(command & PCI_COMMAND_MEMORY); | 165 | disabled = !(command & PCI_COMMAND_MEMORY); |
168 | if (pass == disabled) { | 166 | if (pass == disabled) { |
169 | DBG("PCI: Resource %08lx-%08lx " | 167 | dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n", |
170 | "(f=%lx, d=%d, p=%d)\n", | 168 | (unsigned long long) r->start, |
171 | r->start, r->end, r->flags, disabled, pass); | 169 | (unsigned long long) r->end, |
170 | r->flags, disabled, pass); | ||
172 | pr = pci_find_parent_resource(dev, r); | 171 | pr = pci_find_parent_resource(dev, r); |
173 | if (!pr || request_resource(pr, r) < 0) { | 172 | if (!pr || request_resource(pr, r) < 0) { |
174 | printk(KERN_ERR "PCI: Cannot allocate " | 173 | dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); |
175 | "resource region %d " | ||
176 | "of device %s\n", | ||
177 | idx, pci_name(dev)); | ||
178 | /* We'll assign a new address later */ | 174 | /* We'll assign a new address later */ |
179 | r->end -= r->start; | 175 | r->end -= r->start; |
180 | r->start = 0; | 176 | r->start = 0; |
@@ -187,8 +183,7 @@ static void __init pcibios_allocate_resources(int pass) | |||
187 | /* Turn the ROM off, leave the resource region, | 183 | /* Turn the ROM off, leave the resource region, |
188 | * but keep it unregistered. */ | 184 | * but keep it unregistered. */ |
189 | u32 reg; | 185 | u32 reg; |
190 | DBG("PCI: Switching off ROM of %s\n", | 186 | dev_dbg(&dev->dev, "disabling ROM\n"); |
191 | pci_name(dev)); | ||
192 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 187 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
193 | pci_read_config_dword(dev, | 188 | pci_read_config_dword(dev, |
194 | dev->rom_base_reg, ®); | 189 | dev->rom_base_reg, ®); |
@@ -233,6 +228,8 @@ void __init pcibios_resource_survey(void) | |||
233 | pcibios_allocate_bus_resources(&pci_root_buses); | 228 | pcibios_allocate_bus_resources(&pci_root_buses); |
234 | pcibios_allocate_resources(0); | 229 | pcibios_allocate_resources(0); |
235 | pcibios_allocate_resources(1); | 230 | pcibios_allocate_resources(1); |
231 | |||
232 | e820_reserve_resources_late(); | ||
236 | } | 233 | } |
237 | 234 | ||
238 | /** | 235 | /** |
@@ -257,8 +254,7 @@ void pcibios_set_master(struct pci_dev *dev) | |||
257 | lat = pcibios_max_latency; | 254 | lat = pcibios_max_latency; |
258 | else | 255 | else |
259 | return; | 256 | return; |
260 | printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", | 257 | dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat); |
261 | pci_name(dev), lat); | ||
262 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); | 258 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); |
263 | } | 259 | } |
264 | 260 | ||
@@ -280,6 +276,7 @@ static void pci_track_mmap_page_range(struct vm_area_struct *vma) | |||
280 | static struct vm_operations_struct pci_mmap_ops = { | 276 | static struct vm_operations_struct pci_mmap_ops = { |
281 | .open = pci_track_mmap_page_range, | 277 | .open = pci_track_mmap_page_range, |
282 | .close = pci_unmap_page_range, | 278 | .close = pci_unmap_page_range, |
279 | .access = generic_access_phys, | ||
283 | }; | 280 | }; |
284 | 281 | ||
285 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 282 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 6a06a2eb0597..bf69dbe08bff 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -436,7 +436,7 @@ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
436 | { | 436 | { |
437 | WARN_ON_ONCE(pirq >= 9); | 437 | WARN_ON_ONCE(pirq >= 9); |
438 | if (pirq > 8) { | 438 | if (pirq > 8) { |
439 | printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); | 439 | dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); |
440 | return 0; | 440 | return 0; |
441 | } | 441 | } |
442 | return read_config_nybble(router, 0x74, pirq-1); | 442 | return read_config_nybble(router, 0x74, pirq-1); |
@@ -446,7 +446,7 @@ static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, | |||
446 | { | 446 | { |
447 | WARN_ON_ONCE(pirq >= 9); | 447 | WARN_ON_ONCE(pirq >= 9); |
448 | if (pirq > 8) { | 448 | if (pirq > 8) { |
449 | printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); | 449 | dev_info(&dev->dev, "VLSI router PIRQ escape (%d)\n", pirq); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | write_config_nybble(router, 0x74, pirq-1, irq); | 452 | write_config_nybble(router, 0x74, pirq-1, irq); |
@@ -492,15 +492,17 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq | |||
492 | irq = 0; | 492 | irq = 0; |
493 | if (pirq <= 4) | 493 | if (pirq <= 4) |
494 | irq = read_config_nybble(router, 0x56, pirq - 1); | 494 | irq = read_config_nybble(router, 0x56, pirq - 1); |
495 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", | 495 | dev_info(&dev->dev, |
496 | dev->vendor, dev->device, pirq, irq); | 496 | "AMD756: dev [%04x:%04x], router PIRQ %d get IRQ %d\n", |
497 | dev->vendor, dev->device, pirq, irq); | ||
497 | return irq; | 498 | return irq; |
498 | } | 499 | } |
499 | 500 | ||
500 | static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | 501 | static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
501 | { | 502 | { |
502 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", | 503 | dev_info(&dev->dev, |
503 | dev->vendor, dev->device, pirq, irq); | 504 | "AMD756: dev [%04x:%04x], router PIRQ %d set IRQ %d\n", |
505 | dev->vendor, dev->device, pirq, irq); | ||
504 | if (pirq <= 4) | 506 | if (pirq <= 4) |
505 | write_config_nybble(router, 0x56, pirq - 1, irq); | 507 | write_config_nybble(router, 0x56, pirq - 1, irq); |
506 | return 1; | 508 | return 1; |
@@ -593,6 +595,15 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
593 | r->set = pirq_piix_set; | 595 | r->set = pirq_piix_set; |
594 | return 1; | 596 | return 1; |
595 | } | 597 | } |
598 | |||
599 | if ((device >= PCI_DEVICE_ID_INTEL_PCH_LPC_MIN) && | ||
600 | (device <= PCI_DEVICE_ID_INTEL_PCH_LPC_MAX)) { | ||
601 | r->name = "PIIX/ICH"; | ||
602 | r->get = pirq_piix_get; | ||
603 | r->set = pirq_piix_set; | ||
604 | return 1; | ||
605 | } | ||
606 | |||
596 | return 0; | 607 | return 0; |
597 | } | 608 | } |
598 | 609 | ||
@@ -730,7 +741,6 @@ static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, | |||
730 | switch (device) { | 741 | switch (device) { |
731 | case PCI_DEVICE_ID_AL_M1533: | 742 | case PCI_DEVICE_ID_AL_M1533: |
732 | case PCI_DEVICE_ID_AL_M1563: | 743 | case PCI_DEVICE_ID_AL_M1563: |
733 | printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n"); | ||
734 | r->name = "ALI"; | 744 | r->name = "ALI"; |
735 | r->get = pirq_ali_get; | 745 | r->get = pirq_ali_get; |
736 | r->set = pirq_ali_set; | 746 | r->set = pirq_ali_set; |
@@ -820,7 +830,7 @@ static void __init pirq_find_router(struct irq_router *r) | |||
820 | r->get = NULL; | 830 | r->get = NULL; |
821 | r->set = NULL; | 831 | r->set = NULL; |
822 | 832 | ||
823 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", | 833 | DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n", |
824 | rt->rtr_vendor, rt->rtr_device); | 834 | rt->rtr_vendor, rt->rtr_device); |
825 | 835 | ||
826 | pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); | 836 | pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); |
@@ -840,11 +850,9 @@ static void __init pirq_find_router(struct irq_router *r) | |||
840 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) | 850 | h->probe(r, pirq_router_dev, pirq_router_dev->device)) |
841 | break; | 851 | break; |
842 | } | 852 | } |
843 | printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", | 853 | dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n", |
844 | pirq_router.name, | 854 | pirq_router.name, |
845 | pirq_router_dev->vendor, | 855 | pirq_router_dev->vendor, pirq_router_dev->device); |
846 | pirq_router_dev->device, | ||
847 | pci_name(pirq_router_dev)); | ||
848 | 856 | ||
849 | /* The device remains referenced for the kernel lifetime */ | 857 | /* The device remains referenced for the kernel lifetime */ |
850 | } | 858 | } |
@@ -877,7 +885,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
877 | /* Find IRQ pin */ | 885 | /* Find IRQ pin */ |
878 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 886 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
879 | if (!pin) { | 887 | if (!pin) { |
880 | DBG(KERN_DEBUG " -> no interrupt pin\n"); | 888 | dev_dbg(&dev->dev, "no interrupt pin\n"); |
881 | return 0; | 889 | return 0; |
882 | } | 890 | } |
883 | pin = pin - 1; | 891 | pin = pin - 1; |
@@ -887,20 +895,20 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
887 | if (!pirq_table) | 895 | if (!pirq_table) |
888 | return 0; | 896 | return 0; |
889 | 897 | ||
890 | DBG(KERN_DEBUG "IRQ for %s[%c]", pci_name(dev), 'A' + pin); | ||
891 | info = pirq_get_info(dev); | 898 | info = pirq_get_info(dev); |
892 | if (!info) { | 899 | if (!info) { |
893 | DBG(" -> not found in routing table\n" KERN_DEBUG); | 900 | dev_dbg(&dev->dev, "PCI INT %c not found in routing table\n", |
901 | 'A' + pin); | ||
894 | return 0; | 902 | return 0; |
895 | } | 903 | } |
896 | pirq = info->irq[pin].link; | 904 | pirq = info->irq[pin].link; |
897 | mask = info->irq[pin].bitmap; | 905 | mask = info->irq[pin].bitmap; |
898 | if (!pirq) { | 906 | if (!pirq) { |
899 | DBG(" -> not routed\n" KERN_DEBUG); | 907 | dev_dbg(&dev->dev, "PCI INT %c not routed\n", 'A' + pin); |
900 | return 0; | 908 | return 0; |
901 | } | 909 | } |
902 | DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, | 910 | dev_dbg(&dev->dev, "PCI INT %c -> PIRQ %02x, mask %04x, excl %04x", |
903 | pirq_table->exclusive_irqs); | 911 | 'A' + pin, pirq, mask, pirq_table->exclusive_irqs); |
904 | mask &= pcibios_irq_mask; | 912 | mask &= pcibios_irq_mask; |
905 | 913 | ||
906 | /* Work around broken HP Pavilion Notebooks which assign USB to | 914 | /* Work around broken HP Pavilion Notebooks which assign USB to |
@@ -930,10 +938,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
930 | if (pci_probe & PCI_USE_PIRQ_MASK) | 938 | if (pci_probe & PCI_USE_PIRQ_MASK) |
931 | newirq = 0; | 939 | newirq = 0; |
932 | else | 940 | else |
933 | printk("\n" KERN_WARNING | 941 | dev_warn(&dev->dev, "IRQ %d doesn't match PIRQ mask " |
934 | "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n" | 942 | "%#x; try pci=usepirqmask\n", newirq, mask); |
935 | KERN_DEBUG, newirq, | ||
936 | pci_name(dev)); | ||
937 | } | 943 | } |
938 | if (!newirq && assign) { | 944 | if (!newirq && assign) { |
939 | for (i = 0; i < 16; i++) { | 945 | for (i = 0; i < 16; i++) { |
@@ -944,39 +950,35 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
944 | newirq = i; | 950 | newirq = i; |
945 | } | 951 | } |
946 | } | 952 | } |
947 | DBG(" -> newirq=%d", newirq); | 953 | dev_dbg(&dev->dev, "PCI INT %c -> newirq %d", 'A' + pin, newirq); |
948 | 954 | ||
949 | /* Check if it is hardcoded */ | 955 | /* Check if it is hardcoded */ |
950 | if ((pirq & 0xf0) == 0xf0) { | 956 | if ((pirq & 0xf0) == 0xf0) { |
951 | irq = pirq & 0xf; | 957 | irq = pirq & 0xf; |
952 | DBG(" -> hardcoded IRQ %d\n", irq); | 958 | msg = "hardcoded"; |
953 | msg = "Hardcoded"; | ||
954 | } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ | 959 | } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \ |
955 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) { | 960 | ((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask))) { |
956 | DBG(" -> got IRQ %d\n", irq); | 961 | msg = "found"; |
957 | msg = "Found"; | ||
958 | eisa_set_level_irq(irq); | 962 | eisa_set_level_irq(irq); |
959 | } else if (newirq && r->set && | 963 | } else if (newirq && r->set && |
960 | (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { | 964 | (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { |
961 | DBG(" -> assigning IRQ %d", newirq); | ||
962 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { | 965 | if (r->set(pirq_router_dev, dev, pirq, newirq)) { |
963 | eisa_set_level_irq(newirq); | 966 | eisa_set_level_irq(newirq); |
964 | DBG(" ... OK\n"); | 967 | msg = "assigned"; |
965 | msg = "Assigned"; | ||
966 | irq = newirq; | 968 | irq = newirq; |
967 | } | 969 | } |
968 | } | 970 | } |
969 | 971 | ||
970 | if (!irq) { | 972 | if (!irq) { |
971 | DBG(" ... failed\n"); | ||
972 | if (newirq && mask == (1 << newirq)) { | 973 | if (newirq && mask == (1 << newirq)) { |
973 | msg = "Guessed"; | 974 | msg = "guessed"; |
974 | irq = newirq; | 975 | irq = newirq; |
975 | } else | 976 | } else { |
977 | dev_dbg(&dev->dev, "can't route interrupt\n"); | ||
976 | return 0; | 978 | return 0; |
979 | } | ||
977 | } | 980 | } |
978 | printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, | 981 | dev_info(&dev->dev, "%s PCI INT %c -> IRQ %d\n", msg, 'A' + pin, irq); |
979 | pci_name(dev)); | ||
980 | 982 | ||
981 | /* Update IRQ for all devices with the same pirq value */ | 983 | /* Update IRQ for all devices with the same pirq value */ |
982 | while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { | 984 | while ((dev2 = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) { |
@@ -996,17 +998,17 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
996 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ | 998 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ |
997 | ((1 << dev2->irq) & mask))) { | 999 | ((1 << dev2->irq) & mask))) { |
998 | #ifndef CONFIG_PCI_MSI | 1000 | #ifndef CONFIG_PCI_MSI |
999 | printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", | 1001 | dev_info(&dev2->dev, "IRQ routing conflict: " |
1000 | pci_name(dev2), dev2->irq, irq); | 1002 | "have IRQ %d, want IRQ %d\n", |
1003 | dev2->irq, irq); | ||
1001 | #endif | 1004 | #endif |
1002 | continue; | 1005 | continue; |
1003 | } | 1006 | } |
1004 | dev2->irq = irq; | 1007 | dev2->irq = irq; |
1005 | pirq_penalty[irq]++; | 1008 | pirq_penalty[irq]++; |
1006 | if (dev != dev2) | 1009 | if (dev != dev2) |
1007 | printk(KERN_INFO | 1010 | dev_info(&dev->dev, "sharing IRQ %d with %s\n", |
1008 | "PCI: Sharing IRQ %d with %s\n", | 1011 | irq, pci_name(dev2)); |
1009 | irq, pci_name(dev2)); | ||
1010 | } | 1012 | } |
1011 | } | 1013 | } |
1012 | return 1; | 1014 | return 1; |
@@ -1025,8 +1027,7 @@ static void __init pcibios_fixup_irqs(void) | |||
1025 | * already in use. | 1027 | * already in use. |
1026 | */ | 1028 | */ |
1027 | if (dev->irq >= 16) { | 1029 | if (dev->irq >= 16) { |
1028 | DBG(KERN_DEBUG "%s: ignoring bogus IRQ %d\n", | 1030 | dev_dbg(&dev->dev, "ignoring bogus IRQ %d\n", dev->irq); |
1029 | pci_name(dev), dev->irq); | ||
1030 | dev->irq = 0; | 1031 | dev->irq = 0; |
1031 | } | 1032 | } |
1032 | /* | 1033 | /* |
@@ -1049,35 +1050,44 @@ static void __init pcibios_fixup_irqs(void) | |||
1049 | if (io_apic_assign_pci_irqs) { | 1050 | if (io_apic_assign_pci_irqs) { |
1050 | int irq; | 1051 | int irq; |
1051 | 1052 | ||
1052 | if (pin) { | 1053 | if (!pin) |
1053 | /* | 1054 | continue; |
1054 | * interrupt pins are numbered starting | 1055 | |
1055 | * from 1 | 1056 | /* |
1056 | */ | 1057 | * interrupt pins are numbered starting from 1 |
1057 | pin--; | 1058 | */ |
1058 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1059 | pin--; |
1059 | PCI_SLOT(dev->devfn), pin); | 1060 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, |
1060 | /* | 1061 | PCI_SLOT(dev->devfn), pin); |
1061 | * Busses behind bridges are typically not listed in the MP-table. | 1062 | /* |
1062 | * In this case we have to look up the IRQ based on the parent bus, | 1063 | * Busses behind bridges are typically not listed in the |
1063 | * parent slot, and pin number. The SMP code detects such bridged | 1064 | * MP-table. In this case we have to look up the IRQ |
1064 | * busses itself so we should get into this branch reliably. | 1065 | * based on the parent bus, parent slot, and pin number. |
1065 | */ | 1066 | * The SMP code detects such bridged busses itself so we |
1066 | if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ | 1067 | * should get into this branch reliably. |
1067 | struct pci_dev *bridge = dev->bus->self; | 1068 | */ |
1068 | 1069 | if (irq < 0 && dev->bus->parent) { | |
1069 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1070 | /* go back to the bridge */ |
1070 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1071 | struct pci_dev *bridge = dev->bus->self; |
1071 | PCI_SLOT(bridge->devfn), pin); | 1072 | int bus; |
1072 | if (irq >= 0) | 1073 | |
1073 | printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n", | 1074 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
1074 | pci_name(bridge), 'A' + pin, irq); | 1075 | bus = bridge->bus->number; |
1075 | } | 1076 | irq = IO_APIC_get_PCI_irq_vector(bus, |
1076 | if (irq >= 0) { | 1077 | PCI_SLOT(bridge->devfn), pin); |
1077 | printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | 1078 | if (irq >= 0) |
1078 | pci_name(dev), 'A' + pin, irq); | 1079 | dev_warn(&dev->dev, |
1079 | dev->irq = irq; | 1080 | "using bridge %s INT %c to " |
1080 | } | 1081 | "get IRQ %d\n", |
1082 | pci_name(bridge), | ||
1083 | 'A' + pin, irq); | ||
1084 | } | ||
1085 | if (irq >= 0) { | ||
1086 | dev_info(&dev->dev, | ||
1087 | "PCI->APIC IRQ transform: INT %c " | ||
1088 | "-> IRQ %d\n", | ||
1089 | 'A' + pin, irq); | ||
1090 | dev->irq = irq; | ||
1081 | } | 1091 | } |
1082 | } | 1092 | } |
1083 | #endif | 1093 | #endif |
@@ -1231,25 +1241,24 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1231 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1241 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, |
1232 | PCI_SLOT(bridge->devfn), pin); | 1242 | PCI_SLOT(bridge->devfn), pin); |
1233 | if (irq >= 0) | 1243 | if (irq >= 0) |
1234 | printk(KERN_WARNING | 1244 | dev_warn(&dev->dev, "using bridge %s " |
1235 | "PCI: using PPB %s[%c] to get irq %d\n", | 1245 | "INT %c to get IRQ %d\n", |
1236 | pci_name(bridge), | 1246 | pci_name(bridge), 'A' + pin, |
1237 | 'A' + pin, irq); | 1247 | irq); |
1238 | dev = bridge; | 1248 | dev = bridge; |
1239 | } | 1249 | } |
1240 | dev = temp_dev; | 1250 | dev = temp_dev; |
1241 | if (irq >= 0) { | 1251 | if (irq >= 0) { |
1242 | printk(KERN_INFO | 1252 | dev_info(&dev->dev, "PCI->APIC IRQ transform: " |
1243 | "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | 1253 | "INT %c -> IRQ %d\n", 'A' + pin, irq); |
1244 | pci_name(dev), 'A' + pin, irq); | ||
1245 | dev->irq = irq; | 1254 | dev->irq = irq; |
1246 | return 0; | 1255 | return 0; |
1247 | } else | 1256 | } else |
1248 | msg = " Probably buggy MP table."; | 1257 | msg = "; probably buggy MP table"; |
1249 | } else if (pci_probe & PCI_BIOS_IRQ_SCAN) | 1258 | } else if (pci_probe & PCI_BIOS_IRQ_SCAN) |
1250 | msg = ""; | 1259 | msg = ""; |
1251 | else | 1260 | else |
1252 | msg = " Please try using pci=biosirq."; | 1261 | msg = "; please try using pci=biosirq"; |
1253 | 1262 | ||
1254 | /* | 1263 | /* |
1255 | * With IDE legacy devices the IRQ lookup failure is not | 1264 | * With IDE legacy devices the IRQ lookup failure is not |
@@ -1259,9 +1268,8 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1259 | !(dev->class & 0x5)) | 1268 | !(dev->class & 0x5)) |
1260 | return 0; | 1269 | return 0; |
1261 | 1270 | ||
1262 | printk(KERN_WARNING | 1271 | dev_warn(&dev->dev, "can't find IRQ for PCI INT %c%s\n", |
1263 | "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", | 1272 | 'A' + pin, msg); |
1264 | 'A' + pin, pci_name(dev), msg); | ||
1265 | } | 1273 | } |
1266 | return 0; | 1274 | return 0; |
1267 | } | 1275 | } |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index 132876cc6fca..b722dd481b39 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -14,7 +14,7 @@ static void __devinit pcibios_fixup_peer_bridges(void) | |||
14 | int n, devfn; | 14 | int n, devfn; |
15 | long node; | 15 | long node; |
16 | 16 | ||
17 | if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) | 17 | if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff) |
18 | return; | 18 | return; |
19 | DBG("PCI: Peer bridge fixup\n"); | 19 | DBG("PCI: Peer bridge fixup\n"); |
20 | 20 | ||
@@ -57,14 +57,17 @@ static int __init pci_legacy_init(void) | |||
57 | 57 | ||
58 | int __init pci_subsys_init(void) | 58 | int __init pci_subsys_init(void) |
59 | { | 59 | { |
60 | #ifdef CONFIG_X86_NUMAQ | ||
61 | pci_numaq_init(); | ||
62 | #endif | ||
60 | #ifdef CONFIG_ACPI | 63 | #ifdef CONFIG_ACPI |
61 | pci_acpi_init(); | 64 | pci_acpi_init(); |
62 | #endif | 65 | #endif |
66 | #ifdef CONFIG_X86_VISWS | ||
67 | pci_visws_init(); | ||
68 | #endif | ||
63 | pci_legacy_init(); | 69 | pci_legacy_init(); |
64 | pcibios_irq_init(); | 70 | pcibios_irq_init(); |
65 | #ifdef CONFIG_X86_NUMAQ | ||
66 | pci_numa_init(); | ||
67 | #endif | ||
68 | pcibios_init(); | 71 | pcibios_init(); |
69 | 72 | ||
70 | return 0; | 73 | return 0; |
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 23faaa890ffc..654a2234f8f3 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -209,7 +209,7 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
209 | return name != NULL; | 209 | return name != NULL; |
210 | } | 210 | } |
211 | 211 | ||
212 | static void __init pci_mmcfg_insert_resources(unsigned long resource_flags) | 212 | static void __init pci_mmcfg_insert_resources(void) |
213 | { | 213 | { |
214 | #define PCI_MMCFG_RESOURCE_NAME_LEN 19 | 214 | #define PCI_MMCFG_RESOURCE_NAME_LEN 19 |
215 | int i; | 215 | int i; |
@@ -233,7 +233,7 @@ static void __init pci_mmcfg_insert_resources(unsigned long resource_flags) | |||
233 | cfg->pci_segment); | 233 | cfg->pci_segment); |
234 | res->start = cfg->address; | 234 | res->start = cfg->address; |
235 | res->end = res->start + (num_buses << 20) - 1; | 235 | res->end = res->start + (num_buses << 20) - 1; |
236 | res->flags = IORESOURCE_MEM | resource_flags; | 236 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
237 | insert_resource(&iomem_resource, res); | 237 | insert_resource(&iomem_resource, res); |
238 | names += PCI_MMCFG_RESOURCE_NAME_LEN; | 238 | names += PCI_MMCFG_RESOURCE_NAME_LEN; |
239 | } | 239 | } |
@@ -293,7 +293,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl, | |||
293 | return AE_OK; | 293 | return AE_OK; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int __init is_acpi_reserved(unsigned long start, unsigned long end) | 296 | static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) |
297 | { | 297 | { |
298 | struct resource mcfg_res; | 298 | struct resource mcfg_res; |
299 | 299 | ||
@@ -310,6 +310,41 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end) | |||
310 | return mcfg_res.flags; | 310 | return mcfg_res.flags; |
311 | } | 311 | } |
312 | 312 | ||
313 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); | ||
314 | |||
315 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, | ||
316 | u64 addr, u64 size, int i, | ||
317 | typeof(pci_mmcfg_config[0]) *cfg, int with_e820) | ||
318 | { | ||
319 | u64 old_size = size; | ||
320 | int valid = 0; | ||
321 | |||
322 | while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) { | ||
323 | size >>= 1; | ||
324 | if (size < (16UL<<20)) | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | if (size >= (16UL<<20) || size == old_size) { | ||
329 | printk(KERN_NOTICE | ||
330 | "PCI: MCFG area at %Lx reserved in %s\n", | ||
331 | addr, with_e820?"E820":"ACPI motherboard resources"); | ||
332 | valid = 1; | ||
333 | |||
334 | if (old_size != size) { | ||
335 | /* update end_bus_number */ | ||
336 | cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1); | ||
337 | printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " | ||
338 | "segment %hu buses %u - %u\n", | ||
339 | i, (unsigned long)cfg->address, cfg->pci_segment, | ||
340 | (unsigned int)cfg->start_bus_number, | ||
341 | (unsigned int)cfg->end_bus_number); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | return valid; | ||
346 | } | ||
347 | |||
313 | static void __init pci_mmcfg_reject_broken(int early) | 348 | static void __init pci_mmcfg_reject_broken(int early) |
314 | { | 349 | { |
315 | typeof(pci_mmcfg_config[0]) *cfg; | 350 | typeof(pci_mmcfg_config[0]) *cfg; |
@@ -324,21 +359,22 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
324 | 359 | ||
325 | for (i = 0; i < pci_mmcfg_config_num; i++) { | 360 | for (i = 0; i < pci_mmcfg_config_num; i++) { |
326 | int valid = 0; | 361 | int valid = 0; |
327 | u32 size = (cfg->end_bus_number + 1) << 20; | 362 | u64 addr, size; |
363 | |||
328 | cfg = &pci_mmcfg_config[i]; | 364 | cfg = &pci_mmcfg_config[i]; |
365 | addr = cfg->start_bus_number; | ||
366 | addr <<= 20; | ||
367 | addr += cfg->address; | ||
368 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
369 | size <<= 20; | ||
329 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " | 370 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " |
330 | "segment %hu buses %u - %u\n", | 371 | "segment %hu buses %u - %u\n", |
331 | i, (unsigned long)cfg->address, cfg->pci_segment, | 372 | i, (unsigned long)cfg->address, cfg->pci_segment, |
332 | (unsigned int)cfg->start_bus_number, | 373 | (unsigned int)cfg->start_bus_number, |
333 | (unsigned int)cfg->end_bus_number); | 374 | (unsigned int)cfg->end_bus_number); |
334 | 375 | ||
335 | if (!early && | 376 | if (!early) |
336 | is_acpi_reserved(cfg->address, cfg->address + size - 1)) { | 377 | valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0); |
337 | printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved " | ||
338 | "in ACPI motherboard resources\n", | ||
339 | cfg->address); | ||
340 | valid = 1; | ||
341 | } | ||
342 | 378 | ||
343 | if (valid) | 379 | if (valid) |
344 | continue; | 380 | continue; |
@@ -347,16 +383,11 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
347 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" | 383 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" |
348 | " reserved in ACPI motherboard resources\n", | 384 | " reserved in ACPI motherboard resources\n", |
349 | cfg->address); | 385 | cfg->address); |
386 | |||
350 | /* Don't try to do this check unless configuration | 387 | /* Don't try to do this check unless configuration |
351 | type 1 is available. how about type 2 ?*/ | 388 | type 1 is available. how about type 2 ?*/ |
352 | if (raw_pci_ops && e820_all_mapped(cfg->address, | 389 | if (raw_pci_ops) |
353 | cfg->address + size - 1, | 390 | valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1); |
354 | E820_RESERVED)) { | ||
355 | printk(KERN_NOTICE | ||
356 | "PCI: MCFG area at %Lx reserved in E820\n", | ||
357 | cfg->address); | ||
358 | valid = 1; | ||
359 | } | ||
360 | 391 | ||
361 | if (!valid) | 392 | if (!valid) |
362 | goto reject; | 393 | goto reject; |
@@ -365,7 +396,7 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
365 | return; | 396 | return; |
366 | 397 | ||
367 | reject: | 398 | reject: |
368 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | 399 | printk(KERN_INFO "PCI: Not using MMCONFIG.\n"); |
369 | pci_mmcfg_arch_free(); | 400 | pci_mmcfg_arch_free(); |
370 | kfree(pci_mmcfg_config); | 401 | kfree(pci_mmcfg_config); |
371 | pci_mmcfg_config = NULL; | 402 | pci_mmcfg_config = NULL; |
@@ -403,11 +434,9 @@ static void __init __pci_mmcfg_init(int early) | |||
403 | (pci_mmcfg_config[0].address == 0)) | 434 | (pci_mmcfg_config[0].address == 0)) |
404 | return; | 435 | return; |
405 | 436 | ||
406 | if (pci_mmcfg_arch_init()) { | 437 | if (pci_mmcfg_arch_init()) |
407 | if (known_bridge) | ||
408 | pci_mmcfg_insert_resources(IORESOURCE_BUSY); | ||
409 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 438 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
410 | } else { | 439 | else { |
411 | /* | 440 | /* |
412 | * Signal not to attempt to insert mmcfg resources because | 441 | * Signal not to attempt to insert mmcfg resources because |
413 | * the architecture mmcfg setup could not initialize. | 442 | * the architecture mmcfg setup could not initialize. |
@@ -444,7 +473,7 @@ static int __init pci_mmcfg_late_insert_resources(void) | |||
444 | * marked so it won't cause request errors when __request_region is | 473 | * marked so it won't cause request errors when __request_region is |
445 | * called. | 474 | * called. |
446 | */ | 475 | */ |
447 | pci_mmcfg_insert_resources(0); | 476 | pci_mmcfg_insert_resources(); |
448 | 477 | ||
449 | return 0; | 478 | return 0; |
450 | } | 479 | } |
diff --git a/arch/x86/pci/numa.c b/arch/x86/pci/numaq_32.c index 8b5ca1966731..1177845d3186 100644 --- a/arch/x86/pci/numa.c +++ b/arch/x86/pci/numaq_32.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * numa.c - Low-level PCI access for NUMA-Q machines | 2 | * numaq_32.c - Low-level PCI access for NUMA-Q machines |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
@@ -131,13 +131,14 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
131 | u8 busno, suba, subb; | 131 | u8 busno, suba, subb; |
132 | int quad = BUS2QUAD(d->bus->number); | 132 | int quad = BUS2QUAD(d->bus->number); |
133 | 133 | ||
134 | printk("PCI: Searching for i450NX host bridges on %s\n", pci_name(d)); | 134 | dev_info(&d->dev, "searching for i450NX host bridges\n"); |
135 | reg = 0xd0; | 135 | reg = 0xd0; |
136 | for(pxb=0; pxb<2; pxb++) { | 136 | for(pxb=0; pxb<2; pxb++) { |
137 | pci_read_config_byte(d, reg++, &busno); | 137 | pci_read_config_byte(d, reg++, &busno); |
138 | pci_read_config_byte(d, reg++, &suba); | 138 | pci_read_config_byte(d, reg++, &suba); |
139 | pci_read_config_byte(d, reg++, &subb); | 139 | pci_read_config_byte(d, reg++, &subb); |
140 | DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb); | 140 | dev_dbg(&d->dev, "i450NX PXB %d: %02x/%02x/%02x\n", |
141 | pxb, busno, suba, subb); | ||
141 | if (busno) { | 142 | if (busno) { |
142 | /* Bus A */ | 143 | /* Bus A */ |
143 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); | 144 | pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno)); |
@@ -151,7 +152,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
151 | } | 152 | } |
152 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); | 153 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); |
153 | 154 | ||
154 | int __init pci_numa_init(void) | 155 | int __init pci_numaq_init(void) |
155 | { | 156 | { |
156 | int quad; | 157 | int quad; |
157 | 158 | ||
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 3e25deb821ac..15b9cf6be729 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h | |||
@@ -108,7 +108,8 @@ extern void __init dmi_check_skip_isa_align(void); | |||
108 | /* some common used subsys_initcalls */ | 108 | /* some common used subsys_initcalls */ |
109 | extern int __init pci_acpi_init(void); | 109 | extern int __init pci_acpi_init(void); |
110 | extern int __init pcibios_irq_init(void); | 110 | extern int __init pcibios_irq_init(void); |
111 | extern int __init pci_numa_init(void); | 111 | extern int __init pci_visws_init(void); |
112 | extern int __init pci_numaq_init(void); | ||
112 | extern int __init pcibios_init(void); | 113 | extern int __init pcibios_init(void); |
113 | 114 | ||
114 | /* pci-mmconfig.c */ | 115 | /* pci-mmconfig.c */ |
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index 1a7bed492bb1..42f4cb19faca 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
@@ -86,8 +86,14 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
86 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 86 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
87 | } | 87 | } |
88 | 88 | ||
89 | static int __init pci_visws_init(void) | 89 | int __init pci_visws_init(void) |
90 | { | 90 | { |
91 | if (!is_visws_box()) | ||
92 | return -1; | ||
93 | |||
94 | pcibios_enable_irq = &pci_visws_enable_irq; | ||
95 | pcibios_disable_irq = &pci_visws_disable_irq; | ||
96 | |||
91 | /* The VISWS supports configuration access type 1 only */ | 97 | /* The VISWS supports configuration access type 1 only */ |
92 | pci_probe = (pci_probe | PCI_PROBE_CONF1) & | 98 | pci_probe = (pci_probe | PCI_PROBE_CONF1) & |
93 | ~(PCI_PROBE_BIOS | PCI_PROBE_CONF2); | 99 | ~(PCI_PROBE_BIOS | PCI_PROBE_CONF2); |
@@ -105,18 +111,3 @@ static int __init pci_visws_init(void) | |||
105 | pcibios_resource_survey(); | 111 | pcibios_resource_survey(); |
106 | return 0; | 112 | return 0; |
107 | } | 113 | } |
108 | |||
109 | static __init int pci_subsys_init(void) | ||
110 | { | ||
111 | if (!is_visws_box()) | ||
112 | return -1; | ||
113 | |||
114 | pcibios_enable_irq = &pci_visws_enable_irq; | ||
115 | pcibios_disable_irq = &pci_visws_disable_irq; | ||
116 | |||
117 | pci_visws_init(); | ||
118 | pcibios_init(); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | subsys_initcall(pci_subsys_init); | ||