From: Ohad Ben-Cohen Date: Wed, 1 Jun 2011 23:48:05 +0000 (+0300) Subject: drivers: iommu: move to a dedicated folder X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=ab493a0f0f55d28636ac860ea682d57b84257f10;p=openwrt%2Fstaging%2Fblogic.git drivers: iommu: move to a dedicated folder Create a dedicated folder for iommu drivers, and move the base iommu implementation over there. Grouping the various iommu drivers in a single location will help finding similar problems shared by different platforms, so they could be solved once, in the iommu framework, instead of solved differently (or duplicated) in each driver. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Joerg Roedel --- diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index 1516896e8d17..efb7b7dfc20b 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig @@ -205,9 +205,6 @@ config MSM_GPIOMUX config MSM_V2_TLMM bool -config IOMMU_API - bool - config MSM_SCM bool endif diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 38280ef4a2af..9929e4e11ea0 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -681,6 +681,3 @@ source "lib/Kconfig" config IOMMU_HELPER def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB) - -config IOMMU_API - def_bool (DMAR) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index da349723d411..460d57370016 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -685,6 +685,7 @@ config AMD_IOMMU select SWIOTLB select PCI_MSI select PCI_IOV + select IOMMU_API depends on X86_64 && PCI && ACPI ---help--- With this option you can enable support for AMD IOMMU hardware in @@ -720,9 +721,6 @@ config SWIOTLB config IOMMU_HELPER def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU) -config IOMMU_API - def_bool (AMD_IOMMU || DMAR) - config MAXSMP bool "Enable Maximum number of SMP Processors and NUMA Nodes" depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL @@ -1945,6 +1943,7 @@ config PCI_CNB20LE_QUIRK config DMAR bool "Support for DMA Remapping Devices (EXPERIMENTAL)" depends on PCI_MSI && ACPI && EXPERIMENTAL + select IOMMU_API help DMA remapping (DMAR) devices support enables independent address translations for Direct Memory Access (DMA) from devices. diff --git a/drivers/Kconfig b/drivers/Kconfig index 3bb154d8c8cc..9d513188b47a 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -126,4 +126,6 @@ source "drivers/hwspinlock/Kconfig" source "drivers/clocksource/Kconfig" +source "drivers/iommu/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 09f3232bcdcd..2f7a71a933de 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -122,3 +122,4 @@ obj-y += ieee802154/ obj-y += clk/ obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ +obj-$(CONFIG_IOMMU_API) += iommu/ diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4c5701c15f53..5ab0d07c4578 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o obj-$(CONFIG_SMP) += topology.o -obj-$(CONFIG_IOMMU_API) += iommu.o ifeq ($(CONFIG_SYSFS),y) obj-$(CONFIG_MODULES) += module.o endif diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c deleted file mode 100644 index 6e6b6a11b3ce..000000000000 --- a/drivers/base/iommu.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * Author: Joerg Roedel - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -static struct iommu_ops *iommu_ops; - -void register_iommu(struct iommu_ops *ops) -{ - if (iommu_ops) - BUG(); - - iommu_ops = ops; -} - -bool iommu_found(void) -{ - return iommu_ops != NULL; -} -EXPORT_SYMBOL_GPL(iommu_found); - -struct iommu_domain *iommu_domain_alloc(void) -{ - struct iommu_domain *domain; - int ret; - - domain = kmalloc(sizeof(*domain), GFP_KERNEL); - if (!domain) - return NULL; - - ret = iommu_ops->domain_init(domain); - if (ret) - goto out_free; - - return domain; - -out_free: - kfree(domain); - - return NULL; -} -EXPORT_SYMBOL_GPL(iommu_domain_alloc); - -void iommu_domain_free(struct iommu_domain *domain) -{ - iommu_ops->domain_destroy(domain); - kfree(domain); -} -EXPORT_SYMBOL_GPL(iommu_domain_free); - -int iommu_attach_device(struct iommu_domain *domain, struct device *dev) -{ - return iommu_ops->attach_dev(domain, dev); -} -EXPORT_SYMBOL_GPL(iommu_attach_device); - -void iommu_detach_device(struct iommu_domain *domain, struct device *dev) -{ - iommu_ops->detach_dev(domain, dev); -} -EXPORT_SYMBOL_GPL(iommu_detach_device); - -phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, - unsigned long iova) -{ - return iommu_ops->iova_to_phys(domain, iova); -} -EXPORT_SYMBOL_GPL(iommu_iova_to_phys); - -int iommu_domain_has_cap(struct iommu_domain *domain, - unsigned long cap) -{ - return iommu_ops->domain_has_cap(domain, cap); -} -EXPORT_SYMBOL_GPL(iommu_domain_has_cap); - -int iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, int gfp_order, int prot) -{ - unsigned long invalid_mask; - size_t size; - - size = 0x1000UL << gfp_order; - invalid_mask = size - 1; - - BUG_ON((iova | paddr) & invalid_mask); - - return iommu_ops->map(domain, iova, paddr, gfp_order, prot); -} -EXPORT_SYMBOL_GPL(iommu_map); - -int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order) -{ - unsigned long invalid_mask; - size_t size; - - size = 0x1000UL << gfp_order; - invalid_mask = size - 1; - - BUG_ON(iova & invalid_mask); - - return iommu_ops->unmap(domain, iova, gfp_order); -} -EXPORT_SYMBOL_GPL(iommu_unmap); diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 000000000000..2c5dfb48a22a --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,3 @@ +# IOMMU_API always gets selected by whoever wants it. +config IOMMU_API + bool diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 000000000000..241ba4c46a19 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_IOMMU_API) += iommu.o diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c new file mode 100644 index 000000000000..6e6b6a11b3ce --- /dev/null +++ b/drivers/iommu/iommu.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. + * Author: Joerg Roedel + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +static struct iommu_ops *iommu_ops; + +void register_iommu(struct iommu_ops *ops) +{ + if (iommu_ops) + BUG(); + + iommu_ops = ops; +} + +bool iommu_found(void) +{ + return iommu_ops != NULL; +} +EXPORT_SYMBOL_GPL(iommu_found); + +struct iommu_domain *iommu_domain_alloc(void) +{ + struct iommu_domain *domain; + int ret; + + domain = kmalloc(sizeof(*domain), GFP_KERNEL); + if (!domain) + return NULL; + + ret = iommu_ops->domain_init(domain); + if (ret) + goto out_free; + + return domain; + +out_free: + kfree(domain); + + return NULL; +} +EXPORT_SYMBOL_GPL(iommu_domain_alloc); + +void iommu_domain_free(struct iommu_domain *domain) +{ + iommu_ops->domain_destroy(domain); + kfree(domain); +} +EXPORT_SYMBOL_GPL(iommu_domain_free); + +int iommu_attach_device(struct iommu_domain *domain, struct device *dev) +{ + return iommu_ops->attach_dev(domain, dev); +} +EXPORT_SYMBOL_GPL(iommu_attach_device); + +void iommu_detach_device(struct iommu_domain *domain, struct device *dev) +{ + iommu_ops->detach_dev(domain, dev); +} +EXPORT_SYMBOL_GPL(iommu_detach_device); + +phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + return iommu_ops->iova_to_phys(domain, iova); +} +EXPORT_SYMBOL_GPL(iommu_iova_to_phys); + +int iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return iommu_ops->domain_has_cap(domain, cap); +} +EXPORT_SYMBOL_GPL(iommu_domain_has_cap); + +int iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, int gfp_order, int prot) +{ + unsigned long invalid_mask; + size_t size; + + size = 0x1000UL << gfp_order; + invalid_mask = size - 1; + + BUG_ON((iova | paddr) & invalid_mask); + + return iommu_ops->map(domain, iova, paddr, gfp_order, prot); +} +EXPORT_SYMBOL_GPL(iommu_map); + +int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order) +{ + unsigned long invalid_mask; + size_t size; + + size = 0x1000UL << gfp_order; + invalid_mask = size - 1; + + BUG_ON(iova & invalid_mask); + + return iommu_ops->unmap(domain, iova, gfp_order); +} +EXPORT_SYMBOL_GPL(iommu_unmap);