/*
 * 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/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/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)


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);

	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) {
		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");
