/*
 * Atmel MultiMedia Card Interface driver
 *
 * Copyright (C) 2004-2008 Atmel Corporation
 *
 * 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.
 */
#include <linux/blkdev.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/seq_file.h>
#include <linux/stat.h>

#include <linux/mmc/host.h>

#include <asm/atmel-mci.h>
#include <asm/io.h>
#include <asm/unaligned.h>

#include <asm/arch/board.h>
#include <asm/arch/gpio.h>

#include "atmel-mci-regs.h"

#define ATMCI_DATA_ERROR_FLAGS	(MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE)

enum {
	EVENT_CMD_COMPLETE = 0,
	EVENT_DATA_ERROR,
	EVENT_DATA_COMPLETE,
	EVENT_STOP_SENT,
	EVENT_STOP_COMPLETE,
	EVENT_XFER_COMPLETE,
};

struct atmel_mci {
	struct mmc_host		*mmc;
	void __iomem		*regs;

	struct scatterlist	*sg;
	unsigned int		pio_offset;

	struct mmc_request	*mrq;
	struct mmc_command	*cmd;
	struct mmc_data		*data;

	u32			cmd_status;
	u32			data_status;
	u32			stop_status;
	u32			stop_cmdr;

	u32			mode_reg;
	u32			sdc_reg;

	struct tasklet_struct	tasklet;
	unsigned long		pending_events;
	unsigned long		completed_events;

	int			present;
	int			detect_pin;
	int			wp_pin;

	/* For detect pin debouncing */
	struct timer_list	detect_timer;

	unsigned long		bus_hz;
	unsigned long		mapbase;
	struct clk		*mck;
	struct platform_device	*pdev;
};

#define atmci_is_completed(host, event)				\
	test_bit(event, &host->completed_events)
#define atmci_test_and_clear_pending(host, event)		\
	test_and_clear_bit(event, &host->pending_events)
#define atmci_test_and_set_completed(host, event)		\
	test_and_set_bit(event, &host->completed_events)
#define atmci_set_completed(host, event)			\
	set_bit(event, &host->completed_events)
#define atmci_set_pending(host, event)				\
	set_bit(event, &host->pending_events)
#define atmci_clear_pending(host, event)			\
	clear_bit(event, &host->pending_events)

/*
 * The debugfs stuff below is mostly optimized away when
 * CONFIG_DEBUG_FS is not set.
 */
static int atmci_req_show(struct seq_file *s, void *v)
{
	struct atmel_mci	*host = s->private;
	struct mmc_request	*mrq = host->mrq;
	struct mmc_command	*cmd;
	struct mmc_command	*stop;
	struct mmc_data		*data;

	/* Make sure we get a consistent snapshot */
	spin_lock_irq(&host->mmc->lock);

	if (mrq) {
		cmd = mrq->cmd;
		data = mrq->data;
		stop = mrq->stop;

		if (cmd)
			seq_printf(s,
				"CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
				cmd->opcode, cmd->arg, cmd->flags,
				cmd->resp[0], cmd->resp[1], cmd->resp[2],
				cmd->resp[2], cmd->error);
		if (data)
			seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
				data->bytes_xfered, data->blocks,
				data->blksz, data->flags, data->error);
		if (stop)
			seq_printf(s,
				"CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
				stop->opcode, stop->arg, stop->flags,
				stop->resp[0], stop->resp[1], stop->resp[2],
				stop->resp[2], stop->error);
	}

	spin_unlock_irq(&host->mmc->lock);

	return 0;
}

static int atmci_req_open(struct inode *inode, struct file *file)
{
	return single_open(file, atmci_req_show, inode->i_private);
}

static const struct file_operations atmci_req_fops = {
	.owner		= THIS_MODULE,
	.open		= atmci_req_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void atmci_show_status_reg(struct seq_file *s,
		const char *regname, u32 value)
{
	static const char	*sr_bit[] = {
		[0]	= "CMDRDY",
		[1]	= "RXRDY",
		[2]	= "TXRDY",
		[3]	= "BLKE",
		[4]	= "DTIP",
		[5]	= "NOTBUSY",
		[8]	= "SDIOIRQA",
		[9]	= "SDIOIRQB",
		[16]	= "RINDE",
		[17]	= "RDIRE",
		[18]	= "RCRCE",
		[19]	= "RENDE",
		[20]	= "RTOE",
		[21]	= "DCRCE",
		[22]	= "DTOE",
		[30]	= "OVRE",
		[31]	= "UNRE",
	};
	unsigned int		i;

	seq_printf(s, "%s:\t0x%08x", regname, value);
	for (i = 0; i < ARRAY_SIZE(sr_bit); i++) {
		if (value & (1 << i)) {
			if (sr_bit[i])
				seq_printf(s, " %s", sr_bit[i]);
			else
				seq_puts(s, " UNKNOWN");
		}
	}
	seq_putc(s, '\n');
}

static int atmci_regs_show(struct seq_file *s, void *v)
{
	struct atmel_mci	*host = s->private;
	u32			*buf;

	buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* Grab a more or less consistent snapshot */
	spin_lock_irq(&host->mmc->lock);
	memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
	spin_unlock_irq(&host->mmc->lock);

	seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
			buf[MCI_MR / 4],
			buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "",
			buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "",
			buf[MCI_MR / 4] & 0xff);
	seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]);
	seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]);
	seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]);
	seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n",
			buf[MCI_BLKR / 4],
			buf[MCI_BLKR / 4] & 0xffff,
			(buf[MCI_BLKR / 4] >> 16) & 0xffff);

	/* Don't read RSPR and RDR; it will consume the data there */

	atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
	atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);

	return 0;
}

static int atmci_regs_open(struct inode *inode, struct file *file)
{
	return single_open(file, atmci_regs_show, inode->i_private);
}

static const struct file_operations atmci_regs_fops = {
	.owner		= THIS_MODULE,
	.open		= atmci_regs_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void atmci_init_debugfs(struct atmel_mci *host)
{
	struct mmc_host	*mmc;
	struct dentry	*root;
	struct dentry	*node;
	struct resource	*res;

	mmc = host->mmc;
	root = mmc->debugfs_root;
	if (!root)
		return;

	node = debugfs_create_file("regs", S_IRUSR, root, host,
			&atmci_regs_fops);
	if (IS_ERR(node))
		return;
	if (!node)
		goto err;

	res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
	node->d_inode->i_size = res->end - res->start + 1;

	node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops);
	if (!node)
		goto err;

	node = debugfs_create_x32("pending_events", S_IRUSR, root,
				     (u32 *)&host->pending_events);
	if (!node)
		goto err;

	node = debugfs_create_x32("completed_events", S_IRUSR, root,
				     (u32 *)&host->completed_events);
	if (!node)
		goto err;

	return;

err:
	dev_err(&host->pdev->dev,
		"failed to initialize debugfs for controller\n");
}

static void atmci_enable(struct atmel_mci *host)
{
	clk_enable(host->mck);
	mci_writel(host, CR, MCI_CR_MCIEN);
	mci_writel(host, MR, host->mode_reg);
	mci_writel(host, SDCR, host->sdc_reg);
}

static void atmci_disable(struct atmel_mci *host)
{
	mci_writel(host, CR, MCI_CR_SWRST);

	/* Stall until write is complete, then disable the bus clock */
	mci_readl(host, SR);
	clk_disable(host->mck);
}

static inline unsigned int ns_to_clocks(struct atmel_mci *host,
					unsigned int ns)
{
	return (ns * (host->bus_hz / 1000000) + 999) / 1000;
}

static void atmci_set_timeout(struct atmel_mci *host,
			      struct mmc_data *data)
{
	static unsigned	dtomul_to_shift[] = {
		0, 4, 7, 8, 10, 12, 16, 20
	};
	unsigned	timeout;
	unsigned	dtocyc;
	unsigned	dtomul;

	timeout = ns_to_clocks(host, data->timeout_ns) + data->timeout_clks;

	for (dtomul = 0; dtomul < 8; dtomul++) {
		unsigned shift = dtomul_to_shift[dtomul];
		dtocyc = (timeout + (1 << shift) - 1) >> shift;
		if (dtocyc < 15)
			break;
	}

	if (dtomul >= 8) {
		dtomul = 7;
		dtocyc = 15;
	}

	dev_vdbg(&host->mmc->class_dev, "setting timeout to %u cycles\n",
			dtocyc << dtomul_to_shift[dtomul]);
	mci_writel(host, DTOR, (MCI_DTOMUL(dtomul) | MCI_DTOCYC(dtocyc)));
}

/*
 * Return mask with command flags to be enabled for this command.
 */
static u32 atmci_prepare_command(struct mmc_host *mmc,
				 struct mmc_command *cmd)
{
	struct mmc_data	*data;
	u32		cmdr;

	cmd->error = -EINPROGRESS;

	cmdr = MCI_CMDR_CMDNB(cmd->opcode);

	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136)
			cmdr |= MCI_CMDR_RSPTYP_136BIT;
		else
			cmdr |= MCI_CMDR_RSPTYP_48BIT;
	}

	/*
	 * This should really be MAXLAT_5 for CMD2 and ACMD41, but
	 * it's too difficult to determine whether this is an ACMD or
	 * not. Better make it 64.
	 */
	cmdr |= MCI_CMDR_MAXLAT_64CYC;

	if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN)
		cmdr |= MCI_CMDR_OPDCMD;

	data = cmd->data;
	if (data) {
		cmdr |= MCI_CMDR_START_XFER;
		if (data->flags & MMC_DATA_STREAM)
			cmdr |= MCI_CMDR_STREAM;
		else if (data->blocks > 1)
			cmdr |= MCI_CMDR_MULTI_BLOCK;
		else
			cmdr |= MCI_CMDR_BLOCK;

		if (data->flags & MMC_DATA_READ)
			cmdr |= MCI_CMDR_TRDIR_READ;
	}

	return cmdr;
}

static void atmci_start_command(struct atmel_mci *host,
				struct mmc_command *cmd,
				u32 cmd_flags)
{
	/* Must read host->cmd after testing event flags */
	smp_rmb();
	WARN_ON(host->cmd);
	host->cmd = cmd;

	dev_vdbg(&host->mmc->class_dev,
			"start command: ARGR=0x%08x CMDR=0x%08x\n",
			cmd->arg, cmd_flags);

	mci_writel(host, ARGR, cmd->arg);
	mci_writel(host, CMDR, cmd_flags);
}

static void send_stop_cmd(struct mmc_host *mmc, struct mmc_data *data)
{
	struct atmel_mci *host = mmc_priv(mmc);

	atmci_start_command(host, data->stop, host->stop_cmdr);
	mci_writel(host, IER, MCI_CMDRDY);
}

static void atmci_request_end(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct atmel_mci *host = mmc_priv(mmc);

	WARN_ON(host->cmd || host->data);
	host->mrq = NULL;

	atmci_disable(host);

	mmc_request_done(mmc, mrq);
}

/*
 * Returns a mask of interrupt flags to be enabled after the whole
 * request has been prepared.
 */
static u32 atmci_submit_data(struct mmc_host *mmc, struct mmc_data *data)
{
	struct atmel_mci	*host = mmc_priv(mmc);
	u32			iflags;

	data->error = -EINPROGRESS;

	WARN_ON(host->data);
	host->sg = NULL;
	host->data = data;

	mci_writel(host, BLKR, MCI_BCNT(data->blocks)
			| MCI_BLKLEN(data->blksz));
	dev_vdbg(&mmc->class_dev, "BLKR=0x%08x\n",
			MCI_BCNT(data->blocks) | MCI_BLKLEN(data->blksz));

	iflags = ATMCI_DATA_ERROR_FLAGS;
	host->sg = data->sg;
	host->pio_offset = 0;
	if (data->flags & MMC_DATA_READ)
		iflags |= MCI_RXRDY;
	else
		iflags |= MCI_TXRDY;

	return iflags;
}

static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct atmel_mci	*host = mmc_priv(mmc);
	struct mmc_data		*data;
	struct mmc_command	*cmd;
	u32			iflags;
	u32			cmdflags = 0;

	iflags = mci_readl(host, IMR);
	if (iflags)
		dev_warn(&mmc->class_dev, "WARNING: IMR=0x%08x\n",
				mci_readl(host, IMR));

	WARN_ON(host->mrq != NULL);

	/*
	 * We may "know" the card is gone even though there's still an
	 * electrical connection. If so, we really need to communicate
	 * this to the MMC core since there won't be any more
	 * interrupts as the card is completely removed. Otherwise,
	 * the MMC core might believe the card is still there even
	 * though the card was just removed very slowly.
	 */
	if (!host->present) {
		mrq->cmd->error = -ENOMEDIUM;
		mmc_request_done(mmc, mrq);
		return;
	}

	host->mrq = mrq;
	host->pending_events = 0;
	host->completed_events = 0;

	atmci_enable(host);

	/* We don't support multiple blocks of weird lengths. */
	data = mrq->data;
	if (data) {
		if (data->blocks > 1 && data->blksz & 3)
			goto fail;
		atmci_set_timeout(host, data);
	}

	iflags = MCI_CMDRDY;
	cmd = mrq->cmd;
	cmdflags = atmci_prepare_command(mmc, cmd);
	atmci_start_command(host, cmd, cmdflags);

	if (data)
		iflags |= atmci_submit_data(mmc, data);

	if (mrq->stop) {
		host->stop_cmdr = atmci_prepare_command(mmc, mrq->stop);
		host->stop_cmdr |= MCI_CMDR_STOP_XFER;
		if (!(data->flags & MMC_DATA_WRITE))
			host->stop_cmdr |= MCI_CMDR_TRDIR_READ;
		if (data->flags & MMC_DATA_STREAM)
			host->stop_cmdr |= MCI_CMDR_STREAM;
		else
			host->stop_cmdr |= MCI_CMDR_MULTI_BLOCK;
	}

	/*
	 * We could have enabled interrupts earlier, but I suspect
	 * that would open up a nice can of interesting race
	 * conditions (e.g. command and data complete, but stop not
	 * prepared yet.)
	 */
	mci_writel(host, IER, iflags);

	return;

fail:
	atmci_disable(host);
	host->mrq = NULL;
	mrq->cmd->error = -EINVAL;
	mmc_request_done(mmc, mrq);
}

static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct atmel_mci	*host = mmc_priv(mmc);

	if (ios->clock) {
		u32 clkdiv;

		/* Set clock rate */
		clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1;
		if (clkdiv > 255) {
			dev_warn(&mmc->class_dev,
				"clock %u too slow; using %lu\n",
				ios->clock, host->bus_hz / (2 * 256));
			clkdiv = 255;
		}

		host->mode_reg = MCI_MR_CLKDIV(clkdiv) | MCI_MR_WRPROOF
					| MCI_MR_RDPROOF;
	}

	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_1:
		host->sdc_reg = 0;
		break;
	case MMC_BUS_WIDTH_4:
		host->sdc_reg = MCI_SDCBUS_4BIT;
		break;
	}

	switch (ios->power_mode) {
	case MMC_POWER_ON:
		/* Send init sequence (74 clock cycles) */
		atmci_enable(host);
		mci_writel(host, CMDR, MCI_CMDR_SPCMD_INIT);
		while (!(mci_readl(host, SR) & MCI_CMDRDY))
			cpu_relax();
		atmci_disable(host);
		break;
	default:
		/*
		 * TODO: None of the currently available AVR32-based
		 * boards allow MMC power to be turned off. Implement
		 * power control when this can be tested properly.
		 */
		break;
	}
}

static int atmci_get_ro(struct mmc_host *mmc)
{
	int			read_only = 0;
	struct atmel_mci	*host = mmc_priv(mmc);

	if (host->wp_pin >= 0) {
		read_only = gpio_get_value(host->wp_pin);
		dev_dbg(&mmc->class_dev, "card is %s\n",
				read_only ? "read-only" : "read-write");
	} else {
		dev_dbg(&mmc->class_dev,
			"no pin for checking read-only switch."
			" Assuming write-enable.\n");
	}

	return read_only;
}

static struct mmc_host_ops atmci_ops = {
	.request	= atmci_request,
	.set_ios	= atmci_set_ios,
	.get_ro		= atmci_get_ro,
};

static void atmci_command_complete(struct atmel_mci *host,
			struct mmc_command *cmd, u32 status)
{
	/* Read the response from the card (up to 16 bytes) */
	cmd->resp[0] = mci_readl(host, RSPR);
	cmd->resp[1] = mci_readl(host, RSPR);
	cmd->resp[2] = mci_readl(host, RSPR);
	cmd->resp[3] = mci_readl(host, RSPR);

	if (status & MCI_RTOE)
		cmd->error = -ETIMEDOUT;
	else if ((cmd->flags & MMC_RSP_CRC) && (status & MCI_RCRCE))
		cmd->error = -EILSEQ;
	else if (status & (MCI_RINDE | MCI_RDIRE | MCI_RENDE))
		cmd->error = -EIO;
	else
		cmd->error = 0;

	if (cmd->error) {
		dev_dbg(&host->mmc->class_dev,
			"command error: status=0x%08x\n", status);

		if (cmd->data) {
			host->data = NULL;
			mci_writel(host, IDR, MCI_NOTBUSY
					| MCI_TXRDY | MCI_RXRDY
					| ATMCI_DATA_ERROR_FLAGS);
		}
	}
}

static void atmci_detect_change(unsigned long data)
{
	struct atmel_mci *host = (struct atmel_mci *)data;
	struct mmc_request *mrq = host->mrq;
	int present;

	/*
	 * atmci_remove() sets detect_pin to -1 before freeing the
	 * interrupt. We must not re-enable the interrupt if it has
	 * been freed.
	 */
	smp_rmb();
	if (host->detect_pin < 0)
		return;

	enable_irq(gpio_to_irq(host->detect_pin));
	present = !gpio_get_value(host->detect_pin);

	dev_vdbg(&host->pdev->dev, "detect change: %d (was %d)\n",
			present, host->present);

	if (present != host->present) {
		dev_dbg(&host->mmc->class_dev, "card %s\n",
			present ? "inserted" : "removed");
		host->present = present;

		/* Reset controller if card is gone */
		if (!present) {
			mci_writel(host, CR, MCI_CR_SWRST);
			mci_writel(host, IDR, ~0UL);
			mci_writel(host, CR, MCI_CR_MCIEN);
		}

		/* Clean up queue if present */
		if (mrq) {
			/*
			 * Reset controller to terminate any ongoing
			 * commands or data transfers.
			 */
			mci_writel(host, CR, MCI_CR_SWRST);

			if (!atmci_is_completed(host, EVENT_CMD_COMPLETE))
				mrq->cmd->error = -ENOMEDIUM;

			if (mrq->data && !atmci_is_completed(host,
						EVENT_DATA_COMPLETE)) {
				host->data = NULL;
				mrq->data->error = -ENOMEDIUM;
			}
			if (mrq->stop && !atmci_is_completed(host,
						EVENT_STOP_COMPLETE))
				mrq->stop->error = -ENOMEDIUM;

			host->cmd = NULL;
			atmci_request_end(host->mmc, mrq);
		}

		mmc_detect_change(host->mmc, 0);
	}
}

static void atmci_tasklet_func(unsigned long priv)
{
	struct mmc_host		*mmc = (struct mmc_host *)priv;
	struct atmel_mci	*host = mmc_priv(mmc);
	struct mmc_request	*mrq = host->mrq;
	struct mmc_data		*data = host->data;

	dev_vdbg(&mmc->class_dev,
		"tasklet: pending/completed/mask %lx/%lx/%x\n",
		host->pending_events, host->completed_events,
		mci_readl(host, IMR));

	if (atmci_test_and_clear_pending(host, EVENT_CMD_COMPLETE)) {
		/*
		 * host->cmd must be set to NULL before the interrupt
		 * handler sees EVENT_CMD_COMPLETE
		 */
		host->cmd = NULL;
		smp_wmb();
		atmci_set_completed(host, EVENT_CMD_COMPLETE);
		atmci_command_complete(host, mrq->cmd, host->cmd_status);

		if (!mrq->cmd->error && mrq->stop
				&& atmci_is_completed(host, EVENT_XFER_COMPLETE)
				&& !atmci_test_and_set_completed(host,
					EVENT_STOP_SENT))
			send_stop_cmd(host->mmc, mrq->data);
	}
	if (atmci_test_and_clear_pending(host, EVENT_STOP_COMPLETE)) {
		/*
		 * host->cmd must be set to NULL before the interrupt
		 * handler sees EVENT_STOP_COMPLETE
		 */
		host->cmd = NULL;
		smp_wmb();
		atmci_set_completed(host, EVENT_STOP_COMPLETE);
		atmci_command_complete(host, mrq->stop, host->stop_status);
	}
	if (atmci_test_and_clear_pending(host, EVENT_DATA_ERROR)) {
		u32 status = host->data_status;

		dev_vdbg(&mmc->class_dev, "data error: status=%08x\n", status);

		atmci_set_completed(host, EVENT_DATA_ERROR);
		atmci_set_completed(host, EVENT_DATA_COMPLETE);

		if (status & MCI_DTOE) {
			dev_dbg(&mmc->class_dev,
					"data timeout error\n");
			data->error = -ETIMEDOUT;
		} else if (status & MCI_DCRCE) {
			dev_dbg(&mmc->class_dev, "data CRC error\n");
			data->error = -EILSEQ;
		} else {
			dev_dbg(&mmc->class_dev,
					"data FIFO error (status=%08x)\n",
					status);
			data->error = -EIO;
		}

		if (host->present && data->stop
				&& atmci_is_completed(host, EVENT_CMD_COMPLETE)
				&& !atmci_test_and_set_completed(
					host, EVENT_STOP_SENT))
			send_stop_cmd(host->mmc, data);

		host->data = NULL;
	}
	if (atmci_test_and_clear_pending(host, EVENT_DATA_COMPLETE)) {
		atmci_set_completed(host, EVENT_DATA_COMPLETE);

		if (!atmci_is_completed(host, EVENT_DATA_ERROR)) {
			data->bytes_xfered = data->blocks * data->blksz;
			data->error = 0;
		}

		host->data = NULL;
	}

	if (host->mrq && !host->cmd && !host->data)
		atmci_request_end(mmc, host->mrq);
}

static void atmci_read_data_pio(struct atmel_mci *host)
{
	struct scatterlist	*sg = host->sg;
	void			*buf = sg_virt(sg);
	unsigned int		offset = host->pio_offset;
	struct mmc_data		*data = host->data;
	u32			value;
	u32			status;
	unsigned int		nbytes = 0;

	do {
		value = mci_readl(host, RDR);
		if (likely(offset + 4 <= sg->length)) {
			put_unaligned(value, (u32 *)(buf + offset));

			offset += 4;
			nbytes += 4;

			if (offset == sg->length) {
				host->sg = sg = sg_next(sg);
				if (!sg)
					goto done;

				offset = 0;
				buf = sg_virt(sg);
			}
		} else {
			unsigned int remaining = sg->length - offset;
			memcpy(buf + offset, &value, remaining);
			nbytes += remaining;

			flush_dcache_page(sg_page(sg));
			host->sg = sg = sg_next(sg);
			if (!sg)
				goto done;

			offset = 4 - remaining;
			buf = sg_virt(sg);
			memcpy(buf, (u8 *)&value + remaining, offset);
			nbytes += offset;
		}

		status = mci_readl(host, SR);
		if (status & ATMCI_DATA_ERROR_FLAGS) {
			mci_writel(host, IDR, (MCI_NOTBUSY | MCI_RXRDY
						| ATMCI_DATA_ERROR_FLAGS));
			host->data_status = status;
			atmci_set_pending(host, EVENT_DATA_ERROR);
			tasklet_schedule(&host->tasklet);
			break;
		}
	} while (status & MCI_RXRDY);

	host->pio_offset = offset;
	data->bytes_xfered += nbytes;

	return;

done:
	mci_writel(host, IDR, MCI_RXRDY);
	mci_writel(host, IER, MCI_NOTBUSY);
	data->bytes_xfered += nbytes;
	atmci_set_completed(host, EVENT_XFER_COMPLETE);
	if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE)
			&& !atmci_test_and_set_completed(host, EVENT_STOP_SENT))
		send_stop_cmd(host->mmc, data);
}

static void atmci_write_data_pio(struct atmel_mci *host)
{
	struct scatterlist	*sg = host->sg;
	void			*buf = sg_virt(sg);
	unsigned int		offset = host->pio_offset;
	struct mmc_data		*data = host->data;
	u32			value;
	u32			status;
	unsigned int		nbytes = 0;

	do {
		if (likely(offset + 4 <= sg->length)) {
			value = get_unaligned((u32 *)(buf + offset));
			mci_writel(host, TDR, value);

			offset += 4;
			nbytes += 4;
			if (offset == sg->length) {
				host->sg = sg = sg_next(sg);
				if (!sg)
					goto done;

				offset = 0;
				buf = sg_virt(sg);
			}
		} else {
			unsigned int remaining = sg->length - offset;

			value = 0;
			memcpy(&value, buf + offset, remaining);
			nbytes += remaining;

			host->sg = sg = sg_next(sg);
			if (!sg) {
				mci_writel(host, TDR, value);
				goto done;
			}

			offset = 4 - remaining;
			buf = sg_virt(sg);
			memcpy((u8 *)&value + remaining, buf, offset);
			mci_writel(host, TDR, value);
			nbytes += offset;
		}

		status = mci_readl(host, SR);
		if (status & ATMCI_DATA_ERROR_FLAGS) {
			mci_writel(host, IDR, (MCI_NOTBUSY | MCI_TXRDY
						| ATMCI_DATA_ERROR_FLAGS));
			host->data_status = status;
			atmci_set_pending(host, EVENT_DATA_ERROR);
			tasklet_schedule(&host->tasklet);
			break;
		}
	} while (status & MCI_TXRDY);

	host->pio_offset = offset;
	data->bytes_xfered += nbytes;

	return;

done:
	mci_writel(host, IDR, MCI_TXRDY);
	mci_writel(host, IER, MCI_NOTBUSY);
	data->bytes_xfered += nbytes;
	atmci_set_completed(host, EVENT_XFER_COMPLETE);
	if (data->stop && atmci_is_completed(host, EVENT_CMD_COMPLETE)
			&& !atmci_test_and_set_completed(host, EVENT_STOP_SENT))
		send_stop_cmd(host->mmc, data);
}

static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status)
{
	struct atmel_mci	*host = mmc_priv(mmc);

	mci_writel(host, IDR, MCI_CMDRDY);

	if (atmci_is_completed(host, EVENT_STOP_SENT)) {
		host->stop_status = status;
		atmci_set_pending(host, EVENT_STOP_COMPLETE);
	} else {
		host->cmd_status = status;
		atmci_set_pending(host, EVENT_CMD_COMPLETE);
	}

	tasklet_schedule(&host->tasklet);
}

static irqreturn_t atmci_interrupt(int irq, void *dev_id)
{
	struct mmc_host		*mmc = dev_id;
	struct atmel_mci	*host = mmc_priv(mmc);
	u32			status, mask, pending;
	unsigned int		pass_count = 0;

	spin_lock(&mmc->lock);

	do {
		status = mci_readl(host, SR);
		mask = mci_readl(host, IMR);
		pending = status & mask;
		if (!pending)
			break;

		if (pending & ATMCI_DATA_ERROR_FLAGS) {
			mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS
					| MCI_RXRDY | MCI_TXRDY);
			pending &= mci_readl(host, IMR);
			host->data_status = status;
			atmci_set_pending(host, EVENT_DATA_ERROR);
			tasklet_schedule(&host->tasklet);
		}
		if (pending & MCI_NOTBUSY) {
			mci_writel(host, IDR, (MCI_NOTBUSY
					       | ATMCI_DATA_ERROR_FLAGS));
			atmci_set_pending(host, EVENT_DATA_COMPLETE);
			tasklet_schedule(&host->tasklet);
		}
		if (pending & MCI_RXRDY)
			atmci_read_data_pio(host);
		if (pending & MCI_TXRDY)
			atmci_write_data_pio(host);

		if (pending & MCI_CMDRDY)
			atmci_cmd_interrupt(mmc, status);
	} while (pass_count++ < 5);

	spin_unlock(&mmc->lock);

	return pass_count ? IRQ_HANDLED : IRQ_NONE;
}

static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id)
{
	struct mmc_host		*mmc = dev_id;
	struct atmel_mci	*host = mmc_priv(mmc);

	/*
	 * Disable interrupts until the pin has stabilized and check
	 * the state then. Use mod_timer() since we may be in the
	 * middle of the timer routine when this interrupt triggers.
	 */
	disable_irq_nosync(irq);
	mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(20));

	return IRQ_HANDLED;
}

static int __init atmci_probe(struct platform_device *pdev)
{
	struct mci_platform_data	*pdata;
	struct atmel_mci *host;
	struct mmc_host *mmc;
	struct resource *regs;
	int irq;
	int ret;

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs)
		return -ENXIO;
	pdata = pdev->dev.platform_data;
	if (!pdata)
		return -ENXIO;
	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev);
	if (!mmc)
		return -ENOMEM;

	host = mmc_priv(mmc);
	host->pdev = pdev;
	host->mmc = mmc;
	host->detect_pin = pdata->detect_pin;
	host->wp_pin = pdata->wp_pin;

	host->mck = clk_get(&pdev->dev, "mci_clk");
	if (IS_ERR(host->mck)) {
		ret = PTR_ERR(host->mck);
		goto err_clk_get;
	}

	ret = -ENOMEM;
	host->regs = ioremap(regs->start, regs->end - regs->start + 1);
	if (!host->regs)
		goto err_ioremap;

	clk_enable(host->mck);
	mci_writel(host, CR, MCI_CR_SWRST);
	host->bus_hz = clk_get_rate(host->mck);
	clk_disable(host->mck);

	host->mapbase = regs->start;

	mmc->ops = &atmci_ops;
	mmc->f_min = (host->bus_hz + 511) / 512;
	mmc->f_max = host->bus_hz / 2;
	mmc->ocr_avail	= MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps |= MMC_CAP_4_BIT_DATA;

	mmc->max_hw_segs = 64;
	mmc->max_phys_segs = 64;
	mmc->max_req_size = 32768 * 512;
	mmc->max_blk_size = 32768;
	mmc->max_blk_count = 512;

	tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)mmc);

	ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, mmc);
	if (ret)
		goto err_request_irq;

	/* Assume card is present if we don't have a detect pin */
	host->present = 1;
	if (host->detect_pin >= 0) {
		if (gpio_request(host->detect_pin, "mmc_detect")) {
			dev_dbg(&mmc->class_dev, "no detect pin available\n");
			host->detect_pin = -1;
		} else {
			host->present = !gpio_get_value(host->detect_pin);
		}
	}
	if (host->wp_pin >= 0) {
		if (gpio_request(host->wp_pin, "mmc_wp")) {
			dev_dbg(&mmc->class_dev, "no WP pin available\n");
			host->wp_pin = -1;
		}
	}

	platform_set_drvdata(pdev, host);

	mmc_add_host(mmc);

	if (host->detect_pin >= 0) {
		setup_timer(&host->detect_timer, atmci_detect_change,
				(unsigned long)host);

		ret = request_irq(gpio_to_irq(host->detect_pin),
				atmci_detect_interrupt,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
				"mmc-detect", mmc);
		if (ret) {
			dev_dbg(&mmc->class_dev,
				"could not request IRQ %d for detect pin\n",
				gpio_to_irq(host->detect_pin));
			gpio_free(host->detect_pin);
			host->detect_pin = -1;
		}
	}

	dev_info(&mmc->class_dev,
			"Atmel MCI controller at 0x%08lx irq %d\n",
			host->mapbase, irq);

	atmci_init_debugfs(host);

	return 0;

err_request_irq:
	iounmap(host->regs);
err_ioremap:
	clk_put(host->mck);
err_clk_get:
	mmc_free_host(mmc);
	return ret;
}

static int __exit atmci_remove(struct platform_device *pdev)
{
	struct atmel_mci *host = platform_get_drvdata(pdev);

	platform_set_drvdata(pdev, NULL);

	if (host) {
		/* Debugfs stuff is cleaned up by mmc core */

		if (host->detect_pin >= 0) {
			int pin = host->detect_pin;

			/* Make sure the timer doesn't enable the interrupt */
			host->detect_pin = -1;
			smp_wmb();

			free_irq(gpio_to_irq(pin), host->mmc);
			del_timer_sync(&host->detect_timer);
			gpio_free(pin);
		}

		mmc_remove_host(host->mmc);

		clk_enable(host->mck);
		mci_writel(host, IDR, ~0UL);
		mci_writel(host, CR, MCI_CR_MCIDIS);
		mci_readl(host, SR);
		clk_disable(host->mck);

		if (host->wp_pin >= 0)
			gpio_free(host->wp_pin);

		free_irq(platform_get_irq(pdev, 0), host->mmc);
		iounmap(host->regs);

		clk_put(host->mck);

		mmc_free_host(host->mmc);
	}
	return 0;
}

static struct platform_driver atmci_driver = {
	.remove		= __exit_p(atmci_remove),
	.driver		= {
		.name		= "atmel_mci",
	},
};

static int __init atmci_init(void)
{
	return platform_driver_probe(&atmci_driver, atmci_probe);
}

static void __exit atmci_exit(void)
{
	platform_driver_unregister(&atmci_driver);
}

module_init(atmci_init);
module_exit(atmci_exit);

MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");
MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
MODULE_LICENSE("GPL v2");
