// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#include <linux/amlogic/aml_mkl.h>

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/printk.h>
#include <linux/mutex.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/amlogic/iomap.h>
#include <linux/amlogic/aml_kt.h>

#include "aml_seckey_log.h"

#define AML_MKL_DEVICE_NAME "aml_mkl"
#define DEVICE_INSTANCES 1

/* kl type */
#define KL_TYPE_OLD (0)
#define KL_TYPE_NEW (1)

/* kl offset */
#define KL_PENDING_OFFSET (31U)
#define KL_PENDING_MASK (1)
#define KL_STATUS_OFFSET (29)
#define KL_STATUS_MASK (3)
#define KL_ALGO_OFFSET (28)
#define KL_ALGO_MASK (1)
#define KL_MODE_OFFSET (26)
#define KL_MODE_MASK (3)
#define KL_FLAG_OFFSET (24)
#define KL_FLAG_MASK (3)
#define KL_KEYALGO_OFFSET (20)
#define KL_KEYALGO_MASK (0xf)
#define KL_USERID_OFFSET (16)
#define KL_USERID_MASK (0xf)
#define KL_KTE_OFFSET (8)
#define KL_KTE_MASK (0xff)
#define KL_MRK_OFFSET (4)
#define KL_MRK_MASK (0xf)
#define KL_FUNC_ID_OFFSET (0)
#define KL_FUNC_ID_MASK (0xf)
#define KL_MID_OFFSET (24)
#define KL_MID_MASK (0xff)
#define KL_VID_OFFSET (8)
#define KL_MID_EXTRA_OFFSET (8)
#define KL_TEE_PRIV_OFFSET (7)
#define KL_TEE_PRIV_MASK (1)
#define KL_TEE_SEP_OFFSET (2)
#define KL_TEE_SEP_MASK (3)
#define KL_LEVEL_OFFSET (4)
#define KL_LEVEL_MASK (7)
#define KL_STAGE_OFFSET (0)
#define KL_STAGE_MASK (3)

#define KL_MSR_FUNCID_OFFSET  (0)
#define KL_MSR_KEYALGO_OFFSET (12)
#define KL_MSR_PAYLOAD_OFFSET (16)
#define KL_MSR_BUFLEVEL_OFFSET (4)

/* kl etc */
#define KL_PENDING_WAIT_TIMEOUT (20000)
#define KL_ETSI_MID_MSG (0)

/* kl status */
#define KL_STATUS_OK (0)
#define KL_STATUS_ERROR_PERMISSION_DINED (1)
#define KL_STATUS_ERROR_OTP (2)
#define KL_STATUS_ERROR_DEPOSIT (3)
#define KL_STATUS_ERROR_TIMEOUT (4)
#define KL_STATUS_ERROR_BAD_PARAM (5)
#define KL_STATUS_ERROR_BAD_STATE (6)

struct aml_mkl_dev {
	struct cdev cdev;
	struct mutex lock; /*define mutex*/
	void __iomem *base_addr;
	union {
		struct reg {
			u32 rdy_offset;
			u32 cfg_offset;
			u32 cmd_offset;
			u32 ek_offset;
		} reg;
		struct old_reg {
			u32 start0_offset;
			u32 key1_offset;
			u32 nonce_offset;
			u32 key2_offset;
			u32 key3_offset;
			u32 key4_offset;
			u32 key5_offset;
			u32 key6_offset;
			u32 key7_offset;
		} old_reg;
	};
	u32 kl_type;
	u32 kl_vid_type;
};

static dev_t aml_mkl_devt;
static struct aml_mkl_dev aml_mkl_dev;
static struct class *aml_mkl_class;
static struct dentry *aml_mkl_debug_dent;
u32 kl_log_level = 3;

static int aml_mkl_init_dbgfs(void)
{
	if (!aml_mkl_debug_dent) {
		aml_mkl_debug_dent = debugfs_create_dir("aml_mkl", NULL);
		if (!aml_mkl_debug_dent) {
			KL_LOGE("can not create debugfs directory\n");
			return -ENOMEM;
		}

		debugfs_create_u32("log_level", 0644, aml_mkl_debug_dent, &kl_log_level);
	}
	return 0;
}

static int aml_mkl_open(struct inode *inode, struct file *file)
{
	struct aml_mkl_dev *dev;

	dev = container_of(inode->i_cdev, struct aml_mkl_dev, cdev);
	file->private_data = dev;

	return 0;
}

static int aml_mkl_release(struct inode *inode, struct file *file)
{
	if (!file->private_data)
		return 0;

	file->private_data = NULL;
	return 0;
}

static int aml_mkl_program_key(void __iomem *base_addr, u32 offset, const u8 *data)
{
	int i = 0;
	const u32 *data32 = (const u32 *)data;

	if (!data32)
		return -1;

	for (i = 0; i < 4; i++)
		iowrite32(data32[i], (char *)base_addr + offset + i * sizeof(u32));

	return 0;
}

static int aml_mkl_lock(struct aml_mkl_dev *dev)
{
	int cnt = 0;
	int ret = KL_STATUS_OK;

	if (dev->kl_type == KL_TYPE_OLD) {
		while ((ioread32((char *)dev->base_addr + dev->old_reg.start0_offset) >> 31) & 1) {
			if (cnt++ > KL_PENDING_WAIT_TIMEOUT) {
				KL_LOGE("Error: wait KL ready timeout\n");
				ret = KL_STATUS_ERROR_TIMEOUT;
			}
		}
	} else {
		while (ioread32((char *)dev->base_addr + dev->reg.rdy_offset) != 1) {
			if (cnt++ > KL_PENDING_WAIT_TIMEOUT) {
				KL_LOGE("Error: wait KL ready timeout\n");
				ret = KL_STATUS_ERROR_TIMEOUT;
			}
		}
	}

	return ret;
}

static void aml_mkl_unlock(struct aml_mkl_dev *dev)
{
	iowrite32(1, (char *)dev->base_addr + dev->reg.rdy_offset);
}

static int aml_mkl_read_pending(struct aml_mkl_dev *dev)
{
	int ret = -1;
	int cnt = 0;
	u32 reg_ret = 0;

	do {
		reg_ret = ioread32((char *)dev->base_addr + dev->reg.cfg_offset);
		if (cnt++ > KL_PENDING_WAIT_TIMEOUT) {
			KL_LOGE("Error: wait KL pending done timeout\n");
			ret = KL_STATUS_ERROR_TIMEOUT;
			return ret;
		}
	} while (reg_ret & (1 << KL_PENDING_OFFSET));

	reg_ret = (reg_ret >> KL_STATUS_OFFSET) & KL_STATUS_MASK;
	switch (reg_ret) {
	case 0:
		ret = KL_STATUS_OK;
		break;
	case 1:
		KL_LOGE("Permission Denied Error code: %d\n", reg_ret);
		ret = KL_STATUS_ERROR_BAD_STATE;
		break;
	case 2:
		KL_LOGE("OTP Error code: %d\n", reg_ret);
		ret = KL_STATUS_ERROR_OTP;
		break;
	case 3:
		KL_LOGE("KL Deposit Error code: %d\n", reg_ret);
		ret = KL_STATUS_ERROR_DEPOSIT;
		break;
	}

	return ret;
}

static int aml_mkl_etsi_run(struct file *filp, struct amlkl_params *param)
{
	int ret = KL_STATUS_OK;
	int i;
	int tee_priv = 0;
	u32 reg_val = 0;
	u32 reg_offset = 0;
	struct amlkl_usage *pu;
	struct aml_mkl_dev *dev = filp->private_data;

	if (!param) {
		KL_LOGE("Error: param data has Null\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	pu = &param->usage;
	KL_LOGD("kte:%d, levels:%d, mid:%#x, kl_algo:%d, mrk:%d\n",
		param->kt_handle, param->levels, param->module_id,
		param->kl_algo, param->mrk_cfg_index);
	KL_LOGD("kt usage, crypto:%d, algo:%d, uid:%d\n", pu->crypto, pu->algo,
		pu->uid);

	if (pu->uid & ~KL_USERID_MASK ||
	    (pu->uid > AML_KT_USER_M2M_5 && pu->uid < AML_KT_USER_TSD) ||
	    (pu->uid > AML_KT_USER_TSE && pu->uid < KL_USERID_MASK) ||
	    pu->algo & ~KL_KEYALGO_MASK ||
	    (pu->algo > AML_KT_ALGO_DES && pu->algo < AML_KT_ALGO_NDL) ||
	    (pu->algo > AML_KT_ALGO_CSA2 && pu->algo < AML_KT_ALGO_HMAC) ||
	    (pu->algo > AML_KT_ALGO_HMAC && pu->algo < KL_KEYALGO_MASK) ||
	    pu->crypto & ~KL_FLAG_MASK ||
	    param->levels < AML_KL_LEVEL_3 || param->levels > AML_KL_LEVEL_6 ||
	    param->kl_algo > AML_KL_ALGO_AES ||
	    param->mrk_cfg_index > AML_KL_MRK_ETSI_3) {
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	/* 1. Read KL_REE_RDY to lock KL */
	mutex_lock(&dev->lock);
	if (aml_mkl_lock(dev) != KL_STATUS_OK) {
		KL_LOGE("key ladder not ready\n");
		ret = KL_STATUS_ERROR_BAD_STATE;
		goto unlock_mutex;
	}

	/* 2. Program Eks */
	for (i = 0; i < param->levels; i++) {
		ret = aml_mkl_program_key(dev->base_addr, dev->reg.ek_offset + i * 16,
					  param->eks[param->levels - 1 - i]);
		if (ret != 0) {
			KL_LOGE("Error: Ek data has bad parameter\n");
			ret = KL_STATUS_ERROR_BAD_PARAM;
			goto unlock_mkl;
		}
	}

	/* 3. Program KL_REE_CMD */
	reg_val = 0;
	reg_offset = dev->reg.cmd_offset;
	if (dev->kl_vid_type != 0) {
		/* This part is applicable when ETSI_SW_VID is set in OTP */
		reg_val = (param->module_id << KL_MID_OFFSET |
			param->vid << KL_VID_OFFSET |
			tee_priv << KL_TEE_PRIV_OFFSET);
	} else {
		/* aka MKL_REE_MID for SC2 or before */
		reg_val = (param->module_id << KL_MID_OFFSET |
			KL_ETSI_MID_MSG << KL_MID_EXTRA_OFFSET |
			tee_priv << KL_TEE_PRIV_OFFSET);
	}
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 4. Program KL_REE_CFG with KL_pending to 1 */
	reg_val = 0;
	reg_offset = dev->reg.cfg_offset;
	reg_val = (1 << KL_PENDING_OFFSET | param->kl_algo << KL_ALGO_OFFSET |
		   param->kl_mode << KL_MODE_OFFSET |
		   param->usage.crypto << KL_FLAG_OFFSET |
		   param->usage.algo << KL_KEYALGO_OFFSET |
		   param->usage.uid << KL_USERID_OFFSET |
		   param->kt_handle << KL_KTE_OFFSET |
		   param->mrk_cfg_index << KL_MRK_OFFSET | param->func_id);
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 5. Poll KL_REE_CFG till KL_pending is 0 */
	ret = aml_mkl_read_pending(dev);
	if (ret == KL_STATUS_OK)
		KL_LOGI("ETSI Key Ladder run success\n");

unlock_mkl:
	aml_mkl_unlock(dev);
unlock_mutex:
	mutex_unlock(&dev->lock);

	return ret;
}

static int aml_mkl_etsi_old_run(struct file *filp, struct amlkl_params *param)
{
	int ret = KL_STATUS_OK;
	int i;
	u32 reg_val = 0;
	u32 reg_offset = 0;
	u32 key_addrs[7] = {0};
	u8 zero[16] = {0};
	struct aml_mkl_dev *dev = filp->private_data;

	if (!param) {
		KL_LOGE("Error: param data has Null\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	KL_LOGD("kte:%d, levels:%d, kl_num:%d\n", param->kt_handle, param->levels, param->kl_num);

	if (param->levels < AML_KL_LEVEL_3 ||
		param->levels > AML_KL_LEVEL_6 ||
	    param->kl_num > 10) {
		KL_LOGE("Error: param data has bad parameter\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	key_addrs[0] = dev->old_reg.key1_offset;
	key_addrs[1] = dev->old_reg.key2_offset;
	key_addrs[2] = dev->old_reg.key3_offset;
	key_addrs[3] = dev->old_reg.key4_offset;
	key_addrs[4] = dev->old_reg.key5_offset;
	key_addrs[5] = dev->old_reg.key6_offset;
	key_addrs[6] = dev->old_reg.key7_offset;

	/* 1. Program Eks */
	ret = aml_mkl_program_key(dev->base_addr, dev->old_reg.nonce_offset, zero);
	for (i = 0; i < param->levels; i++) {
		ret = aml_mkl_program_key(dev->base_addr, key_addrs[i],
					param->eks[param->levels - 1 - i]);
	}
	for (i = param->levels; i < 7; i++)
		ret = aml_mkl_program_key(dev->base_addr, key_addrs[i], zero);
	if (ret != 0) {
		KL_LOGE("Error: Ek data has bad parameter\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	/* 2. Program KL_REE_CFG */
	reg_val = 0;
	reg_offset = dev->old_reg.start0_offset;
	reg_val = (param->kl_num << 24 | 0 << 22 |
		   param->kt_handle << 16 | param->vid);
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 3. Wait Busy Done */
	mutex_lock(&dev->lock);
	if (aml_mkl_lock(dev) != KL_STATUS_OK) {
		KL_LOGE("key ladder is busy\n");
		ret = KL_STATUS_ERROR_BAD_STATE;
		goto unlock_mutex;
	}

	aml_mkl_unlock(dev);
	KL_LOGI("ETSI Key Ladder run success\n");

unlock_mutex:
	mutex_unlock(&dev->lock);

	return ret;
}

static int aml_mkl_run(struct file *filp, struct amlkl_params *param)
{
	int ret = KL_STATUS_OK;
	int i;
	int tee_priv = 0;
	u32 reg_val = 0;
	u32 reg_offset = 0;
	struct amlkl_usage *pu;
	struct aml_mkl_dev *dev = filp->private_data;

	if (!param) {
		KL_LOGE("Error: param data has Null\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	pu = &param->usage;
	KL_LOGD("kte:%d, levels:%d, kl_algo:%d, func_id:%d, mrk:%d\n",
		param->kt_handle, param->levels, param->kl_algo, param->func_id,
		param->mrk_cfg_index);
	KL_LOGD("kt usage, crypto:%d, algo:%d, uid:%d\n", pu->crypto, pu->algo,
		pu->uid);

	if (pu->uid & ~KL_USERID_MASK ||
	    (pu->uid > AML_KT_USER_M2M_5 && pu->uid < AML_KT_USER_TSD) ||
	    (pu->uid > AML_KT_USER_TSE && pu->uid < KL_USERID_MASK) ||
	    pu->algo & ~KL_KEYALGO_MASK ||
	    (pu->algo > AML_KT_ALGO_DES && pu->algo < AML_KT_ALGO_NDL) ||
	    (pu->algo > AML_KT_ALGO_CSA2 && pu->algo < AML_KT_ALGO_HMAC) ||
	    (pu->algo > AML_KT_ALGO_HMAC && pu->algo < KL_KEYALGO_MASK) ||
	    pu->crypto & ~KL_FLAG_MASK || param->kl_algo > AML_KL_ALGO_AES) {
		KL_LOGE("Error: param data has bad parameter\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	/* 1. Read KL_REE_RDY to lock KL */
	mutex_lock(&dev->lock);
	if (aml_mkl_lock(dev) != KL_STATUS_OK) {
		KL_LOGE("key ladder not ready\n");
		ret = KL_STATUS_ERROR_BAD_STATE;
		goto unlock_mutex;
	}

	/* 2. Program Eks, fixed level to 3 */
	param->levels = AML_KL_LEVEL_3;
	for (i = 0; i < param->levels; i++) {
		ret = aml_mkl_program_key(dev->base_addr, dev->reg.ek_offset + i * 16,
					  param->eks[param->levels - 1 - i]);
		if (ret != 0) {
			KL_LOGE("Error: Ek data has bad parameter\n");
			ret = KL_STATUS_ERROR_BAD_PARAM;
			goto unlock_mkl;
		}
	}

	/* 3. Program KL_REE_CMD */
	reg_val = 0;
	reg_offset = dev->reg.cmd_offset;
	reg_val = (tee_priv << KL_TEE_PRIV_OFFSET | 0 << KL_LEVEL_OFFSET |
		   0 << KL_STAGE_OFFSET | 0 << KL_TEE_SEP_OFFSET);
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 4. Program KL_REE_CFG with KL_pending to 1 */
	reg_val = 0;
	reg_offset = dev->reg.cfg_offset;
	reg_val = (1 << KL_PENDING_OFFSET | param->kl_algo << KL_ALGO_OFFSET |
		   param->kl_mode << KL_MODE_OFFSET |
		   param->usage.crypto << KL_FLAG_OFFSET |
		   param->usage.algo << KL_KEYALGO_OFFSET |
		   param->usage.uid << KL_USERID_OFFSET |
		   param->kt_handle << KL_KTE_OFFSET |
		   param->mrk_cfg_index << KL_MRK_OFFSET |
		   (param->func_id << KL_FUNC_ID_OFFSET));
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 5. Poll KL_REE_CFG till KL_pending is 0 */
	ret = aml_mkl_read_pending(dev);
	if (ret == KL_STATUS_OK)
		KL_LOGI("AML Key Ladder run success\n");

unlock_mkl:
	aml_mkl_unlock(dev);
unlock_mutex:
	mutex_unlock(&dev->lock);

	return ret;
}

static int aml_mkl_msr_run(struct file *filp, struct amlkl_params *param)
{
	int ret = KL_STATUS_OK;
	int i;
	int tee_priv = 0;
	u32 reg_val = 0;
	u32 reg_offset = 0;
	struct amlkl_usage *pu;
	struct aml_mkl_dev *dev = filp->private_data;

	if (!param) {
		KL_LOGE("Error: param data has Null\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	pu = &param->usage;
	KL_LOGD("kte:%d, kl_algo:%d, func_id:%d\n",
		param->kt_handle, param->kl_algo, param->func_id);
	KL_LOGD("kt usage, crypto:%d, algo:%d, uid:%d\n", pu->crypto, pu->algo,
		pu->uid);

	if (pu->uid & ~KL_USERID_MASK ||
	    (pu->uid > AML_KT_USER_M2M_5 && pu->uid < AML_KT_USER_TSD) ||
	    (pu->uid > AML_KT_USER_TSE && pu->uid < KL_USERID_MASK) ||
	    pu->algo & ~KL_KEYALGO_MASK ||
	    (pu->algo > AML_KT_ALGO_DES && pu->algo < AML_KT_ALGO_NDL) ||
	    (pu->algo > AML_KT_ALGO_CSA2 && pu->algo < AML_KT_ALGO_HMAC) ||
	    (pu->algo > AML_KT_ALGO_HMAC && pu->algo < KL_KEYALGO_MASK) ||
	    pu->crypto & ~KL_FLAG_MASK ||
	    param->kl_algo > AML_KL_ALGO_AES) {
		KL_LOGE("Error: param data has bad parameter\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	if (param->func_id == MSR_KL_FUNC_ID_CWUK ||
			param->func_id == MSR_KL_FUNC_ID_SSUK ||
			param->func_id == MSR_KL_FUNC_ID_CAUK) {
		param->levels = MSR_KL_LEVEL_2;
	} else if (param->func_id == MSR_KL_FUNC_ID_CPUK ||
			param->func_id == MSR_KL_FUNC_ID_CCCK) {
		param->levels = MSR_KL_LEVEL_3;
	} else if (param->func_id == MSR_KL_FUNC_ID_TAUK) {
		param->levels = MSR_KL_LEVEL_1;
	} else {
		KL_LOGE("Error: func_id data has bad parameter\n");
		return KL_STATUS_ERROR_BAD_PARAM;
	}

	/* 1. Read KL_REE_RDY to lock KL */
	mutex_lock(&dev->lock);
	if (aml_mkl_lock(dev) != KL_STATUS_OK) {
		KL_LOGE("key ladder not ready\n");
		ret = KL_STATUS_ERROR_BAD_STATE;
		goto unlock_mutex;
	}

	/* 2. Program Eks */
	for (i = 0; i < param->levels; i++) {
		ret = aml_mkl_program_key(dev->base_addr, dev->reg.ek_offset + i * 16,
					  param->eks[param->levels - 1 - i]);
		if (ret != 0) {
			KL_LOGE("Error: Ek data has bad parameter\n");
			ret = KL_STATUS_ERROR_BAD_PARAM;
			goto unlock_mkl;
		}
	}

	/* 3. Program KL_REE_CMD */
	reg_val = 0;
	reg_offset = dev->reg.cmd_offset;
	reg_val = (param->func_id << KL_MSR_FUNCID_OFFSET |
			param->kl_algo << KL_MSR_KEYALGO_OFFSET |
			param->levels << KL_MSR_PAYLOAD_OFFSET);
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 4. Program KL_REE_CFG with KL_pending to 1 */
	reg_val = 0;
	reg_offset = dev->reg.cfg_offset;
	reg_val = (1 << KL_PENDING_OFFSET |
		   param->kl_mode << KL_MODE_OFFSET |
		   param->usage.crypto << KL_FLAG_OFFSET |
		   param->usage.algo << KL_KEYALGO_OFFSET |
		   param->usage.uid << KL_USERID_OFFSET |
		   param->kt_handle << KL_KTE_OFFSET |
		   (tee_priv << KL_TEE_PRIV_OFFSET) |
		   0 << KL_MSR_BUFLEVEL_OFFSET);
	iowrite32(reg_val, (char *)dev->base_addr + reg_offset);

	/* 5. Poll KL_REE_CFG till KL_pending is 0 */
	ret = aml_mkl_read_pending(dev);
	if (ret == KL_STATUS_OK)
		KL_LOGI("AML MSR Key Ladder run success\n");

unlock_mkl:
	aml_mkl_unlock(dev);
unlock_mutex:
	mutex_unlock(&dev->lock);

	return ret;
}

static long aml_mkl_ioctl(struct file *filp, unsigned int cmd,
			  unsigned long arg)
{
	int ret = -ENOTTY;
	struct amlkl_params kl_param;
	struct aml_mkl_dev *dev = filp->private_data;

	if (!dev->base_addr) {
		KL_LOGE("ERROR: MKL iobase is zero\n");
		return -EFAULT;
	}

	switch (cmd) {
	case AML_MKL_IOCTL_RUN:
		memset(&kl_param, 0, sizeof(kl_param));
		if (copy_from_user(&kl_param, (uint32_t *)arg,
				   sizeof(kl_param))) {
			return -EFAULT;
		}

		if (kl_param.kl_mode == AML_KL_MODE_ETSI) {
			if (dev->kl_type == KL_TYPE_OLD)
				ret = aml_mkl_etsi_old_run(filp, &kl_param);
			else
				ret = aml_mkl_etsi_run(filp, &kl_param);
			if (ret != 0) {
				KL_LOGE("MKL: aml_mkl_etsi_run failed retval=0x%08x\n",
					ret);
				return -EFAULT;
			}
		} else if (kl_param.kl_mode == AML_KL_MODE_AML) {
			if (dev->kl_type == KL_TYPE_OLD) {
				KL_LOGE("MKL: aml_mkl_run failed. not support.\n");
				return -EFAULT;
			}

			ret = aml_mkl_run(filp, &kl_param);
			if (ret != 0) {
				KL_LOGE("MKL: aml_mkl_run failed retval=0x%08x\n",
				       ret);
				return -EFAULT;
			}
		} else if (kl_param.kl_mode == AML_KL_MODE_MSR) {
			if (dev->kl_type == KL_TYPE_OLD) {
				KL_LOGE("MKL: aml_mkl_msr_run failed. not support.\n");
				return -EFAULT;
			}

			ret = aml_mkl_msr_run(filp, &kl_param);
			if (ret != 0) {
				KL_LOGE("MKL: aml_mkl_msr_run failed retval=0x%08x\n",
				       ret);
				return -EFAULT;
			}
		}
		break;
	default:
		KL_LOGE("No appropriate IOCTL found\n");
	}

	return ret;
}

static const struct file_operations aml_mkl_fops = {
	.owner = THIS_MODULE,
	.open = aml_mkl_open,
	.release = aml_mkl_release,
	.unlocked_ioctl = aml_mkl_ioctl,
	.compat_ioctl = aml_mkl_ioctl,
};

static int aml_mkl_get_dts_info(struct aml_mkl_dev *dev, struct platform_device *pdev)
{
	int ret = 0;
	u32 old_offset[2];
	u32 offset[4];

	if (unlikely(!dev)) {
		KL_LOGE("Empty aml_mkl_dev\n");
		return -1;
	}

	ret = of_property_read_u32(pdev->dev.of_node, "kl_type", &dev->kl_type);
	if (ret) {
		KL_LOGE("%s: not found 0x%x\n", "kl_type", dev->kl_type);
		return -1;
	}

	ret = of_property_read_u32(pdev->dev.of_node, "kl_vid_type", &dev->kl_vid_type);
	if (ret) {
		KL_LOGE("%s: not found 0x%x\n", "kl_vid_type", dev->kl_vid_type);
		return -1;
	}

	/* kl register offset */
	if (dev->kl_type == KL_TYPE_OLD) {
		if (of_property_read_u32_array(pdev->dev.of_node, "kl_offset", old_offset,
			ARRAY_SIZE(old_offset)) == 0) {
			dev->old_reg.start0_offset = old_offset[0];
			dev->old_reg.key1_offset = old_offset[1];
			dev->old_reg.nonce_offset = dev->old_reg.key1_offset + 16;
			dev->old_reg.key2_offset = dev->old_reg.nonce_offset + 16;
			dev->old_reg.key3_offset = dev->old_reg.key2_offset + 16;
			dev->old_reg.key4_offset = dev->old_reg.key3_offset + 16;
			dev->old_reg.key5_offset = dev->old_reg.key4_offset + 16;
			dev->old_reg.key6_offset = dev->old_reg.key5_offset + 16;
			dev->old_reg.key7_offset = dev->old_reg.key6_offset + 16;
		} else {
			KL_LOGE("%s not found\n", "kl_offset");
			return -1;
		}
	} else {
		if (of_property_read_u32_array(pdev->dev.of_node, "kl_offset", offset,
			ARRAY_SIZE(offset)) == 0) {
			dev->reg.rdy_offset = offset[0];
			dev->reg.cfg_offset = offset[1];
			dev->reg.cmd_offset = offset[2];
			dev->reg.ek_offset = offset[3];
		} else {
			KL_LOGE("%s: not found\n", "kl_offset");
			return -1;
		}
	}

	return ret;
}

int aml_mkl_init(struct class *aml_mkl_class, struct platform_device *pdev)
{
	int ret = -1;
	struct device *device;
	struct resource *res;

	if (alloc_chrdev_region(&aml_mkl_devt, 0, DEVICE_INSTANCES,
				AML_MKL_DEVICE_NAME) < 0) {
		KL_LOGE("%s device can't be allocated.\n", AML_MKL_DEVICE_NAME);
		return -ENXIO;
	}

	cdev_init(&aml_mkl_dev.cdev, &aml_mkl_fops);
	aml_mkl_dev.cdev.owner = THIS_MODULE;
	ret = cdev_add(&aml_mkl_dev.cdev,
		       MKDEV(MAJOR(aml_mkl_devt), MINOR(aml_mkl_devt)), 1);
	aml_mkl_dev.base_addr = NULL;
	if (unlikely(ret < 0))
		goto unregister_chrdev;

	device = device_create(aml_mkl_class, NULL, aml_mkl_devt, NULL,
			       AML_MKL_DEVICE_NAME);
	if (IS_ERR(device)) {
		KL_LOGE("device_create failed\n");
		ret = PTR_ERR(device);
		goto delete_cdev;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		KL_LOGE("%s: platform_get_resource is failed\n", __func__);
		ret = -ENOMEM;
		goto destroy_device;
	}

	aml_mkl_dev.base_addr = devm_ioremap_resource(&pdev->dev, res);
	if (!aml_mkl_dev.base_addr) {
		KL_LOGE("%s base addr error\n", __func__);
		ret = -ENOMEM;
		goto destroy_device;
	}

	ret = aml_mkl_get_dts_info(&aml_mkl_dev, pdev);
	if (ret != 0) {
		KL_LOGE("%s: cannot find match dts info\n", __func__);
		ret = -EINVAL;
		goto destroy_device;
	}

	mutex_init(&aml_mkl_dev.lock);
	return ret;

destroy_device:
	device_destroy(aml_mkl_class, aml_mkl_devt);
delete_cdev:
	cdev_del(&aml_mkl_dev.cdev);
unregister_chrdev:
	unregister_chrdev_region(aml_mkl_devt, DEVICE_INSTANCES);

	return ret;
}

void aml_mkl_exit(struct class *aml_mkl_class, struct platform_device *pdev)
{
	device_destroy(aml_mkl_class, aml_mkl_devt);
	cdev_del(&aml_mkl_dev.cdev);
	unregister_chrdev_region(MKDEV(MAJOR(aml_mkl_devt),
				       MINOR(aml_mkl_devt)),
				 DEVICE_INSTANCES);
	mutex_destroy(&aml_mkl_dev.lock);
}

static int aml_mkl_probe(struct platform_device *pdev)
{
	int ret = 0;

	aml_mkl_class = class_create(THIS_MODULE, AML_MKL_DEVICE_NAME);
	if (IS_ERR(aml_mkl_class)) {
		KL_LOGE("class_create failed\n");
		ret = PTR_ERR(aml_mkl_class);
		return ret;
	}

	ret = aml_mkl_init(aml_mkl_class, pdev);
	if (unlikely(ret < 0)) {
		KL_LOGE("aml_mkl_core_init failed\n");
		goto device_create_error;
	}

	ret = aml_mkl_init_dbgfs();
	if (ret) {
		KL_LOGE("aml_mkl_init_dbgfs failed\n");
		goto device_create_error;
	}

	return 0;

device_create_error:
	class_destroy(aml_mkl_class);
	return ret;
}

static int aml_mkl_remove(struct platform_device *pdev)
{
	aml_mkl_exit(aml_mkl_class, pdev);
	class_destroy(aml_mkl_class);
	debugfs_remove_recursive(aml_mkl_debug_dent);
	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id aml_mkl_dt_match[] = {
	{
		.compatible = "amlogic,aml_mkl",
	},
	{}
};
MODULE_DEVICE_TABLE(of, aml_mkl_dt_match);
#else
#define aml_mkl_dt_match NULL
#endif

static struct platform_driver aml_mkl_drv = {
	.probe = aml_mkl_probe,
	.remove = aml_mkl_remove,
	.driver = {
		.name = AML_MKL_DEVICE_NAME,
		.of_match_table = aml_mkl_dt_match,
		.owner = THIS_MODULE,
	},
};

int __init aml_seckey_kl_init(void)
{
	int err = 0;

	err = platform_driver_register(&aml_mkl_drv);
	if (err) {
		pr_err("%s: failed to register driver, err %d.\n",
				__func__, err);
		return err;
	}

	return 0;
}

void __exit aml_seckey_kl_exit(void)
{
	platform_driver_unregister(&aml_mkl_drv);
}
