2 * Copyright (C) 2013 Red Hat
3 * Author: Rob Clark <robdclark@gmail.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
23 struct iommu_domain
*domain
;
25 #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
27 static int msm_fault_handler(struct iommu_domain
*iommu
, struct device
*dev
,
28 unsigned long iova
, int flags
, void *arg
)
30 pr_warn_ratelimited("*** fault: iova=%08lx, flags=%d\n", iova
, flags
);
34 static int msm_iommu_attach(struct msm_mmu
*mmu
, const char * const *names
,
37 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
38 return iommu_attach_device(iommu
->domain
, mmu
->dev
);
41 static void msm_iommu_detach(struct msm_mmu
*mmu
, const char * const *names
,
44 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
45 iommu_detach_device(iommu
->domain
, mmu
->dev
);
48 static int msm_iommu_map(struct msm_mmu
*mmu
, uint32_t iova
,
49 struct sg_table
*sgt
, unsigned len
, int prot
)
51 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
52 struct iommu_domain
*domain
= iommu
->domain
;
53 struct scatterlist
*sg
;
54 unsigned int da
= iova
;
61 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
62 dma_addr_t pa
= sg_phys(sg
) - sg
->offset
;
63 size_t bytes
= sg
->length
+ sg
->offset
;
65 VERB("map[%d]: %08x %08lx(%zx)", i
, da
, (unsigned long)pa
, bytes
);
67 ret
= iommu_map(domain
, da
, pa
, bytes
, prot
);
79 for_each_sg(sgt
->sgl
, sg
, i
, j
) {
80 size_t bytes
= sg
->length
+ sg
->offset
;
81 iommu_unmap(domain
, da
, bytes
);
87 static int msm_iommu_unmap(struct msm_mmu
*mmu
, uint32_t iova
,
88 struct sg_table
*sgt
, unsigned len
)
90 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
91 struct iommu_domain
*domain
= iommu
->domain
;
92 struct scatterlist
*sg
;
93 unsigned int da
= iova
;
96 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
97 size_t bytes
= sg
->length
+ sg
->offset
;
100 unmapped
= iommu_unmap(domain
, da
, bytes
);
101 if (unmapped
< bytes
)
104 VERB("unmap[%d]: %08x(%zx)", i
, da
, bytes
);
106 BUG_ON(!PAGE_ALIGNED(bytes
));
114 static void msm_iommu_destroy(struct msm_mmu
*mmu
)
116 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
117 iommu_domain_free(iommu
->domain
);
121 static const struct msm_mmu_funcs funcs
= {
122 .attach
= msm_iommu_attach
,
123 .detach
= msm_iommu_detach
,
124 .map
= msm_iommu_map
,
125 .unmap
= msm_iommu_unmap
,
126 .destroy
= msm_iommu_destroy
,
129 struct msm_mmu
*msm_iommu_new(struct device
*dev
, struct iommu_domain
*domain
)
131 struct msm_iommu
*iommu
;
133 iommu
= kzalloc(sizeof(*iommu
), GFP_KERNEL
);
135 return ERR_PTR(-ENOMEM
);
137 iommu
->domain
= domain
;
138 msm_mmu_init(&iommu
->base
, dev
, &funcs
);
139 iommu_set_fault_handler(domain
, msm_fault_handler
, dev
);