aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/shmobile-iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/shmobile-iommu.c')
-rw-r--r--drivers/iommu/shmobile-iommu.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/iommu/shmobile-iommu.c b/drivers/iommu/shmobile-iommu.c
index f1b00774e4de..a0287519a1d4 100644
--- a/drivers/iommu/shmobile-iommu.c
+++ b/drivers/iommu/shmobile-iommu.c
@@ -42,11 +42,17 @@ struct shmobile_iommu_domain {
42 spinlock_t map_lock; 42 spinlock_t map_lock;
43 spinlock_t attached_list_lock; 43 spinlock_t attached_list_lock;
44 struct list_head attached_list; 44 struct list_head attached_list;
45 struct iommu_domain domain;
45}; 46};
46 47
47static struct shmobile_iommu_archdata *ipmmu_archdata; 48static struct shmobile_iommu_archdata *ipmmu_archdata;
48static struct kmem_cache *l1cache, *l2cache; 49static struct kmem_cache *l1cache, *l2cache;
49 50
51static struct shmobile_iommu_domain *to_sh_domain(struct iommu_domain *dom)
52{
53 return container_of(dom, struct shmobile_iommu_domain, domain);
54}
55
50static int pgtable_alloc(struct shmobile_iommu_domain_pgtable *pgtable, 56static int pgtable_alloc(struct shmobile_iommu_domain_pgtable *pgtable,
51 struct kmem_cache *cache, size_t size) 57 struct kmem_cache *cache, size_t size)
52{ 58{
@@ -82,31 +88,33 @@ static void pgtable_write(struct shmobile_iommu_domain_pgtable *pgtable,
82 sizeof(val) * count, DMA_TO_DEVICE); 88 sizeof(val) * count, DMA_TO_DEVICE);
83} 89}
84 90
85static int shmobile_iommu_domain_init(struct iommu_domain *domain) 91static struct iommu_domain *shmobile_iommu_domain_alloc(unsigned type)
86{ 92{
87 struct shmobile_iommu_domain *sh_domain; 93 struct shmobile_iommu_domain *sh_domain;
88 int i, ret; 94 int i, ret;
89 95
90 sh_domain = kmalloc(sizeof(*sh_domain), GFP_KERNEL); 96 if (type != IOMMU_DOMAIN_UNMANAGED)
97 return NULL;
98
99 sh_domain = kzalloc(sizeof(*sh_domain), GFP_KERNEL);
91 if (!sh_domain) 100 if (!sh_domain)
92 return -ENOMEM; 101 return NULL;
93 ret = pgtable_alloc(&sh_domain->l1, l1cache, L1_SIZE); 102 ret = pgtable_alloc(&sh_domain->l1, l1cache, L1_SIZE);
94 if (ret < 0) { 103 if (ret < 0) {
95 kfree(sh_domain); 104 kfree(sh_domain);
96 return ret; 105 return NULL;
97 } 106 }
98 for (i = 0; i < L1_LEN; i++) 107 for (i = 0; i < L1_LEN; i++)
99 sh_domain->l2[i].pgtable = NULL; 108 sh_domain->l2[i].pgtable = NULL;
100 spin_lock_init(&sh_domain->map_lock); 109 spin_lock_init(&sh_domain->map_lock);
101 spin_lock_init(&sh_domain->attached_list_lock); 110 spin_lock_init(&sh_domain->attached_list_lock);
102 INIT_LIST_HEAD(&sh_domain->attached_list); 111 INIT_LIST_HEAD(&sh_domain->attached_list);
103 domain->priv = sh_domain; 112 return &sh_domain->domain;
104 return 0;
105} 113}
106 114
107static void shmobile_iommu_domain_destroy(struct iommu_domain *domain) 115static void shmobile_iommu_domain_free(struct iommu_domain *domain)
108{ 116{
109 struct shmobile_iommu_domain *sh_domain = domain->priv; 117 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
110 int i; 118 int i;
111 119
112 for (i = 0; i < L1_LEN; i++) { 120 for (i = 0; i < L1_LEN; i++) {
@@ -115,14 +123,13 @@ static void shmobile_iommu_domain_destroy(struct iommu_domain *domain)
115 } 123 }
116 pgtable_free(&sh_domain->l1, l1cache, L1_SIZE); 124 pgtable_free(&sh_domain->l1, l1cache, L1_SIZE);
117 kfree(sh_domain); 125 kfree(sh_domain);
118 domain->priv = NULL;
119} 126}
120 127
121static int shmobile_iommu_attach_device(struct iommu_domain *domain, 128static int shmobile_iommu_attach_device(struct iommu_domain *domain,
122 struct device *dev) 129 struct device *dev)
123{ 130{
124 struct shmobile_iommu_archdata *archdata = dev->archdata.iommu; 131 struct shmobile_iommu_archdata *archdata = dev->archdata.iommu;
125 struct shmobile_iommu_domain *sh_domain = domain->priv; 132 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
126 int ret = -EBUSY; 133 int ret = -EBUSY;
127 134
128 if (!archdata) 135 if (!archdata)
@@ -151,7 +158,7 @@ static void shmobile_iommu_detach_device(struct iommu_domain *domain,
151 struct device *dev) 158 struct device *dev)
152{ 159{
153 struct shmobile_iommu_archdata *archdata = dev->archdata.iommu; 160 struct shmobile_iommu_archdata *archdata = dev->archdata.iommu;
154 struct shmobile_iommu_domain *sh_domain = domain->priv; 161 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
155 162
156 if (!archdata) 163 if (!archdata)
157 return; 164 return;
@@ -214,7 +221,7 @@ static int shmobile_iommu_map(struct iommu_domain *domain, unsigned long iova,
214 phys_addr_t paddr, size_t size, int prot) 221 phys_addr_t paddr, size_t size, int prot)
215{ 222{
216 struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL }; 223 struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
217 struct shmobile_iommu_domain *sh_domain = domain->priv; 224 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
218 unsigned int l1index, l2index; 225 unsigned int l1index, l2index;
219 int ret; 226 int ret;
220 227
@@ -258,7 +265,7 @@ static size_t shmobile_iommu_unmap(struct iommu_domain *domain,
258 unsigned long iova, size_t size) 265 unsigned long iova, size_t size)
259{ 266{
260 struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL }; 267 struct shmobile_iommu_domain_pgtable l2 = { .pgtable = NULL };
261 struct shmobile_iommu_domain *sh_domain = domain->priv; 268 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
262 unsigned int l1index, l2index; 269 unsigned int l1index, l2index;
263 uint32_t l2entry = 0; 270 uint32_t l2entry = 0;
264 size_t ret = 0; 271 size_t ret = 0;
@@ -298,7 +305,7 @@ done:
298static phys_addr_t shmobile_iommu_iova_to_phys(struct iommu_domain *domain, 305static phys_addr_t shmobile_iommu_iova_to_phys(struct iommu_domain *domain,
299 dma_addr_t iova) 306 dma_addr_t iova)
300{ 307{
301 struct shmobile_iommu_domain *sh_domain = domain->priv; 308 struct shmobile_iommu_domain *sh_domain = to_sh_domain(domain);
302 uint32_t l1entry = 0, l2entry = 0; 309 uint32_t l1entry = 0, l2entry = 0;
303 unsigned int l1index, l2index; 310 unsigned int l1index, l2index;
304 311
@@ -355,8 +362,8 @@ static int shmobile_iommu_add_device(struct device *dev)
355} 362}
356 363
357static const struct iommu_ops shmobile_iommu_ops = { 364static const struct iommu_ops shmobile_iommu_ops = {
358 .domain_init = shmobile_iommu_domain_init, 365 .domain_alloc = shmobile_iommu_domain_alloc,
359 .domain_destroy = shmobile_iommu_domain_destroy, 366 .domain_free = shmobile_iommu_domain_free,
360 .attach_dev = shmobile_iommu_attach_device, 367 .attach_dev = shmobile_iommu_attach_device,
361 .detach_dev = shmobile_iommu_detach_device, 368 .detach_dev = shmobile_iommu_detach_device,
362 .map = shmobile_iommu_map, 369 .map = shmobile_iommu_map,