diff options
author | Tony Luck <tony.luck@intel.com> | 2005-06-29 18:21:41 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-06-29 18:21:41 -0400 |
commit | d18bfacff20f08aecf01bb971b110ca108eef3c7 (patch) | |
tree | 255f862839c593c796e609328575b611e3f56cf3 /arch | |
parent | a68db763af9b676590c3fe9ec3f17bf18015eb2f (diff) | |
parent | fd782a4a99d2d3e818b9465c427b10f7f027d7da (diff) |
Auto merge with /home/aegl/GIT/linus
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/irq.c | 7 | ||||
-rw-r--r-- | arch/arm/oprofile/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/oprofile/backtrace.c | 144 | ||||
-rw-r--r-- | arch/arm/oprofile/init.c | 2 | ||||
-rw-r--r-- | arch/arm/oprofile/op_arm_model.h | 2 | ||||
-rw-r--r-- | arch/i386/boot/tools/build.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 57 | ||||
-rw-r--r-- | arch/i386/pci/common.c | 8 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 51 | ||||
-rw-r--r-- | arch/i386/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/mmconfig.c | 39 | ||||
-rw-r--r-- | arch/i386/pci/numa.c | 2 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/acpi.c | 30 | ||||
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 134 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 38 | ||||
-rw-r--r-- | arch/ppc/kernel/pci.c | 21 | ||||
-rw-r--r-- | arch/ppc64/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/pci.c | 22 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 56 | ||||
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 68 |
22 files changed, 554 insertions, 142 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dcd8ef7..620f2ca94ed2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -361,6 +361,11 @@ config NO_IDLE_HZ | |||
361 | Alternatively, if you want dynamic tick automatically enabled | 361 | Alternatively, if you want dynamic tick automatically enabled |
362 | during boot, pass "dyntick=enable" via the kernel command string. | 362 | during boot, pass "dyntick=enable" via the kernel command string. |
363 | 363 | ||
364 | Please note that dynamic tick may affect the accuracy of | ||
365 | timekeeping on some platforms depending on the implementation. | ||
366 | Currently at least OMAP platform is known to have accurate | ||
367 | timekeeping with dynamic tick. | ||
368 | |||
364 | config ARCH_DISCONTIGMEM_ENABLE | 369 | config ARCH_DISCONTIGMEM_ENABLE |
365 | bool | 370 | bool |
366 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 371 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48f4399..cf9f46d88061 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
@@ -40,8 +40,11 @@ | |||
40 | * 04-Nov-2004 Ben Dooks | 40 | * 04-Nov-2004 Ben Dooks |
41 | * Fix standard IRQ wake for EINT0..4 and RTC | 41 | * Fix standard IRQ wake for EINT0..4 and RTC |
42 | * | 42 | * |
43 | * 22-Feb-2004 Ben Dooks | 43 | * 22-Feb-2005 Ben Dooks |
44 | * Fixed edge-triggering on ADC IRQ | 44 | * Fixed edge-triggering on ADC IRQ |
45 | * | ||
46 | * 28-Jun-2005 Ben Dooks | ||
47 | * Mark IRQ_LCD valid | ||
45 | */ | 48 | */ |
46 | 49 | ||
47 | #include <linux/init.h> | 50 | #include <linux/init.h> |
@@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { | |||
366 | #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) | 369 | #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) |
367 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) | 370 | #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) |
368 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) | 371 | #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) |
369 | #define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) | ||
370 | 372 | ||
371 | static inline void | 373 | static inline void |
372 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, | 374 | s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, |
@@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) | |||
716 | case IRQ_UART0: | 718 | case IRQ_UART0: |
717 | case IRQ_UART1: | 719 | case IRQ_UART1: |
718 | case IRQ_UART2: | 720 | case IRQ_UART2: |
719 | case IRQ_LCD: | ||
720 | case IRQ_ADCPARENT: | 721 | case IRQ_ADCPARENT: |
721 | set_irq_chip(irqno, &s3c_irq_level_chip); | 722 | set_irq_chip(irqno, &s3c_irq_level_chip); |
722 | set_irq_handler(irqno, do_level_IRQ); | 723 | set_irq_handler(irqno, do_level_IRQ); |
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9f2b28..8ffb523e6c77 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile | |||
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | |||
6 | oprofilefs.o oprofile_stats.o \ | 6 | oprofilefs.o oprofile_stats.o \ |
7 | timer_int.o ) | 7 | timer_int.o ) |
8 | 8 | ||
9 | oprofile-y := $(DRIVER_OBJS) init.o | 9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o |
10 | oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o | 10 | oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o |
11 | 11 | ||
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 000000000000..ec58d3e2eb8b --- /dev/null +++ b/arch/arm/oprofile/backtrace.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Arm specific backtracing code for oprofile | ||
3 | * | ||
4 | * Copyright 2005 Openedhand Ltd. | ||
5 | * | ||
6 | * Author: Richard Purdie <rpurdie@openedhand.com> | ||
7 | * | ||
8 | * Based on i386 oprofile backtrace code by John Levon, David Smith | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/oprofile.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <asm/ptrace.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | |||
22 | |||
23 | /* | ||
24 | * The registers we're interested in are at the end of the variable | ||
25 | * length saved register structure. The fp points at the end of this | ||
26 | * structure so the address of this struct is: | ||
27 | * (struct frame_tail *)(xxx->fp)-1 | ||
28 | */ | ||
29 | struct frame_tail { | ||
30 | struct frame_tail *fp; | ||
31 | unsigned long sp; | ||
32 | unsigned long lr; | ||
33 | } __attribute__((packed)); | ||
34 | |||
35 | |||
36 | #ifdef CONFIG_FRAME_POINTER | ||
37 | static struct frame_tail* kernel_backtrace(struct frame_tail *tail) | ||
38 | { | ||
39 | oprofile_add_trace(tail->lr); | ||
40 | |||
41 | /* frame pointers should strictly progress back up the stack | ||
42 | * (towards higher addresses) */ | ||
43 | if (tail >= tail->fp) | ||
44 | return NULL; | ||
45 | |||
46 | return tail->fp-1; | ||
47 | } | ||
48 | #endif | ||
49 | |||
50 | static struct frame_tail* user_backtrace(struct frame_tail *tail) | ||
51 | { | ||
52 | struct frame_tail buftail; | ||
53 | |||
54 | /* hardware pte might not be valid due to dirty/accessed bit emulation | ||
55 | * so we use copy_from_user and benefit from exception fixups */ | ||
56 | if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) | ||
57 | return NULL; | ||
58 | |||
59 | oprofile_add_trace(buftail.lr); | ||
60 | |||
61 | /* frame pointers should strictly progress back up the stack | ||
62 | * (towards higher addresses) */ | ||
63 | if (tail >= buftail.fp) | ||
64 | return NULL; | ||
65 | |||
66 | return buftail.fp-1; | ||
67 | } | ||
68 | |||
69 | /* Compare two addresses and see if they're on the same page */ | ||
70 | #define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ | ||
71 | == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) | ||
72 | |||
73 | /* check that the page(s) containing the frame tail are present */ | ||
74 | static int pages_present(struct frame_tail *tail) | ||
75 | { | ||
76 | struct mm_struct * mm = current->mm; | ||
77 | |||
78 | if (!check_user_page_readable(mm, (unsigned long)tail)) | ||
79 | return 0; | ||
80 | |||
81 | if (CMP_ADDR_EQUAL(tail, tail, 8)) | ||
82 | return 1; | ||
83 | |||
84 | if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) | ||
85 | return 0; | ||
86 | |||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * | | /\ Higher addresses | ||
92 | * | | | ||
93 | * --------------- stack base (address of current_thread_info) | ||
94 | * | thread info | | ||
95 | * . . | ||
96 | * | stack | | ||
97 | * --------------- saved regs->ARM_fp value if valid (frame_tail address) | ||
98 | * . . | ||
99 | * --------------- struct pt_regs stored on stack (struct pt_regs *) | ||
100 | * | | | ||
101 | * . . | ||
102 | * | | | ||
103 | * --------------- %esp | ||
104 | * | | | ||
105 | * | | \/ Lower addresses | ||
106 | * | ||
107 | * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values | ||
108 | */ | ||
109 | static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) | ||
110 | { | ||
111 | unsigned long tailaddr = (unsigned long)tail; | ||
112 | unsigned long stack = (unsigned long)regs; | ||
113 | unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; | ||
114 | |||
115 | return (tailaddr > stack) && (tailaddr < stack_base); | ||
116 | } | ||
117 | |||
118 | void arm_backtrace(struct pt_regs const *regs, unsigned int depth) | ||
119 | { | ||
120 | struct frame_tail *tail; | ||
121 | unsigned long last_address = 0; | ||
122 | |||
123 | tail = ((struct frame_tail *) regs->ARM_fp) - 1; | ||
124 | |||
125 | if (!user_mode(regs)) { | ||
126 | |||
127 | #ifdef CONFIG_FRAME_POINTER | ||
128 | while (depth-- && tail && valid_kernel_stack(tail, regs)) { | ||
129 | tail = kernel_backtrace(tail); | ||
130 | } | ||
131 | #endif | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | while (depth-- && tail && !((unsigned long) tail & 3)) { | ||
136 | if ((!CMP_ADDR_EQUAL(last_address, tail, 0) | ||
137 | || !CMP_ADDR_EQUAL(last_address, tail, 8)) | ||
138 | && !pages_present(tail)) | ||
139 | return; | ||
140 | last_address = (unsigned long) tail; | ||
141 | tail = user_backtrace(tail); | ||
142 | } | ||
143 | } | ||
144 | |||
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d3015eb7..d315a3a86c86 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c | |||
@@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
20 | ret = pmu_init(ops, &op_xscale_spec); | 20 | ret = pmu_init(ops, &op_xscale_spec); |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | ops->backtrace = arm_backtrace; | ||
24 | |||
23 | return ret; | 25 | return ret; |
24 | } | 26 | } |
25 | 27 | ||
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4781ad..2148d07484b7 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h | |||
@@ -24,6 +24,8 @@ struct op_arm_model_spec { | |||
24 | extern struct op_arm_model_spec op_xscale_spec; | 24 | extern struct op_arm_model_spec op_xscale_spec; |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); | ||
28 | |||
27 | extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); | 29 | extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); |
28 | extern void pmu_exit(void); | 30 | extern void pmu_exit(void); |
29 | #endif /* OP_ARM_MODEL_H */ | 31 | #endif /* OP_ARM_MODEL_H */ |
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956512e1..6835f6d47c31 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c | |||
@@ -70,7 +70,8 @@ void usage(void) | |||
70 | 70 | ||
71 | int main(int argc, char ** argv) | 71 | int main(int argc, char ** argv) |
72 | { | 72 | { |
73 | unsigned int i, c, sz, setup_sectors; | 73 | unsigned int i, sz, setup_sectors; |
74 | int c; | ||
74 | u32 sys_size; | 75 | u32 sys_size; |
75 | byte major_root, minor_root; | 76 | byte major_root, minor_root; |
76 | struct stat sb; | 77 | struct stat sb; |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0f404b..b7808a89d945 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) | |||
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | #ifdef CONFIG_PCI_MMCONFIG | 161 | #ifdef CONFIG_PCI_MMCONFIG |
162 | static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | 162 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ |
163 | struct acpi_table_mcfg_config *pci_mmcfg_config; | ||
164 | int pci_mmcfg_config_num; | ||
165 | |||
166 | int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | ||
163 | { | 167 | { |
164 | struct acpi_table_mcfg *mcfg; | 168 | struct acpi_table_mcfg *mcfg; |
169 | unsigned long i; | ||
170 | int config_size; | ||
165 | 171 | ||
166 | if (!phys_addr || !size) | 172 | if (!phys_addr || !size) |
167 | return -EINVAL; | 173 | return -EINVAL; |
@@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
172 | return -ENODEV; | 178 | return -ENODEV; |
173 | } | 179 | } |
174 | 180 | ||
175 | if (mcfg->base_reserved) { | 181 | /* how many config structures do we have */ |
176 | printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); | 182 | pci_mmcfg_config_num = 0; |
183 | i = size - sizeof(struct acpi_table_mcfg); | ||
184 | while (i >= sizeof(struct acpi_table_mcfg_config)) { | ||
185 | ++pci_mmcfg_config_num; | ||
186 | i -= sizeof(struct acpi_table_mcfg_config); | ||
187 | }; | ||
188 | if (pci_mmcfg_config_num == 0) { | ||
189 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | ||
177 | return -ENODEV; | 190 | return -ENODEV; |
178 | } | 191 | } |
179 | 192 | ||
180 | pci_mmcfg_base_addr = mcfg->base_address; | 193 | config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); |
194 | pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); | ||
195 | if (!pci_mmcfg_config) { | ||
196 | printk(KERN_WARNING PREFIX | ||
197 | "No memory for MCFG config tables\n"); | ||
198 | return -ENOMEM; | ||
199 | } | ||
200 | |||
201 | memcpy(pci_mmcfg_config, &mcfg->config, config_size); | ||
202 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
203 | if (mcfg->config[i].base_reserved) { | ||
204 | printk(KERN_ERR PREFIX | ||
205 | "MMCONFIG not in low 4GB of memory\n"); | ||
206 | return -ENODEV; | ||
207 | } | ||
208 | } | ||
181 | 209 | ||
182 | return 0; | 210 | return 0; |
183 | } | 211 | } |
184 | #else | 212 | #endif /* CONFIG_PCI_MMCONFIG */ |
185 | #define acpi_parse_mcfg NULL | ||
186 | #endif /* !CONFIG_PCI_MMCONFIG */ | ||
187 | 213 | ||
188 | #ifdef CONFIG_X86_LOCAL_APIC | 214 | #ifdef CONFIG_X86_LOCAL_APIC |
189 | static int __init | 215 | static int __init |
@@ -507,6 +533,22 @@ acpi_unmap_lsapic(int cpu) | |||
507 | EXPORT_SYMBOL(acpi_unmap_lsapic); | 533 | EXPORT_SYMBOL(acpi_unmap_lsapic); |
508 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ | 534 | #endif /* CONFIG_ACPI_HOTPLUG_CPU */ |
509 | 535 | ||
536 | int | ||
537 | acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
538 | { | ||
539 | /* TBD */ | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | EXPORT_SYMBOL(acpi_register_ioapic); | ||
543 | |||
544 | int | ||
545 | acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | ||
546 | { | ||
547 | /* TBD */ | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | EXPORT_SYMBOL(acpi_unregister_ioapic); | ||
551 | |||
510 | static unsigned long __init | 552 | static unsigned long __init |
511 | acpi_scan_rsdp ( | 553 | acpi_scan_rsdp ( |
512 | unsigned long start, | 554 | unsigned long start, |
@@ -1123,7 +1165,6 @@ int __init acpi_boot_init(void) | |||
1123 | acpi_process_madt(); | 1165 | acpi_process_madt(); |
1124 | 1166 | ||
1125 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); | 1167 | acpi_table_parse(ACPI_HPET, acpi_parse_hpet); |
1126 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
1127 | 1168 | ||
1128 | return 0; | 1169 | return 0; |
1129 | } | 1170 | } |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e1af50..87325263cd4f 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | |||
25 | 25 | ||
26 | int pci_routeirq; | 26 | int pci_routeirq; |
27 | int pcibios_last_bus = -1; | 27 | int pcibios_last_bus = -1; |
28 | struct pci_bus *pci_root_bus = NULL; | 28 | unsigned long pirq_table_addr; |
29 | struct pci_bus *pci_root_bus; | ||
29 | struct pci_raw_ops *raw_pci_ops; | 30 | struct pci_raw_ops *raw_pci_ops; |
30 | 31 | ||
31 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 32 | static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
133 | 134 | ||
134 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); | 135 | printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); |
135 | 136 | ||
136 | return pci_scan_bus(busnum, &pci_root_ops, NULL); | 137 | return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); |
137 | } | 138 | } |
138 | 139 | ||
139 | extern u8 pci_cache_line_size; | 140 | extern u8 pci_cache_line_size; |
@@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) | |||
188 | } else if (!strcmp(str, "biosirq")) { | 189 | } else if (!strcmp(str, "biosirq")) { |
189 | pci_probe |= PCI_BIOS_IRQ_SCAN; | 190 | pci_probe |= PCI_BIOS_IRQ_SCAN; |
190 | return NULL; | 191 | return NULL; |
192 | } else if (!strncmp(str, "pirqaddr=", 9)) { | ||
193 | pirq_table_addr = simple_strtoul(str+9, NULL, 0); | ||
194 | return NULL; | ||
191 | } | 195 | } |
192 | #endif | 196 | #endif |
193 | #ifdef CONFIG_PCI_DIRECT | 197 | #ifdef CONFIG_PCI_DIRECT |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f81e661..78ca1ecbb907 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -58,6 +58,35 @@ struct irq_router_handler { | |||
58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | 58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Check passed address for the PCI IRQ Routing Table signature | ||
62 | * and perform checksum verification. | ||
63 | */ | ||
64 | |||
65 | static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) | ||
66 | { | ||
67 | struct irq_routing_table *rt; | ||
68 | int i; | ||
69 | u8 sum; | ||
70 | |||
71 | rt = (struct irq_routing_table *) addr; | ||
72 | if (rt->signature != PIRQ_SIGNATURE || | ||
73 | rt->version != PIRQ_VERSION || | ||
74 | rt->size % 16 || | ||
75 | rt->size < sizeof(struct irq_routing_table)) | ||
76 | return NULL; | ||
77 | sum = 0; | ||
78 | for (i=0; i < rt->size; i++) | ||
79 | sum += addr[i]; | ||
80 | if (!sum) { | ||
81 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
82 | return rt; | ||
83 | } | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
61 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. | 90 | * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. |
62 | */ | 91 | */ |
63 | 92 | ||
@@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) | |||
65 | { | 94 | { |
66 | u8 *addr; | 95 | u8 *addr; |
67 | struct irq_routing_table *rt; | 96 | struct irq_routing_table *rt; |
68 | int i; | ||
69 | u8 sum; | ||
70 | 97 | ||
98 | if (pirq_table_addr) { | ||
99 | rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); | ||
100 | if (rt) | ||
101 | return rt; | ||
102 | printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); | ||
103 | } | ||
71 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { | 104 | for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { |
72 | rt = (struct irq_routing_table *) addr; | 105 | rt = pirq_check_routing_table(addr); |
73 | if (rt->signature != PIRQ_SIGNATURE || | 106 | if (rt) |
74 | rt->version != PIRQ_VERSION || | ||
75 | rt->size % 16 || | ||
76 | rt->size < sizeof(struct irq_routing_table)) | ||
77 | continue; | ||
78 | sum = 0; | ||
79 | for(i=0; i<rt->size; i++) | ||
80 | sum += addr[i]; | ||
81 | if (!sum) { | ||
82 | DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); | ||
83 | return rt; | 107 | return rt; |
84 | } | ||
85 | } | 108 | } |
86 | return NULL; | 109 | return NULL; |
87 | } | 110 | } |
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e3753869..149a9588c256 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c | |||
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) | |||
45 | 45 | ||
46 | printk("PCI: Probing PCI hardware\n"); | 46 | printk("PCI: Probing PCI hardware\n"); |
47 | pci_root_bus = pcibios_scan_root(0); | 47 | pci_root_bus = pcibios_scan_root(0); |
48 | if (pci_root_bus) | ||
49 | pci_bus_add_devices(pci_root_bus); | ||
48 | 50 | ||
49 | pcibios_fixup_peer_bridges(); | 51 | pcibios_fixup_peer_bridges(); |
50 | 52 | ||
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50aa51f4..60f0e7a1162a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -11,11 +11,9 @@ | |||
11 | 11 | ||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
15 | 16 | ||
16 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | ||
17 | u32 pci_mmcfg_base_addr; | ||
18 | |||
19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) | 17 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
20 | 18 | ||
21 | /* The base address of the last MMCONFIG device accessed */ | 19 | /* The base address of the last MMCONFIG device accessed */ |
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device; | |||
24 | /* | 22 | /* |
25 | * Functions for accessing PCI configuration space with MMCONFIG accesses | 23 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
26 | */ | 24 | */ |
25 | static u32 get_base_addr(unsigned int seg, int bus) | ||
26 | { | ||
27 | int cfg_num = -1; | ||
28 | struct acpi_table_mcfg_config *cfg; | ||
29 | |||
30 | while (1) { | ||
31 | ++cfg_num; | ||
32 | if (cfg_num >= pci_mmcfg_config_num) { | ||
33 | /* something bad is going on, no cfg table is found. */ | ||
34 | /* so we fall back to the old way we used to do this */ | ||
35 | /* and just rely on the first entry to be correct. */ | ||
36 | return pci_mmcfg_config[0].base_address; | ||
37 | } | ||
38 | cfg = &pci_mmcfg_config[cfg_num]; | ||
39 | if (cfg->pci_segment_group_number != seg) | ||
40 | continue; | ||
41 | if ((cfg->start_bus_number <= bus) && | ||
42 | (cfg->end_bus_number >= bus)) | ||
43 | return cfg->base_address; | ||
44 | } | ||
45 | } | ||
27 | 46 | ||
28 | static inline void pci_exp_set_dev_base(int bus, int devfn) | 47 | static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) |
29 | { | 48 | { |
30 | u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); | 49 | u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); |
31 | if (dev_base != mmcfg_last_accessed_device) { | 50 | if (dev_base != mmcfg_last_accessed_device) { |
32 | mmcfg_last_accessed_device = dev_base; | 51 | mmcfg_last_accessed_device = dev_base; |
33 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); | 52 | set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); |
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
44 | 63 | ||
45 | spin_lock_irqsave(&pci_config_lock, flags); | 64 | spin_lock_irqsave(&pci_config_lock, flags); |
46 | 65 | ||
47 | pci_exp_set_dev_base(bus, devfn); | 66 | pci_exp_set_dev_base(seg, bus, devfn); |
48 | 67 | ||
49 | switch (len) { | 68 | switch (len) { |
50 | case 1: | 69 | case 1: |
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | |||
73 | 92 | ||
74 | spin_lock_irqsave(&pci_config_lock, flags); | 93 | spin_lock_irqsave(&pci_config_lock, flags); |
75 | 94 | ||
76 | pci_exp_set_dev_base(bus, devfn); | 95 | pci_exp_set_dev_base(seg, bus, devfn); |
77 | 96 | ||
78 | switch (len) { | 97 | switch (len) { |
79 | case 1: | 98 | case 1: |
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void) | |||
101 | { | 120 | { |
102 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 121 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
103 | goto out; | 122 | goto out; |
104 | if (!pci_mmcfg_base_addr) | 123 | |
124 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
125 | if ((pci_mmcfg_config_num == 0) || | ||
126 | (pci_mmcfg_config == NULL) || | ||
127 | (pci_mmcfg_config[0].base_address == 0)) | ||
105 | goto out; | 128 | goto out; |
106 | 129 | ||
107 | /* Kludge for now. Don't use mmconfig on AMD systems because | 130 | /* Kludge for now. Don't use mmconfig on AMD systems because |
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e3695461899..adbe17a38f6f 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c | |||
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void) | |||
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | pci_root_bus = pcibios_scan_root(0); | 117 | pci_root_bus = pcibios_scan_root(0); |
118 | if (pci_root_bus) | ||
119 | pci_bus_add_devices(pci_root_bus); | ||
118 | if (num_online_nodes() > 1) | 120 | if (num_online_nodes() > 1) |
119 | for_each_online_node(quad) { | 121 | for_each_online_node(quad) { |
120 | if (quad == 0) | 122 | if (quad == 0) |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80ca69f3..a80f0f55ff51 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 | 27 | #define PCI_ASSIGN_ALL_BUSSES 0x4000 |
28 | 28 | ||
29 | extern unsigned int pci_probe; | 29 | extern unsigned int pci_probe; |
30 | extern unsigned long pirq_table_addr; | ||
30 | 31 | ||
31 | /* pci-i386.c */ | 32 | /* pci-i386.c */ |
32 | 33 | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e7de0f..cda06f88c66e 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) | |||
236 | if (BAD_MADT_ENTRY(iosapic, end)) | 236 | if (BAD_MADT_ENTRY(iosapic, end)) |
237 | return -EINVAL; | 237 | return -EINVAL; |
238 | 238 | ||
239 | iosapic_init(iosapic->address, iosapic->global_irq_base); | 239 | return iosapic_init(iosapic->address, iosapic->global_irq_base); |
240 | |||
241 | return 0; | ||
242 | } | 240 | } |
243 | 241 | ||
244 | 242 | ||
@@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); | |||
772 | 770 | ||
773 | 771 | ||
774 | #ifdef CONFIG_ACPI_NUMA | 772 | #ifdef CONFIG_ACPI_NUMA |
775 | acpi_status __init | 773 | acpi_status __devinit |
776 | acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | 774 | acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) |
777 | { | 775 | { |
778 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 776 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
@@ -825,4 +823,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) | |||
825 | return AE_OK; | 823 | return AE_OK; |
826 | } | 824 | } |
827 | #endif /* CONFIG_NUMA */ | 825 | #endif /* CONFIG_NUMA */ |
826 | |||
827 | int | ||
828 | acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) | ||
829 | { | ||
830 | int err; | ||
831 | |||
832 | if ((err = iosapic_init(phys_addr, gsi_base))) | ||
833 | return err; | ||
834 | |||
835 | #if CONFIG_ACPI_NUMA | ||
836 | acpi_map_iosapic(handle, 0, NULL, NULL); | ||
837 | #endif /* CONFIG_ACPI_NUMA */ | ||
838 | |||
839 | return 0; | ||
840 | } | ||
841 | EXPORT_SYMBOL(acpi_register_ioapic); | ||
842 | |||
843 | int | ||
844 | acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) | ||
845 | { | ||
846 | return iosapic_remove(gsi_base); | ||
847 | } | ||
848 | EXPORT_SYMBOL(acpi_unregister_ioapic); | ||
849 | |||
828 | #endif /* CONFIG_ACPI_BOOT */ | 850 | #endif /* CONFIG_ACPI_BOOT */ |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b014381df5..c170be095ccd 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -129,14 +129,13 @@ static struct iosapic { | |||
129 | char __iomem *addr; /* base address of IOSAPIC */ | 129 | char __iomem *addr; /* base address of IOSAPIC */ |
130 | unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ | 130 | unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ |
131 | unsigned short num_rte; /* number of RTE in this IOSAPIC */ | 131 | unsigned short num_rte; /* number of RTE in this IOSAPIC */ |
132 | int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ | ||
132 | #ifdef CONFIG_NUMA | 133 | #ifdef CONFIG_NUMA |
133 | unsigned short node; /* numa node association via pxm */ | 134 | unsigned short node; /* numa node association via pxm */ |
134 | #endif | 135 | #endif |
135 | } iosapic_lists[NR_IOSAPICS]; | 136 | } iosapic_lists[NR_IOSAPICS]; |
136 | 137 | ||
137 | static int num_iosapic; | 138 | static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ |
138 | |||
139 | static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ | ||
140 | 139 | ||
141 | static int iosapic_kmalloc_ok; | 140 | static int iosapic_kmalloc_ok; |
142 | static LIST_HEAD(free_rte_list); | 141 | static LIST_HEAD(free_rte_list); |
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) | |||
149 | { | 148 | { |
150 | int i; | 149 | int i; |
151 | 150 | ||
152 | for (i = 0; i < num_iosapic; i++) { | 151 | for (i = 0; i < NR_IOSAPICS; i++) { |
153 | if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) | 152 | if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) |
154 | return i; | 153 | return i; |
155 | } | 154 | } |
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, | |||
598 | rte->refcnt++; | 597 | rte->refcnt++; |
599 | list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); | 598 | list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); |
600 | iosapic_intr_info[vector].count++; | 599 | iosapic_intr_info[vector].count++; |
600 | iosapic_lists[index].rtes_inuse++; | ||
601 | } | 601 | } |
602 | else if (vector_is_shared(vector)) { | 602 | else if (vector_is_shared(vector)) { |
603 | struct iosapic_intr_info *info = &iosapic_intr_info[vector]; | 603 | struct iosapic_intr_info *info = &iosapic_intr_info[vector]; |
@@ -778,7 +778,7 @@ void | |||
778 | iosapic_unregister_intr (unsigned int gsi) | 778 | iosapic_unregister_intr (unsigned int gsi) |
779 | { | 779 | { |
780 | unsigned long flags; | 780 | unsigned long flags; |
781 | int irq, vector; | 781 | int irq, vector, index; |
782 | irq_desc_t *idesc; | 782 | irq_desc_t *idesc; |
783 | u32 low32; | 783 | u32 low32; |
784 | unsigned long trigger, polarity; | 784 | unsigned long trigger, polarity; |
@@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi) | |||
819 | list_del(&rte->rte_list); | 819 | list_del(&rte->rte_list); |
820 | iosapic_intr_info[vector].count--; | 820 | iosapic_intr_info[vector].count--; |
821 | iosapic_free_rte(rte); | 821 | iosapic_free_rte(rte); |
822 | index = find_iosapic(gsi); | ||
823 | iosapic_lists[index].rtes_inuse--; | ||
824 | WARN_ON(iosapic_lists[index].rtes_inuse < 0); | ||
822 | 825 | ||
823 | trigger = iosapic_intr_info[vector].trigger; | 826 | trigger = iosapic_intr_info[vector].trigger; |
824 | polarity = iosapic_intr_info[vector].polarity; | 827 | polarity = iosapic_intr_info[vector].polarity; |
@@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat) | |||
952 | } | 955 | } |
953 | } | 956 | } |
954 | 957 | ||
955 | void __init | 958 | static inline int |
959 | iosapic_alloc (void) | ||
960 | { | ||
961 | int index; | ||
962 | |||
963 | for (index = 0; index < NR_IOSAPICS; index++) | ||
964 | if (!iosapic_lists[index].addr) | ||
965 | return index; | ||
966 | |||
967 | printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); | ||
968 | return -1; | ||
969 | } | ||
970 | |||
971 | static inline void | ||
972 | iosapic_free (int index) | ||
973 | { | ||
974 | memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); | ||
975 | } | ||
976 | |||
977 | static inline int | ||
978 | iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) | ||
979 | { | ||
980 | int index; | ||
981 | unsigned int gsi_end, base, end; | ||
982 | |||
983 | /* check gsi range */ | ||
984 | gsi_end = gsi_base + ((ver >> 16) & 0xff); | ||
985 | for (index = 0; index < NR_IOSAPICS; index++) { | ||
986 | if (!iosapic_lists[index].addr) | ||
987 | continue; | ||
988 | |||
989 | base = iosapic_lists[index].gsi_base; | ||
990 | end = base + iosapic_lists[index].num_rte - 1; | ||
991 | |||
992 | if (gsi_base < base && gsi_end < base) | ||
993 | continue;/* OK */ | ||
994 | |||
995 | if (gsi_base > end && gsi_end > end) | ||
996 | continue; /* OK */ | ||
997 | |||
998 | return -EBUSY; | ||
999 | } | ||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | int __devinit | ||
956 | iosapic_init (unsigned long phys_addr, unsigned int gsi_base) | 1004 | iosapic_init (unsigned long phys_addr, unsigned int gsi_base) |
957 | { | 1005 | { |
958 | int num_rte; | 1006 | int num_rte, err, index; |
959 | unsigned int isa_irq, ver; | 1007 | unsigned int isa_irq, ver; |
960 | char __iomem *addr; | 1008 | char __iomem *addr; |
1009 | unsigned long flags; | ||
1010 | |||
1011 | spin_lock_irqsave(&iosapic_lock, flags); | ||
1012 | { | ||
1013 | addr = ioremap(phys_addr, 0); | ||
1014 | ver = iosapic_version(addr); | ||
961 | 1015 | ||
962 | addr = ioremap(phys_addr, 0); | 1016 | if ((err = iosapic_check_gsi_range(gsi_base, ver))) { |
963 | ver = iosapic_version(addr); | 1017 | iounmap(addr); |
1018 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
1019 | return err; | ||
1020 | } | ||
964 | 1021 | ||
965 | /* | 1022 | /* |
966 | * The MAX_REDIR register holds the highest input pin | 1023 | * The MAX_REDIR register holds the highest input pin |
967 | * number (starting from 0). | 1024 | * number (starting from 0). |
968 | * We add 1 so that we can use it for number of pins (= RTEs) | 1025 | * We add 1 so that we can use it for number of pins (= RTEs) |
969 | */ | 1026 | */ |
970 | num_rte = ((ver >> 16) & 0xff) + 1; | 1027 | num_rte = ((ver >> 16) & 0xff) + 1; |
971 | 1028 | ||
972 | iosapic_lists[num_iosapic].addr = addr; | 1029 | index = iosapic_alloc(); |
973 | iosapic_lists[num_iosapic].gsi_base = gsi_base; | 1030 | iosapic_lists[index].addr = addr; |
974 | iosapic_lists[num_iosapic].num_rte = num_rte; | 1031 | iosapic_lists[index].gsi_base = gsi_base; |
1032 | iosapic_lists[index].num_rte = num_rte; | ||
975 | #ifdef CONFIG_NUMA | 1033 | #ifdef CONFIG_NUMA |
976 | iosapic_lists[num_iosapic].node = MAX_NUMNODES; | 1034 | iosapic_lists[index].node = MAX_NUMNODES; |
977 | #endif | 1035 | #endif |
978 | num_iosapic++; | 1036 | } |
1037 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
979 | 1038 | ||
980 | if ((gsi_base == 0) && pcat_compat) { | 1039 | if ((gsi_base == 0) && pcat_compat) { |
981 | /* | 1040 | /* |
@@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) | |||
986 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) | 1045 | for (isa_irq = 0; isa_irq < 16; ++isa_irq) |
987 | iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); | 1046 | iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); |
988 | } | 1047 | } |
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | #ifdef CONFIG_HOTPLUG | ||
1052 | int | ||
1053 | iosapic_remove (unsigned int gsi_base) | ||
1054 | { | ||
1055 | int index, err = 0; | ||
1056 | unsigned long flags; | ||
1057 | |||
1058 | spin_lock_irqsave(&iosapic_lock, flags); | ||
1059 | { | ||
1060 | index = find_iosapic(gsi_base); | ||
1061 | if (index < 0) { | ||
1062 | printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", | ||
1063 | __FUNCTION__, gsi_base); | ||
1064 | goto out; | ||
1065 | } | ||
1066 | |||
1067 | if (iosapic_lists[index].rtes_inuse) { | ||
1068 | err = -EBUSY; | ||
1069 | printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", | ||
1070 | __FUNCTION__, gsi_base); | ||
1071 | goto out; | ||
1072 | } | ||
1073 | |||
1074 | iounmap(iosapic_lists[index].addr); | ||
1075 | iosapic_free(index); | ||
1076 | } | ||
1077 | out: | ||
1078 | spin_unlock_irqrestore(&iosapic_lock, flags); | ||
1079 | return err; | ||
989 | } | 1080 | } |
1081 | #endif /* CONFIG_HOTPLUG */ | ||
990 | 1082 | ||
991 | #ifdef CONFIG_NUMA | 1083 | #ifdef CONFIG_NUMA |
992 | void __init | 1084 | void __devinit |
993 | map_iosapic_to_node(unsigned int gsi_base, int node) | 1085 | map_iosapic_to_node(unsigned int gsi_base, int node) |
994 | { | 1086 | { |
995 | int index; | 1087 | int index; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4edea113..720a861f88be 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, | 312 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, |
313 | &info); | 313 | &info); |
314 | 314 | ||
315 | pbus = pci_scan_bus(bus, &pci_root_ops, controller); | 315 | pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); |
316 | if (pbus) | 316 | if (pbus) |
317 | pcibios_setup_root_windows(pbus, controller); | 317 | pcibios_setup_root_windows(pbus, controller); |
318 | 318 | ||
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, | |||
373 | res->end = region->end + offset; | 373 | res->end = region->end + offset; |
374 | } | 374 | } |
375 | 375 | ||
376 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | ||
377 | { | ||
378 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
379 | struct resource *devr = &dev->resource[idx]; | ||
380 | |||
381 | if (!dev->bus) | ||
382 | return 0; | ||
383 | for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) { | ||
384 | struct resource *busr = dev->bus->resource[i]; | ||
385 | |||
386 | if (!busr || ((busr->flags ^ devr->flags) & type_mask)) | ||
387 | continue; | ||
388 | if ((devr->start) && (devr->start >= busr->start) && | ||
389 | (devr->end <= busr->end)) | ||
390 | return 1; | ||
391 | } | ||
392 | return 0; | ||
393 | } | ||
394 | |||
376 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 395 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
377 | { | 396 | { |
378 | struct pci_bus_region region; | 397 | struct pci_bus_region region; |
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
386 | region.start = dev->resource[i].start; | 405 | region.start = dev->resource[i].start; |
387 | region.end = dev->resource[i].end; | 406 | region.end = dev->resource[i].end; |
388 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | 407 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); |
389 | pci_claim_resource(dev, i); | 408 | if ((is_valid_resource(dev, i))) |
409 | pci_claim_resource(dev, i); | ||
390 | } | 410 | } |
391 | } | 411 | } |
392 | 412 | ||
@@ -398,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) | |||
398 | { | 418 | { |
399 | struct pci_dev *dev; | 419 | struct pci_dev *dev; |
400 | 420 | ||
421 | if (b->self) { | ||
422 | pci_read_bridge_bases(b); | ||
423 | pcibios_fixup_device_resources(b->self); | ||
424 | } | ||
401 | list_for_each_entry(dev, &b->devices, bus_list) | 425 | list_for_each_entry(dev, &b->devices, bus_list) |
402 | pcibios_fixup_device_resources(dev); | 426 | pcibios_fixup_device_resources(dev); |
403 | 427 | ||
@@ -418,18 +442,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
418 | u16 cmd, old_cmd; | 442 | u16 cmd, old_cmd; |
419 | int idx; | 443 | int idx; |
420 | struct resource *r; | 444 | struct resource *r; |
445 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | ||
421 | 446 | ||
422 | if (!dev) | 447 | if (!dev) |
423 | return -EINVAL; | 448 | return -EINVAL; |
424 | 449 | ||
425 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 450 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
426 | old_cmd = cmd; | 451 | old_cmd = cmd; |
427 | for (idx=0; idx<6; idx++) { | 452 | for (idx=0; idx<PCI_NUM_RESOURCES; idx++) { |
428 | /* Only set up the desired resources. */ | 453 | /* Only set up the desired resources. */ |
429 | if (!(mask & (1 << idx))) | 454 | if (!(mask & (1 << idx))) |
430 | continue; | 455 | continue; |
431 | 456 | ||
432 | r = &dev->resource[idx]; | 457 | r = &dev->resource[idx]; |
458 | if (!(r->flags & type_mask)) | ||
459 | continue; | ||
460 | if ((idx == PCI_ROM_RESOURCE) && | ||
461 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
462 | continue; | ||
433 | if (!r->start && r->end) { | 463 | if (!r->start && r->end) { |
434 | printk(KERN_ERR | 464 | printk(KERN_ERR |
435 | "PCI: Device %s not available because of resource collisions\n", | 465 | "PCI: Device %s not available because of resource collisions\n", |
@@ -441,8 +471,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) | |||
441 | if (r->flags & IORESOURCE_MEM) | 471 | if (r->flags & IORESOURCE_MEM) |
442 | cmd |= PCI_COMMAND_MEMORY; | 472 | cmd |= PCI_COMMAND_MEMORY; |
443 | } | 473 | } |
444 | if (dev->resource[PCI_ROM_RESOURCE].start) | ||
445 | cmd |= PCI_COMMAND_MEMORY; | ||
446 | if (cmd != old_cmd) { | 474 | if (cmd != old_cmd) { |
447 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); | 475 | printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); |
448 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 476 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d72458..70cfb6ffd877 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c | |||
@@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
1495 | *offset += hose->pci_mem_offset; | 1495 | *offset += hose->pci_mem_offset; |
1496 | res_bit = IORESOURCE_MEM; | 1496 | res_bit = IORESOURCE_MEM; |
1497 | } else { | 1497 | } else { |
1498 | io_offset = (unsigned long)hose->io_base_virt; | 1498 | io_offset = hose->io_base_virt - ___IO_BASE; |
1499 | *offset += io_offset; | 1499 | *offset += io_offset; |
1500 | res_bit = IORESOURCE_IO; | 1500 | res_bit = IORESOURCE_IO; |
1501 | } | 1501 | } |
@@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
1522 | 1522 | ||
1523 | /* found it! construct the final physical address */ | 1523 | /* found it! construct the final physical address */ |
1524 | if (mmap_state == pci_mmap_io) | 1524 | if (mmap_state == pci_mmap_io) |
1525 | *offset += hose->io_base_phys - _IO_BASE; | 1525 | *offset += hose->io_base_phys - io_offset; |
1526 | return rp; | 1526 | return rp; |
1527 | } | 1527 | } |
1528 | 1528 | ||
@@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) | |||
1739 | return result; | 1739 | return result; |
1740 | } | 1740 | } |
1741 | 1741 | ||
1742 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
1743 | const struct resource *rsrc, | ||
1744 | u64 *start, u64 *end) | ||
1745 | { | ||
1746 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
1747 | unsigned long offset = 0; | ||
1748 | |||
1749 | if (hose == NULL) | ||
1750 | return; | ||
1751 | |||
1752 | if (rsrc->flags & IORESOURCE_IO) | ||
1753 | offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; | ||
1754 | |||
1755 | *start = rsrc->start + offset; | ||
1756 | *end = rsrc->end + offset; | ||
1757 | } | ||
1758 | |||
1742 | void __init | 1759 | void __init |
1743 | pci_init_resource(struct resource *res, unsigned long start, unsigned long end, | 1760 | pci_init_resource(struct resource *res, unsigned long start, unsigned long end, |
1744 | int flags, char *name) | 1761 | int flags, char *name) |
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c33adf..ffe300611f00 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c | |||
@@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) | |||
245 | 245 | ||
246 | spin_lock(&desc->lock); | 246 | spin_lock(&desc->lock); |
247 | if (!noirqdebug) | 247 | if (!noirqdebug) |
248 | note_interrupt(irq, desc, action_ret); | 248 | note_interrupt(irq, desc, action_ret, regs); |
249 | if (likely(!(desc->status & IRQ_PENDING))) | 249 | if (likely(!(desc->status & IRQ_PENDING))) |
250 | break; | 250 | break; |
251 | desc->status &= ~IRQ_PENDING; | 251 | desc->status &= ~IRQ_PENDING; |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f87d23..ae6f579d3fa0 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
351 | *offset += hose->pci_mem_offset; | 351 | *offset += hose->pci_mem_offset; |
352 | res_bit = IORESOURCE_MEM; | 352 | res_bit = IORESOURCE_MEM; |
353 | } else { | 353 | } else { |
354 | io_offset = (unsigned long)hose->io_base_virt; | 354 | io_offset = (unsigned long)hose->io_base_virt - pci_io_base; |
355 | *offset += io_offset; | 355 | *offset += io_offset; |
356 | res_bit = IORESOURCE_IO; | 356 | res_bit = IORESOURCE_IO; |
357 | } | 357 | } |
@@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, | |||
378 | 378 | ||
379 | /* found it! construct the final physical address */ | 379 | /* found it! construct the final physical address */ |
380 | if (mmap_state == pci_mmap_io) | 380 | if (mmap_state == pci_mmap_io) |
381 | *offset += hose->io_base_phys - io_offset; | 381 | *offset += hose->io_base_phys - io_offset; |
382 | return rp; | 382 | return rp; |
383 | } | 383 | } |
384 | 384 | ||
@@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
944 | } | 944 | } |
945 | EXPORT_SYMBOL(pci_read_irq_line); | 945 | EXPORT_SYMBOL(pci_read_irq_line); |
946 | 946 | ||
947 | void pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
948 | const struct resource *rsrc, | ||
949 | u64 *start, u64 *end) | ||
950 | { | ||
951 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
952 | unsigned long offset = 0; | ||
953 | |||
954 | if (hose == NULL) | ||
955 | return; | ||
956 | |||
957 | if (rsrc->flags & IORESOURCE_IO) | ||
958 | offset = pci_io_base - (unsigned long)hose->io_base_virt + | ||
959 | hose->io_base_phys; | ||
960 | |||
961 | *start = rsrc->start + offset; | ||
962 | *end = rsrc->end + offset; | ||
963 | } | ||
964 | |||
947 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 965 | #endif /* CONFIG_PPC_MULTIPLATFORM */ |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d086fe..7a117ef473c5 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -270,66 +270,10 @@ endmenu | |||
270 | 270 | ||
271 | source "drivers/Kconfig" | 271 | source "drivers/Kconfig" |
272 | 272 | ||
273 | config PRINTER | ||
274 | tristate "Parallel printer support" | ||
275 | depends on PARPORT | ||
276 | ---help--- | ||
277 | If you intend to attach a printer to the parallel port of your Linux | ||
278 | box (as opposed to using a serial printer; if the connector at the | ||
279 | printer has 9 or 25 holes ["female"], then it's serial), say Y. | ||
280 | Also read the Printing-HOWTO, available from | ||
281 | <http://www.tldp.org/docs.html#howto>. | ||
282 | |||
283 | It is possible to share one parallel port among several devices | ||
284 | (e.g. printer and ZIP drive) and it is safe to compile the | ||
285 | corresponding drivers into the kernel. If you want to compile this | ||
286 | driver as a module however, choose M here and read | ||
287 | <file:Documentation/parport.txt>. The module will be called lp. | ||
288 | |||
289 | If you have several parallel ports, you can specify which ports to | ||
290 | use with the "lp" kernel command line option. (Try "man bootparam" | ||
291 | or see the documentation of your boot loader (silo) about how to pass | ||
292 | options to the kernel at boot time.) The syntax of the "lp" command | ||
293 | line option can be found in <file:drivers/char/lp.c>. | ||
294 | |||
295 | If you have more than 8 printers, you need to increase the LP_NO | ||
296 | macro in lp.c and the PARPORT_MAX macro in parport.h. | ||
297 | |||
298 | source "mm/Kconfig" | ||
299 | |||
300 | endmenu | ||
301 | |||
302 | source "drivers/base/Kconfig" | ||
303 | |||
304 | source "drivers/video/Kconfig" | ||
305 | |||
306 | source "drivers/mtd/Kconfig" | ||
307 | |||
308 | source "drivers/serial/Kconfig" | ||
309 | |||
310 | if !SUN4 | 273 | if !SUN4 |
311 | source "drivers/sbus/char/Kconfig" | 274 | source "drivers/sbus/char/Kconfig" |
312 | endif | 275 | endif |
313 | 276 | ||
314 | source "drivers/block/Kconfig" | ||
315 | |||
316 | # Don't frighten a common SBus user | ||
317 | if PCI | ||
318 | |||
319 | source "drivers/ide/Kconfig" | ||
320 | |||
321 | endif | ||
322 | |||
323 | source "drivers/isdn/Kconfig" | ||
324 | |||
325 | source "drivers/scsi/Kconfig" | ||
326 | |||
327 | source "drivers/fc4/Kconfig" | ||
328 | |||
329 | source "drivers/md/Kconfig" | ||
330 | |||
331 | source "net/Kconfig" | ||
332 | |||
333 | # This one must be before the filesystem configs. -DaveM | 277 | # This one must be before the filesystem configs. -DaveM |
334 | 278 | ||
335 | menu "Unix98 PTY support" | 279 | menu "Unix98 PTY support" |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c232fd07..657e88aa0902 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -7,25 +7,50 @@ | |||
7 | 7 | ||
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | ||
10 | #include "pci.h" | 11 | #include "pci.h" |
11 | 12 | ||
12 | #define MMCONFIG_APER_SIZE (256*1024*1024) | 13 | #define MMCONFIG_APER_SIZE (256*1024*1024) |
13 | 14 | ||
14 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | ||
15 | u32 pci_mmcfg_base_addr; | ||
16 | |||
17 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | /* Static virtual mapping of the MMCONFIG aperture */ |
18 | char *pci_mmcfg_virt; | 16 | struct mmcfg_virt { |
17 | struct acpi_table_mcfg_config *cfg; | ||
18 | char *virt; | ||
19 | }; | ||
20 | static struct mmcfg_virt *pci_mmcfg_virt; | ||
19 | 21 | ||
20 | static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) | 22 | static char *get_virt(unsigned int seg, int bus) |
21 | { | 23 | { |
22 | return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); | 24 | int cfg_num = -1; |
25 | struct acpi_table_mcfg_config *cfg; | ||
26 | |||
27 | while (1) { | ||
28 | ++cfg_num; | ||
29 | if (cfg_num >= pci_mmcfg_config_num) { | ||
30 | /* something bad is going on, no cfg table is found. */ | ||
31 | /* so we fall back to the old way we used to do this */ | ||
32 | /* and just rely on the first entry to be correct. */ | ||
33 | return pci_mmcfg_virt[0].virt; | ||
34 | } | ||
35 | cfg = pci_mmcfg_virt[cfg_num].cfg; | ||
36 | if (cfg->pci_segment_group_number != seg) | ||
37 | continue; | ||
38 | if ((cfg->start_bus_number <= bus) && | ||
39 | (cfg->end_bus_number >= bus)) | ||
40 | return pci_mmcfg_virt[cfg_num].virt; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | ||
45 | { | ||
46 | |||
47 | return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); | ||
23 | } | 48 | } |
24 | 49 | ||
25 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | 50 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, |
26 | unsigned int devfn, int reg, int len, u32 *value) | 51 | unsigned int devfn, int reg, int len, u32 *value) |
27 | { | 52 | { |
28 | char *addr = pci_dev_base(bus, devfn); | 53 | char *addr = pci_dev_base(seg, bus, devfn); |
29 | 54 | ||
30 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) | 55 | if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) |
31 | return -EINVAL; | 56 | return -EINVAL; |
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | |||
48 | static int pci_mmcfg_write(unsigned int seg, unsigned int bus, | 73 | static int pci_mmcfg_write(unsigned int seg, unsigned int bus, |
49 | unsigned int devfn, int reg, int len, u32 value) | 74 | unsigned int devfn, int reg, int len, u32 value) |
50 | { | 75 | { |
51 | char *addr = pci_dev_base(bus,devfn); | 76 | char *addr = pci_dev_base(seg, bus, devfn); |
52 | 77 | ||
53 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) | 78 | if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) |
54 | return -EINVAL; | 79 | return -EINVAL; |
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = { | |||
75 | 100 | ||
76 | static int __init pci_mmcfg_init(void) | 101 | static int __init pci_mmcfg_init(void) |
77 | { | 102 | { |
103 | int i; | ||
104 | |||
78 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 105 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
79 | return 0; | 106 | return 0; |
80 | if (!pci_mmcfg_base_addr) | 107 | |
108 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | ||
109 | if ((pci_mmcfg_config_num == 0) || | ||
110 | (pci_mmcfg_config == NULL) || | ||
111 | (pci_mmcfg_config[0].base_address == 0)) | ||
81 | return 0; | 112 | return 0; |
82 | 113 | ||
83 | /* Kludge for now. Don't use mmconfig on AMD systems because | 114 | /* Kludge for now. Don't use mmconfig on AMD systems because |
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void) | |||
88 | return 0; | 119 | return 0; |
89 | 120 | ||
90 | /* RED-PEN i386 doesn't do _nocache right now */ | 121 | /* RED-PEN i386 doesn't do _nocache right now */ |
91 | pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); | 122 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
92 | if (!pci_mmcfg_virt) { | 123 | if (pci_mmcfg_virt == NULL) { |
93 | printk("PCI: Cannot map mmconfig aperture\n"); | 124 | printk("PCI: Can not allocate memory for mmconfig structures\n"); |
94 | return 0; | 125 | return 0; |
95 | } | 126 | } |
127 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
128 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | ||
129 | pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); | ||
130 | if (!pci_mmcfg_virt[i].virt) { | ||
131 | printk("PCI: Cannot map mmconfig aperture for segment %d\n", | ||
132 | pci_mmcfg_config[i].pci_segment_group_number); | ||
133 | return 0; | ||
134 | } | ||
135 | printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); | ||
136 | } | ||
96 | 137 | ||
97 | printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); | ||
98 | raw_pci_ops = &pci_mmcfg; | 138 | raw_pci_ops = &pci_mmcfg; |
99 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 139 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
100 | 140 | ||