spin_lock_irqsave(&data->data_lock, flags);
if (!rockchip_set_iommu_active(data)) {
- if (WARN_ON(pgtable != data->pgtable)) {
+ if (WARN_ON(pgtable != data->pgtable))
ret = -EBUSY;
- rockchip_set_iommu_inactive(data);
- } else {
+ else
ret = 1;
- }
- spin_unlock_irqrestore(&data->data_lock, flags);
dev_info(data->iommu, "(%s) Already enabled\n", data->dbgname);
- return ret;
+ goto enable_out;
}
for (i = 0; i < data->num_res_mem; i++) {
if (!ret) {
dev_info(data->iommu, "(%s), %s failed\n",
data->dbgname, __func__);
- spin_unlock_irqrestore(&data->data_lock, flags);
- return -EBUSY;
+ ret = -EBUSY;
+ goto enable_out;
}
if (!strstr(data->dbgname, "isp")) {
if (!rockchip_iommu_reset(data->res_bases[i],
data->dbgname)) {
- spin_unlock_irqrestore(&data->data_lock, flags);
- return -ENOENT;
+ rockchip_iommu_disable_stall(data->res_bases[i]);
+ ret = -ENOENT;
+ goto enable_out;
}
}
ret = rockchip_iommu_enable_paging(data->res_bases[i]);
if (!ret) {
- spin_unlock_irqrestore(&data->data_lock, flags);
dev_info(data->iommu, "(%s), %s failed\n",
data->dbgname, __func__);
- return -EBUSY;
+ rockchip_iommu_disable_stall(data->res_bases[i]);
+ ret = -EBUSY;
+ goto enable_out;
}
rockchip_iommu_disable_stall(data->res_bases[i]);
}
data->pgtable = pgtable;
+ spin_unlock_irqrestore(&data->data_lock, flags);
dev_dbg(data->iommu,"(%s) Enabled\n", data->dbgname);
+ return 0;
+
+enable_out:
+ rockchip_set_iommu_inactive(data);
spin_unlock_irqrestore(&data->data_lock, flags);
- return 0;
+ return ret;
}
int rockchip_iommu_tlb_invalidate_global(struct device *dev)
{
unsigned long flags;
struct iommu_drvdata *data = dev_get_drvdata(dev->archdata.iommu);
- int ret;
+ int ret = 0;
spin_lock_irqsave(&data->data_lock, flags);
{ .compatible = HEVC_IOMMU_COMPATIBLE_NAME},
{ .compatible = VPU_IOMMU_COMPATIBLE_NAME},
{ .compatible = ISP_IOMMU_COMPATIBLE_NAME},
+ { .compatible = ISP0_IOMMU_COMPATIBLE_NAME},
+ { .compatible = ISP1_IOMMU_COMPATIBLE_NAME},
{ .compatible = VOP_IOMMU_COMPATIBLE_NAME},
{ .compatible = VDEC_IOMMU_COMPATIBLE_NAME},
{ /* end */ }
static int __init rockchip_iommu_init_driver(void)
{
+ struct device_node *np;
int ret;
+ np = of_find_matching_node(NULL, iommu_dt_ids);
+ if (!np) {
+ pr_err("Failed to find legacy iommu devices\n");
+ return -ENODEV;
+ }
+
lv2table_kmem_cache = kmem_cache_create("rk-iommu-lv2table",
LV2TABLE_SIZE, LV2TABLE_SIZE,
0, NULL);