diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 7edd1a40fab3..a45844c7e3a3 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c @@ -279,3 +279,32 @@ __init int iommu_setup(char *p) } return 1; } +__setup("iommu=", iommu_setup); + +void __init pci_iommu_alloc(void) +{ + /* + * The order of these functions is important for + * fall-back/fail-over reasons + */ +#ifdef CONFIG_IOMMU + iommu_hole_init(); +#endif + +#ifdef CONFIG_SWIOTLB + pci_swiotlb_init(); +#endif +} + +static int __init pci_iommu_init(void) +{ +#ifdef CONFIG_IOMMU + gart_iommu_init(); +#endif + + no_iommu_init(); + return 0; +} + +/* Must execute after PCI subsystem */ +fs_initcall(pci_iommu_init); diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 4f67957d2b42..9a93954bed37 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -571,7 +571,7 @@ static struct dma_mapping_ops gart_dma_ops = { .unmap_sg = gart_unmap_sg, }; -static int __init pci_iommu_init(void) +void __init gart_iommu_init(void) { struct agp_kern_info info; unsigned long aper_size; @@ -581,7 +581,7 @@ static int __init pci_iommu_init(void) if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0) { printk(KERN_INFO "PCI-GART: No AMD northbridge found.\n"); - return -ENODEV; + return; } #ifndef CONFIG_AGP_AMD64 @@ -595,11 +595,11 @@ static int __init pci_iommu_init(void) #endif if (swiotlb) - return -ENODEV; + return; /* Did we detect a different HW IOMMU? */ if (iommu_detected && !iommu_aperture) - return -1; + return; if (no_iommu || (!force_iommu && end_pfn <= MAX_DMA32_PFN) || @@ -611,7 +611,7 @@ static int __init pci_iommu_init(void) "but IOMMU not available.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); } - return -ENODEV; + return; } printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); @@ -678,11 +678,10 @@ static int __init pci_iommu_init(void) flush_gart(); dma_ops = &gart_dma_ops; - return 0; } /* Must execute after PCI subsystem */ -fs_initcall(pci_iommu_init); +fs_initcall(gart_iommu_init); void gart_parse_options(char *p) { diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index a9de8f02671f..04b2d7b92d17 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include @@ -702,10 +701,6 @@ void __init setup_arch(char **cmdline_p) e820_setup_gap(); -#ifdef CONFIG_IOMMU - iommu_hole_init(); -#endif - #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con; diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index b83645a2e02d..2f5f5b11e9d0 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -41,8 +41,6 @@ #include #include #include -#include -#include #ifndef Dprintk #define Dprintk(x...) @@ -587,10 +585,7 @@ void __init mem_init(void) { long codesize, reservedpages, datasize, initsize; -#ifdef CONFIG_SWIOTLB - pci_swiotlb_init(); -#endif - no_iommu_init(); + pci_iommu_alloc(); /* How many end-of-memory variables you have, grandma! */ max_low_pfn = end_pfn; diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 3374d34c4acd..4dbc07c54f7a 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -39,8 +39,8 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq); #include #include #include -#include /* for have_iommu */ +extern void pci_iommu_alloc(void); extern int iommu_setup(char *opt); /* The PCI address space does equal the physical memory diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 9d3335b4e9b6..038fe1f47e6f 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -37,7 +37,6 @@ extern void ia32_sysenter_target(void); extern void config_acpi_tables(void); extern void ia32_syscall(void); -extern void iommu_hole_init(void); extern int pmtimer_mark_offset(void); extern void pmtimer_resume(void); @@ -101,13 +100,9 @@ extern int unsynchronized_tsc(void); extern void select_idle_routine(const struct cpuinfo_x86 *c); -extern void gart_parse_options(char *); -extern void __init no_iommu_init(void); - extern unsigned long table_start, table_end; extern int exception_trace; -extern int force_iommu, no_iommu; extern int using_apic_timer; extern int disable_apic; extern unsigned cpu_khz; @@ -116,8 +111,13 @@ extern int skip_ioapic_setup; extern int acpi_ht; extern int acpi_disabled; +extern void no_iommu_init(void); +extern int force_iommu, no_iommu; extern int iommu_detected; #ifdef CONFIG_IOMMU +extern void gart_iommu_init(void); +extern void gart_parse_options(char *); +extern void iommu_hole_init(void); extern int fallback_aper_order; extern int fallback_aper_force; extern int iommu_aperture;