aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-16 17:53:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-16 17:53:01 -0500
commit6f51ee709e4c6b56f2c2a071da2d056a109b9d26 (patch)
tree3287f25e522e362725b8a2fe72f8862f17ddb8ba /arch
parent205dc205ed3ba748bab9770016bbbffb68558146 (diff)
parentfd522d279235b8bcafc39c1040895fe2d938d1e7 (diff)
Merge tag 'iommu-config-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC/iommu configuration update from Arnd Bergmann: "The iomm-config branch contains work from Will Deacon, quoting his description: This series adds automatic IOMMU and DMA-mapping configuration for OF-based DMA masters described using the generic IOMMU devicetree bindings. Although there is plenty of future work around splitting up iommu_ops, adding default IOMMU domains and sorting out automatic IOMMU group creation for the platform_bus, this is already useful enough for people to port over their IOMMU drivers and start using the new probing infrastructure (indeed, Marek has patches queued for the Exynos IOMMU). The branch touches core ARM and IOMMU driver files, and the respective maintainers (Russell King and Joerg Roedel) agreed to have the contents merged through the arm-soc tree. The final version was ready just before the merge window, so we ended up delaying it a bit longer than the rest, but we don't expect to see regressions because this is just additional infrastructure that will get used in drivers starting in 3.20 but is unused so far" * tag 'iommu-config-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: iommu: store DT-probed IOMMU data privately arm: dma-mapping: plumb our iommu mapping ops into arch_setup_dma_ops arm: call iommu_init before of_platform_populate dma-mapping: detect and configure IOMMU in of_dma_configure iommu: fix initialization without 'add_device' callback iommu: provide helper function to configure an IOMMU for an of master iommu: add new iommu_ops callback for adding an OF device dma-mapping: replace set_arch_dma_coherent_ops with arch_setup_dma_ops iommu: provide early initialisation hook for IOMMU drivers
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/dma-mapping.h13
-rw-r--r--arch/arm/kernel/setup.c2
-rw-r--r--arch/arm/mm/dma-mapping.c84
3 files changed, 85 insertions, 14 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index e6e3446abdf6..b52101d37ec7 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -121,13 +121,12 @@ static inline unsigned long dma_max_pfn(struct device *dev)
121} 121}
122#define dma_max_pfn(dev) dma_max_pfn(dev) 122#define dma_max_pfn(dev) dma_max_pfn(dev)
123 123
124static inline int set_arch_dma_coherent_ops(struct device *dev) 124#define arch_setup_dma_ops arch_setup_dma_ops
125{ 125extern void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
126 dev->archdata.dma_coherent = true; 126 struct iommu_ops *iommu, bool coherent);
127 set_dma_ops(dev, &arm_coherent_dma_ops); 127
128 return 0; 128#define arch_teardown_dma_ops arch_teardown_dma_ops
129} 129extern void arch_teardown_dma_ops(struct device *dev);
130#define set_arch_dma_coherent_ops(dev) set_arch_dma_coherent_ops(dev)
131 130
132/* do not use this function in a driver */ 131/* do not use this function in a driver */
133static inline bool is_device_dma_coherent(struct device *dev) 132static inline bool is_device_dma_coherent(struct device *dev)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8361652b6dab..f9c863911038 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -18,6 +18,7 @@
18#include <linux/bootmem.h> 18#include <linux/bootmem.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/screen_info.h> 20#include <linux/screen_info.h>
21#include <linux/of_iommu.h>
21#include <linux/of_platform.h> 22#include <linux/of_platform.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/kexec.h> 24#include <linux/kexec.h>
@@ -806,6 +807,7 @@ static int __init customize_machine(void)
806 * machine from the device tree, if no callback is provided, 807 * machine from the device tree, if no callback is provided,
807 * otherwise we would always need an init_machine callback. 808 * otherwise we would always need an init_machine callback.
808 */ 809 */
810 of_iommu_init();
809 if (machine_desc->init_machine) 811 if (machine_desc->init_machine)
810 machine_desc->init_machine(); 812 machine_desc->init_machine();
811#ifdef CONFIG_OF 813#ifdef CONFIG_OF
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index e8907117861e..7864797609b3 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1947,9 +1947,8 @@ EXPORT_SYMBOL_GPL(arm_iommu_release_mapping);
1947 * arm_iommu_create_mapping) 1947 * arm_iommu_create_mapping)
1948 * 1948 *
1949 * Attaches specified io address space mapping to the provided device, 1949 * Attaches specified io address space mapping to the provided device,
1950 * this replaces the dma operations (dma_map_ops pointer) with the 1950 * More than one client might be attached to the same io address space
1951 * IOMMU aware version. More than one client might be attached to 1951 * mapping.
1952 * the same io address space mapping.
1953 */ 1952 */
1954int arm_iommu_attach_device(struct device *dev, 1953int arm_iommu_attach_device(struct device *dev,
1955 struct dma_iommu_mapping *mapping) 1954 struct dma_iommu_mapping *mapping)
@@ -1962,7 +1961,6 @@ int arm_iommu_attach_device(struct device *dev,
1962 1961
1963 kref_get(&mapping->kref); 1962 kref_get(&mapping->kref);
1964 dev->archdata.mapping = mapping; 1963 dev->archdata.mapping = mapping;
1965 set_dma_ops(dev, &iommu_ops);
1966 1964
1967 pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev)); 1965 pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev));
1968 return 0; 1966 return 0;
@@ -1974,7 +1972,6 @@ EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
1974 * @dev: valid struct device pointer 1972 * @dev: valid struct device pointer
1975 * 1973 *
1976 * Detaches the provided device from a previously attached map. 1974 * Detaches the provided device from a previously attached map.
1977 * This voids the dma operations (dma_map_ops pointer)
1978 */ 1975 */
1979void arm_iommu_detach_device(struct device *dev) 1976void arm_iommu_detach_device(struct device *dev)
1980{ 1977{
@@ -1989,10 +1986,83 @@ void arm_iommu_detach_device(struct device *dev)
1989 iommu_detach_device(mapping->domain, dev); 1986 iommu_detach_device(mapping->domain, dev);
1990 kref_put(&mapping->kref, release_iommu_mapping); 1987 kref_put(&mapping->kref, release_iommu_mapping);
1991 dev->archdata.mapping = NULL; 1988 dev->archdata.mapping = NULL;
1992 set_dma_ops(dev, NULL);
1993 1989
1994 pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev)); 1990 pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
1995} 1991}
1996EXPORT_SYMBOL_GPL(arm_iommu_detach_device); 1992EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
1997 1993
1998#endif 1994static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
1995{
1996 return coherent ? &iommu_coherent_ops : &iommu_ops;
1997}
1998
1999static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
2000 struct iommu_ops *iommu)
2001{
2002 struct dma_iommu_mapping *mapping;
2003
2004 if (!iommu)
2005 return false;
2006
2007 mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
2008 if (IS_ERR(mapping)) {
2009 pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
2010 size, dev_name(dev));
2011 return false;
2012 }
2013
2014 if (arm_iommu_attach_device(dev, mapping)) {
2015 pr_warn("Failed to attached device %s to IOMMU_mapping\n",
2016 dev_name(dev));
2017 arm_iommu_release_mapping(mapping);
2018 return false;
2019 }
2020
2021 return true;
2022}
2023
2024static void arm_teardown_iommu_dma_ops(struct device *dev)
2025{
2026 struct dma_iommu_mapping *mapping = dev->archdata.mapping;
2027
2028 arm_iommu_detach_device(dev);
2029 arm_iommu_release_mapping(mapping);
2030}
2031
2032#else
2033
2034static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
2035 struct iommu_ops *iommu)
2036{
2037 return false;
2038}
2039
2040static void arm_teardown_iommu_dma_ops(struct device *dev) { }
2041
2042#define arm_get_iommu_dma_map_ops arm_get_dma_map_ops
2043
2044#endif /* CONFIG_ARM_DMA_USE_IOMMU */
2045
2046static struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
2047{
2048 return coherent ? &arm_coherent_dma_ops : &arm_dma_ops;
2049}
2050
2051void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
2052 struct iommu_ops *iommu, bool coherent)
2053{
2054 struct dma_map_ops *dma_ops;
2055
2056 dev->archdata.dma_coherent = coherent;
2057 if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu))
2058 dma_ops = arm_get_iommu_dma_map_ops(coherent);
2059 else
2060 dma_ops = arm_get_dma_map_ops(coherent);
2061
2062 set_dma_ops(dev, dma_ops);
2063}
2064
2065void arch_teardown_dma_ops(struct device *dev)
2066{
2067 arm_teardown_iommu_dma_ops(dev);
2068}