Message ID | 20120924120415.8e6929a34c422185a98d3f82@nvidia.com |
---|---|
State | New |
Headers | show |
On Mon, 2012-09-24 at 12:04 +0300, Hiroshi Doyu wrote: > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > index a1a7225..9eae3be 100644 > --- a/drivers/base/platform.c > +++ b/drivers/base/platform.c > @@ -21,6 +21,8 @@ > #include <linux/slab.h> > #include <linux/pm_runtime.h> > > +#include <asm/dma-iommu.h> > + > #include "base.h" > > #define to_platform_driver(drv) (container_of((drv), struct > platform_driver, \ > @@ -305,8 +307,19 @@ int platform_device_add(struct platform_device > *pdev) > dev_name(&pdev->dev), dev_name(pdev->dev.parent)); > > ret = device_add(&pdev->dev); > - if (ret == 0) > - return ret; > + if (ret) > + goto failed; > + > +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU > + if (platform_bus_type.map && !pdev->dev.archdata.mapping) { > + ret = arm_iommu_attach_device(&pdev->dev, > + platform_bus_type.map); > + if (ret) > + goto failed; This is horrible ... you're adding an architecture specific callback into our generic code; that's really a no-no. If the concept of CONFIG_PLATFORM_ENABE_IOMMU is useful to more than just arm, then this could become a generic callback. James
Hi James, On Mon, 24 Sep 2012 11:28:01 +0200 James Bottomley <James.Bottomley@HansenPartnership.com> wrote: > On Mon, 2012-09-24 at 12:04 +0300, Hiroshi Doyu wrote: > > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > > index a1a7225..9eae3be 100644 > > --- a/drivers/base/platform.c > > +++ b/drivers/base/platform.c > > @@ -21,6 +21,8 @@ > > #include <linux/slab.h> > > #include <linux/pm_runtime.h> > > > > +#include <asm/dma-iommu.h> > > + > > #include "base.h" > > > > #define to_platform_driver(drv) (container_of((drv), struct > > platform_driver, \ > > @@ -305,8 +307,19 @@ int platform_device_add(struct platform_device > > *pdev) > > dev_name(&pdev->dev), dev_name(pdev->dev.parent)); > > > > ret = device_add(&pdev->dev); > > - if (ret == 0) > > - return ret; > > + if (ret) > > + goto failed; > > + > > +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU > > + if (platform_bus_type.map && !pdev->dev.archdata.mapping) { > > + ret = arm_iommu_attach_device(&pdev->dev, > > + platform_bus_type.map); > > + if (ret) > > + goto failed; > > This is horrible ... you're adding an architecture specific callback > into our generic code; that's really a no-no. If the concept of > CONFIG_PLATFORM_ENABE_IOMMU is useful to more than just arm, then this > could become a generic callback. As mentioned in the original, this is a heck to explain what is needed. I am looking for some generic solution for how to specify IOMMU info for each platform devices. I'm guessing that some other SoC may have the similar requirements on the above. As you mentioned, this solution should be a generic, not arch specific.
Hello, On Monday, September 24, 2012 11:45 AM Hiroshi Doyu wrote: > On Mon, 24 Sep 2012 11:28:01 +0200 > James Bottomley <James.Bottomley@HansenPartnership.com> wrote: > > > On Mon, 2012-09-24 at 12:04 +0300, Hiroshi Doyu wrote: > > > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > > > index a1a7225..9eae3be 100644 > > > --- a/drivers/base/platform.c > > > +++ b/drivers/base/platform.c > > > @@ -21,6 +21,8 @@ > > > #include <linux/slab.h> > > > #include <linux/pm_runtime.h> > > > > > > +#include <asm/dma-iommu.h> > > > + > > > #include "base.h" > > > > > > #define to_platform_driver(drv) (container_of((drv), struct > > > platform_driver, \ > > > @@ -305,8 +307,19 @@ int platform_device_add(struct platform_device > > > *pdev) > > > dev_name(&pdev->dev), dev_name(pdev->dev.parent)); > > > > > > ret = device_add(&pdev->dev); > > > - if (ret == 0) > > > - return ret; > > > + if (ret) > > > + goto failed; > > > + > > > +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU > > > + if (platform_bus_type.map && !pdev->dev.archdata.mapping) { > > > + ret = arm_iommu_attach_device(&pdev->dev, > > > + platform_bus_type.map); > > > + if (ret) > > > + goto failed; > > > > This is horrible ... you're adding an architecture specific callback > > into our generic code; that's really a no-no. If the concept of > > CONFIG_PLATFORM_ENABE_IOMMU is useful to more than just arm, then this > > could become a generic callback. > > As mentioned in the original, this is a heck to explain what is > needed. I am looking for some generic solution for how to specify > IOMMU info for each platform devices. I'm guessing that some other SoC > may have the similar requirements on the above. As you mentioned, this > solution should be a generic, not arch specific. Please read more about bus notifiers. IMHO a good example is provided in the following thread: http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg12238.html Best regards
Hi Marek, Marek Szyprowski <m.szyprowski@samsung.com> wrote @ Mon, 24 Sep 2012 13:14:51 +0200: > Hello, > > On Monday, September 24, 2012 11:45 AM Hiroshi Doyu wrote: > > > On Mon, 24 Sep 2012 11:28:01 +0200 > > James Bottomley <James.Bottomley@HansenPartnership.com> wrote: > > > > > On Mon, 2012-09-24 at 12:04 +0300, Hiroshi Doyu wrote: > > > > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > > > > index a1a7225..9eae3be 100644 > > > > --- a/drivers/base/platform.c > > > > +++ b/drivers/base/platform.c > > > > @@ -21,6 +21,8 @@ > > > > #include <linux/slab.h> > > > > #include <linux/pm_runtime.h> > > > > > > > > +#include <asm/dma-iommu.h> > > > > + > > > > #include "base.h" > > > > > > > > #define to_platform_driver(drv) (container_of((drv), struct > > > > platform_driver, \ > > > > @@ -305,8 +307,19 @@ int platform_device_add(struct platform_device > > > > *pdev) > > > > dev_name(&pdev->dev), dev_name(pdev->dev.parent)); > > > > > > > > ret = device_add(&pdev->dev); > > > > - if (ret == 0) > > > > - return ret; > > > > + if (ret) > > > > + goto failed; > > > > + > > > > +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU > > > > + if (platform_bus_type.map && !pdev->dev.archdata.mapping) { > > > > + ret = arm_iommu_attach_device(&pdev->dev, > > > > + platform_bus_type.map); > > > > + if (ret) > > > > + goto failed; > > > > > > This is horrible ... you're adding an architecture specific callback > > > into our generic code; that's really a no-no. If the concept of > > > CONFIG_PLATFORM_ENABE_IOMMU is useful to more than just arm, then this > > > could become a generic callback. > > > > As mentioned in the original, this is a heck to explain what is > > needed. I am looking for some generic solution for how to specify > > IOMMU info for each platform devices. I'm guessing that some other SoC > > may have the similar requirements on the above. As you mentioned, this > > solution should be a generic, not arch specific. > > Please read more about bus notifiers. IMHO a good example is provided in > the following thread: > http://www.mail-archive.com/linux-samsung-soc@vger.kernel.org/msg12238.html This bus notifier seems enough flexible to afford the variation of IOMMU map info, like Tegra ASID, which could be platform-specific, and the other could be common too. There's already iommu_bus_notifier too. I'll try to implement something base on this. Thanks for the good info.
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 242289f..28ca7c2 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1899,6 +1899,13 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size, mapping->order = order; spin_lock_init(&mapping->lock); +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU + if (WARN_ON(bus->map)) + goto err3; + + bus->map = mapping; +#endif + mapping->domain = iommu_domain_alloc(bus); if (!mapping->domain) goto err3; diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 3df339c..0f45311 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -308,4 +308,8 @@ config CMA_AREAS endif +config PLATFORM_ENABLE_IOMMU + bool "Make platform devices iommuable" + depends on IOMMU_API + endmenu diff --git a/drivers/base/platform.c b/drivers/base/platform.c index a1a7225..9eae3be 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -21,6 +21,8 @@ #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <asm/dma-iommu.h> + #include "base.h" #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ @@ -305,8 +307,19 @@ int platform_device_add(struct platform_device *pdev) dev_name(&pdev->dev), dev_name(pdev->dev.parent)); ret = device_add(&pdev->dev); - if (ret == 0) - return ret; + if (ret) + goto failed; + +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU + if (platform_bus_type.map && !pdev->dev.archdata.mapping) { + ret = arm_iommu_attach_device(&pdev->dev, + platform_bus_type.map); + if (ret) + goto failed; + } +#endif + + return 0; failed: while (--i >= 0) { diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index b736809..8b7eca1 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -164,7 +164,7 @@ config TEGRA_IOMMU_SMMU config TEGRA_IOMMU_SMMU_LINEAR bool "Physical RAM IOVA Liner Mapping Support" - depends on TEGRA_IOMMU_SMMU + depends on TEGRA_IOMMU_SMMU && !PLATFORM_ENABLE_IOMMU default y help Enables support for linear mapping between physical address diff --git a/include/linux/device.h b/include/linux/device.h index e339929..3dcb501 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -35,6 +35,7 @@ struct subsys_private; struct bus_type; struct device_node; struct iommu_ops; +struct dma_iommu_mapping; struct bus_attribute { struct attribute attr; @@ -106,7 +107,9 @@ struct bus_type { const struct dev_pm_ops *pm; struct iommu_ops *iommu_ops; - +#ifdef CONFIG_PLATFORM_ENABLE_IOMMU + struct dma_iommu_mapping *map; +#endif struct subsys_private *p; };