Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b56ab5ee authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: fd: Attach iommu dynamically"

parents 54c7302b 01a6fad1
Loading
Loading
Loading
Loading
+1 −13
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/iommu.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/ion.h>
@@ -375,15 +374,9 @@ static int msm_fd_open(struct file *file)
		dev_err(device->dev, "Error ion client create\n");
		goto error_ion_client_create;
	}
	ctx->mem_pool.fd_device = ctx->fd_device;
	ctx->mem_pool.domain_num = ctx->fd_device->iommu_domain_num;

	ret = iommu_attach_device(ctx->fd_device->iommu_domain,
		ctx->fd_device->iommu_dev);
	if (ret) {
		dev_err(device->dev, "Can not attach iommu domain\n");
		goto error_iommu_attach;
	}

	ctx->stats = vmalloc(sizeof(*ctx->stats) * MSM_FD_MAX_RESULT_BUFS);
	if (!ctx->stats) {
		dev_err(device->dev, "No memory for face statistics\n");
@@ -394,9 +387,6 @@ static int msm_fd_open(struct file *file)
	return 0;

error_stats_vmalloc:
	iommu_detach_device(ctx->fd_device->iommu_domain,
			ctx->fd_device->iommu_dev);
error_iommu_attach:
	ion_client_destroy(ctx->mem_pool.client);
error_ion_client_create:
	vb2_queue_release(&ctx->vb2_q);
@@ -422,8 +412,6 @@ static int msm_fd_release(struct file *file)
	if (ctx->work_buf.handle)
		msm_fd_hw_unmap_buffer(&ctx->work_buf);

	iommu_detach_device(ctx->fd_device->iommu_domain,
		ctx->fd_device->iommu_dev);
	ion_client_destroy(ctx->mem_pool.client);

	v4l2_fh_del(&ctx->fh);
+4 −0
Original line number Diff line number Diff line
@@ -75,10 +75,12 @@ struct msm_fd_format {

/*
 * struct msm_fd_mem_pool - Structure contain FD memory pool information.
 * @fd_device: Pointer to fd device.
 * @client: Pointer to ion client.
 * @domain_num: Domain number associated with FD hw.
 */
struct msm_fd_mem_pool {
	struct msm_fd_device *fd_device;
	struct ion_client *client;
	int domain_num;
};
@@ -197,6 +199,7 @@ enum msm_fd_mem_resources {
 * @bus_client: Memory access bus client.
 * @iommu_domain: Pointer to FD device iommu domain handler.
 * @iommu_domain_num: FD device iommu domain number.
 * @iommu_attached_cnt: Iommu attached devices reference count.
 * @iommu_dev: Pointer to Ion iommu device.
 * @dev: Pointer to device struct.
 * @v4l2_dev: V4l2 device.
@@ -226,6 +229,7 @@ struct msm_fd_device {

	struct iommu_domain *iommu_domain;
	int iommu_domain_num;
	unsigned int iommu_attached_cnt;

	struct device *iommu_dev;
	struct device *dev;
+68 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/regulator/consumer.h>
#include <linux/msm_iommu_domains.h>
#include <linux/spinlock.h>
#include <linux/iommu.h>
#include <linux/qcom_iommu.h>
#include <linux/msm_ion.h>
#include <linux/msm-bus.h>
@@ -813,6 +814,63 @@ void msm_fd_hw_put(struct msm_fd_device *fd)
	mutex_unlock(&fd->lock);
}

/*
 * msm_fd_hw_attach_iommu - Attach iommu to face detection engine.
 * @fd: Pointer to fd device.
 *
 * Iommu attach have reference count protected by
 * fd device mutex.
 */
static int msm_fd_hw_attach_iommu(struct msm_fd_device *fd)
{
	int ret;

	mutex_lock(&fd->lock);

	if (fd->iommu_attached_cnt == UINT_MAX) {
		dev_err(fd->dev, "Max count reached! can not attach iommu\n");
		goto error;
	}

	if (fd->iommu_attached_cnt == 0) {
		ret = iommu_attach_device(fd->iommu_domain, fd->iommu_dev);
		if (ret < 0) {
			dev_err(fd->dev, "Can not attach iommu domain\n");
			goto error;
		}
	}
	fd->iommu_attached_cnt++;
	mutex_unlock(&fd->lock);

	return 0;

error:
	mutex_unlock(&fd->lock);
	return ret;
}

/*
 * msm_fd_hw_detach_iommu - Detach iommu from face detection engine.
 * @fd: Pointer to fd device.
 *
 * Iommu detach have reference count protected by
 * fd device mutex.
 */
static void msm_fd_hw_detach_iommu(struct msm_fd_device *fd)
{
	mutex_lock(&fd->lock);
	if (fd->iommu_attached_cnt == 0) {
		dev_err(fd->dev, "There is no attached device\n");
		mutex_unlock(&fd->lock);
		return;
	}

	if (--fd->iommu_attached_cnt == 0)
		iommu_detach_device(fd->iommu_domain, fd->iommu_dev);

	mutex_unlock(&fd->lock);
}

/*
 * msm_fd_hw_map_buffer - Map buffer to fd hw mmu.
 * @pool: Pointer to fd memory pool.
@@ -829,12 +887,16 @@ int msm_fd_hw_map_buffer(struct msm_fd_mem_pool *pool, int fd,
	if (!pool || fd < 0)
		return -EINVAL;

	ret = msm_fd_hw_attach_iommu(pool->fd_device);
	if (ret < 0)
		goto error;

	buf->pool = pool;
	buf->fd = fd;

	buf->handle = ion_import_dma_buf(pool->client, buf->fd);
	if (IS_ERR_OR_NULL(buf->handle))
		goto error;
		goto error_import_dma;

	ret = ion_map_iommu(pool->client, buf->handle, pool->domain_num,
		0, SZ_4K, 0, &buf->addr, &buf->size, 0, 0);
@@ -845,6 +907,8 @@ int msm_fd_hw_map_buffer(struct msm_fd_mem_pool *pool, int fd,

error_map_iommu:
	ion_free(pool->client, buf->handle);
error_import_dma:
	msm_fd_hw_detach_iommu(pool->fd_device);
error:
	return -ENOMEM;
}
@@ -855,9 +919,11 @@ error:
 */
void msm_fd_hw_unmap_buffer(struct msm_fd_buf_handle *buf)
{
	if (buf->size)
	if (buf->size) {
		ion_unmap_iommu(buf->pool->client, buf->handle,
			buf->pool->domain_num, 0);
		msm_fd_hw_detach_iommu(buf->pool->fd_device);
	}

	if (!IS_ERR_OR_NULL(buf->handle))
		ion_free(buf->pool->client, buf->handle);