static void iopgtable_clear_entry_all(struct iommu *obj) { int i; spin_lock(&obj->page_table_lock); for (i = 0; i < PTRS_PER_IOPGD; i++) { u32 da; u32 *iopgd; da = i << IOPGD_SHIFT; iopgd = iopgd_offset(obj, da); if (!*iopgd) continue; if (*iopgd & IOPGD_TABLE) iopte_free(iopte_offset(iopgd, 0)); *iopgd = 0; flush_iopgd_range(iopgd, iopgd); } flush_iotlb_all(obj); spin_unlock(&obj->page_table_lock); }
/** * iommu_get - Get iommu handler * @name: target iommu name **/ struct iommu *iommu_get(const char *name) { int err = -ENOMEM; struct device *dev; struct iommu *obj; int rev; dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name, device_match_by_alias); if (!dev) return ERR_PTR(-ENODEV); obj = to_iommu(dev); mutex_lock(&obj->iommu_lock); if (obj->refcount++ == 0) { err = iommu_enable(obj); if (err) goto err_enable; if (!strcmp(obj->name, "ducati")) { rev = GET_OMAP_REVISION(); if (rev == 0x0) iommu_set_twl(obj, false); } flush_iotlb_all(obj); } if (!try_module_get(obj->owner)) goto err_module; mutex_unlock(&obj->iommu_lock); dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name); return obj; err_module: if (obj->refcount == 1) iommu_disable(obj); err_enable: obj->refcount--; mutex_unlock(&obj->iommu_lock); return ERR_PTR(err); }