mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
rockchip: iommu: fix some bugs
1.rewrite irq function 2.rewrite dump_pgtable
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -29,15 +29,13 @@ struct rk_iovmm {
|
||||
struct iommu_drvdata {
|
||||
struct list_head node; /* entry of rk_iommu_domain.clients */
|
||||
struct device *iommu; /* IOMMU's device descriptor */
|
||||
struct device *dev; /* Owner of IOMMU */
|
||||
int num_res_mem;
|
||||
int num_res_irq;
|
||||
const char *dbgname;
|
||||
void __iomem **res_bases;
|
||||
int activations;
|
||||
rwlock_t lock;
|
||||
spinlock_t data_lock;
|
||||
struct iommu_domain *domain; /* domain given to iommu_attach_device() */
|
||||
rockchip_iommu_fault_handler_t fault_handler;
|
||||
unsigned long pgtable;
|
||||
struct rk_iovmm vmm;
|
||||
};
|
||||
@@ -74,31 +72,18 @@ static inline int rockchip_init_iovmm(struct device *iommu,
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_IOMMU
|
||||
|
||||
/**
|
||||
* rockchip_iommu_disable() - disable iommu mmu of ip
|
||||
* @owner: The device whose IOMMU is about to be disabled.
|
||||
*
|
||||
* This function disable iommu to transfer address
|
||||
* from virtual address to physical address
|
||||
*/
|
||||
bool rockchip_iommu_disable(struct device *owner);
|
||||
|
||||
/**
|
||||
* rockchip_iommu_tlb_invalidate() - flush all TLB entry in iommu
|
||||
* @owner: The device whose IOMMU.
|
||||
*
|
||||
* This function flush all TLB entry in iommu
|
||||
*/
|
||||
void rockchip_iommu_tlb_invalidate(struct device *owner);
|
||||
int rockchip_iommu_tlb_invalidate(struct device *owner);
|
||||
|
||||
#else /* CONFIG_ROCKCHIP_IOMMU */
|
||||
static inline bool rockchip_iommu_disable(struct device *owner)
|
||||
static inline int rockchip_iommu_tlb_invalidate(struct device *owner)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
static inline void rockchip_iommu_tlb_invalidate(struct device *owner)
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,12 +33,7 @@ static struct rk_vm_region *find_region(struct rk_iovmm *vmm, dma_addr_t iova)
|
||||
void rockchip_iovmm_set_fault_handler(struct device *dev,
|
||||
rockchip_iommu_fault_handler_t handler)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
|
||||
|
||||
write_lock_irqsave(&data->lock, flags);
|
||||
data->fault_handler = handler;
|
||||
write_unlock_irqrestore(&data->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
int rockchip_iovmm_activate(struct device *dev)
|
||||
@@ -141,11 +136,13 @@ dma_addr_t rockchip_iovmm_map(struct device *dev,
|
||||
|
||||
spin_unlock(&vmm->lock);
|
||||
|
||||
rockchip_iommu_tlb_invalidate(dev);
|
||||
/*
|
||||
pr_err("IOVMM: Allocated VM region @ %#x/%#X bytes.\n",
|
||||
ret = rockchip_iommu_tlb_invalidate(dev);
|
||||
if (ret)
|
||||
goto err_map_map;
|
||||
|
||||
dev_dbg(dev->archdata.iommu, "IOVMM: Allocated VM region @ %#x/%#X bytes.\n",
|
||||
region->start, region->size);
|
||||
*/
|
||||
|
||||
return region->start;
|
||||
|
||||
err_map_map:
|
||||
@@ -154,7 +151,7 @@ err_map_map:
|
||||
err_map_noiomem:
|
||||
kfree(region);
|
||||
err_map_nomem:
|
||||
pr_err("IOVMM: Failed to allocated VM region for %#x bytes.\n", size);
|
||||
dev_err(dev->archdata.iommu, "IOVMM: Failed to allocated VM region for %#x bytes.\n", size);
|
||||
return (dma_addr_t)ret;
|
||||
}
|
||||
|
||||
@@ -189,10 +186,10 @@ void rockchip_iovmm_unmap(struct device *dev, dma_addr_t iova)
|
||||
gen_pool_free(vmm->vmm_pool, region->start, region->size);
|
||||
|
||||
WARN_ON(unmapped_size != region->size);
|
||||
/*
|
||||
pr_err("IOVMM: Unmapped %#x bytes from %#x.\n",
|
||||
|
||||
dev_dbg(dev->archdata.iommu, "IOVMM: Unmapped %#x bytes from %#x.\n",
|
||||
unmapped_size, region->start);
|
||||
*/
|
||||
|
||||
kfree(region);
|
||||
}
|
||||
|
||||
@@ -203,7 +200,7 @@ int rockchip_iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size)
|
||||
int ret;
|
||||
|
||||
if (WARN_ON((phys + size) >= IOVA_START)) {
|
||||
pr_err("Unable to create one to one mapping for %#x @ %#x\n",
|
||||
dev_err(dev->archdata.iommu, "Unable to create one to one mapping for %#x @ %#x\n",
|
||||
size, phys);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -232,7 +229,9 @@ int rockchip_iovmm_map_oto(struct device *dev, phys_addr_t phys, size_t size)
|
||||
|
||||
spin_unlock(&vmm->lock);
|
||||
|
||||
rockchip_iommu_tlb_invalidate(dev);
|
||||
ret = rockchip_iommu_tlb_invalidate(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -262,9 +261,8 @@ void rockchip_iovmm_unmap_oto(struct device *dev, phys_addr_t phys)
|
||||
spin_unlock(&vmm->lock);
|
||||
|
||||
unmapped_size = iommu_unmap(vmm->domain, region->start, region->size);
|
||||
rockchip_iommu_tlb_invalidate(dev);
|
||||
WARN_ON(unmapped_size != region->size);
|
||||
pr_err("IOVMM: Unmapped %#x bytes from %#x.\n",
|
||||
dev_dbg(dev->archdata.iommu, "IOVMM: Unmapped %#x bytes from %#x.\n",
|
||||
unmapped_size, region->start);
|
||||
|
||||
kfree(region);
|
||||
@@ -295,13 +293,13 @@ int rockchip_init_iovmm(struct device *iommu, struct rk_iovmm *vmm)
|
||||
|
||||
INIT_LIST_HEAD(&vmm->regions_list);
|
||||
|
||||
pr_info("IOVMM: Created %#x B IOVMM from %#x.\n",
|
||||
dev_info(iommu, "IOVMM: Created %#x B IOVMM from %#x.\n",
|
||||
IOVM_SIZE, IOVA_START);
|
||||
return 0;
|
||||
err_setup_domain:
|
||||
gen_pool_destroy(vmm->vmm_pool);
|
||||
err_setup_genalloc:
|
||||
pr_err("IOVMM: Failed to create IOVMM (%d)\n", ret);
|
||||
dev_err(iommu, "IOVMM: Failed to create IOVMM (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user