예제 #1
0
int omap_rproc_activate(struct omap_device *od)
{
	int i, ret = 0;
	struct rproc *rproc = platform_get_drvdata(&od->pdev);
	struct device *dev = rproc->dev;
	struct omap_rproc_pdata *pdata = dev->platform_data;
	struct omap_rproc_timers_info *timers = pdata->timers;
	struct omap_rproc_priv *rpp = rproc->priv;
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
	struct iommu *iommu;

	if (!rpp->iommu) {
		iommu = iommu_get(pdata->iommu_name);
		if (IS_ERR(iommu)) {
			dev_err(dev, "iommu_get error: %ld\n",
				PTR_ERR(iommu));
			return PTR_ERR(iommu);
		}
		rpp->iommu = iommu;
	}

	if (!rpp->mbox)
		rpp->mbox = omap_mbox_get(pdata->sus_mbox_name, NULL);
#endif
	/**
	 * explicitly configure a boot address from which remoteproc
	 * starts executing code when taken out of reset.
	 */
	_load_boot_addr(rproc, rpp->bootaddr);

	/**
	 * Domain is in HW SUP thus in hw_auto but
	 * since remoteproc will be enabled clkdm
	 * needs to be in sw_sup (Do not let it idle).
	 */
	if (pdata->clkdm)
		clkdm_wakeup(pdata->clkdm);

	for (i = 0; i < pdata->timers_cnt; i++)
		omap_dm_timer_start(timers[i].odt);

	for (i = 0; i < od->hwmods_cnt; i++) {
		ret = omap_hwmod_enable(od->hwmods[i]);
		if (ret) {
			for (i = 0; i < pdata->timers_cnt; i++)
				omap_dm_timer_stop(timers[i].odt);
			break;
		}
	}

	/**
	 * Domain is in force_wkup but since remoteproc
	 * was enabled it is safe now to switch clkdm
	 * to hw_auto (let it idle).
	 */
	if (pdata->clkdm)
		clkdm_allow_idle(pdata->clkdm);

	return ret;
}
예제 #2
0
static int omap_rproc_iommu_init(struct rproc *rproc,
		 int (*callback)(struct rproc *rproc, u64 fa, u32 flags))
{
	struct device *dev = rproc->dev;
	struct omap_rproc_pdata *pdata = dev->platform_data;
	int ret, i;
	struct iommu *iommu;
	struct omap_rproc_priv *rpp;

	rpp = kzalloc(sizeof(*rpp), GFP_KERNEL);
	if (!rpp)
		return -ENOMEM;

	if (pdata->clkdm)
		clkdm_wakeup(pdata->clkdm);
	iommu_set_isr(pdata->iommu_name, omap_rproc_iommu_isr, rproc);
	iommu_set_secure(pdata->iommu_name, rproc->secure_mode,
						rproc->secure_ttb);
	iommu = iommu_get(pdata->iommu_name);
	if (IS_ERR(iommu)) {
		ret = PTR_ERR(iommu);
		dev_err(dev, "iommu_get error: %d\n", ret);
		goto err_mmu;
	}

	rpp->iommu = iommu;
	rpp->iommu_cb = callback;
	rproc->priv = rpp;

	if (!rproc->secure_mode) {
		for (i = 0; rproc->memory_maps[i].size; i++) {
			const struct rproc_mem_entry *me =
							&rproc->memory_maps[i];

			ret = omap_rproc_map(dev, iommu, me->da, me->pa,
								 me->size);
			if (ret)
				goto err_map;
		}
	}
	if (pdata->clkdm)
		clkdm_allow_idle(pdata->clkdm);

	return 0;

err_map:
	iommu_put(iommu);
err_mmu:
	iommu_set_secure(pdata->iommu_name, false, NULL);
	if (pdata->clkdm)
		clkdm_allow_idle(pdata->clkdm);
	kfree(rpp);
	return ret;
}
예제 #3
0
int __init ispmmu_init(void)
{
	int err = 0;

	isp_get();
	isp_iommu = iommu_get("isp");
	if (IS_ERR(isp_iommu)) {
		err = PTR_ERR(isp_iommu);
		isp_iommu = NULL;
	}
	isp_put();

	return err;
}
예제 #4
0
static int omap_dmm_open(struct inode *inode, struct file *filp)
{
	struct iodmm_struct *iodmm;
	struct iovmm_device *obj;

	obj = container_of(inode->i_cdev, struct iovmm_device, cdev);
	obj->refcount++;

	iodmm = kzalloc(sizeof(struct iodmm_struct), GFP_KERNEL);
	INIT_LIST_HEAD(&iodmm->map_list);

	iodmm->iovmm = obj;
	obj->iommu = iommu_get(obj->name);
	filp->private_data = iodmm;

	return 0;
}