aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/tegra-smmu.c
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2015-03-26 08:43:12 -0400
committerJoerg Roedel <jroedel@suse.de>2015-03-31 09:32:12 -0400
commitd5f1a81ccb8947828f60b50d8e9ed7617259a9ec (patch)
treefb65283a8874b22ed08cc92aefacf3970a93ffb5 /drivers/iommu/tegra-smmu.c
parente1fd1eaa3323b3ea68f2ad3116b8cbe1f34cb2a2 (diff)
iommu/tegra-smmu: Make use of domain_alloc and domain_free
Implement domain_alloc and domain_free iommu-ops as a replacement for domain_init/domain_destroy. Tested-by: Thierry Reding <treding@nvidia.com> Acked-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/tegra-smmu.c')
-rw-r--r--drivers/iommu/tegra-smmu.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 6e134c7c227f..720829724d86 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -31,7 +31,7 @@ struct tegra_smmu {
31}; 31};
32 32
33struct tegra_smmu_as { 33struct tegra_smmu_as {
34 struct iommu_domain *domain; 34 struct iommu_domain domain;
35 struct tegra_smmu *smmu; 35 struct tegra_smmu *smmu;
36 unsigned int use_count; 36 unsigned int use_count;
37 struct page *count; 37 struct page *count;
@@ -40,6 +40,11 @@ struct tegra_smmu_as {
40 u32 attr; 40 u32 attr;
41}; 41};
42 42
43static struct tegra_smmu_as *to_smmu_as(struct iommu_domain *dom)
44{
45 return container_of(dom, struct tegra_smmu_as, domain);
46}
47
43static inline void smmu_writel(struct tegra_smmu *smmu, u32 value, 48static inline void smmu_writel(struct tegra_smmu *smmu, u32 value,
44 unsigned long offset) 49 unsigned long offset)
45{ 50{
@@ -224,30 +229,32 @@ static bool tegra_smmu_capable(enum iommu_cap cap)
224 return false; 229 return false;
225} 230}
226 231
227static int tegra_smmu_domain_init(struct iommu_domain *domain) 232static struct iommu_domain *tegra_smmu_domain_alloc(unsigned type)
228{ 233{
229 struct tegra_smmu_as *as; 234 struct tegra_smmu_as *as;
230 unsigned int i; 235 unsigned int i;
231 uint32_t *pd; 236 uint32_t *pd;
232 237
238 if (type != IOMMU_DOMAIN_UNMANAGED)
239 return NULL;
240
233 as = kzalloc(sizeof(*as), GFP_KERNEL); 241 as = kzalloc(sizeof(*as), GFP_KERNEL);
234 if (!as) 242 if (!as)
235 return -ENOMEM; 243 return NULL;
236 244
237 as->attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE; 245 as->attr = SMMU_PD_READABLE | SMMU_PD_WRITABLE | SMMU_PD_NONSECURE;
238 as->domain = domain;
239 246
240 as->pd = alloc_page(GFP_KERNEL | __GFP_DMA); 247 as->pd = alloc_page(GFP_KERNEL | __GFP_DMA);
241 if (!as->pd) { 248 if (!as->pd) {
242 kfree(as); 249 kfree(as);
243 return -ENOMEM; 250 return NULL;
244 } 251 }
245 252
246 as->count = alloc_page(GFP_KERNEL); 253 as->count = alloc_page(GFP_KERNEL);
247 if (!as->count) { 254 if (!as->count) {
248 __free_page(as->pd); 255 __free_page(as->pd);
249 kfree(as); 256 kfree(as);
250 return -ENOMEM; 257 return NULL;
251 } 258 }
252 259
253 /* clear PDEs */ 260 /* clear PDEs */
@@ -264,14 +271,12 @@ static int tegra_smmu_domain_init(struct iommu_domain *domain)
264 for (i = 0; i < SMMU_NUM_PDE; i++) 271 for (i = 0; i < SMMU_NUM_PDE; i++)
265 pd[i] = 0; 272 pd[i] = 0;
266 273
267 domain->priv = as; 274 return &as->domain;
268
269 return 0;
270} 275}
271 276
272static void tegra_smmu_domain_destroy(struct iommu_domain *domain) 277static void tegra_smmu_domain_free(struct iommu_domain *domain)
273{ 278{
274 struct tegra_smmu_as *as = domain->priv; 279 struct tegra_smmu_as *as = to_smmu_as(domain);
275 280
276 /* TODO: free page directory and page tables */ 281 /* TODO: free page directory and page tables */
277 ClearPageReserved(as->pd); 282 ClearPageReserved(as->pd);
@@ -395,7 +400,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
395 struct device *dev) 400 struct device *dev)
396{ 401{
397 struct tegra_smmu *smmu = dev->archdata.iommu; 402 struct tegra_smmu *smmu = dev->archdata.iommu;
398 struct tegra_smmu_as *as = domain->priv; 403 struct tegra_smmu_as *as = to_smmu_as(domain);
399 struct device_node *np = dev->of_node; 404 struct device_node *np = dev->of_node;
400 struct of_phandle_args args; 405 struct of_phandle_args args;
401 unsigned int index = 0; 406 unsigned int index = 0;
@@ -428,7 +433,7 @@ static int tegra_smmu_attach_dev(struct iommu_domain *domain,
428 433
429static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) 434static void tegra_smmu_detach_dev(struct iommu_domain *domain, struct device *dev)
430{ 435{
431 struct tegra_smmu_as *as = domain->priv; 436 struct tegra_smmu_as *as = to_smmu_as(domain);
432 struct device_node *np = dev->of_node; 437 struct device_node *np = dev->of_node;
433 struct tegra_smmu *smmu = as->smmu; 438 struct tegra_smmu *smmu = as->smmu;
434 struct of_phandle_args args; 439 struct of_phandle_args args;
@@ -524,7 +529,7 @@ static void as_put_pte(struct tegra_smmu_as *as, dma_addr_t iova)
524static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, 529static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
525 phys_addr_t paddr, size_t size, int prot) 530 phys_addr_t paddr, size_t size, int prot)
526{ 531{
527 struct tegra_smmu_as *as = domain->priv; 532 struct tegra_smmu_as *as = to_smmu_as(domain);
528 struct tegra_smmu *smmu = as->smmu; 533 struct tegra_smmu *smmu = as->smmu;
529 unsigned long offset; 534 unsigned long offset;
530 struct page *page; 535 struct page *page;
@@ -548,7 +553,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
548static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, 553static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
549 size_t size) 554 size_t size)
550{ 555{
551 struct tegra_smmu_as *as = domain->priv; 556 struct tegra_smmu_as *as = to_smmu_as(domain);
552 struct tegra_smmu *smmu = as->smmu; 557 struct tegra_smmu *smmu = as->smmu;
553 unsigned long offset; 558 unsigned long offset;
554 struct page *page; 559 struct page *page;
@@ -572,7 +577,7 @@ static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
572static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain, 577static phys_addr_t tegra_smmu_iova_to_phys(struct iommu_domain *domain,
573 dma_addr_t iova) 578 dma_addr_t iova)
574{ 579{
575 struct tegra_smmu_as *as = domain->priv; 580 struct tegra_smmu_as *as = to_smmu_as(domain);
576 struct page *page; 581 struct page *page;
577 unsigned long pfn; 582 unsigned long pfn;
578 u32 *pte; 583 u32 *pte;
@@ -633,8 +638,8 @@ static void tegra_smmu_remove_device(struct device *dev)
633 638
634static const struct iommu_ops tegra_smmu_ops = { 639static const struct iommu_ops tegra_smmu_ops = {
635 .capable = tegra_smmu_capable, 640 .capable = tegra_smmu_capable,
636 .domain_init = tegra_smmu_domain_init, 641 .domain_alloc = tegra_smmu_domain_alloc,
637 .domain_destroy = tegra_smmu_domain_destroy, 642 .domain_free = tegra_smmu_domain_free,
638 .attach_dev = tegra_smmu_attach_dev, 643 .attach_dev = tegra_smmu_attach_dev,
639 .detach_dev = tegra_smmu_detach_dev, 644 .detach_dev = tegra_smmu_detach_dev,
640 .add_device = tegra_smmu_add_device, 645 .add_device = tegra_smmu_add_device,