diff options
Diffstat (limited to 'arch/x86/pci')
-rw-r--r-- | arch/x86/pci/Makefile | 22 | ||||
-rw-r--r-- | arch/x86/pci/Makefile_32 | 24 | ||||
-rw-r--r-- | arch/x86/pci/Makefile_64 | 17 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 21 | ||||
-rw-r--r-- | arch/x86/pci/amd_bus.c (renamed from arch/x86/pci/k8-bus_64.c) | 108 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/direct.c | 25 | ||||
-rw-r--r-- | arch/x86/pci/i386.c | 8 | ||||
-rw-r--r-- | arch/x86/pci/init.c | 4 | ||||
-rw-r--r-- | arch/x86/pci/irq.c | 143 | ||||
-rw-r--r-- | arch/x86/pci/legacy.c | 16 | ||||
-rw-r--r-- | arch/x86/pci/mmconfig-shared.c | 2 | ||||
-rw-r--r-- | arch/x86/pci/mp_bus_to_node.c | 23 | ||||
-rw-r--r-- | arch/x86/pci/numa.c | 33 | ||||
-rw-r--r-- | arch/x86/pci/pci.h | 15 | ||||
-rw-r--r-- | arch/x86/pci/visws.c | 28 |
16 files changed, 239 insertions, 254 deletions
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index c5c8e485fc44..e515e8db842a 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -1,5 +1,17 @@ | |||
1 | ifeq ($(CONFIG_X86_32),y) | 1 | obj-y := i386.o init.o |
2 | include ${srctree}/arch/x86/pci/Makefile_32 | 2 | |
3 | else | 3 | obj-$(CONFIG_PCI_BIOS) += pcbios.o |
4 | include ${srctree}/arch/x86/pci/Makefile_64 | 4 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o |
5 | endif | 5 | obj-$(CONFIG_PCI_DIRECT) += direct.o |
6 | obj-$(CONFIG_PCI_OLPC) += olpc.o | ||
7 | |||
8 | pci-y := fixup.o | ||
9 | pci-$(CONFIG_ACPI) += acpi.o | ||
10 | pci-y += legacy.o irq.o | ||
11 | |||
12 | pci-$(CONFIG_X86_VISWS) += visws.o | ||
13 | |||
14 | pci-$(CONFIG_X86_NUMAQ) += numa.o | ||
15 | |||
16 | obj-y += $(pci-y) common.o early.o | ||
17 | obj-y += amd_bus.o | ||
diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32 deleted file mode 100644 index 89ec35d00efd..000000000000 --- a/arch/x86/pci/Makefile_32 +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | obj-y := i386.o init.o | ||
2 | |||
3 | obj-$(CONFIG_PCI_BIOS) += pcbios.o | ||
4 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_32.o direct.o mmconfig-shared.o | ||
5 | obj-$(CONFIG_PCI_DIRECT) += direct.o | ||
6 | obj-$(CONFIG_PCI_OLPC) += olpc.o | ||
7 | |||
8 | pci-y := fixup.o | ||
9 | |||
10 | # Do not change the ordering here. There is a nasty init function | ||
11 | # ordering dependency which breaks when you move acpi.o below | ||
12 | # legacy/irq.o | ||
13 | pci-$(CONFIG_ACPI) += acpi.o | ||
14 | pci-y += legacy.o irq.o | ||
15 | |||
16 | # Careful: VISWS and NUMAQ overrule the pci-y above. The colons are | ||
17 | # therefor correct. This needs a proper fix by distangling the code. | ||
18 | pci-$(CONFIG_X86_VISWS) := visws.o fixup.o | ||
19 | pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o | ||
20 | |||
21 | # Necessary for NUMAQ as well | ||
22 | pci-$(CONFIG_NUMA) += mp_bus_to_node.o | ||
23 | |||
24 | obj-y += $(pci-y) common.o early.o | ||
diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64 deleted file mode 100644 index 8fbd19832cf6..000000000000 --- a/arch/x86/pci/Makefile_64 +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | # | ||
2 | # Makefile for X86_64 specific PCI routines | ||
3 | # | ||
4 | # Reuse the i386 PCI subsystem | ||
5 | # | ||
6 | EXTRA_CFLAGS += -Iarch/x86/pci | ||
7 | |||
8 | obj-y := i386.o | ||
9 | obj-$(CONFIG_PCI_DIRECT)+= direct.o | ||
10 | obj-y += fixup.o init.o | ||
11 | obj-$(CONFIG_ACPI) += acpi.o | ||
12 | obj-y += legacy.o irq.o common.o early.o | ||
13 | # mmconfig has a 64bit special | ||
14 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o | ||
15 | |||
16 | obj-y += k8-bus_64.o | ||
17 | |||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index d95de2f199cd..19af06927fbc 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -171,8 +171,11 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
171 | if (node != -1) | 171 | if (node != -1) |
172 | set_mp_bus_to_node(busnum, node); | 172 | set_mp_bus_to_node(busnum, node); |
173 | else | 173 | else |
174 | node = get_mp_bus_to_node(busnum); | ||
175 | #endif | 174 | #endif |
175 | node = get_mp_bus_to_node(busnum); | ||
176 | |||
177 | if (node != -1 && !node_online(node)) | ||
178 | node = -1; | ||
176 | 179 | ||
177 | /* Allocate per-root-bus (not per bus) arch-specific data. | 180 | /* Allocate per-root-bus (not per bus) arch-specific data. |
178 | * TODO: leak; this memory is never freed. | 181 | * TODO: leak; this memory is never freed. |
@@ -204,22 +207,23 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
204 | if (!bus) | 207 | if (!bus) |
205 | kfree(sd); | 208 | kfree(sd); |
206 | 209 | ||
210 | if (bus && node != -1) { | ||
207 | #ifdef CONFIG_ACPI_NUMA | 211 | #ifdef CONFIG_ACPI_NUMA |
208 | if (bus) { | 212 | if (pxm >= 0) |
209 | if (pxm >= 0) { | ||
210 | printk(KERN_DEBUG "bus %02x -> pxm %d -> node %d\n", | 213 | printk(KERN_DEBUG "bus %02x -> pxm %d -> node %d\n", |
211 | busnum, pxm, pxm_to_node(pxm)); | 214 | busnum, pxm, node); |
212 | } | 215 | #else |
213 | } | 216 | printk(KERN_DEBUG "bus %02x -> node %d\n", |
217 | busnum, node); | ||
214 | #endif | 218 | #endif |
219 | } | ||
215 | 220 | ||
216 | if (bus && (pci_probe & PCI_USE__CRS)) | 221 | if (bus && (pci_probe & PCI_USE__CRS)) |
217 | get_current_resources(device, busnum, domain, bus); | 222 | get_current_resources(device, busnum, domain, bus); |
218 | return bus; | 223 | return bus; |
219 | } | 224 | } |
220 | 225 | ||
221 | extern int pci_routeirq; | 226 | int __init pci_acpi_init(void) |
222 | static int __init pci_acpi_init(void) | ||
223 | { | 227 | { |
224 | struct pci_dev *dev = NULL; | 228 | struct pci_dev *dev = NULL; |
225 | 229 | ||
@@ -253,4 +257,3 @@ static int __init pci_acpi_init(void) | |||
253 | 257 | ||
254 | return 0; | 258 | return 0; |
255 | } | 259 | } |
256 | subsys_initcall(pci_acpi_init); | ||
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/amd_bus.c index 5c2799c20e47..dbf532369711 100644 --- a/arch/x86/pci/k8-bus_64.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -1,40 +1,25 @@ | |||
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> | ||
4 | #include "pci.h" | ||
5 | |||
6 | #ifdef CONFIG_X86_64 | ||
3 | #include <asm/pci-direct.h> | 7 | #include <asm/pci-direct.h> |
4 | #include <asm/mpspec.h> | 8 | #include <asm/mpspec.h> |
5 | #include <linux/cpumask.h> | 9 | #include <linux/cpumask.h> |
6 | #include <linux/topology.h> | 10 | #endif |
7 | 11 | ||
8 | /* | 12 | /* |
9 | * This discovers the pcibus <-> node mapping on AMD K8. | 13 | * This discovers the pcibus <-> node mapping on AMD K8. |
10 | * also get peer root bus resource for io,mmio | 14 | * also get peer root bus resource for io,mmio |
11 | */ | 15 | */ |
12 | 16 | ||
13 | |||
14 | /* | ||
15 | * sub bus (transparent) will use entres from 3 to store extra from root, | ||
16 | * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? | ||
17 | */ | ||
18 | #define RES_NUM 16 | ||
19 | struct pci_root_info { | ||
20 | char name[12]; | ||
21 | unsigned int res_num; | ||
22 | struct resource res[RES_NUM]; | ||
23 | int bus_min; | ||
24 | int bus_max; | ||
25 | int node; | ||
26 | int link; | ||
27 | }; | ||
28 | |||
29 | /* 4 at this time, it may become to 32 */ | ||
30 | #define PCI_ROOT_NR 4 | ||
31 | static int pci_root_num; | ||
32 | static struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
33 | |||
34 | #ifdef CONFIG_NUMA | 17 | #ifdef CONFIG_NUMA |
35 | 18 | ||
36 | #define BUS_NR 256 | 19 | #define BUS_NR 256 |
37 | 20 | ||
21 | #ifdef CONFIG_X86_64 | ||
22 | |||
38 | static int mp_bus_to_node[BUS_NR]; | 23 | static int mp_bus_to_node[BUS_NR]; |
39 | 24 | ||
40 | void set_mp_bus_to_node(int busnum, int node) | 25 | void set_mp_bus_to_node(int busnum, int node) |
@@ -61,7 +46,52 @@ int get_mp_bus_to_node(int busnum) | |||
61 | 46 | ||
62 | return node; | 47 | return node; |
63 | } | 48 | } |
64 | #endif | 49 | |
50 | #else /* CONFIG_X86_32 */ | ||
51 | |||
52 | static unsigned char mp_bus_to_node[BUS_NR]; | ||
53 | |||
54 | void set_mp_bus_to_node(int busnum, int node) | ||
55 | { | ||
56 | if (busnum >= 0 && busnum < BUS_NR) | ||
57 | mp_bus_to_node[busnum] = (unsigned char) node; | ||
58 | } | ||
59 | |||
60 | int get_mp_bus_to_node(int busnum) | ||
61 | { | ||
62 | int node; | ||
63 | |||
64 | if (busnum < 0 || busnum > (BUS_NR - 1)) | ||
65 | return 0; | ||
66 | node = mp_bus_to_node[busnum]; | ||
67 | return node; | ||
68 | } | ||
69 | |||
70 | #endif /* CONFIG_X86_32 */ | ||
71 | |||
72 | #endif /* CONFIG_NUMA */ | ||
73 | |||
74 | #ifdef CONFIG_X86_64 | ||
75 | |||
76 | /* | ||
77 | * sub bus (transparent) will use entres from 3 to store extra from root, | ||
78 | * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? | ||
79 | */ | ||
80 | #define RES_NUM 16 | ||
81 | struct pci_root_info { | ||
82 | char name[12]; | ||
83 | unsigned int res_num; | ||
84 | struct resource res[RES_NUM]; | ||
85 | int bus_min; | ||
86 | int bus_max; | ||
87 | int node; | ||
88 | int link; | ||
89 | }; | ||
90 | |||
91 | /* 4 at this time, it may become to 32 */ | ||
92 | #define PCI_ROOT_NR 4 | ||
93 | static int pci_root_num; | ||
94 | static struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
65 | 95 | ||
66 | void set_pci_bus_resources_arch_default(struct pci_bus *b) | 96 | void set_pci_bus_resources_arch_default(struct pci_bus *b) |
67 | { | 97 | { |
@@ -384,7 +414,7 @@ static int __init early_fill_mp_bus_info(void) | |||
384 | /* need to take out [0, TOM) for RAM*/ | 414 | /* need to take out [0, TOM) for RAM*/ |
385 | address = MSR_K8_TOP_MEM1; | 415 | address = MSR_K8_TOP_MEM1; |
386 | rdmsrl(address, val); | 416 | rdmsrl(address, val); |
387 | end = (val & 0xffffff8000000ULL); | 417 | end = (val & 0xffffff800000ULL); |
388 | printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20); | 418 | printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20); |
389 | if (end < (1ULL<<32)) | 419 | if (end < (1ULL<<32)) |
390 | update_range(range, 0, end - 1); | 420 | update_range(range, 0, end - 1); |
@@ -478,7 +508,7 @@ static int __init early_fill_mp_bus_info(void) | |||
478 | /* TOP_MEM2 */ | 508 | /* TOP_MEM2 */ |
479 | address = MSR_K8_TOP_MEM2; | 509 | address = MSR_K8_TOP_MEM2; |
480 | rdmsrl(address, val); | 510 | rdmsrl(address, val); |
481 | end = (val & 0xffffff8000000ULL); | 511 | end = (val & 0xffffff800000ULL); |
482 | printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20); | 512 | printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20); |
483 | update_range(range, 1ULL<<32, end - 1); | 513 | update_range(range, 1ULL<<32, end - 1); |
484 | } | 514 | } |
@@ -526,3 +556,31 @@ static int __init early_fill_mp_bus_info(void) | |||
526 | } | 556 | } |
527 | 557 | ||
528 | postcore_initcall(early_fill_mp_bus_info); | 558 | postcore_initcall(early_fill_mp_bus_info); |
559 | |||
560 | #endif | ||
561 | |||
562 | /* common 32/64 bit code */ | ||
563 | |||
564 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) | ||
565 | |||
566 | static void enable_pci_io_ecs_per_cpu(void *unused) | ||
567 | { | ||
568 | u64 reg; | ||
569 | rdmsrl(MSR_AMD64_NB_CFG, reg); | ||
570 | if (!(reg & ENABLE_CF8_EXT_CFG)) { | ||
571 | reg |= ENABLE_CF8_EXT_CFG; | ||
572 | wrmsrl(MSR_AMD64_NB_CFG, reg); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static int __init enable_pci_io_ecs(void) | ||
577 | { | ||
578 | /* assume all cpus from fam10h have IO ECS */ | ||
579 | if (boot_cpu_data.x86 < 0x10) | ||
580 | return 0; | ||
581 | on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1); | ||
582 | pci_probe |= PCI_HAS_IO_ECS; | ||
583 | return 0; | ||
584 | } | ||
585 | |||
586 | postcore_initcall(enable_pci_io_ecs); | ||
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 86aff81a0829..b67732bbb85a 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -404,7 +404,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
404 | 404 | ||
405 | extern u8 pci_cache_line_size; | 405 | extern u8 pci_cache_line_size; |
406 | 406 | ||
407 | static int __init pcibios_init(void) | 407 | int __init pcibios_init(void) |
408 | { | 408 | { |
409 | struct cpuinfo_x86 *c = &boot_cpu_data; | 409 | struct cpuinfo_x86 *c = &boot_cpu_data; |
410 | 410 | ||
@@ -431,8 +431,6 @@ static int __init pcibios_init(void) | |||
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
434 | subsys_initcall(pcibios_init); | ||
435 | |||
436 | char * __devinit pcibios_setup(char *str) | 434 | char * __devinit pcibios_setup(char *str) |
437 | { | 435 | { |
438 | if (!strcmp(str, "off")) { | 436 | if (!strcmp(str, "off")) { |
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 21d1e0e0d535..9915293500fb 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
@@ -8,18 +8,21 @@ | |||
8 | #include "pci.h" | 8 | #include "pci.h" |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Functions for accessing PCI configuration space with type 1 accesses | 11 | * Functions for accessing PCI base (first 256 bytes) and extended |
12 | * (4096 bytes per PCI function) configuration space with type 1 | ||
13 | * accesses. | ||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ | 16 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ |
15 | (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) | 17 | (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \ |
18 | | (devfn << 8) | (reg & 0xFC)) | ||
16 | 19 | ||
17 | static int pci_conf1_read(unsigned int seg, unsigned int bus, | 20 | static int pci_conf1_read(unsigned int seg, unsigned int bus, |
18 | unsigned int devfn, int reg, int len, u32 *value) | 21 | unsigned int devfn, int reg, int len, u32 *value) |
19 | { | 22 | { |
20 | unsigned long flags; | 23 | unsigned long flags; |
21 | 24 | ||
22 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { | 25 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) { |
23 | *value = -1; | 26 | *value = -1; |
24 | return -EINVAL; | 27 | return -EINVAL; |
25 | } | 28 | } |
@@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, | |||
50 | { | 53 | { |
51 | unsigned long flags; | 54 | unsigned long flags; |
52 | 55 | ||
53 | if ((bus > 255) || (devfn > 255) || (reg > 255)) | 56 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
54 | return -EINVAL; | 57 | return -EINVAL; |
55 | 58 | ||
56 | spin_lock_irqsave(&pci_config_lock, flags); | 59 | spin_lock_irqsave(&pci_config_lock, flags); |
@@ -260,10 +263,18 @@ void __init pci_direct_init(int type) | |||
260 | return; | 263 | return; |
261 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", | 264 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", |
262 | type); | 265 | type); |
263 | if (type == 1) | 266 | if (type == 1) { |
264 | raw_pci_ops = &pci_direct_conf1; | 267 | raw_pci_ops = &pci_direct_conf1; |
265 | else | 268 | if (raw_pci_ext_ops) |
266 | raw_pci_ops = &pci_direct_conf2; | 269 | return; |
270 | if (!(pci_probe & PCI_HAS_IO_ECS)) | ||
271 | return; | ||
272 | printk(KERN_INFO "PCI: Using configuration type 1 " | ||
273 | "for extended access\n"); | ||
274 | raw_pci_ext_ops = &pci_direct_conf1; | ||
275 | return; | ||
276 | } | ||
277 | raw_pci_ops = &pci_direct_conf2; | ||
267 | } | 278 | } |
268 | 279 | ||
269 | int __init pci_direct_probe(void) | 280 | int __init pci_direct_probe(void) |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 10fb308fded8..2aafb67dc5f1 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -299,9 +299,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | 300 | ||
301 | prot = pgprot_val(vma->vm_page_prot); | 301 | prot = pgprot_val(vma->vm_page_prot); |
302 | if (pat_wc_enabled && write_combine) | 302 | if (pat_enabled && write_combine) |
303 | prot |= _PAGE_CACHE_WC; | 303 | prot |= _PAGE_CACHE_WC; |
304 | else if (pat_wc_enabled || boot_cpu_data.x86 > 3) | 304 | else if (pat_enabled || boot_cpu_data.x86 > 3) |
305 | /* | 305 | /* |
306 | * ioremap() and ioremap_nocache() defaults to UC MINUS for now. | 306 | * ioremap() and ioremap_nocache() defaults to UC MINUS for now. |
307 | * To avoid attribute conflicts, request UC MINUS here | 307 | * To avoid attribute conflicts, request UC MINUS here |
@@ -334,7 +334,9 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
334 | flags = new_flags; | 334 | flags = new_flags; |
335 | } | 335 | } |
336 | 336 | ||
337 | if (vma->vm_pgoff <= max_pfn_mapped && | 337 | if (((vma->vm_pgoff < max_low_pfn_mapped) || |
338 | (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) && | ||
339 | vma->vm_pgoff < max_pfn_mapped)) && | ||
338 | ioremap_change_attr((unsigned long)__va(addr), len, flags)) { | 340 | ioremap_change_attr((unsigned long)__va(addr), len, flags)) { |
339 | free_memtype(addr, addr + len); | 341 | free_memtype(addr, addr + len); |
340 | return -EINVAL; | 342 | return -EINVAL; |
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index b821f4462d99..d6c950f81858 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | /* arch_initcall has too random ordering, so call the initializers | 5 | /* arch_initcall has too random ordering, so call the initializers |
6 | in the right sequence from here. */ | 6 | in the right sequence from here. */ |
7 | static __init int pci_access_init(void) | 7 | static __init int pci_arch_init(void) |
8 | { | 8 | { |
9 | #ifdef CONFIG_PCI_DIRECT | 9 | #ifdef CONFIG_PCI_DIRECT |
10 | int type = 0; | 10 | int type = 0; |
@@ -40,4 +40,4 @@ static __init int pci_access_init(void) | |||
40 | 40 | ||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | arch_initcall(pci_access_init); | 43 | arch_initcall(pci_arch_init); |
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index c422e10337be..6a06a2eb0597 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c | |||
@@ -102,8 +102,7 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) | |||
102 | return rt; | 102 | return rt; |
103 | printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); | 103 | printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); |
104 | } | 104 | } |
105 | for (addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); | 105 | for (addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { |
106 | addr += 16) { | ||
107 | rt = pirq_check_routing_table(addr); | 106 | rt = pirq_check_routing_table(addr); |
108 | if (rt) | 107 | if (rt) |
109 | return rt; | 108 | return rt; |
@@ -125,17 +124,14 @@ static void __init pirq_peer_trick(void) | |||
125 | struct irq_info *e; | 124 | struct irq_info *e; |
126 | 125 | ||
127 | memset(busmap, 0, sizeof(busmap)); | 126 | memset(busmap, 0, sizeof(busmap)); |
128 | for (i = 0; i < (rt->size - sizeof(struct irq_routing_table)) / | 127 | for (i = 0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { |
129 | sizeof(struct irq_info); i++) { | ||
130 | e = &rt->slots[i]; | 128 | e = &rt->slots[i]; |
131 | #ifdef DEBUG | 129 | #ifdef DEBUG |
132 | { | 130 | { |
133 | int j; | 131 | int j; |
134 | DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, | 132 | DBG(KERN_DEBUG "%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); |
135 | e->devfn/8, e->slot); | ||
136 | for (j = 0; j < 4; j++) | 133 | for (j = 0; j < 4; j++) |
137 | DBG(" %d:%02x/%04x", j, e->irq[j].link, | 134 | DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); |
138 | e->irq[j].bitmap); | ||
139 | DBG("\n"); | 135 | DBG("\n"); |
140 | } | 136 | } |
141 | #endif | 137 | #endif |
@@ -180,8 +176,7 @@ void eisa_set_level_irq(unsigned int irq) | |||
180 | * Common IRQ routing practice: nibbles in config space, | 176 | * Common IRQ routing practice: nibbles in config space, |
181 | * offset by some magic constant. | 177 | * offset by some magic constant. |
182 | */ | 178 | */ |
183 | static unsigned int | 179 | static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) |
184 | read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) | ||
185 | { | 180 | { |
186 | u8 x; | 181 | u8 x; |
187 | unsigned reg = offset + (nr >> 1); | 182 | unsigned reg = offset + (nr >> 1); |
@@ -208,18 +203,15 @@ static void write_config_nybble(struct pci_dev *router, unsigned offset, | |||
208 | */ | 203 | */ |
209 | static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | 204 | static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
210 | { | 205 | { |
211 | static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, | 206 | static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; |
212 | 11, 0, 12, 0, 14, 0, 15 }; | ||
213 | 207 | ||
214 | WARN_ON_ONCE(pirq > 16); | 208 | WARN_ON_ONCE(pirq > 16); |
215 | return irqmap[read_config_nybble(router, 0x48, pirq-1)]; | 209 | return irqmap[read_config_nybble(router, 0x48, pirq-1)]; |
216 | } | 210 | } |
217 | 211 | ||
218 | static int | 212 | static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
219 | pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
220 | { | 213 | { |
221 | static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, | 214 | static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; |
222 | 3, 9, 11, 0, 13, 15 }; | ||
223 | unsigned int val = irqmap[irq]; | 215 | unsigned int val = irqmap[irq]; |
224 | 216 | ||
225 | WARN_ON_ONCE(pirq > 16); | 217 | WARN_ON_ONCE(pirq > 16); |
@@ -242,8 +234,7 @@ static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
242 | return (x < 16) ? x : 0; | 234 | return (x < 16) ? x : 0; |
243 | } | 235 | } |
244 | 236 | ||
245 | static int | 237 | static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
246 | pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
247 | { | 238 | { |
248 | pci_write_config_byte(router, pirq, irq); | 239 | pci_write_config_byte(router, pirq, irq); |
249 | return 1; | 240 | return 1; |
@@ -259,8 +250,7 @@ static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
259 | return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); | 250 | return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); |
260 | } | 251 | } |
261 | 252 | ||
262 | static int | 253 | static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
263 | pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
264 | { | 254 | { |
265 | write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); | 255 | write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); |
266 | return 1; | 256 | return 1; |
@@ -271,8 +261,7 @@ pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | |||
271 | * but without the ugly irq number munging. | 261 | * but without the ugly irq number munging. |
272 | * However, for 82C586, nibble map is different . | 262 | * However, for 82C586, nibble map is different . |
273 | */ | 263 | */ |
274 | static int | 264 | static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
275 | pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | ||
276 | { | 265 | { |
277 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; | 266 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; |
278 | 267 | ||
@@ -280,8 +269,7 @@ pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
280 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); | 269 | return read_config_nybble(router, 0x55, pirqmap[pirq-1]); |
281 | } | 270 | } |
282 | 271 | ||
283 | static int | 272 | static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
284 | pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
285 | { | 273 | { |
286 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; | 274 | static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; |
287 | 275 | ||
@@ -303,8 +291,7 @@ static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
303 | return read_config_nybble(router, 0x43, pirqmap[pirq-1]); | 291 | return read_config_nybble(router, 0x43, pirqmap[pirq-1]); |
304 | } | 292 | } |
305 | 293 | ||
306 | static int | 294 | static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
307 | pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
308 | { | 295 | { |
309 | static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; | 296 | static const unsigned char pirqmap[4] = { 1, 0, 2, 3 }; |
310 | 297 | ||
@@ -322,8 +309,7 @@ static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
322 | return read_config_nybble(router, 0xb8, pirq >> 4); | 309 | return read_config_nybble(router, 0xb8, pirq >> 4); |
323 | } | 310 | } |
324 | 311 | ||
325 | static int | 312 | static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
326 | pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
327 | { | 313 | { |
328 | write_config_nybble(router, 0xb8, pirq >> 4, irq); | 314 | write_config_nybble(router, 0xb8, pirq >> 4, irq); |
329 | return 1; | 315 | return 1; |
@@ -339,8 +325,7 @@ static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
339 | return read_config_nybble(router, 0x5C, (pirq-1)^1); | 325 | return read_config_nybble(router, 0x5C, (pirq-1)^1); |
340 | } | 326 | } |
341 | 327 | ||
342 | static int | 328 | static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
343 | pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
344 | { | 329 | { |
345 | write_config_nybble(router, 0x5C, (pirq-1)^1, irq); | 330 | write_config_nybble(router, 0x5C, (pirq-1)^1, irq); |
346 | return 1; | 331 | return 1; |
@@ -423,8 +408,7 @@ static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
423 | return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); | 408 | return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); |
424 | } | 409 | } |
425 | 410 | ||
426 | static int | 411 | static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
427 | pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
428 | { | 412 | { |
429 | u8 x; | 413 | u8 x; |
430 | int reg; | 414 | int reg; |
@@ -458,8 +442,7 @@ static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | |||
458 | return read_config_nybble(router, 0x74, pirq-1); | 442 | return read_config_nybble(router, 0x74, pirq-1); |
459 | } | 443 | } |
460 | 444 | ||
461 | static int | 445 | static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
462 | pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
463 | { | 446 | { |
464 | WARN_ON_ONCE(pirq >= 9); | 447 | WARN_ON_ONCE(pirq >= 9); |
465 | if (pirq > 8) { | 448 | if (pirq > 8) { |
@@ -481,8 +464,7 @@ pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | |||
481 | * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1, | 464 | * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1, |
482 | * and 0x03 for SMBus. | 465 | * and 0x03 for SMBus. |
483 | */ | 466 | */ |
484 | static int | 467 | static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
485 | pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | ||
486 | { | 468 | { |
487 | outb(pirq, 0xc00); | 469 | outb(pirq, 0xc00); |
488 | return inb(0xc01) & 0xf; | 470 | return inb(0xc01) & 0xf; |
@@ -504,24 +486,20 @@ static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, | |||
504 | * offset 0x56 0-3 PIRQA 4-7 PIRQB | 486 | * offset 0x56 0-3 PIRQA 4-7 PIRQB |
505 | * offset 0x57 0-3 PIRQC 4-7 PIRQD | 487 | * offset 0x57 0-3 PIRQC 4-7 PIRQD |
506 | */ | 488 | */ |
507 | static int | 489 | static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq) |
508 | pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq) | ||
509 | { | 490 | { |
510 | u8 irq; | 491 | u8 irq; |
511 | irq = 0; | 492 | irq = 0; |
512 | if (pirq <= 4) | 493 | if (pirq <= 4) |
513 | irq = read_config_nybble(router, 0x56, pirq - 1); | 494 | irq = read_config_nybble(router, 0x56, pirq - 1); |
514 | printk(KERN_INFO | 495 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", |
515 | "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", | ||
516 | dev->vendor, dev->device, pirq, irq); | 496 | dev->vendor, dev->device, pirq, irq); |
517 | return irq; | 497 | return irq; |
518 | } | 498 | } |
519 | 499 | ||
520 | static int | 500 | static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
521 | pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
522 | { | 501 | { |
523 | printk(KERN_INFO | 502 | printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", |
524 | "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", | ||
525 | dev->vendor, dev->device, pirq, irq); | 503 | dev->vendor, dev->device, pirq, irq); |
526 | if (pirq <= 4) | 504 | if (pirq <= 4) |
527 | write_config_nybble(router, 0x56, pirq - 1, irq); | 505 | write_config_nybble(router, 0x56, pirq - 1, irq); |
@@ -550,8 +528,7 @@ static int pirq_pico_set(struct pci_dev *router, struct pci_dev *dev, int pirq, | |||
550 | 528 | ||
551 | #ifdef CONFIG_PCI_BIOS | 529 | #ifdef CONFIG_PCI_BIOS |
552 | 530 | ||
553 | static int | 531 | static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) |
554 | pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | ||
555 | { | 532 | { |
556 | struct pci_dev *bridge; | 533 | struct pci_dev *bridge; |
557 | int pin = pci_get_interrupt_pin(dev, &bridge); | 534 | int pin = pci_get_interrupt_pin(dev, &bridge); |
@@ -560,14 +537,11 @@ pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) | |||
560 | 537 | ||
561 | #endif | 538 | #endif |
562 | 539 | ||
563 | static __init int | 540 | static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
564 | intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
565 | { | 541 | { |
566 | static struct pci_device_id __initdata pirq_440gx[] = { | 542 | static struct pci_device_id __initdata pirq_440gx[] = { |
567 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | 543 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, |
568 | PCI_DEVICE_ID_INTEL_82443GX_0) }, | 544 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, |
569 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
570 | PCI_DEVICE_ID_INTEL_82443GX_2) }, | ||
571 | { }, | 545 | { }, |
572 | }; | 546 | }; |
573 | 547 | ||
@@ -677,8 +651,7 @@ static __init int via_router_probe(struct irq_router *r, | |||
677 | return 0; | 651 | return 0; |
678 | } | 652 | } |
679 | 653 | ||
680 | static __init int | 654 | static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
681 | vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
682 | { | 655 | { |
683 | switch (device) { | 656 | switch (device) { |
684 | case PCI_DEVICE_ID_VLSI_82C534: | 657 | case PCI_DEVICE_ID_VLSI_82C534: |
@@ -705,8 +678,7 @@ static __init int serverworks_router_probe(struct irq_router *r, | |||
705 | return 0; | 678 | return 0; |
706 | } | 679 | } |
707 | 680 | ||
708 | static __init int | 681 | static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
709 | sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
710 | { | 682 | { |
711 | if (device != PCI_DEVICE_ID_SI_503) | 683 | if (device != PCI_DEVICE_ID_SI_503) |
712 | return 0; | 684 | return 0; |
@@ -717,8 +689,7 @@ sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
717 | return 1; | 689 | return 1; |
718 | } | 690 | } |
719 | 691 | ||
720 | static __init int | 692 | static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
721 | cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
722 | { | 693 | { |
723 | switch (device) { | 694 | switch (device) { |
724 | case PCI_DEVICE_ID_CYRIX_5520: | 695 | case PCI_DEVICE_ID_CYRIX_5520: |
@@ -730,8 +701,7 @@ cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
730 | return 0; | 701 | return 0; |
731 | } | 702 | } |
732 | 703 | ||
733 | static __init int | 704 | static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
734 | opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
735 | { | 705 | { |
736 | switch (device) { | 706 | switch (device) { |
737 | case PCI_DEVICE_ID_OPTI_82C700: | 707 | case PCI_DEVICE_ID_OPTI_82C700: |
@@ -743,8 +713,7 @@ opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
743 | return 0; | 713 | return 0; |
744 | } | 714 | } |
745 | 715 | ||
746 | static __init int | 716 | static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
747 | ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
748 | { | 717 | { |
749 | switch (device) { | 718 | switch (device) { |
750 | case PCI_DEVICE_ID_ITE_IT8330G_0: | 719 | case PCI_DEVICE_ID_ITE_IT8330G_0: |
@@ -756,8 +725,7 @@ ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
756 | return 0; | 725 | return 0; |
757 | } | 726 | } |
758 | 727 | ||
759 | static __init int | 728 | static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
760 | ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
761 | { | 729 | { |
762 | switch (device) { | 730 | switch (device) { |
763 | case PCI_DEVICE_ID_AL_M1533: | 731 | case PCI_DEVICE_ID_AL_M1533: |
@@ -771,8 +739,7 @@ ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
771 | return 0; | 739 | return 0; |
772 | } | 740 | } |
773 | 741 | ||
774 | static __init int | 742 | static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
775 | amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
776 | { | 743 | { |
777 | switch (device) { | 744 | switch (device) { |
778 | case PCI_DEVICE_ID_AMD_VIPER_740B: | 745 | case PCI_DEVICE_ID_AMD_VIPER_740B: |
@@ -792,8 +759,7 @@ amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | |||
792 | return 1; | 759 | return 1; |
793 | } | 760 | } |
794 | 761 | ||
795 | static __init int | 762 | static __init int pico_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
796 | pico_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | ||
797 | { | 763 | { |
798 | switch (device) { | 764 | switch (device) { |
799 | case PCI_DEVICE_ID_PICOPOWER_PT86C523: | 765 | case PCI_DEVICE_ID_PICOPOWER_PT86C523: |
@@ -1030,9 +996,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) | |||
1030 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ | 996 | (!(pci_probe & PCI_USE_PIRQ_MASK) || \ |
1031 | ((1 << dev2->irq) & mask))) { | 997 | ((1 << dev2->irq) & mask))) { |
1032 | #ifndef CONFIG_PCI_MSI | 998 | #ifndef CONFIG_PCI_MSI |
1033 | printk(KERN_INFO | 999 | printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", |
1034 | "IRQ routing conflict for %s, have irq %d, want irq %d\n", | 1000 | pci_name(dev2), dev2->irq, irq); |
1035 | pci_name(dev2), dev2->irq, irq); | ||
1036 | #endif | 1001 | #endif |
1037 | continue; | 1002 | continue; |
1038 | } | 1003 | } |
@@ -1098,23 +1063,18 @@ static void __init pcibios_fixup_irqs(void) | |||
1098 | * parent slot, and pin number. The SMP code detects such bridged | 1063 | * parent slot, and pin number. The SMP code detects such bridged |
1099 | * busses itself so we should get into this branch reliably. | 1064 | * busses itself so we should get into this branch reliably. |
1100 | */ | 1065 | */ |
1101 | if (irq < 0 && dev->bus->parent) { | 1066 | if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ |
1102 | /* go back to the bridge */ | ||
1103 | struct pci_dev *bridge = dev->bus->self; | 1067 | struct pci_dev *bridge = dev->bus->self; |
1104 | 1068 | ||
1105 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1069 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
1106 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, | 1070 | irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, |
1107 | PCI_SLOT(bridge->devfn), | 1071 | PCI_SLOT(bridge->devfn), pin); |
1108 | pin); | ||
1109 | if (irq >= 0) | 1072 | if (irq >= 0) |
1110 | printk(KERN_WARNING | 1073 | printk(KERN_WARNING "PCI: using PPB %s[%c] to get irq %d\n", |
1111 | "PCI: using PPB %s[%c] to get irq %d\n", | 1074 | pci_name(bridge), 'A' + pin, irq); |
1112 | pci_name(bridge), | ||
1113 | 'A' + pin, irq); | ||
1114 | } | 1075 | } |
1115 | if (irq >= 0) { | 1076 | if (irq >= 0) { |
1116 | printk(KERN_INFO | 1077 | printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", |
1117 | "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | ||
1118 | pci_name(dev), 'A' + pin, irq); | 1078 | pci_name(dev), 'A' + pin, irq); |
1119 | dev->irq = irq; | 1079 | dev->irq = irq; |
1120 | } | 1080 | } |
@@ -1180,7 +1140,7 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = { | |||
1180 | { } | 1140 | { } |
1181 | }; | 1141 | }; |
1182 | 1142 | ||
1183 | static int __init pcibios_irq_init(void) | 1143 | int __init pcibios_irq_init(void) |
1184 | { | 1144 | { |
1185 | DBG(KERN_DEBUG "PCI: IRQ init\n"); | 1145 | DBG(KERN_DEBUG "PCI: IRQ init\n"); |
1186 | 1146 | ||
@@ -1218,9 +1178,6 @@ static int __init pcibios_irq_init(void) | |||
1218 | return 0; | 1178 | return 0; |
1219 | } | 1179 | } |
1220 | 1180 | ||
1221 | subsys_initcall(pcibios_irq_init); | ||
1222 | |||
1223 | |||
1224 | static void pirq_penalize_isa_irq(int irq, int active) | 1181 | static void pirq_penalize_isa_irq(int irq, int active) |
1225 | { | 1182 | { |
1226 | /* | 1183 | /* |
@@ -1259,19 +1216,15 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1259 | if (io_apic_assign_pci_irqs) { | 1216 | if (io_apic_assign_pci_irqs) { |
1260 | int irq; | 1217 | int irq; |
1261 | 1218 | ||
1262 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, | 1219 | irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); |
1263 | PCI_SLOT(dev->devfn), pin); | ||
1264 | /* | 1220 | /* |
1265 | * Busses behind bridges are typically not | 1221 | * Busses behind bridges are typically not listed in the MP-table. |
1266 | * listed in the MP-table. In this case we have | 1222 | * In this case we have to look up the IRQ based on the parent bus, |
1267 | * to look up the IRQ based on the parent bus, | 1223 | * parent slot, and pin number. The SMP code detects such bridged |
1268 | * parent slot, and pin number. The SMP code | 1224 | * busses itself so we should get into this branch reliably. |
1269 | * detects such bridged busses itself so we | ||
1270 | * should get into this branch reliably. | ||
1271 | */ | 1225 | */ |
1272 | temp_dev = dev; | 1226 | temp_dev = dev; |
1273 | while (irq < 0 && dev->bus->parent) { | 1227 | while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ |
1274 | /* go back to the bridge */ | ||
1275 | struct pci_dev *bridge = dev->bus->self; | 1228 | struct pci_dev *bridge = dev->bus->self; |
1276 | 1229 | ||
1277 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; | 1230 | pin = (pin + PCI_SLOT(dev->devfn)) % 4; |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index a67921ce60af..132876cc6fca 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -55,4 +55,18 @@ static int __init pci_legacy_init(void) | |||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | subsys_initcall(pci_legacy_init); | 58 | int __init pci_subsys_init(void) |
59 | { | ||
60 | #ifdef CONFIG_ACPI | ||
61 | pci_acpi_init(); | ||
62 | #endif | ||
63 | pci_legacy_init(); | ||
64 | pcibios_irq_init(); | ||
65 | #ifdef CONFIG_X86_NUMAQ | ||
66 | pci_numa_init(); | ||
67 | #endif | ||
68 | pcibios_init(); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | subsys_initcall(pci_subsys_init); | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 0cfebecf2a8f..23faaa890ffc 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -374,7 +374,7 @@ reject: | |||
374 | 374 | ||
375 | static int __initdata known_bridge; | 375 | static int __initdata known_bridge; |
376 | 376 | ||
377 | void __init __pci_mmcfg_init(int early) | 377 | static void __init __pci_mmcfg_init(int early) |
378 | { | 378 | { |
379 | /* MMCONFIG disabled */ | 379 | /* MMCONFIG disabled */ |
380 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 380 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
diff --git a/arch/x86/pci/mp_bus_to_node.c b/arch/x86/pci/mp_bus_to_node.c deleted file mode 100644 index 022943999b84..000000000000 --- a/arch/x86/pci/mp_bus_to_node.c +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | #include <linux/pci.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/topology.h> | ||
4 | |||
5 | #define BUS_NR 256 | ||
6 | |||
7 | static unsigned char mp_bus_to_node[BUS_NR]; | ||
8 | |||
9 | void set_mp_bus_to_node(int busnum, int node) | ||
10 | { | ||
11 | if (busnum >= 0 && busnum < BUS_NR) | ||
12 | mp_bus_to_node[busnum] = (unsigned char) node; | ||
13 | } | ||
14 | |||
15 | int get_mp_bus_to_node(int busnum) | ||
16 | { | ||
17 | int node; | ||
18 | |||
19 | if (busnum < 0 || busnum > (BUS_NR - 1)) | ||
20 | return 0; | ||
21 | node = mp_bus_to_node[busnum]; | ||
22 | return node; | ||
23 | } | ||
diff --git a/arch/x86/pci/numa.c b/arch/x86/pci/numa.c index d9afbae5092b..8b5ca1966731 100644 --- a/arch/x86/pci/numa.c +++ b/arch/x86/pci/numa.c | |||
@@ -6,45 +6,21 @@ | |||
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/nodemask.h> | 7 | #include <linux/nodemask.h> |
8 | #include <mach_apic.h> | 8 | #include <mach_apic.h> |
9 | #include <asm/mpspec.h> | ||
9 | #include "pci.h" | 10 | #include "pci.h" |
10 | 11 | ||
11 | #define XQUAD_PORTIO_BASE 0xfe400000 | 12 | #define XQUAD_PORTIO_BASE 0xfe400000 |
12 | #define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ | 13 | #define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */ |
13 | 14 | ||
14 | int mp_bus_id_to_node[MAX_MP_BUSSES]; | ||
15 | #define BUS2QUAD(global) (mp_bus_id_to_node[global]) | 15 | #define BUS2QUAD(global) (mp_bus_id_to_node[global]) |
16 | 16 | ||
17 | int mp_bus_id_to_local[MAX_MP_BUSSES]; | ||
18 | #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) | 17 | #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) |
19 | 18 | ||
20 | void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, | ||
21 | struct mpc_config_translation *translation) | ||
22 | { | ||
23 | int quad = translation->trans_quad; | ||
24 | int local = translation->trans_local; | ||
25 | |||
26 | mp_bus_id_to_node[m->mpc_busid] = quad; | ||
27 | mp_bus_id_to_local[m->mpc_busid] = local; | ||
28 | printk(KERN_INFO "Bus #%d is %s (node %d)\n", | ||
29 | m->mpc_busid, name, quad); | ||
30 | } | ||
31 | |||
32 | int quad_local_to_mp_bus_id [NR_CPUS/4][4]; | ||
33 | #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) | 19 | #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) |
34 | void mpc_oem_pci_bus(struct mpc_config_bus *m, | ||
35 | struct mpc_config_translation *translation) | ||
36 | { | ||
37 | int quad = translation->trans_quad; | ||
38 | int local = translation->trans_local; | ||
39 | |||
40 | quad_local_to_mp_bus_id[quad][local] = m->mpc_busid; | ||
41 | } | ||
42 | 20 | ||
43 | /* Where the IO area was mapped on multiquad, always 0 otherwise */ | 21 | /* Where the IO area was mapped on multiquad, always 0 otherwise */ |
44 | void *xquad_portio; | 22 | void *xquad_portio; |
45 | #ifdef CONFIG_X86_NUMAQ | ||
46 | EXPORT_SYMBOL(xquad_portio); | 23 | EXPORT_SYMBOL(xquad_portio); |
47 | #endif | ||
48 | 24 | ||
49 | #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port) | 25 | #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port) |
50 | 26 | ||
@@ -175,10 +151,13 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) | |||
175 | } | 151 | } |
176 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); | 152 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); |
177 | 153 | ||
178 | static int __init pci_numa_init(void) | 154 | int __init pci_numa_init(void) |
179 | { | 155 | { |
180 | int quad; | 156 | int quad; |
181 | 157 | ||
158 | if (!found_numaq) | ||
159 | return 0; | ||
160 | |||
182 | raw_pci_ops = &pci_direct_conf1_mq; | 161 | raw_pci_ops = &pci_direct_conf1_mq; |
183 | 162 | ||
184 | if (pcibios_scanned++) | 163 | if (pcibios_scanned++) |
@@ -197,5 +176,3 @@ static int __init pci_numa_init(void) | |||
197 | } | 176 | } |
198 | return 0; | 177 | return 0; |
199 | } | 178 | } |
200 | |||
201 | subsys_initcall(pci_numa_init); | ||
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 291dafec07b7..3e25deb821ac 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h | |||
@@ -27,7 +27,8 @@ | |||
27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 | 27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 |
28 | #define PCI_USE__CRS 0x10000 | 28 | #define PCI_USE__CRS 0x10000 |
29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 | 29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 |
30 | #define PCI_NOASSIGN_ROMS 0x40000 | 30 | #define PCI_HAS_IO_ECS 0x40000 |
31 | #define PCI_NOASSIGN_ROMS 0x80000 | ||
31 | 32 | ||
32 | extern unsigned int pci_probe; | 33 | extern unsigned int pci_probe; |
33 | extern unsigned long pirq_table_addr; | 34 | extern unsigned long pirq_table_addr; |
@@ -39,9 +40,6 @@ enum pci_bf_sort_state { | |||
39 | pci_dmi_bf, | 40 | pci_dmi_bf, |
40 | }; | 41 | }; |
41 | 42 | ||
42 | extern void __init dmi_check_pciprobe(void); | ||
43 | extern void __init dmi_check_skip_isa_align(void); | ||
44 | |||
45 | /* pci-i386.c */ | 43 | /* pci-i386.c */ |
46 | 44 | ||
47 | extern unsigned int pcibios_max_latency; | 45 | extern unsigned int pcibios_max_latency; |
@@ -99,10 +97,19 @@ extern struct pci_raw_ops *raw_pci_ext_ops; | |||
99 | 97 | ||
100 | extern struct pci_raw_ops pci_direct_conf1; | 98 | extern struct pci_raw_ops pci_direct_conf1; |
101 | 99 | ||
100 | /* arch_initcall level */ | ||
102 | extern int pci_direct_probe(void); | 101 | extern int pci_direct_probe(void); |
103 | extern void pci_direct_init(int type); | 102 | extern void pci_direct_init(int type); |
104 | extern void pci_pcbios_init(void); | 103 | extern void pci_pcbios_init(void); |
105 | extern int pci_olpc_init(void); | 104 | extern int pci_olpc_init(void); |
105 | extern void __init dmi_check_pciprobe(void); | ||
106 | extern void __init dmi_check_skip_isa_align(void); | ||
107 | |||
108 | /* some common used subsys_initcalls */ | ||
109 | extern int __init pci_acpi_init(void); | ||
110 | extern int __init pcibios_irq_init(void); | ||
111 | extern int __init pci_numa_init(void); | ||
112 | extern int __init pcibios_init(void); | ||
106 | 113 | ||
107 | /* pci-mmconfig.c */ | 114 | /* pci-mmconfig.c */ |
108 | 115 | ||
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index c2df4e97eed6..1a7bed492bb1 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
@@ -8,18 +8,19 @@ | |||
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | 10 | ||
11 | #include "cobalt.h" | 11 | #include <asm/setup.h> |
12 | #include "lithium.h" | 12 | #include <asm/visws/cobalt.h> |
13 | #include <asm/visws/lithium.h> | ||
13 | 14 | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
15 | 16 | ||
16 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } | 17 | static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } |
17 | static void pci_visws_disable_irq(struct pci_dev *dev) { } | 18 | static void pci_visws_disable_irq(struct pci_dev *dev) { } |
18 | 19 | ||
19 | int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; | 20 | /* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */ |
20 | void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; | 21 | /* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */ |
21 | 22 | ||
22 | void __init pcibios_penalize_isa_irq(int irq, int active) {} | 23 | /* void __init pcibios_penalize_isa_irq(int irq, int active) {} */ |
23 | 24 | ||
24 | 25 | ||
25 | unsigned int pci_bus0, pci_bus1; | 26 | unsigned int pci_bus0, pci_bus1; |
@@ -85,7 +86,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
85 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 86 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
86 | } | 87 | } |
87 | 88 | ||
88 | static int __init pcibios_init(void) | 89 | static int __init pci_visws_init(void) |
89 | { | 90 | { |
90 | /* The VISWS supports configuration access type 1 only */ | 91 | /* The VISWS supports configuration access type 1 only */ |
91 | pci_probe = (pci_probe | PCI_PROBE_CONF1) & | 92 | pci_probe = (pci_probe | PCI_PROBE_CONF1) & |
@@ -105,4 +106,17 @@ static int __init pcibios_init(void) | |||
105 | return 0; | 106 | return 0; |
106 | } | 107 | } |
107 | 108 | ||
108 | subsys_initcall(pcibios_init); | 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); | ||