@@ -1415,6 +1415,27 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
return unmapped;
}
EXPORT_SYMBOL_GPL(iommu_unmap);
+int iommu_get_single_reserved(struct iommu_domain *domain,
+ phys_addr_t addr, int prot,
+ dma_addr_t *iova)
+{
+ if (!domain->ops->get_single_reserved)
+ return -ENODEV;
+
+ return domain->ops->get_single_reserved(domain, addr, prot, iova);
+
+}
+EXPORT_SYMBOL_GPL(iommu_get_single_reserved);
+
+void iommu_put_single_reserved(struct iommu_domain *domain,
+ dma_addr_t iova)
+{
+ if (!domain->ops->put_single_reserved)
+ return;
+
+ domain->ops->put_single_reserved(domain, iova);
+}
+EXPORT_SYMBOL_GPL(iommu_put_single_reserved);
size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
struct scatterlist *sg, unsigned int nents, int prot)
@@ -201,6 +201,21 @@ struct iommu_ops {
unsigned long order);
/* frees the reserved iova domain */
void (*free_reserved_iova_domain)(struct iommu_domain *domain);
+ /**
+ * allocate a reserved iova page and bind it onto the page that
+ * contains a physical address (@addr), returns the @iova bound to
+ * @addr. In case the 2 pages already are bound simply return @iova
+ * and increment a ref count.
+ */
+ int (*get_single_reserved)(struct iommu_domain *domain,
+ phys_addr_t addr, int prot,
+ dma_addr_t *iova);
+ /**
+ * decrement a ref count of the iova page. If null, unmap the iova page
+ * and release the iova
+ */
+ void (*put_single_reserved)(struct iommu_domain *domain,
+ dma_addr_t iova);
#ifdef CONFIG_OF_IOMMU
int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
@@ -276,6 +291,11 @@ extern int iommu_alloc_reserved_iova_domain(struct iommu_domain *domain,
dma_addr_t iova, size_t size,
unsigned long order);
extern void iommu_free_reserved_iova_domain(struct iommu_domain *domain);
+extern int iommu_get_single_reserved(struct iommu_domain *domain,
+ phys_addr_t paddr, int prot,
+ dma_addr_t *iova);
+extern void iommu_put_single_reserved(struct iommu_domain *domain,
+ dma_addr_t iova);
struct device *iommu_device_create(struct device *parent, void *drvdata,
const struct attribute_group **groups,
const char *fmt, ...) __printf(4, 5);
@@ -562,6 +582,17 @@ static void iommu_free_reserved_iova_domain(struct iommu_domain *domain)
{
}
+static int iommu_get_single_reserved(struct iommu_domain *domain,
+ phys_addr_t paddr, int prot,
+ dma_addr_t *iova)
+{
+ return -EINVAL;
+}
+static void iommu_put_single_reserved(struct iommu_domain *domain,
+ dma_addr_t iova)
+{
+}
+
#endif /* CONFIG_IOMMU_API */
#endif /* __LINUX_IOMMU_H */