mirror of https://gitee.com/openkylin/linux.git
iommu: provide helper function to configure an IOMMU for an of master
The generic IOMMU device-tree bindings can be used to add arbitrary OF masters to an IOMMU with a compliant binding. This patch introduces of_iommu_configure, which does exactly that. Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Joerg Roedel <jroedel@suse.de> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
d0f60a44f5
commit
7eba1d5148
|
@ -15,7 +15,7 @@ if IOMMU_SUPPORT
|
|||
|
||||
config OF_IOMMU
|
||||
def_bool y
|
||||
depends on OF
|
||||
depends on OF && IOMMU_API
|
||||
|
||||
config FSL_PAMU
|
||||
bool "Freescale IOMMU support"
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_iommu.h>
|
||||
|
@ -93,6 +94,38 @@ int of_get_dma_window(struct device_node *dn, const char *prefix, int index,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(of_get_dma_window);
|
||||
|
||||
struct iommu_ops *of_iommu_configure(struct device *dev)
|
||||
{
|
||||
struct of_phandle_args iommu_spec;
|
||||
struct device_node *np;
|
||||
struct iommu_ops *ops = NULL;
|
||||
int idx = 0;
|
||||
|
||||
/*
|
||||
* We don't currently walk up the tree looking for a parent IOMMU.
|
||||
* See the `Notes:' section of
|
||||
* Documentation/devicetree/bindings/iommu/iommu.txt
|
||||
*/
|
||||
while (!of_parse_phandle_with_args(dev->of_node, "iommus",
|
||||
"#iommu-cells", idx,
|
||||
&iommu_spec)) {
|
||||
np = iommu_spec.np;
|
||||
ops = of_iommu_get_ops(np);
|
||||
|
||||
if (!ops || !ops->of_xlate || ops->of_xlate(dev, &iommu_spec))
|
||||
goto err_put_node;
|
||||
|
||||
of_node_put(np);
|
||||
idx++;
|
||||
}
|
||||
|
||||
return ops;
|
||||
|
||||
err_put_node:
|
||||
of_node_put(np);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void __init of_iommu_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __OF_IOMMU_H
|
||||
#define __OF_IOMMU_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
|
@ -11,6 +12,7 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix,
|
|||
size_t *size);
|
||||
|
||||
extern void of_iommu_init(void);
|
||||
extern struct iommu_ops *of_iommu_configure(struct device *dev);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -22,6 +24,10 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix,
|
|||
}
|
||||
|
||||
static inline void of_iommu_init(void) { }
|
||||
static inline struct iommu_ops *of_iommu_configure(struct device *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_OF_IOMMU */
|
||||
|
||||
|
|
Loading…
Reference in New Issue