Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thomas Gleixner and committed by
H. Peter Anvin
b72d0db9 cf4c43dd

+53 -46
+1
arch/x86/include/asm/numaq.h
··· 30 30 31 31 extern int found_numaq; 32 32 extern int get_memcfg_numaq(void); 33 + extern int pci_numaq_init(void); 33 34 34 35 extern void *xquad_portio; 35 36
+8 -1
arch/x86/include/asm/pci.h
··· 45 45 46 46 #ifdef CONFIG_PCI 47 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 54 #else 49 - #define pcibios_assign_all_busses() 0 55 + # define pcibios_assign_all_busses() 0 56 + # define x86_default_pci_init NULL 50 57 #endif 51 58 52 59 extern unsigned long pci_mem_start;
+11 -3
arch/x86/include/asm/pci_x86.h
··· 82 82 83 83 extern unsigned int pcibios_irq_mask; 84 84 85 - extern int pcibios_scanned; 86 85 extern spinlock_t pci_config_lock; 87 86 88 87 extern int (*pcibios_enable_irq)(struct pci_dev *dev); ··· 111 112 /* some common used subsys_initcalls */ 112 113 extern int __init pci_acpi_init(void); 113 114 extern int __init pcibios_irq_init(void); 114 - extern int __init pci_visws_init(void); 115 - extern int __init pci_numaq_init(void); 116 115 extern int __init pcibios_init(void); 116 + extern int pci_legacy_init(void); 117 117 118 118 /* pci-mmconfig.c */ 119 119 ··· 180 182 { 181 183 asm volatile("movl %%eax,(%1)" : : "a" (val), "r" (pos) : "memory"); 182 184 } 185 + 186 + #ifdef CONFIG_PCI 187 + # ifdef CONFIG_ACPI 188 + # define x86_default_pci_init pci_acpi_init 189 + # else 190 + # define x86_default_pci_init pci_legacy_init 191 + # endif 192 + #else 193 + # define x86_default_pci_init NULL 194 + #endif
-2
arch/x86/include/asm/setup.h
··· 37 37 38 38 #ifdef CONFIG_X86_VISWS 39 39 extern void visws_early_detect(void); 40 - extern int is_visws_box(void); 41 40 #else 42 41 static inline void visws_early_detect(void) { } 43 - static inline int is_visws_box(void) { return 0; } 44 42 #endif 45 43 46 44 extern unsigned long saved_video_mode;
+2
arch/x86/include/asm/visws/cobalt.h
··· 122 122 123 123 extern char visws_board_rev; 124 124 125 + extern int pci_visws_init(void); 126 + 125 127 #endif /* _ASM_X86_VISWS_COBALT_H */
+9
arch/x86/include/asm/x86_init.h
··· 98 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 110 * struct x86_init_ops - functions for platform specific setup 103 111 * ··· 118 110 struct x86_init_paging paging; 119 111 struct x86_init_timers timers; 120 112 struct x86_init_iommu iommu; 113 + struct x86_init_pci pci; 121 114 }; 122 115 123 116 /**
+4
arch/x86/kernel/acpi/boot.c
··· 35 35 #include <linux/ioport.h> 36 36 #include <linux/pci.h> 37 37 38 + #include <asm/pci_x86.h> 38 39 #include <asm/pgtable.h> 39 40 #include <asm/io_apic.h> 40 41 #include <asm/apic.h> ··· 1604 1603 acpi_process_madt(); 1605 1604 1606 1605 acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet); 1606 + 1607 + if (!acpi_noirq) 1608 + x86_init.pci.init = pci_acpi_init; 1607 1609 1608 1610 return 0; 1609 1611 }
+1
arch/x86/kernel/apic/numaq_32.c
··· 277 277 x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus; 278 278 x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info; 279 279 x86_init.timers.tsc_pre_init = numaq_tsc_init; 280 + x86_init.pci.init = pci_numaq_init; 280 281 } 281 282 } 282 283
+1 -5
arch/x86/kernel/visws_quirks.c
··· 49 49 char visws_board_type = -1; 50 50 char visws_board_rev = -1; 51 51 52 - int is_visws_box(void) 53 - { 54 - return visws_board_type >= 0; 55 - } 56 - 57 52 static void __init visws_time_init(void) 58 53 { 59 54 printk(KERN_INFO "Starting Cobalt Timer system clock\n"); ··· 237 242 x86_init.irqs.pre_vector_init = visws_pre_intr_init; 238 243 x86_init.irqs.trap_init = visws_trap_init; 239 244 x86_init.timers.timer_init = visws_time_init; 245 + x86_init.pci.init = pci_visws_init; 240 246 241 247 /* 242 248 * Install reboot quirks:
+5
arch/x86/kernel/x86_init.c
··· 7 7 8 8 #include <asm/bios_ebda.h> 9 9 #include <asm/paravirt.h> 10 + #include <asm/pci_x86.h> 10 11 #include <asm/mpspec.h> 11 12 #include <asm/setup.h> 12 13 #include <asm/apic.h> ··· 70 69 71 70 .iommu = { 72 71 .iommu_init = iommu_init_noop, 72 + }, 73 + 74 + .pci = { 75 + .init = x86_default_pci_init, 73 76 }, 74 77 }; 75 78
+1 -5
arch/x86/pci/acpi.c
··· 282 282 { 283 283 struct pci_dev *dev = NULL; 284 284 285 - if (pcibios_scanned) 286 - return 0; 287 - 288 285 if (acpi_noirq) 289 - return 0; 286 + return -ENODEV; 290 287 291 288 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); 292 289 acpi_irq_penalty_init(); 293 - pcibios_scanned++; 294 290 pcibios_enable_irq = acpi_pci_irq_enable; 295 291 pcibios_disable_irq = acpi_pci_irq_disable; 296 292
-6
arch/x86/pci/common.c
··· 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 75 * This interrupt-safe spinlock protects all accesses to PCI 82 76 * configuration space. 83 77 */
+8 -14
arch/x86/pci/legacy.c
··· 35 35 } 36 36 } 37 37 38 - static int __init pci_legacy_init(void) 38 + int __init pci_legacy_init(void) 39 39 { 40 40 if (!raw_pci_ops) { 41 41 printk("PCI: System does not support PCI\n"); 42 42 return 0; 43 43 } 44 - 45 - if (pcibios_scanned++) 46 - return 0; 47 44 48 45 printk("PCI: Probing PCI hardware\n"); 49 46 pci_root_bus = pcibios_scan_root(0); ··· 52 55 53 56 int __init pci_subsys_init(void) 54 57 { 55 - #ifdef CONFIG_X86_NUMAQ 56 - pci_numaq_init(); 57 - #endif 58 - #ifdef CONFIG_ACPI 59 - pci_acpi_init(); 60 - #endif 61 - #ifdef CONFIG_X86_VISWS 62 - pci_visws_init(); 63 - #endif 64 - pci_legacy_init(); 58 + /* 59 + * The init function returns an non zero value when 60 + * pci_legacy_init should be invoked. 61 + */ 62 + if (x86_init.pci.init()) 63 + pci_legacy_init(); 64 + 65 65 pcibios_fixup_peer_bridges(); 66 66 pcibios_irq_init(); 67 67 pcibios_init();
-6
arch/x86/pci/numaq_32.c
··· 152 152 { 153 153 int quad; 154 154 155 - if (!found_numaq) 156 - return 0; 157 - 158 155 raw_pci_ops = &pci_direct_conf1_mq; 159 - 160 - if (pcibios_scanned++) 161 - return 0; 162 156 163 157 pci_root_bus = pcibios_scan_root(0); 164 158 if (pci_root_bus)
+2 -4
arch/x86/pci/visws.c
··· 69 69 70 70 int __init pci_visws_init(void) 71 71 { 72 - if (!is_visws_box()) 73 - return -1; 74 - 75 72 pcibios_enable_irq = &pci_visws_enable_irq; 76 73 pcibios_disable_irq = &pci_visws_disable_irq; 77 74 ··· 87 90 pci_scan_bus_with_sysdata(pci_bus1); 88 91 pci_fixup_irqs(pci_common_swizzle, visws_map_irq); 89 92 pcibios_resource_survey(); 90 - return 0; 93 + /* Request bus scan */ 94 + return 1; 91 95 }