diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2009-08-29 10:24:51 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-19 19:12:29 -0500 |
commit | b72d0db9dd41da1f2ec6274b03e8909583c64e41 (patch) | |
tree | 6424768067546f3aa4bd2e5d0a11d6459a6aad51 /arch/x86 | |
parent | cf4c43dd439b90a1a876b3f836ebe745abb9a269 (diff) |
x86: Move pci init function to x86_init
The PCI initialization in pci_subsys_init() is a mess. pci_numaq_init,
pci_acpi_init, pci_visws_init and pci_legacy_init are called and each
implementation checks and eventually modifies the global variable
pcibios_scanned.
x86_init functions allow us to do this more elegant. The pci.init
function pointer is preset to pci_legacy_init. numaq, acpi and visws
can modify the pointer in their early setup functions. The functions
return 0 when they did the full initialization including bus scan. A
non zero return value indicates that pci_legacy_init needs to be
called either because the selected function failed or wants the
generic bus scan in pci_legacy_init to happen (e.g. visws).
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
LKML-Reference: <43F901BD926A4E43B106BF17856F07559FB80CFE@orsmsx508.amr.corp.intel.com>
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jacob Pan <jacob.jun.pan@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/numaq.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/pci.h | 9 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 14 | ||||
-rw-r--r-- | arch/x86/include/asm/setup.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/visws/cobalt.h | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/x86_init.h | 9 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/apic/numaq_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/visws_quirks.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/x86_init.c | 5 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 6 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 6 | ||||
-rw-r--r-- | arch/x86/pci/legacy.c | 22 | ||||
-rw-r--r-- | arch/x86/pci/numaq_32.c | 6 | ||||
-rw-r--r-- | arch/x86/pci/visws.c | 6 |
15 files changed, 53 insertions, 46 deletions
diff --git a/arch/x86/include/asm/numaq.h b/arch/x86/include/asm/numaq.h index 9f0a5f5d29ec..ef6bf81f8460 100644 --- a/arch/x86/include/asm/numaq.h +++ b/arch/x86/include/asm/numaq.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | extern int found_numaq; | 31 | extern int found_numaq; |
32 | extern int get_memcfg_numaq(void); | 32 | extern int get_memcfg_numaq(void); |
33 | extern int pci_numaq_init(void); | ||
33 | 34 | ||
34 | extern void *xquad_portio; | 35 | extern void *xquad_portio; |
35 | 36 | ||
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index ada8c201d513..8bd433ccc242 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -45,8 +45,15 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
45 | 45 | ||
46 | #ifdef CONFIG_PCI | 46 | #ifdef CONFIG_PCI |
47 | extern unsigned int pcibios_assign_all_busses(void); | 47 | extern unsigned int pcibios_assign_all_busses(void); |
48 | extern int pci_legacy_init(void); | ||
49 | # ifdef CONFIG_ACPI | ||
50 | # define x86_default_pci_init pci_acpi_init | ||
51 | # else | ||
52 | # define x86_default_pci_init pci_legacy_init | ||
53 | # endif | ||
48 | #else | 54 | #else |
49 | #define pcibios_assign_all_busses() 0 | 55 | # define pcibios_assign_all_busses() 0 |
56 | # define x86_default_pci_init NULL | ||
50 | #endif | 57 | #endif |
51 | 58 | ||
52 | extern unsigned long pci_mem_start; | 59 | extern unsigned long pci_mem_start; |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b4bf9a942ed0..440124f1224d 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -82,7 +82,6 @@ struct irq_routing_table { | |||
82 | 82 | ||
83 | extern unsigned int pcibios_irq_mask; | 83 | extern unsigned int pcibios_irq_mask; |
84 | 84 | ||
85 | extern int pcibios_scanned; | ||
86 | extern spinlock_t pci_config_lock; | 85 | extern spinlock_t pci_config_lock; |
87 | 86 | ||
88 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 87 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
@@ -112,9 +111,8 @@ extern void __init dmi_check_skip_isa_align(void); | |||
112 | /* some common used subsys_initcalls */ | 111 | /* some common used subsys_initcalls */ |
113 | extern int __init pci_acpi_init(void); | 112 | extern int __init pci_acpi_init(void); |
114 | extern int __init pcibios_irq_init(void); | 113 | extern int __init pcibios_irq_init(void); |
115 | extern int __init pci_visws_init(void); | ||
116 | extern int __init pci_numaq_init(void); | ||
117 | extern int __init pcibios_init(void); | 114 | extern int __init pcibios_init(void); |
115 | extern int pci_legacy_init(void); | ||
118 | 116 | ||
119 | /* pci-mmconfig.c */ | 117 | /* pci-mmconfig.c */ |
120 | 118 | ||
@@ -182,3 +180,13 @@ static inline void mmio_config_writel(void __iomem *pos, u32 val) | |||
182 | { | 180 | { |
183 | asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory"); | 181 | asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory"); |
184 | } | 182 | } |
183 | |||
184 | #ifdef CONFIG_PCI | ||
185 | # ifdef CONFIG_ACPI | ||
186 | # define x86_default_pci_init pci_acpi_init | ||
187 | # else | ||
188 | # define x86_default_pci_init pci_legacy_init | ||
189 | # endif | ||
190 | #else | ||
191 | # define x86_default_pci_init NULL | ||
192 | #endif | ||
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index 18e496c98ff0..86b1506f4179 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h | |||
@@ -37,10 +37,8 @@ void setup_bios_corruption_check(void); | |||
37 | 37 | ||
38 | #ifdef CONFIG_X86_VISWS | 38 | #ifdef CONFIG_X86_VISWS |
39 | extern void visws_early_detect(void); | 39 | extern void visws_early_detect(void); |
40 | extern int is_visws_box(void); | ||
41 | #else | 40 | #else |
42 | static inline void visws_early_detect(void) { } | 41 | static inline void visws_early_detect(void) { } |
43 | static inline int is_visws_box(void) { return 0; } | ||
44 | #endif | 42 | #endif |
45 | 43 | ||
46 | extern unsigned long saved_video_mode; | 44 | extern unsigned long saved_video_mode; |
diff --git a/arch/x86/include/asm/visws/cobalt.h b/arch/x86/include/asm/visws/cobalt.h index 166adf61e770..2edb37637ead 100644 --- a/arch/x86/include/asm/visws/cobalt.h +++ b/arch/x86/include/asm/visws/cobalt.h | |||
@@ -122,4 +122,6 @@ extern char visws_board_type; | |||
122 | 122 | ||
123 | extern char visws_board_rev; | 123 | extern char visws_board_rev; |
124 | 124 | ||
125 | extern int pci_visws_init(void); | ||
126 | |||
125 | #endif /* _ASM_X86_VISWS_COBALT_H */ | 127 | #endif /* _ASM_X86_VISWS_COBALT_H */ |
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index ea0e8ea15e15..f145d843f03d 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h | |||
@@ -98,6 +98,14 @@ struct x86_init_iommu { | |||
98 | int (*iommu_init)(void); | 98 | int (*iommu_init)(void); |
99 | }; | 99 | }; |
100 | 100 | ||
101 | /* | ||
102 | * struct x86_init_pci - platform specific pci init functions | ||
103 | * @init: platform specific pci init | ||
104 | */ | ||
105 | struct x86_init_pci { | ||
106 | int (*init)(void); | ||
107 | }; | ||
108 | |||
101 | /** | 109 | /** |
102 | * struct x86_init_ops - functions for platform specific setup | 110 | * struct x86_init_ops - functions for platform specific setup |
103 | * | 111 | * |
@@ -110,6 +118,7 @@ struct x86_init_ops { | |||
110 | struct x86_init_paging paging; | 118 | struct x86_init_paging paging; |
111 | struct x86_init_timers timers; | 119 | struct x86_init_timers timers; |
112 | struct x86_init_iommu iommu; | 120 | struct x86_init_iommu iommu; |
121 | struct x86_init_pci pci; | ||
113 | }; | 122 | }; |
114 | 123 | ||
115 | /** | 124 | /** |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0acbcdfa5ca4..054a5f5548b0 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | 37 | ||
38 | #include <asm/pci_x86.h> | ||
38 | #include <asm/pgtable.h> | 39 | #include <asm/pgtable.h> |
39 | #include <asm/io_apic.h> | 40 | #include <asm/io_apic.h> |
40 | #include <asm/apic.h> | 41 | #include <asm/apic.h> |
@@ -1604,6 +1605,9 @@ int __init acpi_boot_init(void) | |||
1604 | 1605 | ||
1605 | acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); | 1606 | acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); |
1606 | 1607 | ||
1608 | if (!acpi_noirq) | ||
1609 | x86_init.pci.init = pci_acpi_init; | ||
1610 | |||
1607 | return 0; | 1611 | return 0; |
1608 | } | 1612 | } |
1609 | 1613 | ||
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 98c4665f251c..be5c4fd47778 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -277,6 +277,7 @@ static __init void early_check_numaq(void) | |||
277 | x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus; | 277 | x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus; |
278 | x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info; | 278 | x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info; |
279 | x86_init.timers.tsc_pre_init = numaq_tsc_init; | 279 | x86_init.timers.tsc_pre_init = numaq_tsc_init; |
280 | x86_init.pci.init = pci_numaq_init; | ||
280 | } | 281 | } |
281 | } | 282 | } |
282 | 283 | ||
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c index 34a279a7471d..843e9d30a1e3 100644 --- a/arch/x86/kernel/visws_quirks.c +++ b/arch/x86/kernel/visws_quirks.c | |||
@@ -49,11 +49,6 @@ extern int no_broadcast; | |||
49 | char visws_board_type = -1; | 49 | char visws_board_type = -1; |
50 | char visws_board_rev = -1; | 50 | char visws_board_rev = -1; |
51 | 51 | ||
52 | int is_visws_box(void) | ||
53 | { | ||
54 | return visws_board_type >= 0; | ||
55 | } | ||
56 | |||
57 | static void __init visws_time_init(void) | 52 | static void __init visws_time_init(void) |
58 | { | 53 | { |
59 | printk(KERN_INFO "Starting Cobalt Timer system clock\n"); | 54 | printk(KERN_INFO "Starting Cobalt Timer system clock\n"); |
@@ -242,6 +237,7 @@ void __init visws_early_detect(void) | |||
242 | x86_init.irqs.pre_vector_init = visws_pre_intr_init; | 237 | x86_init.irqs.pre_vector_init = visws_pre_intr_init; |
243 | x86_init.irqs.trap_init = visws_trap_init; | 238 | x86_init.irqs.trap_init = visws_trap_init; |
244 | x86_init.timers.timer_init = visws_time_init; | 239 | x86_init.timers.timer_init = visws_time_init; |
240 | x86_init.pci.init = pci_visws_init; | ||
245 | 241 | ||
246 | /* | 242 | /* |
247 | * Install reboot quirks: | 243 | * Install reboot quirks: |
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index ccd179dec36e..81faa6d67d69 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <asm/bios_ebda.h> | 8 | #include <asm/bios_ebda.h> |
9 | #include <asm/paravirt.h> | 9 | #include <asm/paravirt.h> |
10 | #include <asm/pci_x86.h> | ||
10 | #include <asm/mpspec.h> | 11 | #include <asm/mpspec.h> |
11 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
12 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
@@ -70,6 +71,10 @@ struct x86_init_ops x86_init __initdata = { | |||
70 | .iommu = { | 71 | .iommu = { |
71 | .iommu_init = iommu_init_noop, | 72 | .iommu_init = iommu_init_noop, |
72 | }, | 73 | }, |
74 | |||
75 | .pci = { | ||
76 | .init = x86_default_pci_init, | ||
77 | }, | ||
73 | }; | 78 | }; |
74 | 79 | ||
75 | struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { | 80 | struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 959e548a7039..73b3fe9aa716 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -282,15 +282,11 @@ int __init pci_acpi_init(void) | |||
282 | { | 282 | { |
283 | struct pci_dev *dev = NULL; | 283 | struct pci_dev *dev = NULL; |
284 | 284 | ||
285 | if (pcibios_scanned) | ||
286 | return 0; | ||
287 | |||
288 | if (acpi_noirq) | 285 | if (acpi_noirq) |
289 | return 0; | 286 | return -ENODEV; |
290 | 287 | ||
291 | printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); | 288 | printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); |
292 | acpi_irq_penalty_init(); | 289 | acpi_irq_penalty_init(); |
293 | pcibios_scanned++; | ||
294 | pcibios_enable_irq = acpi_pci_irq_enable; | 290 | pcibios_enable_irq = acpi_pci_irq_enable; |
295 | pcibios_disable_irq = acpi_pci_irq_disable; | 291 | pcibios_disable_irq = acpi_pci_irq_disable; |
296 | 292 | ||
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index d2552c68e94d..f5770b5846a6 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -72,12 +72,6 @@ struct pci_ops pci_root_ops = { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * legacy, numa, and acpi all want to call pcibios_scan_root | ||
76 | * from their initcalls. This flag prevents that. | ||
77 | */ | ||
78 | int pcibios_scanned; | ||
79 | |||
80 | /* | ||
81 | * This interrupt-safe spinlock protects all accesses to PCI | 75 | * This interrupt-safe spinlock protects all accesses to PCI |
82 | * configuration space. | 76 | * configuration space. |
83 | */ | 77 | */ |
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index 4061bb0f267d..0daf264ddb6c 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -35,16 +35,13 @@ static void __devinit pcibios_fixup_peer_bridges(void) | |||
35 | } | 35 | } |
36 | } | 36 | } |
37 | 37 | ||
38 | static int __init pci_legacy_init(void) | 38 | int __init pci_legacy_init(void) |
39 | { | 39 | { |
40 | if (!raw_pci_ops) { | 40 | if (!raw_pci_ops) { |
41 | printk("PCI: System does not support PCI\n"); | 41 | printk("PCI: System does not support PCI\n"); |
42 | return 0; | 42 | return 0; |
43 | } | 43 | } |
44 | 44 | ||
45 | if (pcibios_scanned++) | ||
46 | return 0; | ||
47 | |||
48 | printk("PCI: Probing PCI hardware\n"); | 45 | printk("PCI: Probing PCI hardware\n"); |
49 | pci_root_bus = pcibios_scan_root(0); | 46 | pci_root_bus = pcibios_scan_root(0); |
50 | if (pci_root_bus) | 47 | if (pci_root_bus) |
@@ -55,16 +52,13 @@ static int __init pci_legacy_init(void) | |||
55 | 52 | ||
56 | int __init pci_subsys_init(void) | 53 | int __init pci_subsys_init(void) |
57 | { | 54 | { |
58 | #ifdef CONFIG_X86_NUMAQ | 55 | /* |
59 | pci_numaq_init(); | 56 | * The init function returns an non zero value when |
60 | #endif | 57 | * pci_legacy_init should be invoked. |
61 | #ifdef CONFIG_ACPI | 58 | */ |
62 | pci_acpi_init(); | 59 | if (x86_init.pci.init()) |
63 | #endif | 60 | pci_legacy_init(); |
64 | #ifdef CONFIG_X86_VISWS | 61 | |
65 | pci_visws_init(); | ||
66 | #endif | ||
67 | pci_legacy_init(); | ||
68 | pcibios_fixup_peer_bridges(); | 62 | pcibios_fixup_peer_bridges(); |
69 | pcibios_irq_init(); | 63 | pcibios_irq_init(); |
70 | pcibios_init(); | 64 | pcibios_init(); |
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 8eb295e116f6..45c0c9e45903 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c | |||
@@ -152,14 +152,8 @@ int __init pci_numaq_init(void) | |||
152 | { | 152 | { |
153 | int quad; | 153 | int quad; |
154 | 154 | ||
155 | if (!found_numaq) | ||
156 | return 0; | ||
157 | |||
158 | raw_pci_ops = &pci_direct_conf1_mq; | 155 | raw_pci_ops = &pci_direct_conf1_mq; |
159 | 156 | ||
160 | if (pcibios_scanned++) | ||
161 | return 0; | ||
162 | |||
163 | pci_root_bus = pcibios_scan_root(0); | 157 | pci_root_bus = pcibios_scan_root(0); |
164 | if (pci_root_bus) | 158 | if (pci_root_bus) |
165 | pci_bus_add_devices(pci_root_bus); | 159 | pci_bus_add_devices(pci_root_bus); |
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c index bcead7a46871..03008f72eb04 100644 --- a/arch/x86/pci/visws.c +++ b/arch/x86/pci/visws.c | |||
@@ -69,9 +69,6 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
69 | 69 | ||
70 | int __init pci_visws_init(void) | 70 | int __init pci_visws_init(void) |
71 | { | 71 | { |
72 | if (!is_visws_box()) | ||
73 | return -1; | ||
74 | |||
75 | pcibios_enable_irq = &pci_visws_enable_irq; | 72 | pcibios_enable_irq = &pci_visws_enable_irq; |
76 | pcibios_disable_irq = &pci_visws_disable_irq; | 73 | pcibios_disable_irq = &pci_visws_disable_irq; |
77 | 74 | ||
@@ -90,5 +87,6 @@ int __init pci_visws_init(void) | |||
90 | pci_scan_bus_with_sysdata(pci_bus1); | 87 | pci_scan_bus_with_sysdata(pci_bus1); |
91 | pci_fixup_irqs(pci_common_swizzle, visws_map_irq); | 88 | pci_fixup_irqs(pci_common_swizzle, visws_map_irq); |
92 | pcibios_resource_survey(); | 89 | pcibios_resource_survey(); |
93 | return 0; | 90 | /* Request bus scan */ |
91 | return 1; | ||
94 | } | 92 | } |