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 **names
, int cnt
)
36 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
37 return iommu_attach_device(iommu
->domain
, mmu
->dev
);
40 static void msm_iommu_detach(struct msm_mmu
*mmu
, const char **names
, int cnt
)
42 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
43 iommu_detach_device(iommu
->domain
, mmu
->dev
);
46 static int msm_iommu_map(struct msm_mmu
*mmu
, uint32_t iova
,
47 struct sg_table
*sgt
, unsigned len
, int prot
)
49 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
50 struct iommu_domain
*domain
= iommu
->domain
;
51 struct scatterlist
*sg
;
52 unsigned int da
= iova
;
59 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
60 u32 pa
= sg_phys(sg
) - sg
->offset
;
61 size_t bytes
= sg
->length
+ sg
->offset
;
63 VERB("map[%d]: %08x %08x(%zx)", i
, iova
, pa
, bytes
);
65 ret
= iommu_map(domain
, da
, pa
, bytes
, prot
);
77 for_each_sg(sgt
->sgl
, sg
, i
, j
) {
78 size_t bytes
= sg
->length
+ sg
->offset
;
79 iommu_unmap(domain
, da
, bytes
);
85 static int msm_iommu_unmap(struct msm_mmu
*mmu
, uint32_t iova
,
86 struct sg_table
*sgt
, unsigned len
)
88 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
89 struct iommu_domain
*domain
= iommu
->domain
;
90 struct scatterlist
*sg
;
91 unsigned int da
= iova
;
94 for_each_sg(sgt
->sgl
, sg
, sgt
->nents
, i
) {
95 size_t bytes
= sg
->length
+ sg
->offset
;
98 unmapped
= iommu_unmap(domain
, da
, bytes
);
102 VERB("unmap[%d]: %08x(%zx)", i
, iova
, bytes
);
104 BUG_ON(!PAGE_ALIGNED(bytes
));
112 static void msm_iommu_destroy(struct msm_mmu
*mmu
)
114 struct msm_iommu
*iommu
= to_msm_iommu(mmu
);
115 iommu_domain_free(iommu
->domain
);
119 static const struct msm_mmu_funcs funcs
= {
120 .attach
= msm_iommu_attach
,
121 .detach
= msm_iommu_detach
,
122 .map
= msm_iommu_map
,
123 .unmap
= msm_iommu_unmap
,
124 .destroy
= msm_iommu_destroy
,
127 struct msm_mmu
*msm_iommu_new(struct device
*dev
, struct iommu_domain
*domain
)
129 struct msm_iommu
*iommu
;
131 iommu
= kzalloc(sizeof(*iommu
), GFP_KERNEL
);
133 return ERR_PTR(-ENOMEM
);
135 iommu
->domain
= domain
;
136 msm_mmu_init(&iommu
->base
, dev
, &funcs
);
137 iommu_set_fault_handler(domain
, msm_fault_handler
, dev
);