1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2013 Red Hat
4 * Author: Rob Clark <robdclark@gmail.com>
12 struct iommu_domain
*domain
;
14 #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
16 static int msm_fault_handler(struct iommu_domain
*domain
, struct device
*dev
,
17 unsigned long iova
, int flags
, void *arg
)
19 struct msm_iommu
*iommu
= arg
;
20 if (iommu
->base
.handler
)
21 return iommu
->base
.handler(iommu
->base
.arg
, iova
, flags
);
22 pr_warn_ratelimited("*** fault: iova=%16lx, flags=%d\n", iova
, flags
);
26 static int msm_iommu_attach(struct msm_mmu
*mmu
)
28 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
30 return iommu_attach_device(iommu
->domain
, mmu
->dev
);
33 static void msm_iommu_detach(struct msm_mmu
*mmu
)
35 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
37 iommu_detach_device(iommu
->domain
, mmu
->dev
);
40 static int msm_iommu_map(struct msm_mmu
*mmu
, uint64_t iova
,
41 struct sg_table
*sgt
, unsigned len
, int prot
)
43 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
46 ret
= iommu_map_sg(iommu
->domain
, iova
, sgt
->sgl
, sgt
->nents
, prot
);
49 return (ret
== len
) ? 0 : -EINVAL
;
52 static int msm_iommu_unmap(struct msm_mmu
*mmu
, uint64_t iova
, unsigned len
)
54 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
56 iommu_unmap(iommu
->domain
, iova
, len
);
61 static void msm_iommu_destroy(struct msm_mmu
*mmu
)
63 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
64 iommu_domain_free(iommu
->domain
);
68 static const struct msm_mmu_funcs funcs
= {
69 .attach
= msm_iommu_attach
,
70 .detach
= msm_iommu_detach
,
72 .unmap
= msm_iommu_unmap
,
73 .destroy
= msm_iommu_destroy
,
76 struct msm_mmu
*msm_iommu_new(struct device
*dev
, struct iommu_domain
*domain
)
78 struct msm_iommu
*iommu
;
80 iommu
= kzalloc(sizeof(*iommu
), GFP_KERNEL
);
82 return ERR_PTR(-ENOMEM
);
84 iommu
->domain
= domain
;
85 msm_mmu_init(&iommu
->base
, dev
, &funcs
);
86 iommu_set_fault_handler(domain
, msm_fault_handler
, iommu
);