/*MMU init for internal structure*/
int isp_mmu_init(struct isp_mmu *mmu, struct isp_mmu_client *driver)
{
	if (!mmu)		/* error */
		return -EINVAL;
	if (!driver)		/* error */
		return -EINVAL;

	if (!driver->name)
		dev_warn(atomisp_dev, "NULL name for MMU driver...\n");

	mmu->driver = driver;

	if (!driver->set_pd_base || !driver->tlb_flush_all) {
		dev_err(atomisp_dev,
			    "set_pd_base or tlb_flush_all operation "
			     "not provided.\n");
		return -EINVAL;
	}

	if (!driver->tlb_flush_range)
		driver->tlb_flush_range = isp_mmu_flush_tlb_range_default;

	if (!driver->pte_valid_mask) {
		dev_err(atomisp_dev, "PTE_MASK is missing from mmu driver\n");
		return -EINVAL;
	}

	mmu->l1_pte = driver->null_pte;

	mutex_init(&mmu->pt_mutex);

#ifndef CSS20
	isp_mmu_flush_tlb(mmu);
#endif /* CSS20 */

#ifdef USE_KMEM_CACHE
	mmu->tbl_cache = kmem_cache_create("iopte_cache", ISP_PAGE_SIZE,
						//ISP_L1PT_PTES, SLAB_HWCACHE_ALIGN,
					   ISP_PAGE_SIZE, SLAB_HWCACHE_ALIGN,
					   NULL);
	if (!mmu->tbl_cache)
		return -ENOMEM;
#endif

	return 0;
}
예제 #2
0
static void isp_mmu_flush_tlb_range_default(struct isp_mmu *mmu,
					      unsigned int start,
					      unsigned int size)
{
	isp_mmu_flush_tlb(mmu);
}