summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2019-08-13 03:25:09 -0400
committerTony Luck <tony.luck@intel.com>2019-08-16 14:33:57 -0400
commit974f83ec1e5afeeb4c9028feb74ffa4ee70e71b7 (patch)
tree79d9378ae00206cda4d2a41f2a79361b014c4fb5
parent16567ca85fce11e2a20f22404ed0ceb133c4408e (diff)
ia64: rework iommu probing
ia64 currently organizes the iommu probing along machves, which isn't very helpful. Instead just try to probe for Intel IOMMUs in mem_init as they are properly described in ACPI and if none was found initialize the swiotlb buffer. The HP SBA handling is then only done delayed when the actual hardware is probed. Only in the case that we actually found usable IOMMUs we then set up the DMA ops and free the not needed swiotlb buffer. This scheme gets rid of the need for the dma_init machvec operation, and the dig_vtd machvec. Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lkml.kernel.org/r/20190813072514.23299-24-hch@lst.de Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/Kconfig5
-rw-r--r--arch/ia64/Makefile1
-rw-r--r--arch/ia64/dig/Makefile5
-rw-r--r--arch/ia64/dig/machvec_vtd.c3
-rw-r--r--arch/ia64/hp/common/sba_iommu.c82
-rw-r--r--arch/ia64/include/asm/acpi.h2
-rw-r--r--arch/ia64/include/asm/machvec.h11
-rw-r--r--arch/ia64/include/asm/machvec_dig_vtd.h19
-rw-r--r--arch/ia64/include/asm/machvec_hpzx1.h2
-rw-r--r--arch/ia64/include/asm/pci.h3
-rw-r--r--arch/ia64/kernel/acpi.c15
-rw-r--r--arch/ia64/kernel/dma-mapping.c6
-rw-r--r--arch/ia64/kernel/pci-dma.c21
-rw-r--r--arch/ia64/mm/init.c16
14 files changed, 40 insertions, 151 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index a42ab41ee8ab..9a8c7ec60cfc 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -146,11 +146,6 @@ config IA64_DIG
146 bool "DIG-compliant" 146 bool "DIG-compliant"
147 select SWIOTLB 147 select SWIOTLB
148 148
149config IA64_DIG_VTD
150 bool "DIG+Intel+IOMMU"
151 select INTEL_IOMMU
152 select PCI_MSI
153
154config IA64_HP_ZX1 149config IA64_HP_ZX1
155 bool "HP-zx1/sx1000" 150 bool "HP-zx1/sx1000"
156 help 151 help
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 0b3647efde5d..22deb5e6f346 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -51,7 +51,6 @@ head-y := arch/ia64/kernel/head.o
51libs-y += arch/ia64/lib/ 51libs-y += arch/ia64/lib/
52core-y += arch/ia64/kernel/ arch/ia64/mm/ 52core-y += arch/ia64/kernel/ arch/ia64/mm/
53core-$(CONFIG_IA64_DIG) += arch/ia64/dig/ 53core-$(CONFIG_IA64_DIG) += arch/ia64/dig/
54core-$(CONFIG_IA64_DIG_VTD) += arch/ia64/dig/
55core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/ 54core-$(CONFIG_IA64_GENERIC) += arch/ia64/dig/
56core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/ 55core-$(CONFIG_IA64_HP_ZX1) += arch/ia64/dig/
57core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ 56core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/
diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
index e7f830825470..5c2f638c31f4 100644
--- a/arch/ia64/dig/Makefile
+++ b/arch/ia64/dig/Makefile
@@ -7,9 +7,4 @@
7# 7#
8 8
9obj-y := setup.o 9obj-y := setup.o
10ifeq ($(CONFIG_INTEL_IOMMU), y)
11obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o
12else
13obj-$(CONFIG_IA64_GENERIC) += machvec.o 10obj-$(CONFIG_IA64_GENERIC) += machvec.o
14endif
15
diff --git a/arch/ia64/dig/machvec_vtd.c b/arch/ia64/dig/machvec_vtd.c
deleted file mode 100644
index 7cd3eb471cad..000000000000
--- a/arch/ia64/dig/machvec_vtd.c
+++ /dev/null
@@ -1,3 +0,0 @@
1#define MACHVEC_PLATFORM_NAME dig_vtd
2#define MACHVEC_PLATFORM_HEADER <asm/machvec_dig_vtd.h>
3#include <asm/machvec_init.h>
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 215fa688b729..a7eff5e6d260 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -35,6 +35,7 @@
35#include <linux/iommu-helper.h> 35#include <linux/iommu-helper.h>
36#include <linux/dma-mapping.h> 36#include <linux/dma-mapping.h>
37#include <linux/prefetch.h> 37#include <linux/prefetch.h>
38#include <linux/swiotlb.h>
38 39
39#include <asm/delay.h> /* ia64_get_itc() */ 40#include <asm/delay.h> /* ia64_get_itc() */
40#include <asm/io.h> 41#include <asm/io.h>
@@ -43,8 +44,6 @@
43 44
44#include <asm/acpi-ext.h> 45#include <asm/acpi-ext.h>
45 46
46extern int swiotlb_late_init_with_default_size (size_t size);
47
48#define PFX "IOC: " 47#define PFX "IOC: "
49 48
50/* 49/*
@@ -2056,27 +2055,33 @@ static int __init acpi_sba_ioc_init_acpi(void)
2056/* This has to run before acpi_scan_init(). */ 2055/* This has to run before acpi_scan_init(). */
2057arch_initcall(acpi_sba_ioc_init_acpi); 2056arch_initcall(acpi_sba_ioc_init_acpi);
2058 2057
2058static int sba_dma_supported (struct device *dev, u64 mask)
2059{
2060 /* make sure it's at least 32bit capable */
2061 return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
2062}
2063
2064static const struct dma_map_ops sba_dma_ops = {
2065 .alloc = sba_alloc_coherent,
2066 .free = sba_free_coherent,
2067 .map_page = sba_map_page,
2068 .unmap_page = sba_unmap_page,
2069 .map_sg = sba_map_sg_attrs,
2070 .unmap_sg = sba_unmap_sg_attrs,
2071 .dma_supported = sba_dma_supported,
2072};
2073
2059static int __init 2074static int __init
2060sba_init(void) 2075sba_init(void)
2061{ 2076{
2062 if (!ia64_platform_is("hpzx1")) 2077 /*
2063 return 0; 2078 * If we are booting a kdump kernel, the sba_iommu will cause devices
2064 2079 * that were not shutdown properly to MCA as soon as they are turned
2065#if defined(CONFIG_IA64_GENERIC) 2080 * back on. Our only option for a successful kdump kernel boot is to
2066 /* If we are booting a kdump kernel, the sba_iommu will 2081 * use swiotlb.
2067 * cause devices that were not shutdown properly to MCA
2068 * as soon as they are turned back on. Our only option for
2069 * a successful kdump kernel boot is to use the swiotlb.
2070 */ 2082 */
2071 if (is_kdump_kernel()) { 2083 if (is_kdump_kernel())
2072 dma_ops = NULL;
2073 if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
2074 panic("Unable to initialize software I/O TLB:"
2075 " Try machvec=dig boot option");
2076 machvec_init("dig");
2077 return 0; 2084 return 0;
2078 }
2079#endif
2080 2085
2081 /* 2086 /*
2082 * ioc_found should be populated by the acpi_sba_ioc_handler's .attach() 2087 * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
@@ -2085,22 +2090,8 @@ sba_init(void)
2085 while (ioc_found) 2090 while (ioc_found)
2086 acpi_sba_ioc_add(ioc_found); 2091 acpi_sba_ioc_add(ioc_found);
2087 2092
2088 if (!ioc_list) { 2093 if (!ioc_list)
2089#ifdef CONFIG_IA64_GENERIC
2090 /*
2091 * If we didn't find something sba_iommu can claim, we
2092 * need to setup the swiotlb and switch to the dig machvec.
2093 */
2094 dma_ops = NULL;
2095 if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
2096 panic("Unable to find SBA IOMMU or initialize "
2097 "software I/O TLB: Try machvec=dig boot option");
2098 machvec_init("dig");
2099#else
2100 panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
2101#endif
2102 return 0; 2094 return 0;
2103 }
2104 2095
2105 { 2096 {
2106 struct pci_bus *b = NULL; 2097 struct pci_bus *b = NULL;
@@ -2108,6 +2099,10 @@ sba_init(void)
2108 sba_connect_bus(b); 2099 sba_connect_bus(b);
2109 } 2100 }
2110 2101
2102 /* no need for swiotlb with the iommu */
2103 swiotlb_exit();
2104 dma_ops = &sba_dma_ops;
2105
2111#ifdef CONFIG_PROC_FS 2106#ifdef CONFIG_PROC_FS
2112 ioc_proc_init(); 2107 ioc_proc_init();
2113#endif 2108#endif
@@ -2123,12 +2118,6 @@ nosbagart(char *str)
2123 return 1; 2118 return 1;
2124} 2119}
2125 2120
2126static int sba_dma_supported (struct device *dev, u64 mask)
2127{
2128 /* make sure it's at least 32bit capable */
2129 return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
2130}
2131
2132__setup("nosbagart", nosbagart); 2121__setup("nosbagart", nosbagart);
2133 2122
2134static int __init 2123static int __init
@@ -2153,18 +2142,3 @@ sba_page_override(char *str)
2153} 2142}
2154 2143
2155__setup("sbapagesize=",sba_page_override); 2144__setup("sbapagesize=",sba_page_override);
2156
2157const struct dma_map_ops sba_dma_ops = {
2158 .alloc = sba_alloc_coherent,
2159 .free = sba_free_coherent,
2160 .map_page = sba_map_page,
2161 .unmap_page = sba_unmap_page,
2162 .map_sg = sba_map_sg_attrs,
2163 .unmap_sg = sba_unmap_sg_attrs,
2164 .dma_supported = sba_dma_supported,
2165};
2166
2167void sba_dma_init(void)
2168{
2169 dma_ops = &sba_dma_ops;
2170}
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index 9e563df73038..be6bf3e499a6 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -43,8 +43,6 @@ static inline const char *acpi_get_sysname (void)
43 return "uv"; 43 return "uv";
44# elif defined (CONFIG_IA64_DIG) 44# elif defined (CONFIG_IA64_DIG)
45 return "dig"; 45 return "dig";
46# elif defined(CONFIG_IA64_DIG_VTD)
47 return "dig_vtd";
48# else 46# else
49# error Unknown platform. Fix acpi.c. 47# error Unknown platform. Fix acpi.c.
50# endif 48# endif
diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h
index fa867e980d87..b22d0499b58c 100644
--- a/arch/ia64/include/asm/machvec.h
+++ b/arch/ia64/include/asm/machvec.h
@@ -16,14 +16,11 @@
16struct device; 16struct device;
17 17
18typedef void ia64_mv_setup_t (char **); 18typedef void ia64_mv_setup_t (char **);
19typedef void ia64_mv_dma_init (void);
20 19
21extern void machvec_setup (char **); 20extern void machvec_setup (char **);
22 21
23# if defined (CONFIG_IA64_DIG) 22# if defined (CONFIG_IA64_DIG)
24# include <asm/machvec_dig.h> 23# include <asm/machvec_dig.h>
25# elif defined(CONFIG_IA64_DIG_VTD)
26# include <asm/machvec_dig_vtd.h>
27# elif defined (CONFIG_IA64_HP_ZX1) 24# elif defined (CONFIG_IA64_HP_ZX1)
28# include <asm/machvec_hpzx1.h> 25# include <asm/machvec_hpzx1.h>
29# elif defined (CONFIG_IA64_SGI_UV) 26# elif defined (CONFIG_IA64_SGI_UV)
@@ -35,7 +32,6 @@ extern void machvec_setup (char **);
35# else 32# else
36# define ia64_platform_name ia64_mv.name 33# define ia64_platform_name ia64_mv.name
37# define platform_setup ia64_mv.setup 34# define platform_setup ia64_mv.setup
38# define platform_dma_init ia64_mv.dma_init
39# endif 35# endif
40 36
41/* __attribute__((__aligned__(16))) is required to make size of the 37/* __attribute__((__aligned__(16))) is required to make size of the
@@ -46,14 +42,12 @@ extern void machvec_setup (char **);
46struct ia64_machine_vector { 42struct ia64_machine_vector {
47 const char *name; 43 const char *name;
48 ia64_mv_setup_t *setup; 44 ia64_mv_setup_t *setup;
49 ia64_mv_dma_init *dma_init;
50} __attribute__((__aligned__(16))); /* align attrib? see above comment */ 45} __attribute__((__aligned__(16))); /* align attrib? see above comment */
51 46
52#define MACHVEC_INIT(name) \ 47#define MACHVEC_INIT(name) \
53{ \ 48{ \
54 #name, \ 49 #name, \
55 platform_setup, \ 50 platform_setup, \
56 platform_dma_init, \
57} 51}
58 52
59extern struct ia64_machine_vector ia64_mv; 53extern struct ia64_machine_vector ia64_mv;
@@ -64,8 +58,6 @@ extern void machvec_init_from_cmdline(const char *cmdline);
64# error Unknown configuration. Update arch/ia64/include/asm/machvec.h. 58# error Unknown configuration. Update arch/ia64/include/asm/machvec.h.
65# endif /* CONFIG_IA64_GENERIC */ 59# endif /* CONFIG_IA64_GENERIC */
66 60
67extern void swiotlb_dma_init(void);
68
69/* 61/*
70 * Define default versions so we can extend machvec for new platforms without having 62 * Define default versions so we can extend machvec for new platforms without having
71 * to update the machvec files for all existing platforms. 63 * to update the machvec files for all existing platforms.
@@ -73,8 +65,5 @@ extern void swiotlb_dma_init(void);
73#ifndef platform_setup 65#ifndef platform_setup
74# define platform_setup machvec_setup 66# define platform_setup machvec_setup
75#endif 67#endif
76#ifndef platform_dma_init
77# define platform_dma_init swiotlb_dma_init
78#endif
79 68
80#endif /* _ASM_IA64_MACHVEC_H */ 69#endif /* _ASM_IA64_MACHVEC_H */
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h
deleted file mode 100644
index bb44eb9039dd..000000000000
--- a/arch/ia64/include/asm/machvec_dig_vtd.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_IA64_MACHVEC_DIG_VTD_h
3#define _ASM_IA64_MACHVEC_DIG_VTD_h
4
5extern ia64_mv_setup_t dig_setup;
6extern ia64_mv_dma_init pci_iommu_alloc;
7
8/*
9 * This stuff has dual use!
10 *
11 * For a generic kernel, the macros are used to initialize the
12 * platform's machvec structure. When compiling a non-generic kernel,
13 * the macros are used directly.
14 */
15#define ia64_platform_name "dig_vtd"
16#define platform_setup dig_setup
17#define platform_dma_init pci_iommu_alloc
18
19#endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */
diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h
index 5299ac38bfb6..7d37998ffdbf 100644
--- a/arch/ia64/include/asm/machvec_hpzx1.h
+++ b/arch/ia64/include/asm/machvec_hpzx1.h
@@ -3,7 +3,6 @@
3#define _ASM_IA64_MACHVEC_HPZX1_h 3#define _ASM_IA64_MACHVEC_HPZX1_h
4 4
5extern ia64_mv_setup_t dig_setup; 5extern ia64_mv_setup_t dig_setup;
6extern ia64_mv_dma_init sba_dma_init;
7 6
8/* 7/*
9 * This stuff has dual use! 8 * This stuff has dual use!
@@ -14,6 +13,5 @@ extern ia64_mv_dma_init sba_dma_init;
14 */ 13 */
15#define ia64_platform_name "hpzx1" 14#define ia64_platform_name "hpzx1"
16#define platform_setup dig_setup 15#define platform_setup dig_setup
17#define platform_dma_init sba_dma_init
18 16
19#endif /* _ASM_IA64_MACHVEC_HPZX1_h */ 17#endif /* _ASM_IA64_MACHVEC_HPZX1_h */
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index ef91b780a3f2..8c163d1d0189 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -69,7 +69,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
69 return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14); 69 return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14);
70} 70}
71 71
72#ifdef CONFIG_INTEL_IOMMU
73extern void pci_iommu_alloc(void);
74#endif
75#endif /* _ASM_IA64_PCI_H */ 72#endif /* _ASM_IA64_PCI_H */
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index a63e472f5317..644f34e4342e 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -65,9 +65,6 @@ acpi_get_sysname(void)
65 struct acpi_table_rsdp *rsdp; 65 struct acpi_table_rsdp *rsdp;
66 struct acpi_table_xsdt *xsdt; 66 struct acpi_table_xsdt *xsdt;
67 struct acpi_table_header *hdr; 67 struct acpi_table_header *hdr;
68#ifdef CONFIG_INTEL_IOMMU
69 u64 i, nentries;
70#endif
71 68
72 rsdp_phys = acpi_find_rsdp(); 69 rsdp_phys = acpi_find_rsdp();
73 if (!rsdp_phys) { 70 if (!rsdp_phys) {
@@ -98,18 +95,6 @@ acpi_get_sysname(void)
98 return "uv"; 95 return "uv";
99 } 96 }
100 97
101#ifdef CONFIG_INTEL_IOMMU
102 /* Look for Intel IOMMU */
103 nentries = (hdr->length - sizeof(*hdr)) /
104 sizeof(xsdt->table_offset_entry[0]);
105 for (i = 0; i < nentries; i++) {
106 hdr = __va(xsdt->table_offset_entry[i]);
107 if (strncmp(hdr->signature, ACPI_SIG_DMAR,
108 sizeof(ACPI_SIG_DMAR) - 1) == 0)
109 return "dig_vtd";
110 }
111#endif
112
113 return "dig"; 98 return "dig";
114} 99}
115#endif /* CONFIG_IA64_GENERIC */ 100#endif /* CONFIG_IA64_GENERIC */
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
index 4be5ee04ccfa..53aaa8597920 100644
--- a/arch/ia64/kernel/dma-mapping.c
+++ b/arch/ia64/kernel/dma-mapping.c
@@ -1,6 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2#include <linux/dma-direct.h> 2#include <linux/dma-direct.h>
3#include <linux/swiotlb.h>
4#include <linux/export.h> 3#include <linux/export.h>
5 4
6/* Set this to 1 if there is a HW IOMMU in the system */ 5/* Set this to 1 if there is a HW IOMMU in the system */
@@ -27,9 +26,4 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
27{ 26{
28 return page_to_pfn(virt_to_page(cpu_addr)); 27 return page_to_pfn(virt_to_page(cpu_addr));
29} 28}
30
31void __init swiotlb_dma_init(void)
32{
33 swiotlb_init(1);
34}
35#endif 29#endif
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index fe988c49f01c..c5a8df9e77d0 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -34,24 +34,3 @@ static int __init pci_iommu_init(void)
34 34
35/* Must execute after PCI subsystem */ 35/* Must execute after PCI subsystem */
36fs_initcall(pci_iommu_init); 36fs_initcall(pci_iommu_init);
37
38void __init pci_iommu_alloc(void)
39{
40 /*
41 * The order of these functions is important for
42 * fall-back/fail-over reasons
43 */
44 detect_intel_iommu();
45
46#ifdef CONFIG_SWIOTLB
47 if (!iommu_detected) {
48#ifdef CONFIG_IA64_GENERIC
49 printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
50 machvec_init("dig");
51 swiotlb_dma_init();
52#else
53 panic("Unable to find Intel IOMMU");
54#endif /* CONFIG_IA64_GENERIC */
55 }
56#endif /* CONFIG_SWIOTLB */
57}
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 9a4a16439900..ed3ced65705e 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -9,6 +9,7 @@
9#include <linux/init.h> 9#include <linux/init.h>
10 10
11#include <linux/dma-noncoherent.h> 11#include <linux/dma-noncoherent.h>
12#include <linux/dmar.h>
12#include <linux/efi.h> 13#include <linux/efi.h>
13#include <linux/elf.h> 14#include <linux/elf.h>
14#include <linux/memblock.h> 15#include <linux/memblock.h>
@@ -23,6 +24,7 @@
23#include <linux/proc_fs.h> 24#include <linux/proc_fs.h>
24#include <linux/bitops.h> 25#include <linux/bitops.h>
25#include <linux/kexec.h> 26#include <linux/kexec.h>
27#include <linux/swiotlb.h>
26 28
27#include <asm/dma.h> 29#include <asm/dma.h>
28#include <asm/io.h> 30#include <asm/io.h>
@@ -633,11 +635,17 @@ mem_init (void)
633 BUG_ON(PTRS_PER_PTE * sizeof(pte_t) != PAGE_SIZE); 635 BUG_ON(PTRS_PER_PTE * sizeof(pte_t) != PAGE_SIZE);
634 636
635 /* 637 /*
636 * This needs to be called _after_ the command line has been parsed but _before_ 638 * This needs to be called _after_ the command line has been parsed but
637 * any drivers that may need the PCI DMA interface are initialized or bootmem has 639 * _before_ any drivers that may need the PCI DMA interface are
638 * been freed. 640 * initialized or bootmem has been freed.
639 */ 641 */
640 platform_dma_init(); 642#ifdef CONFIG_INTEL_IOMMU
643 detect_intel_iommu();
644 if (!iommu_detected)
645#endif
646#ifdef CONFIG_SWIOTLB
647 swiotlb_init(1);
648#endif
641 649
642#ifdef CONFIG_FLATMEM 650#ifdef CONFIG_FLATMEM
643 BUG_ON(!mem_map); 651 BUG_ON(!mem_map);