/*
 * ambarella_crypto.c
 *
 * History:
 *	2009/09/07 - [Qiao Wang]
 *
 * Copyright (C) 2004-2009, Ambarella, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#include <crypto/algapi.h>
#include <crypto/aes.h>
#include <crypto/des.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/platform_device.h>

#include <mach/hardware.h>
#include <plat/crypto.h>

#include <linux/cryptohash.h>
#include <crypto/internal/hash.h>
#include <crypto/sha.h>
#include <crypto/md5.h>


static DECLARE_COMPLETION(g_aes_irq_wait);
static DECLARE_COMPLETION(g_des_irq_wait);
static DECLARE_COMPLETION(g_md5_sha1_irq_wait);

static int config_polling_mode = 0;
module_param(config_polling_mode, int, S_IRUGO);

static const char *ambdev_name =
	"Ambarella Media Processor Cryptography Engine";

struct des_ctx {
	u32 expkey[DES_EXPKEY_WORDS];
};


static md5_digest_t g_md5_digest __attribute__((__aligned__(4)));
static md5_data_t g_md5_data __attribute__((__aligned__(4)));
static sha1_digest_t g_sha1_digest __attribute__((__aligned__(4)));
static sha1_data_t g_sha1_data __attribute__((__aligned__(4)));

static void __ambarella_crypto_aligned_common64(u32 * src, u32 * dst) {
	__asm__ __volatile__ (
	"mov r2, %0 \n\t"
	"ldmia r2, {r3-r4} \n\t"
	"mov r2, %1 \n\t"
	"stmia r2, {r3-r4} \n\t"
	:
	: "r"(src) , "r"(dst)
	: "r2", "r3", "r4", "memory" );
}


static int _ambarella_crypto_aligned_read64(u32 * buf,u32 * addr, unsigned int len) {
	int errCode = -1;
	int i;
	if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
		/* address and length should be 64 bit aligned */
		for (i = 0; i < len/8; i++) {
			__ambarella_crypto_aligned_common64((u32 *)(addr + 2*i),  (u32 *)(buf + 2*i));
		}
		errCode = 0;
	};
	return errCode;

}


static int _ambarella_crypto_aligned_write64(u32 * addr,u32 * buf, unsigned int len ) {
	int errCode = -1;
	int i;
	if ( ( 0 == (((u32) addr) & 0x07) ) && (0 == (len%8))) {
		/* address and length should be 64 bit aligned */
		for (i = 0; i < len/8; i++) {
			__ambarella_crypto_aligned_common64((u32 *)(buf + 2*i), (u32 *)(addr + 2*i));
		}
		errCode = 0;
	};
	return errCode;

}




struct ambarella_platform_crypto_info *platform_info;

//merge temp buffer
#define MAX_MERGE_SIZE 8
__attribute__ ((aligned (4))) u32 merg[MAX_MERGE_SIZE]={};

struct ambarella_crypto_dev_info {
	unsigned char __iomem 		*regbase;

	struct platform_device		*pdev;
	struct resource				*mem;
	unsigned int				aes_irq;
	unsigned int				des_irq;

	unsigned int				md5_sha1_irq;

	struct ambarella_platform_crypto_info *platform_info;
};
struct aes_fun_t{
	void (*opcode)(u32);
	void (*wdata)(u32*,u32*,int);
	void (*rdata)(u32*,u32*,int);
	u32*  (*reg_enc)(void);
	u32* (*reg_dec)(void);
}aes_fun;
u32* aes_reg_enc_dec_32(void)
{
	 return((u32*)CRYPT_A_INPUT1);
}
u32* aes_reg_enc_64(void)
{
	return( (u32*)CRYPT_A_INPUT1);
}

u32* aes_reg_dec_64(void)
{
	// When run the a5s or other with 32-bit register,this defined is NULL ,
	//so make sure correct in ambarella_crypto_probe
	return( (u32*)CRYPT_A_INPUT2);
}

void swap_write(u32 *offset,u32 *src,int size)
{
	int point=0;
	int len=size;

	for(size=(size>>2)-1;size >= 0;size--,point++){
		*(merg+point) = ntohl(*(src+size));
	}
	//the iONE registers need to accessed by 64-bit boundaries
	_ambarella_crypto_aligned_write64(offset,merg,len);

}

void swap_read(u32 *offset,u32 *src,int size)
{
	int point=0,len=size;

	//the iONE registers need to accessed by 64-bit boundaries
	_ambarella_crypto_aligned_read64(merg,src,len);
	for(size=(size>>2)-1;size >= 0;size--,point++){
		*(offset+point) = ntohl(*(merg+size));
	}
}

void aes_opcode(u32 flag)
{
	// When run the a7 or higher version with 64-bit  register,this defined is NULL,
	//so make sure correct in ambarella_crypto_probe
	amba_writel(CRYPT_A_OPCODE, flag);
}

void null_fun(u32 flag) {};

static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct crypto_aes_ctx *ctx=crypto_tfm_ctx(tfm);
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
	u32 ready;
	u32 *offset=NULL;
	switch (ctx->key_length){
	case 16:
		offset = (u32*)CRYPT_A_128_96_REG;
		aes_fun.wdata(offset,ctx->key_enc,16);
		break;
	case 24:
		offset = (u32*)CRYPT_A_192_160_REG;
		aes_fun.wdata(offset,ctx->key_enc,24);
		break;
	case 32:
		offset = (u32*)CRYPT_A_256_224_REG;
		aes_fun.wdata(offset,ctx->key_enc,32);
		break;
	}
	//enc or dec option mode
	aes_fun.opcode(AMBA_HW_ENCRYPT_CMD);

	//get the input offset
	offset = aes_fun.reg_enc();

	//input the src
	aes_fun.wdata(offset,(u32*)src,16);

	if(likely(config_polling_mode == 0)) {
		wait_for_completion_interruptible(&g_aes_irq_wait);
	}else{
		do{
			ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
		}while(ready != 1);
	}

	//get the output
	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
	aes_fun.rdata(dst,offset,16);
}


static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct crypto_aes_ctx *ctx = crypto_tfm_ctx(tfm);
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
	u32 ready;
	u32 *offset=NULL;
	switch (ctx->key_length) {
	case 16:
		offset = (u32*)CRYPT_A_128_96_REG;
		aes_fun.wdata(offset,ctx->key_enc,16);
	        break;
	case 24:
		offset = (u32*)CRYPT_A_192_160_REG;
		aes_fun.wdata(offset,ctx->key_enc,24);
	        break;
	case 32:
		offset = (u32*)CRYPT_A_256_224_REG;
		aes_fun.wdata(offset,ctx->key_enc,32);
	        break;
	}
	//enc or dec option mode
	aes_fun.opcode(AMBA_HW_DECRYPT_CMD);

	//get the input offset
	offset = aes_fun.reg_dec();

	//input the src
	aes_fun.wdata(offset,(u32*)src,16);

	if(likely(config_polling_mode == 0)) {
		wait_for_completion_interruptible(&g_aes_irq_wait);
	}else{
		do{
			ready = amba_readl(CRYPT_A_OUTPUT_READY_REG);
		}while(ready != 1);
	}

	//get the output
	offset = (u32*)CRYPT_A_OUTPUT_96_REG;
	aes_fun.rdata(dst,offset,16);
}

static struct crypto_alg aes_alg = {
	.cra_name		=	"aes",
	.cra_driver_name	=	"aes-ambarella",
	.cra_priority		=	AMBARELLA_CRA_PRIORITY,
	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
	.cra_blocksize		=	AES_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
	.cra_module		=	THIS_MODULE,
	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
	.cra_u			=	{
		.cipher = {
			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
			.cia_setkey	   		= 	crypto_aes_set_key,
			.cia_encrypt	 	=	aes_encrypt,
			.cia_decrypt	  	=	aes_decrypt,
		}
	}
};

struct des_fun_t{
	void (*opcode)(u32);
	void (*wdata)(u32*,u32*,int);
	void (*rdata)(u32*,u32*,int);
	u32* (*reg_enc)(void);
	u32* (*reg_dec)(void);
}des_fun;

u32* des_reg_enc_dec_32(void)
{
	return((u32*)CRYPT_D_INPUT1);
}

u32* des_reg_enc_64(void)
{
	return((u32*)CRYPT_D_INPUT1);
}

u32* des_reg_dec_64(void)
{
	// When run the a5s or other with 32-bit register,this defined is NULL ,
	//so make sure correct in ambarella_crypto_probe
	return((u32*)CRYPT_D_INPUT2);
}

void des_opcode(u32 flag)
{
	// When run the a7 or higher version with 64-bit  register,this defined is NULL,
	//so make sure correct in ambarella_crypto_probe
	amba_writel(CRYPT_D_OPCODE, flag);
}

static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
		      unsigned int keylen)
{
	struct des_ctx *dctx = crypto_tfm_ctx(tfm);
	u32 *flags = &tfm->crt_flags;
	u32 tmp[DES_EXPKEY_WORDS];
	int ret;


	/* Expand to tmp */
	ret = des_ekey(tmp, key);

	if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
		return -EINVAL;
	}

	/* Copy to output */
	memcpy(dctx->expkey, key, keylen);

	return 0;
}

static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
	u32 ready;
	u32 *offset=NULL;
	//set key
	des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);

	//enc or dec option mode
	des_fun.opcode(AMBA_HW_ENCRYPT_CMD);

	//get the input offset
	offset = des_fun.reg_enc();

	//input the src
	aes_fun.wdata(offset,(u32*)src,8);

	if(likely(config_polling_mode == 0)) {
		wait_for_completion_interruptible(&g_des_irq_wait);
	}else{
		do{
			ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
		}while(ready != 1);
	}

	//get the output
	offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
	aes_fun.rdata(dst,offset,8);
}

static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
	struct des_ctx *ctx = crypto_tfm_ctx(tfm);
	const __le32 *src = (const __le32 *)in;
	__le32 *dst = (__le32 *)out;
	u32 ready;
	u32 *offset=NULL;

	//set key
	des_fun.wdata((u32*)CRYPT_D_HI_REG,ctx->expkey,8);

	//enc or dec option mode
	des_fun.opcode(AMBA_HW_DECRYPT_CMD);

	//get the input offset
	offset = des_fun.reg_dec();

	//input the src
	aes_fun.wdata(offset,(u32*)src,8);

	if(likely(config_polling_mode == 0)) {
		wait_for_completion_interruptible(&g_des_irq_wait);
	}else{
		do{
			ready = amba_readl(CRYPT_D_OUTPUT_READY_REG);
		}while(ready != 1);
	}

	//get the output
	offset = (u32*)CRYPT_D_OUTPUT_HI_REG;
	aes_fun.rdata(dst,offset,8);

}


static struct crypto_alg des_alg = {
	.cra_name		=	"des",
	.cra_driver_name	=	"des-ambarella",
	.cra_priority		=	AMBARELLA_CRA_PRIORITY,
	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
	.cra_blocksize		=	DES_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct des_ctx),
	.cra_module		=	THIS_MODULE,
	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
	.cra_u			=	{
		.cipher = {
			.cia_min_keysize	=	DES_KEY_SIZE,
			.cia_max_keysize	=	DES_KEY_SIZE,
			.cia_setkey		=	des_setkey,
			.cia_encrypt		=	des_encrypt,
			.cia_decrypt		=	des_decrypt
		}
	}
};

static int ecb_aes_encrypt(struct blkcipher_desc *desc,
			   struct scatterlist *dst, struct scatterlist *src,
			   unsigned int nbytes)
{
	return 0;
}

static int ecb_aes_decrypt(struct blkcipher_desc *desc,
			   struct scatterlist *dst, struct scatterlist *src,
			   unsigned int nbytes)
{
	int err = 0;
	return err;
}

static struct crypto_alg ecb_aes_alg = {
	.cra_name		=	"ecb(aes)",
	.cra_driver_name	=	"ecb-aes-ambarella",
	.cra_priority		=	AMBARELLA_COMPOSITE_PRIORITY,
	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
	.cra_blocksize		=	AES_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
	.cra_type		=	&crypto_blkcipher_type,
	.cra_module		=	THIS_MODULE,
	.cra_list		=	LIST_HEAD_INIT(ecb_aes_alg.cra_list),
	.cra_u			=	{
		.blkcipher = {
			.min_keysize		=	AES_MIN_KEY_SIZE,
			.max_keysize		=	AES_MAX_KEY_SIZE,
			.setkey	   		= 	crypto_aes_set_key,
			.encrypt		=	ecb_aes_encrypt,
			.decrypt		=	ecb_aes_decrypt,
		}
	}
};

static int cbc_aes_encrypt(struct blkcipher_desc *desc,
			   struct scatterlist *dst, struct scatterlist *src,
			   unsigned int nbytes)
{
	int err = 0;

	return err;
}

static int cbc_aes_decrypt(struct blkcipher_desc *desc,
			   struct scatterlist *dst, struct scatterlist *src,
			   unsigned int nbytes)
{
	int err = 0;

	return err;
}

static struct crypto_alg cbc_aes_alg = {
	.cra_name		=	"cbc(aes)",
	.cra_driver_name	=	"cbc-aes-ambarella",
	.cra_priority		=	AMBARELLA_COMPOSITE_PRIORITY,
	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
	.cra_blocksize		=	AES_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
	.cra_alignmask		=	AMBARELLA_CRYPTO_ALIGNMENT - 1,
	.cra_type		=	&crypto_blkcipher_type,
	.cra_module		=	THIS_MODULE,
	.cra_list		=	LIST_HEAD_INIT(cbc_aes_alg.cra_list),
	.cra_u			=	{
		.blkcipher = {
			.min_keysize		=	AES_MIN_KEY_SIZE,
			.max_keysize		=	AES_MAX_KEY_SIZE,
			.ivsize			=	AES_BLOCK_SIZE,
			.setkey	   		= 	crypto_aes_set_key,
			.encrypt		=	cbc_aes_encrypt,
			.decrypt		=	cbc_aes_decrypt,
		}
	}
};
/************************************MD5 START**************************/

struct md5_sha1_fun_t{
	void (*wdata)(u32*,u32*,int);
	void (*rdata)(u32*,u32*,int);
}md5_sha1_fun;

static void ambarella_md5_transform(u32 *hash, u32 const *in)
{
	u32 ready;

	memcpy(&g_md5_digest.digest_0, hash, 16);

	do{
		ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
	}while(ready != 1);

	md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INIT_31_0,&(g_md5_digest.digest_0),16);

	do{
		ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
	}while(ready != 1);

	memcpy(&g_md5_data.data[0], in, 64);

	md5_sha1_fun.wdata((u32 *)CRYPT_MD5_INPUT_31_0,&(g_md5_data.data[0]),64);

	if(likely(config_polling_mode == 0)) {
		do {
			ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
		} while (!ready);
	}else{
		do{
			ready = amba_readl(CRYPT_MD5_OUTPUT_READY);
		}while(ready != 1);
	}

	md5_sha1_fun.rdata(&(g_md5_digest.digest_0),(u32 *)CRYPT_MD5_OUTPUT_31_0, 16);

	memcpy(hash, &g_md5_digest.digest_0, 16);
}

static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
{
	while (words--) {
		__le32_to_cpus(buf);
		buf++;
	}
}

static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
{
	while (words--) {
		__cpu_to_le32s(buf);
		buf++;
	}
}

static inline void ambarella_md5_transform_helper(struct md5_state *ctx)
{
	le32_to_cpu_array(ctx->block, sizeof(ctx->block)/sizeof(u32));
	ambarella_md5_transform(ctx->hash, ctx->block);
}

static int ambarella_md5_init(struct shash_desc *desc)
{
	struct md5_state *mctx = shash_desc_ctx(desc);

	mctx->hash[0] = 0x67452301;
	mctx->hash[1] = 0xefcdab89;
	mctx->hash[2] = 0x98badcfe;
	mctx->hash[3] = 0x10325476;
	mctx->byte_count = 0;

	return 0;
}

static int ambarella_md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
{
	struct md5_state *mctx = shash_desc_ctx(desc);
	const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);

	mctx->byte_count += len;

	if (avail > len) {
		memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
		       data, len);
		return 0;
	}

	memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
	       data, avail);

	ambarella_md5_transform_helper(mctx);
	data += avail;
	len -= avail;

	while (len >= sizeof(mctx->block)) {
		memcpy(mctx->block, data, sizeof(mctx->block));
		ambarella_md5_transform_helper(mctx);
		data += sizeof(mctx->block);
		len -= sizeof(mctx->block);
	}

	memcpy(mctx->block, data, len);

	return 0;
}

static int ambarella_md5_final(struct shash_desc *desc, u8 *out)
{
	struct md5_state *mctx = shash_desc_ctx(desc);
	const unsigned int offset = mctx->byte_count & 0x3f;
	char *p = (char *)mctx->block + offset;
	int padding = 56 - (offset + 1);

	*p++ = 0x80;
	if (padding < 0) {
		memset(p, 0x00, padding + sizeof (u64));
		ambarella_md5_transform_helper(mctx);
		p = (char *)mctx->block;
		padding = 56;
	}

	memset(p, 0, padding);
	mctx->block[14] = mctx->byte_count << 3;
	mctx->block[15] = mctx->byte_count >> 29;
	le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
	                  sizeof(u64)) / sizeof(u32));
	ambarella_md5_transform(mctx->hash, mctx->block);
	cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
	memcpy(out, mctx->hash, sizeof(mctx->hash));
	memset(mctx, 0, sizeof(*mctx));

	return 0;
}

static int ambarella_md5_export(struct shash_desc *desc, void *out)
{
	struct md5_state *ctx = shash_desc_ctx(desc);

	memcpy(out, ctx, sizeof(*ctx));
	return 0;
}

static int ambarella_md5_import(struct shash_desc *desc, const void *in)
{
	struct md5_state *ctx = shash_desc_ctx(desc);

	memcpy(ctx, in, sizeof(*ctx));
	return 0;
}

static struct shash_alg md5_alg = {
	.digestsize	=	MD5_DIGEST_SIZE,
	.init		=	ambarella_md5_init,
	.update		=	ambarella_md5_update,
	.final		=	ambarella_md5_final,
	.export		=	ambarella_md5_export,
	.import		=	ambarella_md5_import,
	.descsize	=	sizeof(struct md5_state),
	.statesize	=	sizeof(struct md5_state),
	.base		=	{
		.cra_name	=	"md5",
		.cra_driver_name=	"md5-ambarella",
		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
		.cra_blocksize	=	MD5_HMAC_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
};
/************************************MD5 END**************************/

/************************************SHA1 START**************************/
static inline void be32_to_cpu_array(u32 *buf, unsigned int words)
{
	while (words--) {
		__be32_to_cpus(buf);
		buf++;
	}
}

static inline void cpu_to_be32_array(u32 *buf, unsigned int words)
{
	while (words--) {
		__cpu_to_be32s(buf);
		buf++;
	}
}

static int ambarella_sha1_init(struct shash_desc *desc)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);

	*sctx = (struct sha1_state){
		.state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
	};

	return 0;
}

void md5_sha1_write64(u32 * addr,u32 * buf, unsigned int len )
{
	/* len%8 ,align at 64bit*/
	if ((len&0x7)){
		len += (len&0x7);
	}
	_ambarella_crypto_aligned_write64(addr,buf,len);
}

void md5_sha1_read64(u32 * addr,u32 * buf, unsigned int len )
{
	/* len%8 ,align at 64bit*/
	if ((len&0x7)){
		len += (len&0x7);
	}
	_ambarella_crypto_aligned_read64(addr,buf,len);
}

void ambarella_sha1_transform(__u32 *digest, const char *in, __u32 *W)
{
    u32 ready;
    cpu_to_be32_array(digest, 5);
    memcpy(&g_sha1_digest.digest_0, digest, 16);
    g_sha1_digest.digest_128 = digest[4];

    do{
        ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
    }while(ready != 1);

    md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INIT_31_0,&(g_sha1_digest.digest_0),20);
    do{
        ready= amba_readl(CRYPT_MD5_SHA1_READY_INPUT);
    }while(ready != 1);

    memcpy(&g_sha1_data.data[0], in, 64);

    md5_sha1_fun.wdata((u32 *)CRYPT_SHA1_INPUT_31_0,&(g_sha1_data.data[0]),64);

    if(likely(config_polling_mode == 0)) {
        do {
            ready = try_wait_for_completion(&g_md5_sha1_irq_wait);
        } while (!ready);
    }else{
        do{
            ready = amba_readl(CRYPT_SHA1_OUTPUT_READY);
        }while(ready != 1);
    }


    md5_sha1_fun.rdata(&(g_sha1_digest.digest_0),(u32 *)CRYPT_SHA1_OUTPUT_31_0,20);

    memcpy(digest, &g_sha1_digest.digest_0, 20);
    cpu_to_be32_array(digest, 5);
}



static int ambarella_sha1_update(struct shash_desc *desc, const u8 *data,
			unsigned int len)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);
	unsigned int partial, done;
	const u8 *src;

	partial = sctx->count & 0x3f;
	sctx->count += len;
	done = 0;
	src = data;

	if ((partial + len) > 63) {
		u32 temp[SHA_WORKSPACE_WORDS];

		if (partial) {
			done = -partial;
			memcpy(sctx->buffer + partial, data, done + 64);
			src = sctx->buffer;
		}

		do {
			ambarella_sha1_transform(sctx->state, src, temp);
			done += 64;
			src = data + done;
		} while (done + 63 < len);

		memset(temp, 0, sizeof(temp));
		partial = 0;
	}
	memcpy(sctx->buffer + partial, src, len - done);

	return 0;
}

/* Add padding and return the message digest. */
static int ambarella_sha1_final(struct shash_desc *desc, u8 *out)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);
	__be32 *dst = (__be32 *)out;
	u32 i, index, padlen;
	__be64 bits;
	static const u8 padding[64] = { 0x80, };

	bits = cpu_to_be64(sctx->count << 3);

	/* Pad out to 56 mod 64 */
	index = sctx->count & 0x3f;
	padlen = (index < 56) ? (56 - index) : ((64+56) - index);
	ambarella_sha1_update(desc, padding, padlen);

	/* Append length */
	ambarella_sha1_update(desc, (const u8 *)&bits, sizeof(bits));

	/* Store state in digest */
	for (i = 0; i < 5; i++)
		dst[i] = cpu_to_be32(sctx->state[i]);

	/* Wipe context */
	memset(sctx, 0, sizeof *sctx);

	return 0;
}

static int ambarella_sha1_export(struct shash_desc *desc, void *out)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);

	memcpy(out, sctx, sizeof(*sctx));
	return 0;
}

static int ambarella_sha1_import(struct shash_desc *desc, const void *in)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);

	memcpy(sctx, in, sizeof(*sctx));
	return 0;
}


static struct shash_alg sha1_alg = {
	.digestsize	=	SHA1_DIGEST_SIZE,
	.init		=	ambarella_sha1_init,
	.update		=	ambarella_sha1_update,
	.final		=	ambarella_sha1_final,
	.export		=	ambarella_sha1_export,
	.import		=	ambarella_sha1_import,
	.descsize	=	sizeof(struct sha1_state),
	.statesize	=	sizeof(struct sha1_state),
	.base		=	{
		.cra_name	=	"sha1",
		.cra_driver_name=	"sha1-ambarella",
		.cra_flags	=	CRYPTO_ALG_TYPE_SHASH,
		.cra_blocksize	=	SHA1_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
};

/************************************SHA1 END****************************/

static irqreturn_t ambarella_aes_irq(int irqno, void *dev_id)
{
	complete(&g_aes_irq_wait);

	return IRQ_HANDLED;
}
static irqreturn_t ambarella_des_irq(int irqno, void *dev_id)
{
	complete(&g_des_irq_wait);

	return IRQ_HANDLED;
}

static irqreturn_t ambarella_md5_sha1_irq(int irqno, void *dev_id)
{
	complete(&g_md5_sha1_irq_wait);

	return IRQ_HANDLED;
}

static int __devinit ambarella_crypto_probe(struct platform_device *pdev)
{
	int	errCode;
	int	aes_irq, des_irq;
	struct resource	*mem = 0;
	struct resource	*ioarea;
	struct ambarella_crypto_dev_info *pinfo = 0;
	int	md5_sha1_irq = 0;

	platform_info = (struct ambarella_platform_crypto_info *)pdev->dev.platform_data;
	if (platform_info == NULL) {
		dev_err(&pdev->dev, "%s: Can't get platform_data!\n", __func__);
		errCode = - EPERM;
		goto crypto_errCode_na;
	}

	if(likely(config_polling_mode == 0)) {
		mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "registers");
		if (mem == NULL) {
			dev_err(&pdev->dev, "Get crypto mem resource failed!\n");
			errCode = -ENXIO;
			goto crypto_errCode_na;
		}

		aes_irq = platform_get_irq_byname(pdev,"aes-irq");
		if (aes_irq == -ENXIO) {
			dev_err(&pdev->dev, "Get crypto aes irq resource failed!\n");
			errCode = -ENXIO;
			goto crypto_errCode_na;
		}

		des_irq = platform_get_irq_byname(pdev,"des-irq");
		if (des_irq == -ENXIO) {
			dev_err(&pdev->dev, "Get crypto des irq resource failed!\n");
			errCode = -ENXIO;
			goto crypto_errCode_na;
		}

		if (platform_info->md5_sha1 == 1) {
			md5_sha1_irq = platform_get_irq_byname(pdev,"md5-sha1-irq");
			if (md5_sha1_irq == -ENXIO) {
				dev_err(&pdev->dev, "Get crypto md5/sha1 irq resource failed!\n");
				errCode = -ENXIO;
				goto crypto_errCode_na;
			}
		}

		ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, pdev->name);
		if (ioarea == NULL) {
			dev_err(&pdev->dev, "Request crypto ioarea failed!\n");
			errCode = -EBUSY;
			goto crypto_errCode_na;
		}

		pinfo = kzalloc(sizeof(struct ambarella_crypto_dev_info), GFP_KERNEL);
		if (pinfo == NULL) {
			dev_err(&pdev->dev, "Out of memory!\n");
			errCode = -ENOMEM;
			goto crypto_errCode_ioarea;
		}

		pinfo->regbase = (unsigned char __iomem *)mem->start;
		pinfo->mem = mem;
		pinfo->pdev = pdev;
		pinfo->aes_irq = aes_irq;
		pinfo->des_irq = des_irq;
		if (platform_info->md5_sha1 == 1) {
			pinfo->md5_sha1_irq = md5_sha1_irq;
		}
		pinfo->platform_info = platform_info;

		platform_set_drvdata(pdev, pinfo);

		amba_writel(CRYPT_A_INT_EN_REG, 0x0001);
		amba_writel(CRYPT_D_INT_EN_REG, 0x0001);

		if (platform_info->md5_sha1 == 1) {
			amba_writel(CRYPT_MD5_INT_EN, 0x0001);
			amba_writel(CRYPT_SHA1_INT_EN, 0x0001);
		}

		errCode = request_irq(pinfo->aes_irq, ambarella_aes_irq,
			IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
		if (errCode) {
			dev_err(&pdev->dev,
				"%s: Request aes IRQ failed!\n", __func__);
			goto crypto_errCode_kzalloc;
		}

		errCode = request_irq(pinfo->des_irq, ambarella_des_irq,
			IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
		if (errCode) {
			dev_err(&pdev->dev,
				"%s: Request des IRQ failed!\n", __func__);
			goto crypto_errCode_free_aes_irq;
		}

		if (platform_info->md5_sha1 == 1) {
			errCode = request_irq(pinfo->md5_sha1_irq, ambarella_md5_sha1_irq,
				IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
			if (errCode) {
				dev_err(&pdev->dev,
					"%s: Request md5/sha1 IRQ failed!\n", __func__);
				goto crypto_errCode_free_md5_sha1_irq;
			}
		}
	}
	//TODO: need to add a7 mode switch.now, it's default as compatibility mode
	if (platform_info->mode_switch == 1) {
		amba_writel(CRYPT_BINARY_COMP, 0x0000); // set a7 to compatibility mode
	}

	if (platform_info->binary_mode == 1){
		aes_fun.opcode = aes_opcode;
		des_fun.opcode = des_opcode;
	}else{
		aes_fun.opcode = null_fun;
		des_fun.opcode = null_fun;
	}

	if (platform_info->data_swap == 1){
		aes_fun.wdata = swap_write;
		aes_fun.rdata = swap_read;
		des_fun.wdata = swap_write;
		des_fun.rdata = swap_read;
	}else{
		aes_fun.wdata = (void*)memcpy;
		aes_fun.rdata = (void*)memcpy;
		des_fun.wdata = (void*)memcpy;
		des_fun.rdata = (void*)memcpy;
	}

	if (platform_info->reg_64 == 1){
		aes_fun.reg_enc = aes_reg_enc_64;
		aes_fun.reg_dec = aes_reg_dec_64;
		des_fun.reg_enc = des_reg_enc_64;
		des_fun.reg_dec = des_reg_dec_64;
	}else{
		aes_fun.reg_enc = aes_reg_enc_dec_32;
		aes_fun.reg_dec = aes_reg_enc_dec_32;
		des_fun.reg_enc = des_reg_enc_dec_32;
		des_fun.reg_dec = des_reg_enc_dec_32;
	}

	if (platform_info->md5_sha1 == 1) {
		if (platform_info->md5_sha1_64bit == 1) {
			md5_sha1_fun.wdata = (void*)md5_sha1_write64;
			md5_sha1_fun.rdata = (void*)md5_sha1_read64;
		}else{
			md5_sha1_fun.wdata = (void*)memcpy;
			md5_sha1_fun.rdata = (void*)memcpy;
		}
		if ((errCode = crypto_register_shash(&sha1_alg))) {
			dev_err(&pdev->dev, "reigster sha1_alg  failed.\n");
			if(likely(config_polling_mode == 0)) {
				goto crypto_errCode_free_md5_sha1_irq;
			} else {
				goto crypto_errCode_na;
			}
		}
		if ((errCode = crypto_register_shash(&md5_alg))) {
			dev_err(&pdev->dev, "reigster md5_alg  failed.\n");
			if(likely(config_polling_mode == 0)) {
				goto crypto_errCode_free_md5_sha1_irq;
			} else {
				goto crypto_errCode_na;
			}
		}
	}

	if ((errCode = crypto_register_alg(&aes_alg))) {
		dev_err(&pdev->dev, "reigster aes_alg  failed.\n");
		if(likely(config_polling_mode == 0)) {
			goto crypto_errCode_free_des_irq;
		} else {
			goto crypto_errCode_na;
		}
	}

	if ((errCode = crypto_register_alg(&des_alg))) {
		dev_err(&pdev->dev, "reigster des_alg failed.\n");

		crypto_unregister_alg(&aes_alg);

		if(likely(config_polling_mode == 0)) {
			goto crypto_errCode_free_des_irq;
		} else {
			goto crypto_errCode_na;
		}
	}

	if(likely(config_polling_mode == 0))
		dev_notice(&pdev->dev,"%s probed(interrupt mode).\n", ambdev_name);
	else
		dev_notice(&pdev->dev,"%s probed(polling mode).\n", ambdev_name);

	goto crypto_errCode_na;

crypto_errCode_free_md5_sha1_irq:
	if (platform_info->md5_sha1 == 1) {
		free_irq(pinfo->md5_sha1_irq, pinfo);
	}

crypto_errCode_free_des_irq:
	free_irq(pinfo->des_irq, pinfo);

crypto_errCode_free_aes_irq:
	free_irq(pinfo->aes_irq, pinfo);

crypto_errCode_kzalloc:
	platform_set_drvdata(pdev, NULL);
	kfree(pinfo);

crypto_errCode_ioarea:
	release_mem_region(mem->start, (mem->end - mem->start) + 1);

crypto_errCode_na:
	return errCode;
}

static int __exit ambarella_crypto_remove(struct platform_device *pdev)
{
	int errCode = 0;
	struct ambarella_crypto_dev_info *pinfo;

	if (platform_info->md5_sha1 == 1) {
		crypto_unregister_shash(&sha1_alg);
		crypto_unregister_shash(&md5_alg);
	}

	crypto_unregister_alg(&aes_alg);
	crypto_unregister_alg(&des_alg);

	pinfo = platform_get_drvdata(pdev);

	if (pinfo && config_polling_mode == 0) {
		if (platform_info->md5_sha1 == 1) {
			free_irq(pinfo->md5_sha1_irq, pinfo);
		}
		free_irq(pinfo->aes_irq, pinfo);
		free_irq(pinfo->des_irq, pinfo);
		platform_set_drvdata(pdev, NULL);
		release_mem_region(pinfo->mem->start,
			(pinfo->mem->end - pinfo->mem->start) + 1);
		kfree(pinfo);
	}
	dev_notice(&pdev->dev, "%s removed.\n", ambdev_name);

	return errCode;
}

static const char ambarella_crypto_name[] = "ambarella-crypto";

static struct platform_driver ambarella_crypto_driver = {
	.remove		= __exit_p(ambarella_crypto_remove),
#ifdef CONFIG_PM
	.suspend	= NULL,
	.resume		= NULL,
#endif
	.driver		= {
		.name	= ambarella_crypto_name,
		.owner	= THIS_MODULE,
	},
};

static int __init ambarella_crypto_init(void)
{
	return platform_driver_probe(&ambarella_crypto_driver,
		ambarella_crypto_probe);
}

static void __exit ambarella_crypto_exit(void)
{
	platform_driver_unregister(&ambarella_crypto_driver);
}

module_init(ambarella_crypto_init);
module_exit(ambarella_crypto_exit);

MODULE_DESCRIPTION("Ambarella Cryptography Engine");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Qiao Wang");
MODULE_ALIAS("crypo-all");

