// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2016, Linaro Limited
 */

#define pr_fmt(fmt) "%s: " fmt, __func__

#include <linux/cdev.h>
#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/slab.h>
#include <linux/tee_core.h>
#include <linux/uaccess.h>
#include <crypto/sha1.h>
#include "tee_private.h"

#define TEE_NUM_DEVICES	32

#define TEE_IOCTL_PARAM_SIZE(x) (size_mul(sizeof(struct tee_param), (x)))

#define TEE_UUID_NS_NAME_SIZE	128

/*
 * TEE Client UUID name space identifier (UUIDv4)
 *
 * Value here is random UUID that is allocated as name space identifier for
 * forming Client UUID's for TEE environment using UUIDv5 scheme.
 */
static const uuid_t tee_client_uuid_ns = UUID_INIT(0x58ac9ca0, 0x2086, 0x4683,
						   0xa1, 0xb8, 0xec, 0x4b,
						   0xc0, 0x8e, 0x01, 0xb6);

/*
 * Unprivileged devices in the lower half range and privileged devices in
 * the upper half range.
 */
static DECLARE_BITMAP(dev_mask, TEE_NUM_DEVICES);
static DEFINE_SPINLOCK(driver_lock);

static const struct class tee_class;
static dev_t tee_devt;

struct tee_context *teedev_open(struct tee_device *teedev)
{
	int rc;
	struct tee_context *ctx;

	if (!tee_device_get(teedev))
		return ERR_PTR(-EINVAL);

	ctx = kzalloc_obj(*ctx);
	if (!ctx) {
		rc = -ENOMEM;
		goto err;
	}

	kref_init(&ctx->refcount);
	ctx->teedev = teedev;
	rc = teedev->desc->ops->open(ctx);
	if (rc)
		goto err;

	return ctx;
err:
	kfree(ctx);
	tee_device_put(teedev);
	return ERR_PTR(rc);

}
EXPORT_SYMBOL_GPL(teedev_open);

void teedev_ctx_get(struct tee_context *ctx)
{
	if (ctx->releasing)
		return;

	kref_get(&ctx->refcount);
}
EXPORT_SYMBOL_GPL(teedev_ctx_get);

static void teedev_ctx_release(struct kref *ref)
{
	struct tee_context *ctx = container_of(ref, struct tee_context,
					       refcount);
	ctx->releasing = true;
	ctx->teedev->desc->ops->release(ctx);
	kfree(ctx);
}

void teedev_ctx_put(struct tee_context *ctx)
{
	if (ctx->releasing)
		return;

	kref_put(&ctx->refcount, teedev_ctx_release);
}
EXPORT_SYMBOL_GPL(teedev_ctx_put);

void teedev_close_context(struct tee_context *ctx)
{
	struct tee_device *teedev = ctx->teedev;

	if (teedev->desc->ops->close_context)
		teedev->desc->ops->close_context(ctx);

	teedev_ctx_put(ctx);
	tee_device_put(teedev);
}
EXPORT_SYMBOL_GPL(teedev_close_context);

static int tee_open(struct inode *inode, struct file *filp)
{
	struct tee_context *ctx;

	ctx = teedev_open(container_of(inode->i_cdev, struct tee_device, cdev));
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);

	/*
	 * Default user-space behaviour is to wait for tee-supplicant
	 * if not present for any requests in this context.
	 */
	ctx->supp_nowait = false;
	filp->private_data = ctx;
	return 0;
}

static int tee_release(struct inode *inode, struct file *filp)
{
	teedev_close_context(filp->private_data);
	return 0;
}

/**
 * uuid_v5() - Calculate UUIDv5
 * @uuid: Resulting UUID
 * @ns: Name space ID for UUIDv5 function
 * @name: Name for UUIDv5 function
 * @size: Size of name
 *
 * UUIDv5 is specific in RFC 4122.
 *
 * This implements section (for SHA-1):
 * 4.3.  Algorithm for Creating a Name-Based UUID
 */
static void uuid_v5(uuid_t *uuid, const uuid_t *ns, const void *name,
		    size_t size)
{
	unsigned char hash[SHA1_DIGEST_SIZE];
	struct sha1_ctx ctx;

	sha1_init(&ctx);
	sha1_update(&ctx, (const u8 *)ns, sizeof(*ns));
	sha1_update(&ctx, (const u8 *)name, size);
	sha1_final(&ctx, hash);

	memcpy(uuid->b, hash, UUID_SIZE);

	/* Tag for version 5 */
	uuid->b[6] = (hash[6] & 0x0F) | 0x50;
	uuid->b[8] = (hash[8] & 0x3F) | 0x80;
}

int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
				 const u8 connection_data[TEE_IOCTL_UUID_LEN])
{
	gid_t ns_grp = (gid_t)-1;
	kgid_t grp = INVALID_GID;
	char *name = NULL;
	int name_len;
	int rc = 0;

	if (connection_method == TEE_IOCTL_LOGIN_PUBLIC ||
	    connection_method == TEE_IOCTL_LOGIN_REE_KERNEL) {
		/* Nil UUID to be passed to TEE environment */
		uuid_copy(uuid, &uuid_null);
		return 0;
	}

	/*
	 * In Linux environment client UUID is based on UUIDv5.
	 *
	 * Determine client UUID with following semantics for 'name':
	 *
	 * For TEEC_LOGIN_USER:
	 * uid=<uid>
	 *
	 * For TEEC_LOGIN_GROUP:
	 * gid=<gid>
	 *
	 */

	name = kzalloc(TEE_UUID_NS_NAME_SIZE, GFP_KERNEL);
	if (!name)
		return -ENOMEM;

	switch (connection_method) {
	case TEE_IOCTL_LOGIN_USER:
		name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "uid=%x",
				    current_euid().val);
		if (name_len >= TEE_UUID_NS_NAME_SIZE) {
			rc = -E2BIG;
			goto out_free_name;
		}
		break;

	case TEE_IOCTL_LOGIN_GROUP:
		memcpy(&ns_grp, connection_data, sizeof(gid_t));
		grp = make_kgid(current_user_ns(), ns_grp);
		if (!gid_valid(grp) || !in_egroup_p(grp)) {
			rc = -EPERM;
			goto out_free_name;
		}

		name_len = snprintf(name, TEE_UUID_NS_NAME_SIZE, "gid=%x",
				    grp.val);
		if (name_len >= TEE_UUID_NS_NAME_SIZE) {
			rc = -E2BIG;
			goto out_free_name;
		}
		break;

	default:
		rc = -EINVAL;
		goto out_free_name;
	}

	uuid_v5(uuid, &tee_client_uuid_ns, name, name_len);
out_free_name:
	kfree(name);

	return rc;
}
EXPORT_SYMBOL_GPL(tee_session_calc_client_uuid);

static int tee_ioctl_version(struct tee_context *ctx,
			     struct tee_ioctl_version_data __user *uvers)
{
	struct tee_ioctl_version_data vers;

	ctx->teedev->desc->ops->get_version(ctx->teedev, &vers);

	if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED)
		vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED;

	if (copy_to_user(uvers, &vers, sizeof(vers)))
		return -EFAULT;

	return 0;
}

static int tee_ioctl_shm_alloc(struct tee_context *ctx,
			       struct tee_ioctl_shm_alloc_data __user *udata)
{
	long ret;
	struct tee_ioctl_shm_alloc_data data;
	struct tee_shm *shm;

	if (copy_from_user(&data, udata, sizeof(data)))
		return -EFAULT;

	/* Currently no input flags are supported */
	if (data.flags)
		return -EINVAL;

	shm = tee_shm_alloc_user_buf(ctx, data.size);
	if (IS_ERR(shm))
		return PTR_ERR(shm);

	data.id = shm->id;
	data.size = shm->size;

	if (copy_to_user(udata, &data, sizeof(data)))
		ret = -EFAULT;
	else
		ret = tee_shm_get_fd(shm);

	/*
	 * When user space closes the file descriptor the shared memory
	 * should be freed or if tee_shm_get_fd() failed then it will
	 * be freed immediately.
	 */
	tee_shm_put(shm);
	return ret;
}

static int
tee_ioctl_shm_register(struct tee_context *ctx,
		       struct tee_ioctl_shm_register_data __user *udata)
{
	long ret;
	struct tee_ioctl_shm_register_data data;
	struct tee_shm *shm;

	if (copy_from_user(&data, udata, sizeof(data)))
		return -EFAULT;

	/* Currently no input flags are supported */
	if (data.flags)
		return -EINVAL;

	shm = tee_shm_register_user_buf(ctx, data.addr, data.length);
	if (IS_ERR(shm))
		return PTR_ERR(shm);

	data.id = shm->id;
	data.length = shm->size;

	if (copy_to_user(udata, &data, sizeof(data)))
		ret = -EFAULT;
	else
		ret = tee_shm_get_fd(shm);
	/*
	 * When user space closes the file descriptor the shared memory
	 * should be freed or if tee_shm_get_fd() failed then it will
	 * be freed immediately.
	 */
	tee_shm_put(shm);
	return ret;
}

static int
tee_ioctl_shm_register_fd(struct tee_context *ctx,
			  struct tee_ioctl_shm_register_fd_data __user *udata)
{
	struct tee_ioctl_shm_register_fd_data data;
	struct tee_shm *shm;
	long ret;

	if (copy_from_user(&data, udata, sizeof(data)))
		return -EFAULT;

	/* Currently no input flags are supported */
	if (data.flags)
		return -EINVAL;

	shm = tee_shm_register_fd(ctx, data.fd);
	if (IS_ERR(shm))
		return -EINVAL;

	data.id = shm->id;
	data.flags = shm->flags;
	data.size = shm->size;

	if (copy_to_user(udata, &data, sizeof(data)))
		ret = -EFAULT;
	else
		ret = tee_shm_get_fd(shm);

	/*
	 * When user space closes the file descriptor the shared memory
	 * should be freed or if tee_shm_get_fd() failed then it will
	 * be freed immediately.
	 */
	tee_shm_put(shm);
	return ret;
}

static int param_from_user_memref(struct tee_context *ctx,
				  struct tee_param_memref *memref,
				  struct tee_ioctl_param *ip)
{
	struct tee_shm *shm;
	size_t offs = 0;

	/*
	 * If a NULL pointer is passed to a TA in the TEE,
	 * the ip.c IOCTL parameters is set to TEE_MEMREF_NULL
	 * indicating a NULL memory reference.
	 */
	if (ip->c != TEE_MEMREF_NULL) {
		/*
		 * If we fail to get a pointer to a shared
		 * memory object (and increase the ref count)
		 * from an identifier we return an error. All
		 * pointers that has been added in params have
		 * an increased ref count. It's the callers
		 * responibility to do tee_shm_put() on all
		 * resolved pointers.
		 */
		shm = tee_shm_get_from_id(ctx, ip->c);
		if (IS_ERR(shm))
			return PTR_ERR(shm);

		/*
		 * Ensure offset + size does not overflow
		 * offset and does not overflow the size of
		 * the referred shared memory object.
		 */
		if ((ip->a + ip->b) < ip->a ||
		    (ip->a + ip->b) > shm->size) {
			tee_shm_put(shm);
			return -EINVAL;
		}

		if (shm->flags & TEE_SHM_DMA_BUF) {
			struct tee_shm_dmabuf_ref *ref;

			ref = container_of(shm, struct tee_shm_dmabuf_ref, shm);
			if (ref->parent_shm) {
				/*
				 * The shm already has one reference to
				 * ref->parent_shm so we are clear of 0.
				 * We're getting another reference since
				 * this shm will be used in the parameter
				 * list instead of the shm we got with
				 * tee_shm_get_from_id() above.
				 */
				refcount_inc(&ref->parent_shm->refcount);
				tee_shm_put(shm);
				shm = ref->parent_shm;
				offs = ref->offset;
			}
		}
	} else if (ctx->cap_memref_null) {
		/* Pass NULL pointer to OP-TEE */
		shm = NULL;
	} else {
		return -EINVAL;
	}

	memref->shm_offs = ip->a + offs;
	memref->size = ip->b;
	memref->shm = shm;

	return 0;
}

static int params_from_user(struct tee_context *ctx, struct tee_param *params,
			    size_t num_params,
			    struct tee_ioctl_param __user *uparams)
{
	size_t n;

	for (n = 0; n < num_params; n++) {
		struct tee_ioctl_param ip;
		int rc;

		if (copy_from_user(&ip, uparams + n, sizeof(ip)))
			return -EFAULT;

		/* All unused attribute bits has to be zero */
		if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK)
			return -EINVAL;

		params[n].attr = ip.attr;
		switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
			params[n].u.value.a = ip.a;
			params[n].u.value.b = ip.b;
			params[n].u.value.c = ip.c;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
			params[n].u.ubuf.uaddr = u64_to_user_ptr(ip.a);
			params[n].u.ubuf.size = ip.b;

			if (!access_ok(params[n].u.ubuf.uaddr,
				       params[n].u.ubuf.size))
				return -EFAULT;

			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
			params[n].u.objref.id = ip.a;
			params[n].u.objref.flags = ip.b;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
			rc = param_from_user_memref(ctx, &params[n].u.memref,
						    &ip);
			if (rc)
				return rc;
			break;
		default:
			/* Unknown attribute */
			return -EINVAL;
		}
	}
	return 0;
}

static int params_to_user(struct tee_ioctl_param __user *uparams,
			  size_t num_params, struct tee_param *params)
{
	size_t n;

	for (n = 0; n < num_params; n++) {
		struct tee_ioctl_param __user *up = uparams + n;
		struct tee_param *p = params + n;

		switch (p->attr) {
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
			if (put_user(p->u.value.a, &up->a) ||
			    put_user(p->u.value.b, &up->b) ||
			    put_user(p->u.value.c, &up->c))
				return -EFAULT;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
			if (put_user((u64)p->u.ubuf.size, &up->b))
				return -EFAULT;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
			if (put_user(p->u.objref.id, &up->a) ||
			    put_user(p->u.objref.flags, &up->b))
				return -EFAULT;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
			if (put_user((u64)p->u.memref.size, &up->b))
				return -EFAULT;
			break;
		default:
			break;
		}
	}
	return 0;
}

static void free_params(struct tee_param *params, size_t num_params)
{
	size_t n;

	if (!params)
		return;

	for (n = 0; n < num_params; n++)
		if (tee_param_is_memref(params + n) && params[n].u.memref.shm)
			tee_shm_put(params[n].u.memref.shm);

	kfree(params);
}

static int tee_ioctl_open_session(struct tee_context *ctx,
				  struct tee_ioctl_buf_data __user *ubuf)
{
	int rc;
	struct tee_ioctl_buf_data buf;
	struct tee_ioctl_open_session_arg __user *uarg;
	struct tee_ioctl_open_session_arg arg;
	struct tee_ioctl_param __user *uparams = NULL;
	struct tee_param *params = NULL;
	bool have_session = false;

	if (!ctx->teedev->desc->ops->open_session)
		return -EINVAL;

	if (copy_from_user(&buf, ubuf, sizeof(buf)))
		return -EFAULT;

	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
	    buf.buf_len < sizeof(struct tee_ioctl_open_session_arg))
		return -EINVAL;

	uarg = u64_to_user_ptr(buf.buf_ptr);
	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len)
		return -EINVAL;

	if (arg.num_params) {
		params = kzalloc_objs(struct tee_param, arg.num_params);
		if (!params)
			return -ENOMEM;
		uparams = uarg->params;
		rc = params_from_user(ctx, params, arg.num_params, uparams);
		if (rc)
			goto out;
	}

	if (arg.clnt_login >= TEE_IOCTL_LOGIN_REE_KERNEL_MIN &&
	    arg.clnt_login <= TEE_IOCTL_LOGIN_REE_KERNEL_MAX) {
		pr_debug("login method not allowed for user-space client\n");
		rc = -EPERM;
		goto out;
	}

	rc = ctx->teedev->desc->ops->open_session(ctx, &arg, params);
	if (rc)
		goto out;
	have_session = true;

	if (put_user(arg.session, &uarg->session) ||
	    put_user(arg.ret, &uarg->ret) ||
	    put_user(arg.ret_origin, &uarg->ret_origin)) {
		rc = -EFAULT;
		goto out;
	}
	rc = params_to_user(uparams, arg.num_params, params);
out:
	/*
	 * If we've succeeded to open the session but failed to communicate
	 * it back to user space, close the session again to avoid leakage.
	 */
	if (rc && have_session && ctx->teedev->desc->ops->close_session)
		ctx->teedev->desc->ops->close_session(ctx, arg.session);
	free_params(params, arg.num_params);
	return rc;
}

static int tee_ioctl_invoke(struct tee_context *ctx,
			    struct tee_ioctl_buf_data __user *ubuf)
{
	int rc;
	struct tee_ioctl_buf_data buf;
	struct tee_ioctl_invoke_arg __user *uarg;
	struct tee_ioctl_invoke_arg arg;
	struct tee_ioctl_param __user *uparams = NULL;
	struct tee_param *params = NULL;

	if (!ctx->teedev->desc->ops->invoke_func)
		return -EINVAL;

	if (copy_from_user(&buf, ubuf, sizeof(buf)))
		return -EFAULT;

	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
	    buf.buf_len < sizeof(struct tee_ioctl_invoke_arg))
		return -EINVAL;

	uarg = u64_to_user_ptr(buf.buf_ptr);
	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (size_add(sizeof(arg), TEE_IOCTL_PARAM_SIZE(arg.num_params)) != buf.buf_len)
		return -EINVAL;

	if (arg.num_params) {
		params = kzalloc_objs(struct tee_param, arg.num_params);
		if (!params)
			return -ENOMEM;
		uparams = uarg->params;
		rc = params_from_user(ctx, params, arg.num_params, uparams);
		if (rc)
			goto out;
	}

	rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params);
	if (rc)
		goto out;

	if (put_user(arg.ret, &uarg->ret) ||
	    put_user(arg.ret_origin, &uarg->ret_origin)) {
		rc = -EFAULT;
		goto out;
	}
	rc = params_to_user(uparams, arg.num_params, params);
out:
	free_params(params, arg.num_params);
	return rc;
}

static int tee_ioctl_object_invoke(struct tee_context *ctx,
				   struct tee_ioctl_buf_data __user *ubuf)
{
	int rc;
	struct tee_ioctl_buf_data buf;
	struct tee_ioctl_object_invoke_arg __user *uarg;
	struct tee_ioctl_object_invoke_arg arg;
	struct tee_ioctl_param __user *uparams = NULL;
	struct tee_param *params = NULL;

	if (!ctx->teedev->desc->ops->object_invoke_func)
		return -EINVAL;

	if (copy_from_user(&buf, ubuf, sizeof(buf)))
		return -EFAULT;

	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
	    buf.buf_len < sizeof(struct tee_ioctl_object_invoke_arg))
		return -EINVAL;

	uarg = u64_to_user_ptr(buf.buf_ptr);
	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
		return -EINVAL;

	if (arg.num_params) {
		params = kzalloc_objs(struct tee_param, arg.num_params);
		if (!params)
			return -ENOMEM;
		uparams = uarg->params;
		rc = params_from_user(ctx, params, arg.num_params, uparams);
		if (rc)
			goto out;
	}

	rc = ctx->teedev->desc->ops->object_invoke_func(ctx, &arg, params);
	if (rc)
		goto out;

	if (put_user(arg.ret, &uarg->ret)) {
		rc = -EFAULT;
		goto out;
	}
	rc = params_to_user(uparams, arg.num_params, params);
out:
	free_params(params, arg.num_params);
	return rc;
}

static int tee_ioctl_cancel(struct tee_context *ctx,
			    struct tee_ioctl_cancel_arg __user *uarg)
{
	struct tee_ioctl_cancel_arg arg;

	if (!ctx->teedev->desc->ops->cancel_req)
		return -EINVAL;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	return ctx->teedev->desc->ops->cancel_req(ctx, arg.cancel_id,
						  arg.session);
}

static int
tee_ioctl_close_session(struct tee_context *ctx,
			struct tee_ioctl_close_session_arg __user *uarg)
{
	struct tee_ioctl_close_session_arg arg;

	if (!ctx->teedev->desc->ops->close_session)
		return -EINVAL;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	return ctx->teedev->desc->ops->close_session(ctx, arg.session);
}

static int params_to_supp(struct tee_context *ctx,
			  struct tee_ioctl_param __user *uparams,
			  size_t num_params, struct tee_param *params)
{
	size_t n;

	for (n = 0; n < num_params; n++) {
		struct tee_ioctl_param ip;
		struct tee_param *p = params + n;

		ip.attr = p->attr;
		switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
			ip.a = p->u.value.a;
			ip.b = p->u.value.b;
			ip.c = p->u.value.c;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
			ip.a = (__force unsigned long)p->u.ubuf.uaddr;
			ip.b = p->u.ubuf.size;
			ip.c = 0;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
			ip.a = p->u.objref.id;
			ip.b = p->u.objref.flags;
			ip.c = 0;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
			ip.b = p->u.memref.size;
			if (!p->u.memref.shm) {
				ip.a = 0;
				ip.c = (u64)-1; /* invalid shm id */
				break;
			}
			ip.a = p->u.memref.shm_offs;
			ip.c = p->u.memref.shm->id;
			break;
		default:
			ip.a = 0;
			ip.b = 0;
			ip.c = 0;
			break;
		}

		if (copy_to_user(uparams + n, &ip, sizeof(ip)))
			return -EFAULT;
	}

	return 0;
}

static int tee_ioctl_supp_recv(struct tee_context *ctx,
			       struct tee_ioctl_buf_data __user *ubuf)
{
	int rc;
	struct tee_ioctl_buf_data buf;
	struct tee_iocl_supp_recv_arg __user *uarg;
	struct tee_param *params;
	u32 num_params;
	u32 func;

	if (!ctx->teedev->desc->ops->supp_recv)
		return -EINVAL;

	if (copy_from_user(&buf, ubuf, sizeof(buf)))
		return -EFAULT;

	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
	    buf.buf_len < sizeof(struct tee_iocl_supp_recv_arg))
		return -EINVAL;

	uarg = u64_to_user_ptr(buf.buf_ptr);
	if (get_user(num_params, &uarg->num_params))
		return -EFAULT;

	if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) != buf.buf_len)
		return -EINVAL;

	params = kzalloc_objs(struct tee_param, num_params);
	if (!params)
		return -ENOMEM;

	rc = params_from_user(ctx, params, num_params, uarg->params);
	if (rc) {
		free_params(params, num_params);
		return rc;
	}

	/*
	 * supp_recv() may consume and replace the supplied parameters, so the
	 * final cleanup cannot use free_params() like the other ioctl paths.
	 */
	rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params);
	if (rc)
		goto out;

	if (put_user(func, &uarg->func) ||
	    put_user(num_params, &uarg->num_params)) {
		rc = -EFAULT;
		goto out;
	}

	rc = params_to_supp(ctx, uarg->params, num_params, params);
out:
	kfree(params);
	return rc;
}

static int params_from_supp(struct tee_param *params, size_t num_params,
			    struct tee_ioctl_param __user *uparams)
{
	size_t n;

	for (n = 0; n < num_params; n++) {
		struct tee_param *p = params + n;
		struct tee_ioctl_param ip;

		if (copy_from_user(&ip, uparams + n, sizeof(ip)))
			return -EFAULT;

		/* All unused attribute bits has to be zero */
		if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK)
			return -EINVAL;

		p->attr = ip.attr;
		switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
			/* Only out and in/out values can be updated */
			p->u.value.a = ip.a;
			p->u.value.b = ip.b;
			p->u.value.c = ip.c;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
			p->u.ubuf.uaddr = u64_to_user_ptr(ip.a);
			p->u.ubuf.size = ip.b;

			if (!access_ok(params[n].u.ubuf.uaddr,
				       params[n].u.ubuf.size))
				return -EFAULT;

			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
			p->u.objref.id = ip.a;
			p->u.objref.flags = ip.b;
			break;
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
			/*
			 * Only the size of the memref can be updated.
			 * Since we don't have access to the original
			 * parameters here, only store the supplied size.
			 * The driver will copy the updated size into the
			 * original parameters.
			 */
			p->u.memref.shm = NULL;
			p->u.memref.shm_offs = 0;
			p->u.memref.size = ip.b;
			break;
		default:
			memset(&p->u, 0, sizeof(p->u));
			break;
		}
	}
	return 0;
}

static int tee_ioctl_supp_send(struct tee_context *ctx,
			       struct tee_ioctl_buf_data __user *ubuf)
{
	long rc;
	struct tee_ioctl_buf_data buf;
	struct tee_iocl_supp_send_arg __user *uarg;
	struct tee_param *params;
	u32 num_params;
	u32 ret;

	/* Not valid for this driver */
	if (!ctx->teedev->desc->ops->supp_send)
		return -EINVAL;

	if (copy_from_user(&buf, ubuf, sizeof(buf)))
		return -EFAULT;

	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
	    buf.buf_len < sizeof(struct tee_iocl_supp_send_arg))
		return -EINVAL;

	uarg = u64_to_user_ptr(buf.buf_ptr);
	if (get_user(ret, &uarg->ret) ||
	    get_user(num_params, &uarg->num_params))
		return -EFAULT;

	if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) > buf.buf_len)
		return -EINVAL;

	params = kzalloc_objs(struct tee_param, num_params);
	if (!params)
		return -ENOMEM;

	rc = params_from_supp(params, num_params, uarg->params);
	if (rc)
		goto out;

	rc = ctx->teedev->desc->ops->supp_send(ctx, ret, num_params, params);
out:
	kfree(params);
	return rc;
}

static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct tee_context *ctx = filp->private_data;
	void __user *uarg = (void __user *)arg;

	switch (cmd) {
	case TEE_IOC_VERSION:
		return tee_ioctl_version(ctx, uarg);
	case TEE_IOC_SHM_ALLOC:
		return tee_ioctl_shm_alloc(ctx, uarg);
	case TEE_IOC_SHM_REGISTER:
		return tee_ioctl_shm_register(ctx, uarg);
	case TEE_IOC_SHM_REGISTER_FD:
		return tee_ioctl_shm_register_fd(ctx, uarg);
	case TEE_IOC_OPEN_SESSION:
		return tee_ioctl_open_session(ctx, uarg);
	case TEE_IOC_INVOKE:
		return tee_ioctl_invoke(ctx, uarg);
	case TEE_IOC_OBJECT_INVOKE:
		return tee_ioctl_object_invoke(ctx, uarg);
	case TEE_IOC_CANCEL:
		return tee_ioctl_cancel(ctx, uarg);
	case TEE_IOC_CLOSE_SESSION:
		return tee_ioctl_close_session(ctx, uarg);
	case TEE_IOC_SUPPL_RECV:
		return tee_ioctl_supp_recv(ctx, uarg);
	case TEE_IOC_SUPPL_SEND:
		return tee_ioctl_supp_send(ctx, uarg);
	default:
		return -EINVAL;
	}
}

static const struct file_operations tee_fops = {
	.owner = THIS_MODULE,
	.open = tee_open,
	.release = tee_release,
	.unlocked_ioctl = tee_ioctl,
	.compat_ioctl = compat_ptr_ioctl,
};

static void tee_release_device(struct device *dev)
{
	struct tee_device *teedev = container_of(dev, struct tee_device, dev);

	spin_lock(&driver_lock);
	clear_bit(teedev->id, dev_mask);
	spin_unlock(&driver_lock);
	mutex_destroy(&teedev->mutex);
	idr_destroy(&teedev->idr);
	kfree(teedev);
}

/**
 * tee_device_alloc() - Allocate a new struct tee_device instance
 * @teedesc:	Descriptor for this driver
 * @dev:	Parent device for this device
 * @pool:	Shared memory pool, NULL if not used
 * @driver_data: Private driver data for this device
 *
 * Allocates a new struct tee_device instance. The device is
 * removed by tee_device_unregister().
 *
 * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
 */
struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
				    struct device *dev,
				    struct tee_shm_pool *pool,
				    void *driver_data)
{
	struct tee_device *teedev;
	void *ret;
	int rc, max_id;
	int offs = 0;

	if (!teedesc || !teedesc->name || !teedesc->ops ||
	    !teedesc->ops->get_version || !teedesc->ops->open ||
	    !teedesc->ops->release)
		return ERR_PTR(-EINVAL);

	teedev = kzalloc_obj(*teedev);
	if (!teedev) {
		ret = ERR_PTR(-ENOMEM);
		goto err;
	}

	max_id = TEE_NUM_DEVICES / 2;

	if (teedesc->flags & TEE_DESC_PRIVILEGED) {
		offs = TEE_NUM_DEVICES / 2;
		max_id = TEE_NUM_DEVICES;
	}

	spin_lock(&driver_lock);
	teedev->id = find_next_zero_bit(dev_mask, max_id, offs);
	if (teedev->id < max_id)
		set_bit(teedev->id, dev_mask);
	spin_unlock(&driver_lock);

	if (teedev->id >= max_id) {
		ret = ERR_PTR(-ENOMEM);
		goto err;
	}

	snprintf(teedev->name, sizeof(teedev->name), "tee%s%d",
		 teedesc->flags & TEE_DESC_PRIVILEGED ? "priv" : "",
		 teedev->id - offs);

	teedev->dev.class = &tee_class;
	teedev->dev.release = tee_release_device;
	teedev->dev.parent = dev;

	teedev->dev.devt = MKDEV(MAJOR(tee_devt), teedev->id);

	rc = dev_set_name(&teedev->dev, "%s", teedev->name);
	if (rc) {
		ret = ERR_PTR(rc);
		goto err_devt;
	}

	cdev_init(&teedev->cdev, &tee_fops);
	teedev->cdev.owner = teedesc->owner;

	dev_set_drvdata(&teedev->dev, driver_data);
	device_initialize(&teedev->dev);

	/* 1 as tee_device_unregister() does one final tee_device_put() */
	teedev->num_users = 1;
	init_completion(&teedev->c_no_users);
	mutex_init(&teedev->mutex);
	idr_init(&teedev->idr);

	teedev->desc = teedesc;
	teedev->pool = pool;

	return teedev;
err_devt:
	unregister_chrdev_region(teedev->dev.devt, 1);
err:
	pr_err("could not register %s driver\n",
	       teedesc->flags & TEE_DESC_PRIVILEGED ? "privileged" : "client");
	if (teedev && teedev->id < TEE_NUM_DEVICES) {
		spin_lock(&driver_lock);
		clear_bit(teedev->id, dev_mask);
		spin_unlock(&driver_lock);
	}
	kfree(teedev);
	return ret;
}
EXPORT_SYMBOL_GPL(tee_device_alloc);

void tee_device_set_dev_groups(struct tee_device *teedev,
			       const struct attribute_group **dev_groups)
{
	teedev->dev.groups = dev_groups;
}
EXPORT_SYMBOL_GPL(tee_device_set_dev_groups);

static ssize_t implementation_id_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct tee_device *teedev = container_of(dev, struct tee_device, dev);
	struct tee_ioctl_version_data vers;

	teedev->desc->ops->get_version(teedev, &vers);
	return sysfs_emit(buf, "%d\n", vers.impl_id);
}
static DEVICE_ATTR_RO(implementation_id);

static struct attribute *tee_dev_attrs[] = {
	&dev_attr_implementation_id.attr,
	NULL
};

static const struct attribute_group tee_dev_group = {
	.attrs = tee_dev_attrs,
};

static ssize_t revision_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct tee_device *teedev = container_of(dev, struct tee_device, dev);
	char version[TEE_REVISION_STR_SIZE];
	int ret;

	if (!teedev->desc->ops->get_tee_revision)
		return -ENODEV;

	ret = teedev->desc->ops->get_tee_revision(teedev, version,
						  sizeof(version));
	if (ret)
		return ret;

	return sysfs_emit(buf, "%s\n", version);
}
static DEVICE_ATTR_RO(revision);

static struct attribute *tee_revision_attrs[] = {
	&dev_attr_revision.attr,
	NULL
};

static umode_t tee_revision_attr_is_visible(struct kobject *kobj,
					    struct attribute *attr, int n)
{
	struct device *dev = kobj_to_dev(kobj);
	struct tee_device *teedev = container_of(dev, struct tee_device, dev);

	if (teedev->desc->ops->get_tee_revision)
		return attr->mode;

	return 0;
}

static const struct attribute_group tee_revision_group = {
	.attrs = tee_revision_attrs,
	.is_visible = tee_revision_attr_is_visible,
};

static const struct attribute_group *tee_dev_groups[] = {
	&tee_dev_group,
	&tee_revision_group,
	NULL
};

static const struct class tee_class = {
	.name = "tee",
	.dev_groups = tee_dev_groups,
};

/**
 * tee_device_register() - Registers a TEE device
 * @teedev:	Device to register
 *
 * tee_device_unregister() need to be called to remove the @teedev if
 * this function fails.
 *
 * @returns < 0 on failure
 */
int tee_device_register(struct tee_device *teedev)
{
	int rc;

	if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
		dev_err(&teedev->dev, "attempt to register twice\n");
		return -EINVAL;
	}

	rc = cdev_device_add(&teedev->cdev, &teedev->dev);
	if (rc) {
		dev_err(&teedev->dev,
			"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
			teedev->name, MAJOR(teedev->dev.devt),
			MINOR(teedev->dev.devt), rc);
		return rc;
	}

	teedev->flags |= TEE_DEVICE_FLAG_REGISTERED;
	return 0;
}
EXPORT_SYMBOL_GPL(tee_device_register);

void tee_device_put(struct tee_device *teedev)
{
	mutex_lock(&teedev->mutex);
	/* Shouldn't put in this state */
	if (!WARN_ON(!teedev->desc)) {
		teedev->num_users--;
		if (!teedev->num_users) {
			teedev->desc = NULL;
			complete(&teedev->c_no_users);
		}
	}
	mutex_unlock(&teedev->mutex);
}
EXPORT_SYMBOL_GPL(tee_device_put);

bool tee_device_get(struct tee_device *teedev)
{
	mutex_lock(&teedev->mutex);
	if (!teedev->desc) {
		mutex_unlock(&teedev->mutex);
		return false;
	}
	teedev->num_users++;
	mutex_unlock(&teedev->mutex);
	return true;
}
EXPORT_SYMBOL_GPL(tee_device_get);

/**
 * tee_device_unregister() - Removes a TEE device
 * @teedev:	Device to unregister
 *
 * This function should be called to remove the @teedev even if
 * tee_device_register() hasn't been called yet. Does nothing if
 * @teedev is NULL.
 */
void tee_device_unregister(struct tee_device *teedev)
{
	if (!teedev)
		return;

	tee_device_put_all_dma_heaps(teedev);

	if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED)
		cdev_device_del(&teedev->cdev, &teedev->dev);

	tee_device_put(teedev);
	wait_for_completion(&teedev->c_no_users);

	/*
	 * No need to take a mutex any longer now since teedev->desc was
	 * set to NULL before teedev->c_no_users was completed.
	 */

	teedev->pool = NULL;

	put_device(&teedev->dev);
}
EXPORT_SYMBOL_GPL(tee_device_unregister);

/**
 * tee_get_drvdata() - Return driver_data pointer
 * @teedev:	Device containing the driver_data pointer
 * @returns the driver_data pointer supplied to tee_device_alloc().
 */
void *tee_get_drvdata(struct tee_device *teedev)
{
	return dev_get_drvdata(&teedev->dev);
}
EXPORT_SYMBOL_GPL(tee_get_drvdata);

struct match_dev_data {
	struct tee_ioctl_version_data *vers;
	const void *data;
	int (*match)(struct tee_ioctl_version_data *, const void *);
};

static int match_dev(struct device *dev, const void *data)
{
	const struct match_dev_data *match_data = data;
	struct tee_device *teedev = container_of(dev, struct tee_device, dev);

	teedev->desc->ops->get_version(teedev, match_data->vers);
	return match_data->match(match_data->vers, match_data->data);
}

struct tee_context *
tee_client_open_context(struct tee_context *start,
			int (*match)(struct tee_ioctl_version_data *,
				     const void *),
			const void *data, struct tee_ioctl_version_data *vers)
{
	struct device *dev = NULL;
	struct device *put_dev = NULL;
	struct tee_context *ctx = NULL;
	struct tee_ioctl_version_data v;
	struct match_dev_data match_data = { vers ? vers : &v, data, match };

	if (start)
		dev = &start->teedev->dev;

	do {
		dev = class_find_device(&tee_class, dev, &match_data, match_dev);
		if (!dev) {
			ctx = ERR_PTR(-ENOENT);
			break;
		}

		put_device(put_dev);
		put_dev = dev;

		ctx = teedev_open(container_of(dev, struct tee_device, dev));
	} while (IS_ERR(ctx) && PTR_ERR(ctx) != -ENOMEM);

	put_device(put_dev);
	/*
	 * Default behaviour for in kernel client is to not wait for
	 * tee-supplicant if not present for any requests in this context.
	 * Also this flag could be configured again before call to
	 * tee_client_open_session() if any in kernel client requires
	 * different behaviour.
	 */
	if (!IS_ERR(ctx))
		ctx->supp_nowait = true;

	return ctx;
}
EXPORT_SYMBOL_GPL(tee_client_open_context);

void tee_client_close_context(struct tee_context *ctx)
{
	teedev_close_context(ctx);
}
EXPORT_SYMBOL_GPL(tee_client_close_context);

void tee_client_get_version(struct tee_context *ctx,
			    struct tee_ioctl_version_data *vers)
{
	ctx->teedev->desc->ops->get_version(ctx->teedev, vers);
}
EXPORT_SYMBOL_GPL(tee_client_get_version);

int tee_client_open_session(struct tee_context *ctx,
			    struct tee_ioctl_open_session_arg *arg,
			    struct tee_param *param)
{
	if (!ctx->teedev->desc->ops->open_session)
		return -EINVAL;
	return ctx->teedev->desc->ops->open_session(ctx, arg, param);
}
EXPORT_SYMBOL_GPL(tee_client_open_session);

int tee_client_close_session(struct tee_context *ctx, u32 session)
{
	if (!ctx->teedev->desc->ops->close_session)
		return -EINVAL;
	return ctx->teedev->desc->ops->close_session(ctx, session);
}
EXPORT_SYMBOL_GPL(tee_client_close_session);

int tee_client_system_session(struct tee_context *ctx, u32 session)
{
	if (!ctx->teedev->desc->ops->system_session)
		return -EINVAL;
	return ctx->teedev->desc->ops->system_session(ctx, session);
}
EXPORT_SYMBOL_GPL(tee_client_system_session);

int tee_client_invoke_func(struct tee_context *ctx,
			   struct tee_ioctl_invoke_arg *arg,
			   struct tee_param *param)
{
	if (!ctx->teedev->desc->ops->invoke_func)
		return -EINVAL;
	return ctx->teedev->desc->ops->invoke_func(ctx, arg, param);
}
EXPORT_SYMBOL_GPL(tee_client_invoke_func);

int tee_client_cancel_req(struct tee_context *ctx,
			  struct tee_ioctl_cancel_arg *arg)
{
	if (!ctx->teedev->desc->ops->cancel_req)
		return -EINVAL;
	return ctx->teedev->desc->ops->cancel_req(ctx, arg->cancel_id,
						  arg->session);
}

static int tee_client_device_match(struct device *dev,
				   const struct device_driver *drv)
{
	const struct tee_client_device_id *id_table;
	struct tee_client_device *tee_device;

	id_table = to_tee_client_driver(drv)->id_table;
	tee_device = to_tee_client_device(dev);

	while (!uuid_is_null(&id_table->uuid)) {
		if (uuid_equal(&tee_device->id.uuid, &id_table->uuid))
			return 1;
		id_table++;
	}

	return 0;
}

static int tee_client_device_uevent(const struct device *dev,
				    struct kobj_uevent_env *env)
{
	uuid_t *dev_id = &to_tee_client_device(dev)->id.uuid;

	return add_uevent_var(env, "MODALIAS=tee:%pUb", dev_id);
}

static int tee_client_device_probe(struct device *dev)
{
	struct tee_client_device *tcdev = to_tee_client_device(dev);
	struct tee_client_driver *drv = to_tee_client_driver(dev->driver);

	if (drv->probe)
		return drv->probe(tcdev);
	else
		return 0;
}

static void tee_client_device_remove(struct device *dev)
{
	struct tee_client_device *tcdev = to_tee_client_device(dev);
	struct tee_client_driver *drv = to_tee_client_driver(dev->driver);

	if (drv->remove)
		drv->remove(tcdev);
}

static void tee_client_device_shutdown(struct device *dev)
{
	struct tee_client_device *tcdev = to_tee_client_device(dev);
	struct tee_client_driver *drv = to_tee_client_driver(dev->driver);

	if (dev->driver && drv->shutdown)
		drv->shutdown(tcdev);
}

const struct bus_type tee_bus_type = {
	.name		= "tee",
	.match		= tee_client_device_match,
	.uevent		= tee_client_device_uevent,
	.probe		= tee_client_device_probe,
	.remove		= tee_client_device_remove,
	.shutdown	= tee_client_device_shutdown,
};
EXPORT_SYMBOL_GPL(tee_bus_type);

static int tee_client_device_probe_legacy(struct tee_client_device *tcdev)
{
	struct device *dev = &tcdev->dev;
	struct device_driver *driver = dev->driver;

	return driver->probe(dev);
}

static void tee_client_device_remove_legacy(struct tee_client_device *tcdev)
{
	struct device *dev = &tcdev->dev;
	struct device_driver *driver = dev->driver;

	driver->remove(dev);
}

static void tee_client_device_shutdown_legacy(struct tee_client_device *tcdev)
{
	struct device *dev = &tcdev->dev;
	struct device_driver *driver = dev->driver;

	driver->shutdown(dev);
}

int __tee_client_driver_register(struct tee_client_driver *tee_driver,
				 struct module *owner)
{
	tee_driver->driver.owner = owner;
	tee_driver->driver.bus = &tee_bus_type;

	/*
	 * Drivers that have callbacks set for tee_driver->driver need updating
	 * to use the callbacks in tee_driver instead. driver_register() warns
	 * about that, so no need to warn here, too.
	 */
	if (!tee_driver->probe && tee_driver->driver.probe)
		tee_driver->probe = tee_client_device_probe_legacy;
	if (!tee_driver->remove && tee_driver->driver.remove)
		tee_driver->remove = tee_client_device_remove_legacy;
	if (!tee_driver->shutdown && tee_driver->driver.probe)
		tee_driver->shutdown = tee_client_device_shutdown_legacy;

	return driver_register(&tee_driver->driver);
}
EXPORT_SYMBOL_GPL(__tee_client_driver_register);

void tee_client_driver_unregister(struct tee_client_driver *tee_driver)
{
	driver_unregister(&tee_driver->driver);
}
EXPORT_SYMBOL_GPL(tee_client_driver_unregister);

static int __init tee_init(void)
{
	int rc;

	rc = class_register(&tee_class);
	if (rc) {
		pr_err("couldn't create class\n");
		return rc;
	}

	rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee");
	if (rc) {
		pr_err("failed to allocate char dev region\n");
		goto out_unreg_class;
	}

	rc = bus_register(&tee_bus_type);
	if (rc) {
		pr_err("failed to register tee bus\n");
		goto out_unreg_chrdev;
	}

	return 0;

out_unreg_chrdev:
	unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
out_unreg_class:
	class_unregister(&tee_class);

	return rc;
}

static void __exit tee_exit(void)
{
	bus_unregister(&tee_bus_type);
	unregister_chrdev_region(tee_devt, TEE_NUM_DEVICES);
	class_unregister(&tee_class);
}

subsys_initcall(tee_init);
module_exit(tee_exit);

MODULE_AUTHOR("Linaro");
MODULE_DESCRIPTION("TEE Driver");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS("DMA_BUF");
MODULE_IMPORT_NS("DMA_BUF_HEAP");
