/*
 * Cryptographic API.
 *
 * Support for ATMEL SHA1/SHA256 HW acceleration.
 *
 * Copyright (c) 2012 Eukréa Electromatique - ATMEL
 * Author: Nicolas Royer <nicolas@eukrea.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Some ideas are from omap-sham.c drivers.
 */


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/hw_random.h>
#include <linux/platform_device.h>

#include <linux/device.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
#include <linux/of_device.h>
#include <linux/delay.h>
#include <linux/crypto.h>
#include <linux/cryptohash.h>
#include <crypto/scatterwalk.h>
#include <crypto/algapi.h>
#include <crypto/sha.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#include <linux/platform_data/crypto-atmel.h>
#include "atmel-sha-regs.h"
#include "atmel-authenc.h"

/* SHA flags */
#define SHA_FLAGS_BUSY			BIT(0)
#define	SHA_FLAGS_FINAL			BIT(1)
#define SHA_FLAGS_DMA_ACTIVE	BIT(2)
#define SHA_FLAGS_OUTPUT_READY	BIT(3)
#define SHA_FLAGS_INIT			BIT(4)
#define SHA_FLAGS_CPU			BIT(5)
#define SHA_FLAGS_DMA_READY		BIT(6)
#define SHA_FLAGS_DUMP_REG	BIT(7)

/* bits[11:8] are reserved. */

#define SHA_FLAGS_FINUP		BIT(16)
#define SHA_FLAGS_SG		BIT(17)
#define SHA_FLAGS_ERROR		BIT(23)
#define SHA_FLAGS_PAD		BIT(24)
#define SHA_FLAGS_RESTORE	BIT(25)
#define SHA_FLAGS_IDATAR0	BIT(26)
#define SHA_FLAGS_WAIT_DATARDY	BIT(27)

#define SHA_OP_INIT	0
#define SHA_OP_UPDATE	1
#define SHA_OP_FINAL	2
#define SHA_OP_DIGEST	3

#define SHA_BUFFER_LEN		(PAGE_SIZE / 16)

#define ATMEL_SHA_DMA_THRESHOLD		56

struct atmel_sha_caps {
	bool	has_dma;
	bool	has_dualbuff;
	bool	has_sha224;
	bool	has_sha_384_512;
	bool	has_uihv;
	bool	has_hmac;
};

struct atmel_sha_dev;

/*
 * .statesize = sizeof(struct atmel_sha_reqctx) must be <= PAGE_SIZE / 8 as
 * tested by the ahash_prepare_alg() function.
 */
struct atmel_sha_reqctx {
	struct atmel_sha_dev	*dd;
	unsigned long	flags;
	unsigned long	op;

	u8	digest[SHA512_DIGEST_SIZE] __aligned(sizeof(u32));
	u64	digcnt[2];
	size_t	bufcnt;
	size_t	buflen;
	dma_addr_t	dma_addr;

	/* walk state */
	struct scatterlist	*sg;
	unsigned int	offset;	/* offset in current sg */
	unsigned int	total;	/* total request */

	size_t block_size;
	size_t hash_size;

	u8 buffer[SHA_BUFFER_LEN + SHA512_BLOCK_SIZE] __aligned(sizeof(u32));
};

typedef int (*atmel_sha_fn_t)(struct atmel_sha_dev *);

struct atmel_sha_ctx {
	struct atmel_sha_dev	*dd;
	atmel_sha_fn_t		start;

	unsigned long		flags;
};

#define ATMEL_SHA_QUEUE_LENGTH	50

struct atmel_sha_dma {
	struct dma_chan			*chan;
	struct dma_slave_config dma_conf;
	struct scatterlist	*sg;
	int			nents;
	unsigned int		last_sg_length;
};

struct atmel_sha_dev {
	struct list_head	list;
	unsigned long		phys_base;
	struct device		*dev;
	struct clk			*iclk;
	int					irq;
	void __iomem		*io_base;

	spinlock_t		lock;
	int			err;
	struct tasklet_struct	done_task;
	struct tasklet_struct	queue_task;

	unsigned long		flags;
	struct crypto_queue	queue;
	struct ahash_request	*req;
	bool			is_async;
	bool			force_complete;
	atmel_sha_fn_t		resume;
	atmel_sha_fn_t		cpu_transfer_complete;

	struct atmel_sha_dma	dma_lch_in;

	struct atmel_sha_caps	caps;

	struct scatterlist	tmp;

	u32	hw_version;
};

struct atmel_sha_drv {
	struct list_head	dev_list;
	spinlock_t		lock;
};

static struct atmel_sha_drv atmel_sha = {
	.dev_list = LIST_HEAD_INIT(atmel_sha.dev_list),
	.lock = __SPIN_LOCK_UNLOCKED(atmel_sha.lock),
};

#ifdef VERBOSE_DEBUG
static const char *atmel_sha_reg_name(u32 offset, char *tmp, size_t sz, bool wr)
{
	switch (offset) {
	case SHA_CR:
		return "CR";

	case SHA_MR:
		return "MR";

	case SHA_IER:
		return "IER";

	case SHA_IDR:
		return "IDR";

	case SHA_IMR:
		return "IMR";

	case SHA_ISR:
		return "ISR";

	case SHA_MSR:
		return "MSR";

	case SHA_BCR:
		return "BCR";

	case SHA_REG_DIN(0):
	case SHA_REG_DIN(1):
	case SHA_REG_DIN(2):
	case SHA_REG_DIN(3):
	case SHA_REG_DIN(4):
	case SHA_REG_DIN(5):
	case SHA_REG_DIN(6):
	case SHA_REG_DIN(7):
	case SHA_REG_DIN(8):
	case SHA_REG_DIN(9):
	case SHA_REG_DIN(10):
	case SHA_REG_DIN(11):
	case SHA_REG_DIN(12):
	case SHA_REG_DIN(13):
	case SHA_REG_DIN(14):
	case SHA_REG_DIN(15):
		snprintf(tmp, sz, "IDATAR[%u]", (offset - SHA_REG_DIN(0)) >> 2);
		break;

	case SHA_REG_DIGEST(0):
	case SHA_REG_DIGEST(1):
	case SHA_REG_DIGEST(2):
	case SHA_REG_DIGEST(3):
	case SHA_REG_DIGEST(4):
	case SHA_REG_DIGEST(5):
	case SHA_REG_DIGEST(6):
	case SHA_REG_DIGEST(7):
	case SHA_REG_DIGEST(8):
	case SHA_REG_DIGEST(9):
	case SHA_REG_DIGEST(10):
	case SHA_REG_DIGEST(11):
	case SHA_REG_DIGEST(12):
	case SHA_REG_DIGEST(13):
	case SHA_REG_DIGEST(14):
	case SHA_REG_DIGEST(15):
		if (wr)
			snprintf(tmp, sz, "IDATAR[%u]",
				 16u + ((offset - SHA_REG_DIGEST(0)) >> 2));
		else
			snprintf(tmp, sz, "ODATAR[%u]",
				 (offset - SHA_REG_DIGEST(0)) >> 2);
		break;

	case SHA_HW_VERSION:
		return "HWVER";

	default:
		snprintf(tmp, sz, "0x%02x", offset);
		break;
	}

	return tmp;
}

#endif /* VERBOSE_DEBUG */

static inline u32 atmel_sha_read(struct atmel_sha_dev *dd, u32 offset)
{
	u32 value = readl_relaxed(dd->io_base + offset);

#ifdef VERBOSE_DEBUG
	if (dd->flags & SHA_FLAGS_DUMP_REG) {
		char tmp[16];

		dev_vdbg(dd->dev, "read 0x%08x from %s\n", value,
			 atmel_sha_reg_name(offset, tmp, sizeof(tmp), false));
	}
#endif /* VERBOSE_DEBUG */

	return value;
}

static inline void atmel_sha_write(struct atmel_sha_dev *dd,
					u32 offset, u32 value)
{
#ifdef VERBOSE_DEBUG
	if (dd->flags & SHA_FLAGS_DUMP_REG) {
		char tmp[16];

		dev_vdbg(dd->dev, "write 0x%08x into %s\n", value,
			 atmel_sha_reg_name(offset, tmp, sizeof(tmp), true));
	}
#endif /* VERBOSE_DEBUG */

	writel_relaxed(value, dd->io_base + offset);
}

static inline int atmel_sha_complete(struct atmel_sha_dev *dd, int err)
{
	struct ahash_request *req = dd->req;

	dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
		       SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY |
		       SHA_FLAGS_DUMP_REG);

	clk_disable(dd->iclk);

	if ((dd->is_async || dd->force_complete) && req->base.complete)
		req->base.complete(&req->base, err);

	/* handle new request */
	tasklet_schedule(&dd->queue_task);

	return err;
}

static size_t atmel_sha_append_sg(struct atmel_sha_reqctx *ctx)
{
	size_t count;

	while ((ctx->bufcnt < ctx->buflen) && ctx->total) {
		count = min(ctx->sg->length - ctx->offset, ctx->total);
		count = min(count, ctx->buflen - ctx->bufcnt);

		if (count <= 0) {
			/*
			* Check if count <= 0 because the buffer is full or
			* because the sg length is 0. In the latest case,
			* check if there is another sg in the list, a 0 length
			* sg doesn't necessarily mean the end of the sg list.
			*/
			if ((ctx->sg->length == 0) && !sg_is_last(ctx->sg)) {
				ctx->sg = sg_next(ctx->sg);
				continue;
			} else {
				break;
			}
		}

		scatterwalk_map_and_copy(ctx->buffer + ctx->bufcnt, ctx->sg,
			ctx->offset, count, 0);

		ctx->bufcnt += count;
		ctx->offset += count;
		ctx->total -= count;

		if (ctx->offset == ctx->sg->length) {
			ctx->sg = sg_next(ctx->sg);
			if (ctx->sg)
				ctx->offset = 0;
			else
				ctx->total = 0;
		}
	}

	return 0;
}

/*
 * The purpose of this padding is to ensure that the padded message is a
 * multiple of 512 bits (SHA1/SHA224/SHA256) or 1024 bits (SHA384/SHA512).
 * The bit "1" is appended at the end of the message followed by
 * "padlen-1" zero bits. Then a 64 bits block (SHA1/SHA224/SHA256) or
 * 128 bits block (SHA384/SHA512) equals to the message length in bits
 * is appended.
 *
 * For SHA1/SHA224/SHA256, padlen is calculated as followed:
 *  - if message length < 56 bytes then padlen = 56 - message length
 *  - else padlen = 64 + 56 - message length
 *
 * For SHA384/SHA512, padlen is calculated as followed:
 *  - if message length < 112 bytes then padlen = 112 - message length
 *  - else padlen = 128 + 112 - message length
 */
static void atmel_sha_fill_padding(struct atmel_sha_reqctx *ctx, int length)
{
	unsigned int index, padlen;
	u64 bits[2];
	u64 size[2];

	size[0] = ctx->digcnt[0];
	size[1] = ctx->digcnt[1];

	size[0] += ctx->bufcnt;
	if (size[0] < ctx->bufcnt)
		size[1]++;

	size[0] += length;
	if (size[0]  < length)
		size[1]++;

	bits[1] = cpu_to_be64(size[0] << 3);
	bits[0] = cpu_to_be64(size[1] << 3 | size[0] >> 61);

	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	case SHA_FLAGS_SHA384:
	case SHA_FLAGS_SHA512:
		index = ctx->bufcnt & 0x7f;
		padlen = (index < 112) ? (112 - index) : ((128+112) - index);
		*(ctx->buffer + ctx->bufcnt) = 0x80;
		memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen-1);
		memcpy(ctx->buffer + ctx->bufcnt + padlen, bits, 16);
		ctx->bufcnt += padlen + 16;
		ctx->flags |= SHA_FLAGS_PAD;
		break;

	default:
		index = ctx->bufcnt & 0x3f;
		padlen = (index < 56) ? (56 - index) : ((64+56) - index);
		*(ctx->buffer + ctx->bufcnt) = 0x80;
		memset(ctx->buffer + ctx->bufcnt + 1, 0, padlen-1);
		memcpy(ctx->buffer + ctx->bufcnt + padlen, &bits[1], 8);
		ctx->bufcnt += padlen + 8;
		ctx->flags |= SHA_FLAGS_PAD;
		break;
	}
}

static struct atmel_sha_dev *atmel_sha_find_dev(struct atmel_sha_ctx *tctx)
{
	struct atmel_sha_dev *dd = NULL;
	struct atmel_sha_dev *tmp;

	spin_lock_bh(&atmel_sha.lock);
	if (!tctx->dd) {
		list_for_each_entry(tmp, &atmel_sha.dev_list, list) {
			dd = tmp;
			break;
		}
		tctx->dd = dd;
	} else {
		dd = tctx->dd;
	}

	spin_unlock_bh(&atmel_sha.lock);

	return dd;
}

static int atmel_sha_init(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_ctx *tctx = crypto_ahash_ctx(tfm);
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct atmel_sha_dev *dd = atmel_sha_find_dev(tctx);

	ctx->dd = dd;

	ctx->flags = 0;

	dev_dbg(dd->dev, "init: digest size: %d\n",
		crypto_ahash_digestsize(tfm));

	switch (crypto_ahash_digestsize(tfm)) {
	case SHA1_DIGEST_SIZE:
		ctx->flags |= SHA_FLAGS_SHA1;
		ctx->block_size = SHA1_BLOCK_SIZE;
		break;
	case SHA224_DIGEST_SIZE:
		ctx->flags |= SHA_FLAGS_SHA224;
		ctx->block_size = SHA224_BLOCK_SIZE;
		break;
	case SHA256_DIGEST_SIZE:
		ctx->flags |= SHA_FLAGS_SHA256;
		ctx->block_size = SHA256_BLOCK_SIZE;
		break;
	case SHA384_DIGEST_SIZE:
		ctx->flags |= SHA_FLAGS_SHA384;
		ctx->block_size = SHA384_BLOCK_SIZE;
		break;
	case SHA512_DIGEST_SIZE:
		ctx->flags |= SHA_FLAGS_SHA512;
		ctx->block_size = SHA512_BLOCK_SIZE;
		break;
	default:
		return -EINVAL;
		break;
	}

	ctx->bufcnt = 0;
	ctx->digcnt[0] = 0;
	ctx->digcnt[1] = 0;
	ctx->buflen = SHA_BUFFER_LEN;

	return 0;
}

static void atmel_sha_write_ctrl(struct atmel_sha_dev *dd, int dma)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	u32 valmr = SHA_MR_MODE_AUTO;
	unsigned int i, hashsize = 0;

	if (likely(dma)) {
		if (!dd->caps.has_dma)
			atmel_sha_write(dd, SHA_IER, SHA_INT_TXBUFE);
		valmr = SHA_MR_MODE_PDC;
		if (dd->caps.has_dualbuff)
			valmr |= SHA_MR_DUALBUFF;
	} else {
		atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY);
	}

	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	case SHA_FLAGS_SHA1:
		valmr |= SHA_MR_ALGO_SHA1;
		hashsize = SHA1_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA224:
		valmr |= SHA_MR_ALGO_SHA224;
		hashsize = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA256:
		valmr |= SHA_MR_ALGO_SHA256;
		hashsize = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA384:
		valmr |= SHA_MR_ALGO_SHA384;
		hashsize = SHA512_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA512:
		valmr |= SHA_MR_ALGO_SHA512;
		hashsize = SHA512_DIGEST_SIZE;
		break;

	default:
		break;
	}

	/* Setting CR_FIRST only for the first iteration */
	if (!(ctx->digcnt[0] || ctx->digcnt[1])) {
		atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);
	} else if (dd->caps.has_uihv && (ctx->flags & SHA_FLAGS_RESTORE)) {
		const u32 *hash = (const u32 *)ctx->digest;

		/*
		 * Restore the hardware context: update the User Initialize
		 * Hash Value (UIHV) with the value saved when the latest
		 * 'update' operation completed on this very same crypto
		 * request.
		 */
		ctx->flags &= ~SHA_FLAGS_RESTORE;
		atmel_sha_write(dd, SHA_CR, SHA_CR_WUIHV);
		for (i = 0; i < hashsize / sizeof(u32); ++i)
			atmel_sha_write(dd, SHA_REG_DIN(i), hash[i]);
		atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);
		valmr |= SHA_MR_UIHV;
	}
	/*
	 * WARNING: If the UIHV feature is not available, the hardware CANNOT
	 * process concurrent requests: the internal registers used to store
	 * the hash/digest are still set to the partial digest output values
	 * computed during the latest round.
	 */

	atmel_sha_write(dd, SHA_MR, valmr);
}

static inline int atmel_sha_wait_for_data_ready(struct atmel_sha_dev *dd,
						atmel_sha_fn_t resume)
{
	u32 isr = atmel_sha_read(dd, SHA_ISR);

	if (unlikely(isr & SHA_INT_DATARDY))
		return resume(dd);

	dd->resume = resume;
	atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY);
	return -EINPROGRESS;
}

static int atmel_sha_xmit_cpu(struct atmel_sha_dev *dd, const u8 *buf,
			      size_t length, int final)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	int count, len32;
	const u32 *buffer = (const u32 *)buf;

	dev_dbg(dd->dev, "xmit_cpu: digcnt: 0x%llx 0x%llx, length: %zd, final: %d\n",
		ctx->digcnt[1], ctx->digcnt[0], length, final);

	atmel_sha_write_ctrl(dd, 0);

	/* should be non-zero before next lines to disable clocks later */
	ctx->digcnt[0] += length;
	if (ctx->digcnt[0] < length)
		ctx->digcnt[1]++;

	if (final)
		dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */

	len32 = DIV_ROUND_UP(length, sizeof(u32));

	dd->flags |= SHA_FLAGS_CPU;

	for (count = 0; count < len32; count++)
		atmel_sha_write(dd, SHA_REG_DIN(count), buffer[count]);

	return -EINPROGRESS;
}

static int atmel_sha_xmit_pdc(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	int len32;

	dev_dbg(dd->dev, "xmit_pdc: digcnt: 0x%llx 0x%llx, length: %zd, final: %d\n",
		ctx->digcnt[1], ctx->digcnt[0], length1, final);

	len32 = DIV_ROUND_UP(length1, sizeof(u32));
	atmel_sha_write(dd, SHA_PTCR, SHA_PTCR_TXTDIS);
	atmel_sha_write(dd, SHA_TPR, dma_addr1);
	atmel_sha_write(dd, SHA_TCR, len32);

	len32 = DIV_ROUND_UP(length2, sizeof(u32));
	atmel_sha_write(dd, SHA_TNPR, dma_addr2);
	atmel_sha_write(dd, SHA_TNCR, len32);

	atmel_sha_write_ctrl(dd, 1);

	/* should be non-zero before next lines to disable clocks later */
	ctx->digcnt[0] += length1;
	if (ctx->digcnt[0] < length1)
		ctx->digcnt[1]++;

	if (final)
		dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */

	dd->flags |=  SHA_FLAGS_DMA_ACTIVE;

	/* Start DMA transfer */
	atmel_sha_write(dd, SHA_PTCR, SHA_PTCR_TXTEN);

	return -EINPROGRESS;
}

static void atmel_sha_dma_callback(void *data)
{
	struct atmel_sha_dev *dd = data;

	dd->is_async = true;

	/* dma_lch_in - completed - wait DATRDY */
	atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY);
}

static int atmel_sha_xmit_dma(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	struct dma_async_tx_descriptor	*in_desc;
	struct scatterlist sg[2];

	dev_dbg(dd->dev, "xmit_dma: digcnt: 0x%llx 0x%llx, length: %zd, final: %d\n",
		ctx->digcnt[1], ctx->digcnt[0], length1, final);

	dd->dma_lch_in.dma_conf.src_maxburst = 16;
	dd->dma_lch_in.dma_conf.dst_maxburst = 16;

	dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf);

	if (length2) {
		sg_init_table(sg, 2);
		sg_dma_address(&sg[0]) = dma_addr1;
		sg_dma_len(&sg[0]) = length1;
		sg_dma_address(&sg[1]) = dma_addr2;
		sg_dma_len(&sg[1]) = length2;
		in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, sg, 2,
			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	} else {
		sg_init_table(sg, 1);
		sg_dma_address(&sg[0]) = dma_addr1;
		sg_dma_len(&sg[0]) = length1;
		in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, sg, 1,
			DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	}
	if (!in_desc)
		return atmel_sha_complete(dd, -EINVAL);

	in_desc->callback = atmel_sha_dma_callback;
	in_desc->callback_param = dd;

	atmel_sha_write_ctrl(dd, 1);

	/* should be non-zero before next lines to disable clocks later */
	ctx->digcnt[0] += length1;
	if (ctx->digcnt[0] < length1)
		ctx->digcnt[1]++;

	if (final)
		dd->flags |= SHA_FLAGS_FINAL; /* catch last interrupt */

	dd->flags |=  SHA_FLAGS_DMA_ACTIVE;

	/* Start DMA transfer */
	dmaengine_submit(in_desc);
	dma_async_issue_pending(dd->dma_lch_in.chan);

	return -EINPROGRESS;
}

static int atmel_sha_xmit_start(struct atmel_sha_dev *dd, dma_addr_t dma_addr1,
		size_t length1, dma_addr_t dma_addr2, size_t length2, int final)
{
	if (dd->caps.has_dma)
		return atmel_sha_xmit_dma(dd, dma_addr1, length1,
				dma_addr2, length2, final);
	else
		return atmel_sha_xmit_pdc(dd, dma_addr1, length1,
				dma_addr2, length2, final);
}

static int atmel_sha_update_cpu(struct atmel_sha_dev *dd)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	int bufcnt;

	atmel_sha_append_sg(ctx);
	atmel_sha_fill_padding(ctx, 0);
	bufcnt = ctx->bufcnt;
	ctx->bufcnt = 0;

	return atmel_sha_xmit_cpu(dd, ctx->buffer, bufcnt, 1);
}

static int atmel_sha_xmit_dma_map(struct atmel_sha_dev *dd,
					struct atmel_sha_reqctx *ctx,
					size_t length, int final)
{
	ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer,
				ctx->buflen + ctx->block_size, DMA_TO_DEVICE);
	if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
		dev_err(dd->dev, "dma %zu bytes error\n", ctx->buflen +
				ctx->block_size);
		return atmel_sha_complete(dd, -EINVAL);
	}

	ctx->flags &= ~SHA_FLAGS_SG;

	/* next call does not fail... so no unmap in the case of error */
	return atmel_sha_xmit_start(dd, ctx->dma_addr, length, 0, 0, final);
}

static int atmel_sha_update_dma_slow(struct atmel_sha_dev *dd)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	unsigned int final;
	size_t count;

	atmel_sha_append_sg(ctx);

	final = (ctx->flags & SHA_FLAGS_FINUP) && !ctx->total;

	dev_dbg(dd->dev, "slow: bufcnt: %zu, digcnt: 0x%llx 0x%llx, final: %d\n",
		 ctx->bufcnt, ctx->digcnt[1], ctx->digcnt[0], final);

	if (final)
		atmel_sha_fill_padding(ctx, 0);

	if (final || (ctx->bufcnt == ctx->buflen)) {
		count = ctx->bufcnt;
		ctx->bufcnt = 0;
		return atmel_sha_xmit_dma_map(dd, ctx, count, final);
	}

	return 0;
}

static int atmel_sha_update_dma_start(struct atmel_sha_dev *dd)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);
	unsigned int length, final, tail;
	struct scatterlist *sg;
	unsigned int count;

	if (!ctx->total)
		return 0;

	if (ctx->bufcnt || ctx->offset)
		return atmel_sha_update_dma_slow(dd);

	dev_dbg(dd->dev, "fast: digcnt: 0x%llx 0x%llx, bufcnt: %zd, total: %u\n",
		ctx->digcnt[1], ctx->digcnt[0], ctx->bufcnt, ctx->total);

	sg = ctx->sg;

	if (!IS_ALIGNED(sg->offset, sizeof(u32)))
		return atmel_sha_update_dma_slow(dd);

	if (!sg_is_last(sg) && !IS_ALIGNED(sg->length, ctx->block_size))
		/* size is not ctx->block_size aligned */
		return atmel_sha_update_dma_slow(dd);

	length = min(ctx->total, sg->length);

	if (sg_is_last(sg)) {
		if (!(ctx->flags & SHA_FLAGS_FINUP)) {
			/* not last sg must be ctx->block_size aligned */
			tail = length & (ctx->block_size - 1);
			length -= tail;
		}
	}

	ctx->total -= length;
	ctx->offset = length; /* offset where to start slow */

	final = (ctx->flags & SHA_FLAGS_FINUP) && !ctx->total;

	/* Add padding */
	if (final) {
		tail = length & (ctx->block_size - 1);
		length -= tail;
		ctx->total += tail;
		ctx->offset = length; /* offset where to start slow */

		sg = ctx->sg;
		atmel_sha_append_sg(ctx);

		atmel_sha_fill_padding(ctx, length);

		ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer,
			ctx->buflen + ctx->block_size, DMA_TO_DEVICE);
		if (dma_mapping_error(dd->dev, ctx->dma_addr)) {
			dev_err(dd->dev, "dma %zu bytes error\n",
				ctx->buflen + ctx->block_size);
			return atmel_sha_complete(dd, -EINVAL);
		}

		if (length == 0) {
			ctx->flags &= ~SHA_FLAGS_SG;
			count = ctx->bufcnt;
			ctx->bufcnt = 0;
			return atmel_sha_xmit_start(dd, ctx->dma_addr, count, 0,
					0, final);
		} else {
			ctx->sg = sg;
			if (!dma_map_sg(dd->dev, ctx->sg, 1,
				DMA_TO_DEVICE)) {
					dev_err(dd->dev, "dma_map_sg  error\n");
					return atmel_sha_complete(dd, -EINVAL);
			}

			ctx->flags |= SHA_FLAGS_SG;

			count = ctx->bufcnt;
			ctx->bufcnt = 0;
			return atmel_sha_xmit_start(dd, sg_dma_address(ctx->sg),
					length, ctx->dma_addr, count, final);
		}
	}

	if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) {
		dev_err(dd->dev, "dma_map_sg  error\n");
		return atmel_sha_complete(dd, -EINVAL);
	}

	ctx->flags |= SHA_FLAGS_SG;

	/* next call does not fail... so no unmap in the case of error */
	return atmel_sha_xmit_start(dd, sg_dma_address(ctx->sg), length, 0,
								0, final);
}

static int atmel_sha_update_dma_stop(struct atmel_sha_dev *dd)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(dd->req);

	if (ctx->flags & SHA_FLAGS_SG) {
		dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE);
		if (ctx->sg->length == ctx->offset) {
			ctx->sg = sg_next(ctx->sg);
			if (ctx->sg)
				ctx->offset = 0;
		}
		if (ctx->flags & SHA_FLAGS_PAD) {
			dma_unmap_single(dd->dev, ctx->dma_addr,
				ctx->buflen + ctx->block_size, DMA_TO_DEVICE);
		}
	} else {
		dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen +
						ctx->block_size, DMA_TO_DEVICE);
	}

	return 0;
}

static int atmel_sha_update_req(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	int err;

	dev_dbg(dd->dev, "update_req: total: %u, digcnt: 0x%llx 0x%llx\n",
		ctx->total, ctx->digcnt[1], ctx->digcnt[0]);

	if (ctx->flags & SHA_FLAGS_CPU)
		err = atmel_sha_update_cpu(dd);
	else
		err = atmel_sha_update_dma_start(dd);

	/* wait for dma completion before can take more data */
	dev_dbg(dd->dev, "update: err: %d, digcnt: 0x%llx 0%llx\n",
			err, ctx->digcnt[1], ctx->digcnt[0]);

	return err;
}

static int atmel_sha_final_req(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	int err = 0;
	int count;

	if (ctx->bufcnt >= ATMEL_SHA_DMA_THRESHOLD) {
		atmel_sha_fill_padding(ctx, 0);
		count = ctx->bufcnt;
		ctx->bufcnt = 0;
		err = atmel_sha_xmit_dma_map(dd, ctx, count, 1);
	}
	/* faster to handle last block with cpu */
	else {
		atmel_sha_fill_padding(ctx, 0);
		count = ctx->bufcnt;
		ctx->bufcnt = 0;
		err = atmel_sha_xmit_cpu(dd, ctx->buffer, count, 1);
	}

	dev_dbg(dd->dev, "final_req: err: %d\n", err);

	return err;
}

static void atmel_sha_copy_hash(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	u32 *hash = (u32 *)ctx->digest;
	unsigned int i, hashsize;

	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	case SHA_FLAGS_SHA1:
		hashsize = SHA1_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA224:
	case SHA_FLAGS_SHA256:
		hashsize = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA384:
	case SHA_FLAGS_SHA512:
		hashsize = SHA512_DIGEST_SIZE;
		break;

	default:
		/* Should not happen... */
		return;
	}

	for (i = 0; i < hashsize / sizeof(u32); ++i)
		hash[i] = atmel_sha_read(ctx->dd, SHA_REG_DIGEST(i));
	ctx->flags |= SHA_FLAGS_RESTORE;
}

static void atmel_sha_copy_ready_hash(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

	if (!req->result)
		return;

	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	default:
	case SHA_FLAGS_SHA1:
		memcpy(req->result, ctx->digest, SHA1_DIGEST_SIZE);
		break;

	case SHA_FLAGS_SHA224:
		memcpy(req->result, ctx->digest, SHA224_DIGEST_SIZE);
		break;

	case SHA_FLAGS_SHA256:
		memcpy(req->result, ctx->digest, SHA256_DIGEST_SIZE);
		break;

	case SHA_FLAGS_SHA384:
		memcpy(req->result, ctx->digest, SHA384_DIGEST_SIZE);
		break;

	case SHA_FLAGS_SHA512:
		memcpy(req->result, ctx->digest, SHA512_DIGEST_SIZE);
		break;
	}
}

static int atmel_sha_finish(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct atmel_sha_dev *dd = ctx->dd;

	if (ctx->digcnt[0] || ctx->digcnt[1])
		atmel_sha_copy_ready_hash(req);

	dev_dbg(dd->dev, "digcnt: 0x%llx 0x%llx, bufcnt: %zd\n", ctx->digcnt[1],
		ctx->digcnt[0], ctx->bufcnt);

	return 0;
}

static void atmel_sha_finish_req(struct ahash_request *req, int err)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct atmel_sha_dev *dd = ctx->dd;

	if (!err) {
		atmel_sha_copy_hash(req);
		if (SHA_FLAGS_FINAL & dd->flags)
			err = atmel_sha_finish(req);
	} else {
		ctx->flags |= SHA_FLAGS_ERROR;
	}

	/* atomic operation is not needed here */
	(void)atmel_sha_complete(dd, err);
}

static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
{
	int err;

	err = clk_enable(dd->iclk);
	if (err)
		return err;

	if (!(SHA_FLAGS_INIT & dd->flags)) {
		atmel_sha_write(dd, SHA_CR, SHA_CR_SWRST);
		dd->flags |= SHA_FLAGS_INIT;
		dd->err = 0;
	}

	return 0;
}

static inline unsigned int atmel_sha_get_version(struct atmel_sha_dev *dd)
{
	return atmel_sha_read(dd, SHA_HW_VERSION) & 0x00000fff;
}

static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
{
	atmel_sha_hw_init(dd);

	dd->hw_version = atmel_sha_get_version(dd);

	dev_info(dd->dev,
			"version: 0x%x\n", dd->hw_version);

	clk_disable(dd->iclk);
}

static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
				  struct ahash_request *req)
{
	struct crypto_async_request *async_req, *backlog;
	struct atmel_sha_ctx *ctx;
	unsigned long flags;
	bool start_async;
	int err = 0, ret = 0;

	spin_lock_irqsave(&dd->lock, flags);
	if (req)
		ret = ahash_enqueue_request(&dd->queue, req);

	if (SHA_FLAGS_BUSY & dd->flags) {
		spin_unlock_irqrestore(&dd->lock, flags);
		return ret;
	}

	backlog = crypto_get_backlog(&dd->queue);
	async_req = crypto_dequeue_request(&dd->queue);
	if (async_req)
		dd->flags |= SHA_FLAGS_BUSY;

	spin_unlock_irqrestore(&dd->lock, flags);

	if (!async_req)
		return ret;

	if (backlog)
		backlog->complete(backlog, -EINPROGRESS);

	ctx = crypto_tfm_ctx(async_req->tfm);

	dd->req = ahash_request_cast(async_req);
	start_async = (dd->req != req);
	dd->is_async = start_async;
	dd->force_complete = false;

	/* WARNING: ctx->start() MAY change dd->is_async. */
	err = ctx->start(dd);
	return (start_async) ? ret : err;
}

static int atmel_sha_done(struct atmel_sha_dev *dd);

static int atmel_sha_start(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	int err;

	dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n",
						ctx->op, req->nbytes);

	err = atmel_sha_hw_init(dd);
	if (err)
		return atmel_sha_complete(dd, err);

	/*
	 * atmel_sha_update_req() and atmel_sha_final_req() can return either:
	 *  -EINPROGRESS: the hardware is busy and the SHA driver will resume
	 *                its job later in the done_task.
	 *                This is the main path.
	 *
	 * 0: the SHA driver can continue its job then release the hardware
	 *    later, if needed, with atmel_sha_finish_req().
	 *    This is the alternate path.
	 *
	 * < 0: an error has occurred so atmel_sha_complete(dd, err) has already
	 *      been called, hence the hardware has been released.
	 *      The SHA driver must stop its job without calling
	 *      atmel_sha_finish_req(), otherwise atmel_sha_complete() would be
	 *      called a second time.
	 *
	 * Please note that currently, atmel_sha_final_req() never returns 0.
	 */

	dd->resume = atmel_sha_done;
	if (ctx->op == SHA_OP_UPDATE) {
		err = atmel_sha_update_req(dd);
		if (!err && (ctx->flags & SHA_FLAGS_FINUP))
			/* no final() after finup() */
			err = atmel_sha_final_req(dd);
	} else if (ctx->op == SHA_OP_FINAL) {
		err = atmel_sha_final_req(dd);
	}

	if (!err)
		/* done_task will not finish it, so do it here */
		atmel_sha_finish_req(req, err);

	dev_dbg(dd->dev, "exit, err: %d\n", err);

	return err;
}

static int atmel_sha_enqueue(struct ahash_request *req, unsigned int op)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct atmel_sha_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
	struct atmel_sha_dev *dd = tctx->dd;

	ctx->op = op;

	return atmel_sha_handle_queue(dd, req);
}

static int atmel_sha_update(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

	if (!req->nbytes)
		return 0;

	ctx->total = req->nbytes;
	ctx->sg = req->src;
	ctx->offset = 0;

	if (ctx->flags & SHA_FLAGS_FINUP) {
		if (ctx->bufcnt + ctx->total < ATMEL_SHA_DMA_THRESHOLD)
			/* faster to use CPU for short transfers */
			ctx->flags |= SHA_FLAGS_CPU;
	} else if (ctx->bufcnt + ctx->total < ctx->buflen) {
		atmel_sha_append_sg(ctx);
		return 0;
	}
	return atmel_sha_enqueue(req, SHA_OP_UPDATE);
}

static int atmel_sha_final(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

	ctx->flags |= SHA_FLAGS_FINUP;

	if (ctx->flags & SHA_FLAGS_ERROR)
		return 0; /* uncompleted hash is not needed */

	if (ctx->flags & SHA_FLAGS_PAD)
		/* copy ready hash (+ finalize hmac) */
		return atmel_sha_finish(req);

	return atmel_sha_enqueue(req, SHA_OP_FINAL);
}

static int atmel_sha_finup(struct ahash_request *req)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	int err1, err2;

	ctx->flags |= SHA_FLAGS_FINUP;

	err1 = atmel_sha_update(req);
	if (err1 == -EINPROGRESS ||
	    (err1 == -EBUSY && (ahash_request_flags(req) &
				CRYPTO_TFM_REQ_MAY_BACKLOG)))
		return err1;

	/*
	 * final() has to be always called to cleanup resources
	 * even if udpate() failed, except EINPROGRESS
	 */
	err2 = atmel_sha_final(req);

	return err1 ?: err2;
}

static int atmel_sha_digest(struct ahash_request *req)
{
	return atmel_sha_init(req) ?: atmel_sha_finup(req);
}


static int atmel_sha_export(struct ahash_request *req, void *out)
{
	const struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

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

static int atmel_sha_import(struct ahash_request *req, const void *in)
{
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

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

static int atmel_sha_cra_init(struct crypto_tfm *tfm)
{
	struct atmel_sha_ctx *ctx = crypto_tfm_ctx(tfm);

	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
				 sizeof(struct atmel_sha_reqctx));
	ctx->start = atmel_sha_start;

	return 0;
}

static struct ahash_alg sha_1_256_algs[] = {
{
	.init		= atmel_sha_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.finup		= atmel_sha_finup,
	.digest		= atmel_sha_digest,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA1_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "sha1",
			.cra_driver_name	= "atmel-sha1",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA1_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_cra_init,
		}
	}
},
{
	.init		= atmel_sha_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.finup		= atmel_sha_finup,
	.digest		= atmel_sha_digest,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA256_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "sha256",
			.cra_driver_name	= "atmel-sha256",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA256_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_cra_init,
		}
	}
},
};

static struct ahash_alg sha_224_alg = {
	.init		= atmel_sha_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.finup		= atmel_sha_finup,
	.digest		= atmel_sha_digest,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA224_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "sha224",
			.cra_driver_name	= "atmel-sha224",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA224_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_cra_init,
		}
	}
};

static struct ahash_alg sha_384_512_algs[] = {
{
	.init		= atmel_sha_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.finup		= atmel_sha_finup,
	.digest		= atmel_sha_digest,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA384_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "sha384",
			.cra_driver_name	= "atmel-sha384",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA384_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_ctx),
			.cra_alignmask		= 0x3,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_cra_init,
		}
	}
},
{
	.init		= atmel_sha_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.finup		= atmel_sha_finup,
	.digest		= atmel_sha_digest,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA512_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "sha512",
			.cra_driver_name	= "atmel-sha512",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA512_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_ctx),
			.cra_alignmask		= 0x3,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_cra_init,
		}
	}
},
};

static void atmel_sha_queue_task(unsigned long data)
{
	struct atmel_sha_dev *dd = (struct atmel_sha_dev *)data;

	atmel_sha_handle_queue(dd, NULL);
}

static int atmel_sha_done(struct atmel_sha_dev *dd)
{
	int err = 0;

	if (SHA_FLAGS_CPU & dd->flags) {
		if (SHA_FLAGS_OUTPUT_READY & dd->flags) {
			dd->flags &= ~SHA_FLAGS_OUTPUT_READY;
			goto finish;
		}
	} else if (SHA_FLAGS_DMA_READY & dd->flags) {
		if (SHA_FLAGS_DMA_ACTIVE & dd->flags) {
			dd->flags &= ~SHA_FLAGS_DMA_ACTIVE;
			atmel_sha_update_dma_stop(dd);
			if (dd->err) {
				err = dd->err;
				goto finish;
			}
		}
		if (SHA_FLAGS_OUTPUT_READY & dd->flags) {
			/* hash or semi-hash ready */
			dd->flags &= ~(SHA_FLAGS_DMA_READY |
						SHA_FLAGS_OUTPUT_READY);
			err = atmel_sha_update_dma_start(dd);
			if (err != -EINPROGRESS)
				goto finish;
		}
	}
	return err;

finish:
	/* finish curent request */
	atmel_sha_finish_req(dd->req, err);

	return err;
}

static void atmel_sha_done_task(unsigned long data)
{
	struct atmel_sha_dev *dd = (struct atmel_sha_dev *)data;

	dd->is_async = true;
	(void)dd->resume(dd);
}

static irqreturn_t atmel_sha_irq(int irq, void *dev_id)
{
	struct atmel_sha_dev *sha_dd = dev_id;
	u32 reg;

	reg = atmel_sha_read(sha_dd, SHA_ISR);
	if (reg & atmel_sha_read(sha_dd, SHA_IMR)) {
		atmel_sha_write(sha_dd, SHA_IDR, reg);
		if (SHA_FLAGS_BUSY & sha_dd->flags) {
			sha_dd->flags |= SHA_FLAGS_OUTPUT_READY;
			if (!(SHA_FLAGS_CPU & sha_dd->flags))
				sha_dd->flags |= SHA_FLAGS_DMA_READY;
			tasklet_schedule(&sha_dd->done_task);
		} else {
			dev_warn(sha_dd->dev, "SHA interrupt when no active requests.\n");
		}
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}


/* DMA transfer functions */

static bool atmel_sha_dma_check_aligned(struct atmel_sha_dev *dd,
					struct scatterlist *sg,
					size_t len)
{
	struct atmel_sha_dma *dma = &dd->dma_lch_in;
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	size_t bs = ctx->block_size;
	int nents;

	for (nents = 0; sg; sg = sg_next(sg), ++nents) {
		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
			return false;

		/*
		 * This is the last sg, the only one that is allowed to
		 * have an unaligned length.
		 */
		if (len <= sg->length) {
			dma->nents = nents + 1;
			dma->last_sg_length = sg->length;
			sg->length = ALIGN(len, sizeof(u32));
			return true;
		}

		/* All other sg lengths MUST be aligned to the block size. */
		if (!IS_ALIGNED(sg->length, bs))
			return false;

		len -= sg->length;
	}

	return false;
}

static void atmel_sha_dma_callback2(void *data)
{
	struct atmel_sha_dev *dd = data;
	struct atmel_sha_dma *dma = &dd->dma_lch_in;
	struct scatterlist *sg;
	int nents;

	dmaengine_terminate_all(dma->chan);
	dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);

	sg = dma->sg;
	for (nents = 0; nents < dma->nents - 1; ++nents)
		sg = sg_next(sg);
	sg->length = dma->last_sg_length;

	dd->is_async = true;
	(void)atmel_sha_wait_for_data_ready(dd, dd->resume);
}

static int atmel_sha_dma_start(struct atmel_sha_dev *dd,
			       struct scatterlist *src,
			       size_t len,
			       atmel_sha_fn_t resume)
{
	struct atmel_sha_dma *dma = &dd->dma_lch_in;
	struct dma_slave_config *config = &dma->dma_conf;
	struct dma_chan *chan = dma->chan;
	struct dma_async_tx_descriptor *desc;
	dma_cookie_t cookie;
	unsigned int sg_len;
	int err;

	dd->resume = resume;

	/*
	 * dma->nents has already been initialized by
	 * atmel_sha_dma_check_aligned().
	 */
	dma->sg = src;
	sg_len = dma_map_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);
	if (!sg_len) {
		err = -ENOMEM;
		goto exit;
	}

	config->src_maxburst = 16;
	config->dst_maxburst = 16;
	err = dmaengine_slave_config(chan, config);
	if (err)
		goto unmap_sg;

	desc = dmaengine_prep_slave_sg(chan, dma->sg, sg_len, DMA_MEM_TO_DEV,
				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	if (!desc) {
		err = -ENOMEM;
		goto unmap_sg;
	}

	desc->callback = atmel_sha_dma_callback2;
	desc->callback_param = dd;
	cookie = dmaengine_submit(desc);
	err = dma_submit_error(cookie);
	if (err)
		goto unmap_sg;

	dma_async_issue_pending(chan);

	return -EINPROGRESS;

unmap_sg:
	dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);
exit:
	return atmel_sha_complete(dd, err);
}


/* CPU transfer functions */

static int atmel_sha_cpu_transfer(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	const u32 *words = (const u32 *)ctx->buffer;
	size_t i, num_words;
	u32 isr, din, din_inc;

	din_inc = (ctx->flags & SHA_FLAGS_IDATAR0) ? 0 : 1;
	for (;;) {
		/* Write data into the Input Data Registers. */
		num_words = DIV_ROUND_UP(ctx->bufcnt, sizeof(u32));
		for (i = 0, din = 0; i < num_words; ++i, din += din_inc)
			atmel_sha_write(dd, SHA_REG_DIN(din), words[i]);

		ctx->offset += ctx->bufcnt;
		ctx->total -= ctx->bufcnt;

		if (!ctx->total)
			break;

		/*
		 * Prepare next block:
		 * Fill ctx->buffer now with the next data to be written into
		 * IDATARx: it gives time for the SHA hardware to process
		 * the current data so the SHA_INT_DATARDY flag might be set
		 * in SHA_ISR when polling this register at the beginning of
		 * the next loop.
		 */
		ctx->bufcnt = min_t(size_t, ctx->block_size, ctx->total);
		scatterwalk_map_and_copy(ctx->buffer, ctx->sg,
					 ctx->offset, ctx->bufcnt, 0);

		/* Wait for hardware to be ready again. */
		isr = atmel_sha_read(dd, SHA_ISR);
		if (!(isr & SHA_INT_DATARDY)) {
			/* Not ready yet. */
			dd->resume = atmel_sha_cpu_transfer;
			atmel_sha_write(dd, SHA_IER, SHA_INT_DATARDY);
			return -EINPROGRESS;
		}
	}

	if (unlikely(!(ctx->flags & SHA_FLAGS_WAIT_DATARDY)))
		return dd->cpu_transfer_complete(dd);

	return atmel_sha_wait_for_data_ready(dd, dd->cpu_transfer_complete);
}

static int atmel_sha_cpu_start(struct atmel_sha_dev *dd,
			       struct scatterlist *sg,
			       unsigned int len,
			       bool idatar0_only,
			       bool wait_data_ready,
			       atmel_sha_fn_t resume)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);

	if (!len)
		return resume(dd);

	ctx->flags &= ~(SHA_FLAGS_IDATAR0 | SHA_FLAGS_WAIT_DATARDY);

	if (idatar0_only)
		ctx->flags |= SHA_FLAGS_IDATAR0;

	if (wait_data_ready)
		ctx->flags |= SHA_FLAGS_WAIT_DATARDY;

	ctx->sg = sg;
	ctx->total = len;
	ctx->offset = 0;

	/* Prepare the first block to be written. */
	ctx->bufcnt = min_t(size_t, ctx->block_size, ctx->total);
	scatterwalk_map_and_copy(ctx->buffer, ctx->sg,
				 ctx->offset, ctx->bufcnt, 0);

	dd->cpu_transfer_complete = resume;
	return atmel_sha_cpu_transfer(dd);
}

static int atmel_sha_cpu_hash(struct atmel_sha_dev *dd,
			      const void *data, unsigned int datalen,
			      bool auto_padding,
			      atmel_sha_fn_t resume)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	u32 msglen = (auto_padding) ? datalen : 0;
	u32 mr = SHA_MR_MODE_AUTO;

	if (!(IS_ALIGNED(datalen, ctx->block_size) || auto_padding))
		return atmel_sha_complete(dd, -EINVAL);

	mr |= (ctx->flags & SHA_FLAGS_ALGO_MASK);
	atmel_sha_write(dd, SHA_MR, mr);
	atmel_sha_write(dd, SHA_MSR, msglen);
	atmel_sha_write(dd, SHA_BCR, msglen);
	atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);

	sg_init_one(&dd->tmp, data, datalen);
	return atmel_sha_cpu_start(dd, &dd->tmp, datalen, false, true, resume);
}


/* hmac functions */

struct atmel_sha_hmac_key {
	bool			valid;
	unsigned int		keylen;
	u8			buffer[SHA512_BLOCK_SIZE];
	u8			*keydup;
};

static inline void atmel_sha_hmac_key_init(struct atmel_sha_hmac_key *hkey)
{
	memset(hkey, 0, sizeof(*hkey));
}

static inline void atmel_sha_hmac_key_release(struct atmel_sha_hmac_key *hkey)
{
	kfree(hkey->keydup);
	memset(hkey, 0, sizeof(*hkey));
}

static inline int atmel_sha_hmac_key_set(struct atmel_sha_hmac_key *hkey,
					 const u8 *key,
					 unsigned int keylen)
{
	atmel_sha_hmac_key_release(hkey);

	if (keylen > sizeof(hkey->buffer)) {
		hkey->keydup = kmemdup(key, keylen, GFP_KERNEL);
		if (!hkey->keydup)
			return -ENOMEM;

	} else {
		memcpy(hkey->buffer, key, keylen);
	}

	hkey->valid = true;
	hkey->keylen = keylen;
	return 0;
}

static inline bool atmel_sha_hmac_key_get(const struct atmel_sha_hmac_key *hkey,
					  const u8 **key,
					  unsigned int *keylen)
{
	if (!hkey->valid)
		return false;

	*keylen = hkey->keylen;
	*key = (hkey->keydup) ? hkey->keydup : hkey->buffer;
	return true;
}


struct atmel_sha_hmac_ctx {
	struct atmel_sha_ctx	base;

	struct atmel_sha_hmac_key	hkey;
	u32			ipad[SHA512_BLOCK_SIZE / sizeof(u32)];
	u32			opad[SHA512_BLOCK_SIZE / sizeof(u32)];
	atmel_sha_fn_t		resume;
};

static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
				atmel_sha_fn_t resume);
static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
				      const u8 *key, unsigned int keylen);
static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd);

static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd);
static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd);

static int atmel_sha_hmac_setup(struct atmel_sha_dev *dd,
				atmel_sha_fn_t resume)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	unsigned int keylen;
	const u8 *key;
	size_t bs;

	hmac->resume = resume;
	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	case SHA_FLAGS_SHA1:
		ctx->block_size = SHA1_BLOCK_SIZE;
		ctx->hash_size = SHA1_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA224:
		ctx->block_size = SHA224_BLOCK_SIZE;
		ctx->hash_size = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA256:
		ctx->block_size = SHA256_BLOCK_SIZE;
		ctx->hash_size = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA384:
		ctx->block_size = SHA384_BLOCK_SIZE;
		ctx->hash_size = SHA512_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA512:
		ctx->block_size = SHA512_BLOCK_SIZE;
		ctx->hash_size = SHA512_DIGEST_SIZE;
		break;

	default:
		return atmel_sha_complete(dd, -EINVAL);
	}
	bs = ctx->block_size;

	if (likely(!atmel_sha_hmac_key_get(&hmac->hkey, &key, &keylen)))
		return resume(dd);

	/* Compute K' from K. */
	if (unlikely(keylen > bs))
		return atmel_sha_hmac_prehash_key(dd, key, keylen);

	/* Prepare ipad. */
	memcpy((u8 *)hmac->ipad, key, keylen);
	memset((u8 *)hmac->ipad + keylen, 0, bs - keylen);
	return atmel_sha_hmac_compute_ipad_hash(dd);
}

static int atmel_sha_hmac_prehash_key(struct atmel_sha_dev *dd,
				      const u8 *key, unsigned int keylen)
{
	return atmel_sha_cpu_hash(dd, key, keylen, true,
				  atmel_sha_hmac_prehash_key_done);
}

static int atmel_sha_hmac_prehash_key_done(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	size_t ds = crypto_ahash_digestsize(tfm);
	size_t bs = ctx->block_size;
	size_t i, num_words = ds / sizeof(u32);

	/* Prepare ipad. */
	for (i = 0; i < num_words; ++i)
		hmac->ipad[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));
	memset((u8 *)hmac->ipad + ds, 0, bs - ds);
	return atmel_sha_hmac_compute_ipad_hash(dd);
}

static int atmel_sha_hmac_compute_ipad_hash(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	size_t bs = ctx->block_size;
	size_t i, num_words = bs / sizeof(u32);

	memcpy(hmac->opad, hmac->ipad, bs);
	for (i = 0; i < num_words; ++i) {
		hmac->ipad[i] ^= 0x36363636;
		hmac->opad[i] ^= 0x5c5c5c5c;
	}

	return atmel_sha_cpu_hash(dd, hmac->ipad, bs, false,
				  atmel_sha_hmac_compute_opad_hash);
}

static int atmel_sha_hmac_compute_opad_hash(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	size_t bs = ctx->block_size;
	size_t hs = ctx->hash_size;
	size_t i, num_words = hs / sizeof(u32);

	for (i = 0; i < num_words; ++i)
		hmac->ipad[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));
	return atmel_sha_cpu_hash(dd, hmac->opad, bs, false,
				  atmel_sha_hmac_setup_done);
}

static int atmel_sha_hmac_setup_done(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	size_t hs = ctx->hash_size;
	size_t i, num_words = hs / sizeof(u32);

	for (i = 0; i < num_words; ++i)
		hmac->opad[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));
	atmel_sha_hmac_key_release(&hmac->hkey);
	return hmac->resume(dd);
}

static int atmel_sha_hmac_start(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	int err;

	err = atmel_sha_hw_init(dd);
	if (err)
		return atmel_sha_complete(dd, err);

	switch (ctx->op) {
	case SHA_OP_INIT:
		err = atmel_sha_hmac_setup(dd, atmel_sha_hmac_init_done);
		break;

	case SHA_OP_UPDATE:
		dd->resume = atmel_sha_done;
		err = atmel_sha_update_req(dd);
		break;

	case SHA_OP_FINAL:
		dd->resume = atmel_sha_hmac_final;
		err = atmel_sha_final_req(dd);
		break;

	case SHA_OP_DIGEST:
		err = atmel_sha_hmac_setup(dd, atmel_sha_hmac_digest2);
		break;

	default:
		return atmel_sha_complete(dd, -EINVAL);
	}

	return err;
}

static int atmel_sha_hmac_setkey(struct crypto_ahash *tfm, const u8 *key,
				 unsigned int keylen)
{
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);

	return atmel_sha_hmac_key_set(&hmac->hkey, key, keylen);
}

static int atmel_sha_hmac_init(struct ahash_request *req)
{
	int err;

	err = atmel_sha_init(req);
	if (err)
		return err;

	return atmel_sha_enqueue(req, SHA_OP_INIT);
}

static int atmel_sha_hmac_init_done(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	size_t bs = ctx->block_size;
	size_t hs = ctx->hash_size;

	ctx->bufcnt = 0;
	ctx->digcnt[0] = bs;
	ctx->digcnt[1] = 0;
	ctx->flags |= SHA_FLAGS_RESTORE;
	memcpy(ctx->digest, hmac->ipad, hs);
	return atmel_sha_complete(dd, 0);
}

static int atmel_sha_hmac_final(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	u32 *digest = (u32 *)ctx->digest;
	size_t ds = crypto_ahash_digestsize(tfm);
	size_t bs = ctx->block_size;
	size_t hs = ctx->hash_size;
	size_t i, num_words;
	u32 mr;

	/* Save d = SHA((K' + ipad) | msg). */
	num_words = ds / sizeof(u32);
	for (i = 0; i < num_words; ++i)
		digest[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));

	/* Restore context to finish computing SHA((K' + opad) | d). */
	atmel_sha_write(dd, SHA_CR, SHA_CR_WUIHV);
	num_words = hs / sizeof(u32);
	for (i = 0; i < num_words; ++i)
		atmel_sha_write(dd, SHA_REG_DIN(i), hmac->opad[i]);

	mr = SHA_MR_MODE_AUTO | SHA_MR_UIHV;
	mr |= (ctx->flags & SHA_FLAGS_ALGO_MASK);
	atmel_sha_write(dd, SHA_MR, mr);
	atmel_sha_write(dd, SHA_MSR, bs + ds);
	atmel_sha_write(dd, SHA_BCR, ds);
	atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);

	sg_init_one(&dd->tmp, digest, ds);
	return atmel_sha_cpu_start(dd, &dd->tmp, ds, false, true,
				   atmel_sha_hmac_final_done);
}

static int atmel_sha_hmac_final_done(struct atmel_sha_dev *dd)
{
	/*
	 * req->result might not be sizeof(u32) aligned, so copy the
	 * digest into ctx->digest[] before memcpy() the data into
	 * req->result.
	 */
	atmel_sha_copy_hash(dd->req);
	atmel_sha_copy_ready_hash(dd->req);
	return atmel_sha_complete(dd, 0);
}

static int atmel_sha_hmac_digest(struct ahash_request *req)
{
	int err;

	err = atmel_sha_init(req);
	if (err)
		return err;

	return atmel_sha_enqueue(req, SHA_OP_DIGEST);
}

static int atmel_sha_hmac_digest2(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_reqctx *ctx = ahash_request_ctx(req);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	size_t hs = ctx->hash_size;
	size_t i, num_words = hs / sizeof(u32);
	bool use_dma = false;
	u32 mr;

	/* Special case for empty message. */
	if (!req->nbytes)
		return atmel_sha_complete(dd, -EINVAL); // TODO:

	/* Check DMA threshold and alignment. */
	if (req->nbytes > ATMEL_SHA_DMA_THRESHOLD &&
	    atmel_sha_dma_check_aligned(dd, req->src, req->nbytes))
		use_dma = true;

	/* Write both initial hash values to compute a HMAC. */
	atmel_sha_write(dd, SHA_CR, SHA_CR_WUIHV);
	for (i = 0; i < num_words; ++i)
		atmel_sha_write(dd, SHA_REG_DIN(i), hmac->ipad[i]);

	atmel_sha_write(dd, SHA_CR, SHA_CR_WUIEHV);
	for (i = 0; i < num_words; ++i)
		atmel_sha_write(dd, SHA_REG_DIN(i), hmac->opad[i]);

	/* Write the Mode, Message Size, Bytes Count then Control Registers. */
	mr = (SHA_MR_HMAC | SHA_MR_DUALBUFF);
	mr |= ctx->flags & SHA_FLAGS_ALGO_MASK;
	if (use_dma)
		mr |= SHA_MR_MODE_IDATAR0;
	else
		mr |= SHA_MR_MODE_AUTO;
	atmel_sha_write(dd, SHA_MR, mr);

	atmel_sha_write(dd, SHA_MSR, req->nbytes);
	atmel_sha_write(dd, SHA_BCR, req->nbytes);

	atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);

	/* Process data. */
	if (use_dma)
		return atmel_sha_dma_start(dd, req->src, req->nbytes,
					   atmel_sha_hmac_final_done);

	return atmel_sha_cpu_start(dd, req->src, req->nbytes, false, true,
				   atmel_sha_hmac_final_done);
}

static int atmel_sha_hmac_cra_init(struct crypto_tfm *tfm)
{
	struct atmel_sha_hmac_ctx *hmac = crypto_tfm_ctx(tfm);

	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
				 sizeof(struct atmel_sha_reqctx));
	hmac->base.start = atmel_sha_hmac_start;
	atmel_sha_hmac_key_init(&hmac->hkey);

	return 0;
}

static void atmel_sha_hmac_cra_exit(struct crypto_tfm *tfm)
{
	struct atmel_sha_hmac_ctx *hmac = crypto_tfm_ctx(tfm);

	atmel_sha_hmac_key_release(&hmac->hkey);
}

static struct ahash_alg sha_hmac_algs[] = {
{
	.init		= atmel_sha_hmac_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.digest		= atmel_sha_hmac_digest,
	.setkey		= atmel_sha_hmac_setkey,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA1_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "hmac(sha1)",
			.cra_driver_name	= "atmel-hmac-sha1",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA1_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_hmac_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_hmac_cra_init,
			.cra_exit		= atmel_sha_hmac_cra_exit,
		}
	}
},
{
	.init		= atmel_sha_hmac_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.digest		= atmel_sha_hmac_digest,
	.setkey		= atmel_sha_hmac_setkey,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA224_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "hmac(sha224)",
			.cra_driver_name	= "atmel-hmac-sha224",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA224_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_hmac_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_hmac_cra_init,
			.cra_exit		= atmel_sha_hmac_cra_exit,
		}
	}
},
{
	.init		= atmel_sha_hmac_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.digest		= atmel_sha_hmac_digest,
	.setkey		= atmel_sha_hmac_setkey,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA256_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "hmac(sha256)",
			.cra_driver_name	= "atmel-hmac-sha256",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA256_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_hmac_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_hmac_cra_init,
			.cra_exit		= atmel_sha_hmac_cra_exit,
		}
	}
},
{
	.init		= atmel_sha_hmac_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.digest		= atmel_sha_hmac_digest,
	.setkey		= atmel_sha_hmac_setkey,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA384_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "hmac(sha384)",
			.cra_driver_name	= "atmel-hmac-sha384",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA384_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_hmac_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_hmac_cra_init,
			.cra_exit		= atmel_sha_hmac_cra_exit,
		}
	}
},
{
	.init		= atmel_sha_hmac_init,
	.update		= atmel_sha_update,
	.final		= atmel_sha_final,
	.digest		= atmel_sha_hmac_digest,
	.setkey		= atmel_sha_hmac_setkey,
	.export		= atmel_sha_export,
	.import		= atmel_sha_import,
	.halg = {
		.digestsize	= SHA512_DIGEST_SIZE,
		.statesize	= sizeof(struct atmel_sha_reqctx),
		.base	= {
			.cra_name		= "hmac(sha512)",
			.cra_driver_name	= "atmel-hmac-sha512",
			.cra_priority		= 100,
			.cra_flags		= CRYPTO_ALG_ASYNC,
			.cra_blocksize		= SHA512_BLOCK_SIZE,
			.cra_ctxsize		= sizeof(struct atmel_sha_hmac_ctx),
			.cra_alignmask		= 0,
			.cra_module		= THIS_MODULE,
			.cra_init		= atmel_sha_hmac_cra_init,
			.cra_exit		= atmel_sha_hmac_cra_exit,
		}
	}
},
};

#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC)
/* authenc functions */

static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd);
static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd);


struct atmel_sha_authenc_ctx {
	struct crypto_ahash	*tfm;
};

struct atmel_sha_authenc_reqctx {
	struct atmel_sha_reqctx	base;

	atmel_aes_authenc_fn_t	cb;
	struct atmel_aes_dev	*aes_dev;

	/* _init() parameters. */
	struct scatterlist	*assoc;
	u32			assoclen;
	u32			textlen;

	/* _final() parameters. */
	u32			*digest;
	unsigned int		digestlen;
};

static void atmel_sha_authenc_complete(struct crypto_async_request *areq,
				       int err)
{
	struct ahash_request *req = areq->data;
	struct atmel_sha_authenc_reqctx *authctx  = ahash_request_ctx(req);

	authctx->cb(authctx->aes_dev, err, authctx->base.dd->is_async);
}

static int atmel_sha_authenc_start(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	int err;

	/*
	 * Force atmel_sha_complete() to call req->base.complete(), ie
	 * atmel_sha_authenc_complete(), which in turn calls authctx->cb().
	 */
	dd->force_complete = true;

	err = atmel_sha_hw_init(dd);
	return authctx->cb(authctx->aes_dev, err, dd->is_async);
}

bool atmel_sha_authenc_is_ready(void)
{
	struct atmel_sha_ctx dummy;

	dummy.dd = NULL;
	return (atmel_sha_find_dev(&dummy) != NULL);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_is_ready);

unsigned int atmel_sha_authenc_get_reqsize(void)
{
	return sizeof(struct atmel_sha_authenc_reqctx);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_get_reqsize);

struct atmel_sha_authenc_ctx *atmel_sha_authenc_spawn(unsigned long mode)
{
	struct atmel_sha_authenc_ctx *auth;
	struct crypto_ahash *tfm;
	struct atmel_sha_ctx *tctx;
	const char *name;
	int err = -EINVAL;

	switch (mode & SHA_FLAGS_MODE_MASK) {
	case SHA_FLAGS_HMAC_SHA1:
		name = "atmel-hmac-sha1";
		break;

	case SHA_FLAGS_HMAC_SHA224:
		name = "atmel-hmac-sha224";
		break;

	case SHA_FLAGS_HMAC_SHA256:
		name = "atmel-hmac-sha256";
		break;

	case SHA_FLAGS_HMAC_SHA384:
		name = "atmel-hmac-sha384";
		break;

	case SHA_FLAGS_HMAC_SHA512:
		name = "atmel-hmac-sha512";
		break;

	default:
		goto error;
	}

	tfm = crypto_alloc_ahash(name, 0, 0);
	if (IS_ERR(tfm)) {
		err = PTR_ERR(tfm);
		goto error;
	}
	tctx = crypto_ahash_ctx(tfm);
	tctx->start = atmel_sha_authenc_start;
	tctx->flags = mode;

	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
	if (!auth) {
		err = -ENOMEM;
		goto err_free_ahash;
	}
	auth->tfm = tfm;

	return auth;

err_free_ahash:
	crypto_free_ahash(tfm);
error:
	return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_spawn);

void atmel_sha_authenc_free(struct atmel_sha_authenc_ctx *auth)
{
	if (auth)
		crypto_free_ahash(auth->tfm);
	kfree(auth);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_free);

int atmel_sha_authenc_setkey(struct atmel_sha_authenc_ctx *auth,
			     const u8 *key, unsigned int keylen,
			     u32 *flags)
{
	struct crypto_ahash *tfm = auth->tfm;
	int err;

	crypto_ahash_clear_flags(tfm, CRYPTO_TFM_REQ_MASK);
	crypto_ahash_set_flags(tfm, *flags & CRYPTO_TFM_REQ_MASK);
	err = crypto_ahash_setkey(tfm, key, keylen);
	*flags = crypto_ahash_get_flags(tfm);

	return err;
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_setkey);

int atmel_sha_authenc_schedule(struct ahash_request *req,
			       struct atmel_sha_authenc_ctx *auth,
			       atmel_aes_authenc_fn_t cb,
			       struct atmel_aes_dev *aes_dev)
{
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	struct atmel_sha_reqctx *ctx = &authctx->base;
	struct crypto_ahash *tfm = auth->tfm;
	struct atmel_sha_ctx *tctx = crypto_ahash_ctx(tfm);
	struct atmel_sha_dev *dd;

	/* Reset request context (MUST be done first). */
	memset(authctx, 0, sizeof(*authctx));

	/* Get SHA device. */
	dd = atmel_sha_find_dev(tctx);
	if (!dd)
		return cb(aes_dev, -ENODEV, false);

	/* Init request context. */
	ctx->dd = dd;
	ctx->buflen = SHA_BUFFER_LEN;
	authctx->cb = cb;
	authctx->aes_dev = aes_dev;
	ahash_request_set_tfm(req, tfm);
	ahash_request_set_callback(req, 0, atmel_sha_authenc_complete, req);

	return atmel_sha_handle_queue(dd, req);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_schedule);

int atmel_sha_authenc_init(struct ahash_request *req,
			   struct scatterlist *assoc, unsigned int assoclen,
			   unsigned int textlen,
			   atmel_aes_authenc_fn_t cb,
			   struct atmel_aes_dev *aes_dev)
{
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	struct atmel_sha_reqctx *ctx = &authctx->base;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	struct atmel_sha_dev *dd = ctx->dd;

	if (unlikely(!IS_ALIGNED(assoclen, sizeof(u32))))
		return atmel_sha_complete(dd, -EINVAL);

	authctx->cb = cb;
	authctx->aes_dev = aes_dev;
	authctx->assoc = assoc;
	authctx->assoclen = assoclen;
	authctx->textlen = textlen;

	ctx->flags = hmac->base.flags;
	return atmel_sha_hmac_setup(dd, atmel_sha_authenc_init2);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_init);

static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	struct atmel_sha_reqctx *ctx = &authctx->base;
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm);
	size_t hs = ctx->hash_size;
	size_t i, num_words = hs / sizeof(u32);
	u32 mr, msg_size;

	atmel_sha_write(dd, SHA_CR, SHA_CR_WUIHV);
	for (i = 0; i < num_words; ++i)
		atmel_sha_write(dd, SHA_REG_DIN(i), hmac->ipad[i]);

	atmel_sha_write(dd, SHA_CR, SHA_CR_WUIEHV);
	for (i = 0; i < num_words; ++i)
		atmel_sha_write(dd, SHA_REG_DIN(i), hmac->opad[i]);

	mr = (SHA_MR_MODE_IDATAR0 |
	      SHA_MR_HMAC |
	      SHA_MR_DUALBUFF);
	mr |= ctx->flags & SHA_FLAGS_ALGO_MASK;
	atmel_sha_write(dd, SHA_MR, mr);

	msg_size = authctx->assoclen + authctx->textlen;
	atmel_sha_write(dd, SHA_MSR, msg_size);
	atmel_sha_write(dd, SHA_BCR, msg_size);

	atmel_sha_write(dd, SHA_CR, SHA_CR_FIRST);

	/* Process assoc data. */
	return atmel_sha_cpu_start(dd, authctx->assoc, authctx->assoclen,
				   true, false,
				   atmel_sha_authenc_init_done);
}

static int atmel_sha_authenc_init_done(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);

	return authctx->cb(authctx->aes_dev, 0, dd->is_async);
}

int atmel_sha_authenc_final(struct ahash_request *req,
			    u32 *digest, unsigned int digestlen,
			    atmel_aes_authenc_fn_t cb,
			    struct atmel_aes_dev *aes_dev)
{
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	struct atmel_sha_reqctx *ctx = &authctx->base;
	struct atmel_sha_dev *dd = ctx->dd;

	switch (ctx->flags & SHA_FLAGS_ALGO_MASK) {
	case SHA_FLAGS_SHA1:
		authctx->digestlen = SHA1_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA224:
		authctx->digestlen = SHA224_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA256:
		authctx->digestlen = SHA256_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA384:
		authctx->digestlen = SHA384_DIGEST_SIZE;
		break;

	case SHA_FLAGS_SHA512:
		authctx->digestlen = SHA512_DIGEST_SIZE;
		break;

	default:
		return atmel_sha_complete(dd, -EINVAL);
	}
	if (authctx->digestlen > digestlen)
		authctx->digestlen = digestlen;

	authctx->cb = cb;
	authctx->aes_dev = aes_dev;
	authctx->digest = digest;
	return atmel_sha_wait_for_data_ready(dd,
					     atmel_sha_authenc_final_done);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_final);

static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd)
{
	struct ahash_request *req = dd->req;
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	size_t i, num_words = authctx->digestlen / sizeof(u32);

	for (i = 0; i < num_words; ++i)
		authctx->digest[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i));

	return atmel_sha_complete(dd, 0);
}

void atmel_sha_authenc_abort(struct ahash_request *req)
{
	struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req);
	struct atmel_sha_reqctx *ctx = &authctx->base;
	struct atmel_sha_dev *dd = ctx->dd;

	/* Prevent atmel_sha_complete() from calling req->base.complete(). */
	dd->is_async = false;
	dd->force_complete = false;
	(void)atmel_sha_complete(dd, 0);
}
EXPORT_SYMBOL_GPL(atmel_sha_authenc_abort);

#endif /* CONFIG_CRYPTO_DEV_ATMEL_AUTHENC */


static void atmel_sha_unregister_algs(struct atmel_sha_dev *dd)
{
	int i;

	if (dd->caps.has_hmac)
		for (i = 0; i < ARRAY_SIZE(sha_hmac_algs); i++)
			crypto_unregister_ahash(&sha_hmac_algs[i]);

	for (i = 0; i < ARRAY_SIZE(sha_1_256_algs); i++)
		crypto_unregister_ahash(&sha_1_256_algs[i]);

	if (dd->caps.has_sha224)
		crypto_unregister_ahash(&sha_224_alg);

	if (dd->caps.has_sha_384_512) {
		for (i = 0; i < ARRAY_SIZE(sha_384_512_algs); i++)
			crypto_unregister_ahash(&sha_384_512_algs[i]);
	}
}

static int atmel_sha_register_algs(struct atmel_sha_dev *dd)
{
	int err, i, j;

	for (i = 0; i < ARRAY_SIZE(sha_1_256_algs); i++) {
		err = crypto_register_ahash(&sha_1_256_algs[i]);
		if (err)
			goto err_sha_1_256_algs;
	}

	if (dd->caps.has_sha224) {
		err = crypto_register_ahash(&sha_224_alg);
		if (err)
			goto err_sha_224_algs;
	}

	if (dd->caps.has_sha_384_512) {
		for (i = 0; i < ARRAY_SIZE(sha_384_512_algs); i++) {
			err = crypto_register_ahash(&sha_384_512_algs[i]);
			if (err)
				goto err_sha_384_512_algs;
		}
	}

	if (dd->caps.has_hmac) {
		for (i = 0; i < ARRAY_SIZE(sha_hmac_algs); i++) {
			err = crypto_register_ahash(&sha_hmac_algs[i]);
			if (err)
				goto err_sha_hmac_algs;
		}
	}

	return 0;

	/*i = ARRAY_SIZE(sha_hmac_algs);*/
err_sha_hmac_algs:
	for (j = 0; j < i; j++)
		crypto_unregister_ahash(&sha_hmac_algs[j]);
	i = ARRAY_SIZE(sha_384_512_algs);
err_sha_384_512_algs:
	for (j = 0; j < i; j++)
		crypto_unregister_ahash(&sha_384_512_algs[j]);
	crypto_unregister_ahash(&sha_224_alg);
err_sha_224_algs:
	i = ARRAY_SIZE(sha_1_256_algs);
err_sha_1_256_algs:
	for (j = 0; j < i; j++)
		crypto_unregister_ahash(&sha_1_256_algs[j]);

	return err;
}

static bool atmel_sha_filter(struct dma_chan *chan, void *slave)
{
	struct at_dma_slave	*sl = slave;

	if (sl && sl->dma_dev == chan->device->dev) {
		chan->private = sl;
		return true;
	} else {
		return false;
	}
}

static int atmel_sha_dma_init(struct atmel_sha_dev *dd,
				struct crypto_platform_data *pdata)
{
	dma_cap_mask_t mask_in;

	/* Try to grab DMA channel */
	dma_cap_zero(mask_in);
	dma_cap_set(DMA_SLAVE, mask_in);

	dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask_in,
			atmel_sha_filter, &pdata->dma_slave->rxdata, dd->dev, "tx");
	if (!dd->dma_lch_in.chan) {
		dev_warn(dd->dev, "no DMA channel available\n");
		return -ENODEV;
	}

	dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV;
	dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base +
		SHA_REG_DIN(0);
	dd->dma_lch_in.dma_conf.src_maxburst = 1;
	dd->dma_lch_in.dma_conf.src_addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;
	dd->dma_lch_in.dma_conf.dst_maxburst = 1;
	dd->dma_lch_in.dma_conf.dst_addr_width =
		DMA_SLAVE_BUSWIDTH_4_BYTES;
	dd->dma_lch_in.dma_conf.device_fc = false;

	return 0;
}

static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd)
{
	dma_release_channel(dd->dma_lch_in.chan);
}

static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
{

	dd->caps.has_dma = 0;
	dd->caps.has_dualbuff = 0;
	dd->caps.has_sha224 = 0;
	dd->caps.has_sha_384_512 = 0;
	dd->caps.has_uihv = 0;
	dd->caps.has_hmac = 0;

	/* keep only major version number */
	switch (dd->hw_version & 0xff0) {
	case 0x510:
		dd->caps.has_dma = 1;
		dd->caps.has_dualbuff = 1;
		dd->caps.has_sha224 = 1;
		dd->caps.has_sha_384_512 = 1;
		dd->caps.has_uihv = 1;
		dd->caps.has_hmac = 1;
		break;
	case 0x420:
		dd->caps.has_dma = 1;
		dd->caps.has_dualbuff = 1;
		dd->caps.has_sha224 = 1;
		dd->caps.has_sha_384_512 = 1;
		dd->caps.has_uihv = 1;
		break;
	case 0x410:
		dd->caps.has_dma = 1;
		dd->caps.has_dualbuff = 1;
		dd->caps.has_sha224 = 1;
		dd->caps.has_sha_384_512 = 1;
		break;
	case 0x400:
		dd->caps.has_dma = 1;
		dd->caps.has_dualbuff = 1;
		dd->caps.has_sha224 = 1;
		break;
	case 0x320:
		break;
	default:
		dev_warn(dd->dev,
				"Unmanaged sha version, set minimum capabilities\n");
		break;
	}
}

#if defined(CONFIG_OF)
static const struct of_device_id atmel_sha_dt_ids[] = {
	{ .compatible = "atmel,at91sam9g46-sha" },
	{ /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids);

static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct crypto_platform_data *pdata;

	if (!np) {
		dev_err(&pdev->dev, "device node not found\n");
		return ERR_PTR(-EINVAL);
	}

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	pdata->dma_slave = devm_kzalloc(&pdev->dev,
					sizeof(*(pdata->dma_slave)),
					GFP_KERNEL);
	if (!pdata->dma_slave)
		return ERR_PTR(-ENOMEM);

	return pdata;
}
#else /* CONFIG_OF */
static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev)
{
	return ERR_PTR(-EINVAL);
}
#endif

static int atmel_sha_probe(struct platform_device *pdev)
{
	struct atmel_sha_dev *sha_dd;
	struct crypto_platform_data	*pdata;
	struct device *dev = &pdev->dev;
	struct resource *sha_res;
	int err;

	sha_dd = devm_kzalloc(&pdev->dev, sizeof(*sha_dd), GFP_KERNEL);
	if (sha_dd == NULL) {
		err = -ENOMEM;
		goto sha_dd_err;
	}

	sha_dd->dev = dev;

	platform_set_drvdata(pdev, sha_dd);

	INIT_LIST_HEAD(&sha_dd->list);
	spin_lock_init(&sha_dd->lock);

	tasklet_init(&sha_dd->done_task, atmel_sha_done_task,
					(unsigned long)sha_dd);
	tasklet_init(&sha_dd->queue_task, atmel_sha_queue_task,
					(unsigned long)sha_dd);

	crypto_init_queue(&sha_dd->queue, ATMEL_SHA_QUEUE_LENGTH);

	/* Get the base address */
	sha_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!sha_res) {
		dev_err(dev, "no MEM resource info\n");
		err = -ENODEV;
		goto res_err;
	}
	sha_dd->phys_base = sha_res->start;

	/* Get the IRQ */
	sha_dd->irq = platform_get_irq(pdev,  0);
	if (sha_dd->irq < 0) {
		dev_err(dev, "no IRQ resource info\n");
		err = sha_dd->irq;
		goto res_err;
	}

	err = devm_request_irq(&pdev->dev, sha_dd->irq, atmel_sha_irq,
			       IRQF_SHARED, "atmel-sha", sha_dd);
	if (err) {
		dev_err(dev, "unable to request sha irq.\n");
		goto res_err;
	}

	/* Initializing the clock */
	sha_dd->iclk = devm_clk_get(&pdev->dev, "sha_clk");
	if (IS_ERR(sha_dd->iclk)) {
		dev_err(dev, "clock initialization failed.\n");
		err = PTR_ERR(sha_dd->iclk);
		goto res_err;
	}

	sha_dd->io_base = devm_ioremap_resource(&pdev->dev, sha_res);
	if (IS_ERR(sha_dd->io_base)) {
		dev_err(dev, "can't ioremap\n");
		err = PTR_ERR(sha_dd->io_base);
		goto res_err;
	}

	err = clk_prepare(sha_dd->iclk);
	if (err)
		goto res_err;

	atmel_sha_hw_version_init(sha_dd);

	atmel_sha_get_cap(sha_dd);

	if (sha_dd->caps.has_dma) {
		pdata = pdev->dev.platform_data;
		if (!pdata) {
			pdata = atmel_sha_of_init(pdev);
			if (IS_ERR(pdata)) {
				dev_err(&pdev->dev, "platform data not available\n");
				err = PTR_ERR(pdata);
				goto iclk_unprepare;
			}
		}
		if (!pdata->dma_slave) {
			err = -ENXIO;
			goto iclk_unprepare;
		}
		err = atmel_sha_dma_init(sha_dd, pdata);
		if (err)
			goto err_sha_dma;

		dev_info(dev, "using %s for DMA transfers\n",
				dma_chan_name(sha_dd->dma_lch_in.chan));
	}

	spin_lock(&atmel_sha.lock);
	list_add_tail(&sha_dd->list, &atmel_sha.dev_list);
	spin_unlock(&atmel_sha.lock);

	err = atmel_sha_register_algs(sha_dd);
	if (err)
		goto err_algs;

	dev_info(dev, "Atmel SHA1/SHA256%s%s\n",
			sha_dd->caps.has_sha224 ? "/SHA224" : "",
			sha_dd->caps.has_sha_384_512 ? "/SHA384/SHA512" : "");

	return 0;

err_algs:
	spin_lock(&atmel_sha.lock);
	list_del(&sha_dd->list);
	spin_unlock(&atmel_sha.lock);
	if (sha_dd->caps.has_dma)
		atmel_sha_dma_cleanup(sha_dd);
err_sha_dma:
iclk_unprepare:
	clk_unprepare(sha_dd->iclk);
res_err:
	tasklet_kill(&sha_dd->queue_task);
	tasklet_kill(&sha_dd->done_task);
sha_dd_err:
	dev_err(dev, "initialization failed.\n");

	return err;
}

static int atmel_sha_remove(struct platform_device *pdev)
{
	struct atmel_sha_dev *sha_dd;

	sha_dd = platform_get_drvdata(pdev);
	if (!sha_dd)
		return -ENODEV;
	spin_lock(&atmel_sha.lock);
	list_del(&sha_dd->list);
	spin_unlock(&atmel_sha.lock);

	atmel_sha_unregister_algs(sha_dd);

	tasklet_kill(&sha_dd->queue_task);
	tasklet_kill(&sha_dd->done_task);

	if (sha_dd->caps.has_dma)
		atmel_sha_dma_cleanup(sha_dd);

	clk_unprepare(sha_dd->iclk);

	return 0;
}

static struct platform_driver atmel_sha_driver = {
	.probe		= atmel_sha_probe,
	.remove		= atmel_sha_remove,
	.driver		= {
		.name	= "atmel_sha",
		.of_match_table	= of_match_ptr(atmel_sha_dt_ids),
	},
};

module_platform_driver(atmel_sha_driver);

MODULE_DESCRIPTION("Atmel SHA (1/256/224/384/512) hw acceleration support.");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Nicolas Royer - Eukréa Electromatique");
