diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-03-26 13:43:04 +0100 |
---|---|---|
committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:14:53 -0700 |
commit | fd7eedeeebf2b958cc99cbf1be0825fc5b1c9001 (patch) | |
tree | cbf14b4262a684ffc61ffb4eb8f1bfcc0ca4dece /drivers/iommu/iommu.c | |
parent | 02041d42382b3bfaaf695823c710e2f8766c0fdc (diff) |
iommu: Introduce domain_alloc and domain_free iommu_ops
These new call-backs defer the allocation and destruction of
'struct iommu_domain' to the iommu driver. This allows
drivers to embed this struct into their private domain
structures and to get rid of the domain_init and
domain_destroy call-backs when all drivers have been
converted.
Tested-by: Thierry Reding <treding@nvidia.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/iommu.c')
-rw-r--r-- | drivers/iommu/iommu.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index f6797ec8447d..4746bd23fff0 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -942,26 +942,34 @@ void iommu_reg_write(struct iommu_domain *domain, unsigned long offset, struct iommu_domain *iommu_domain_alloc(struct bus_type *bus) { + const struct iommu_ops *ops; struct iommu_domain *domain; - int ret; if (bus == NULL || bus->iommu_ops == NULL) return NULL; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + ops = bus->iommu_ops; + + if (ops->domain_alloc) + domain = ops->domain_alloc(); + else + domain = kzalloc(sizeof(*domain), GFP_KERNEL); + if (!domain) return NULL; domain->ops = bus->iommu_ops; - ret = domain->ops->domain_init(domain); - if (ret) + if (ops->domain_init && domain->ops->domain_init(domain)) goto out_free; return domain; out_free: - kfree(domain); + if (ops->domain_free) + ops->domain_free(domain); + else + kfree(domain); return NULL; } @@ -969,10 +977,15 @@ EXPORT_SYMBOL_GPL(iommu_domain_alloc); void iommu_domain_free(struct iommu_domain *domain) { - if (likely(domain->ops->domain_destroy != NULL)) - domain->ops->domain_destroy(domain); + const struct iommu_ops *ops = domain->ops; - kfree(domain); + if (likely(ops->domain_destroy != NULL)) + ops->domain_destroy(domain); + + if (ops->domain_free) + ops->domain_free(domain); + else + kfree(domain); } EXPORT_SYMBOL_GPL(iommu_domain_free); |