/*
 *  linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver
 *
 *  Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
 *
 *  Copyright (C) 2006 Malcolm Noyes
 *
 * 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.
 */

/*
   This is the AT91RM9200 MCI driver that has been tested with both MMC cards
   and SD-cards.  Boards that support write protect are now supported.
   The CCAT91SBC001 board does not support SD cards.

   The three entry points are at91_mci_request, at91_mci_set_ios
   and at91_mci_get_ro.

   SET IOS
     This configures the device to put it into the correct mode and clock speed
     required.

   MCI REQUEST
     MCI request processes the commands sent in the mmc_request structure. This
     can consist of a processing command and a stop command in the case of
     multiple block transfers.

     There are three main types of request, commands, reads and writes.

     Commands are straight forward. The command is submitted to the controller and
     the request function returns. When the controller generates an interrupt to indicate
     the command is finished, the response to the command are read and the mmc_request_done
     function called to end the request.

     Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)
     controller to manage the transfers.

     A read is done from the controller directly to the scatterlist passed in from the request.
     Due to a bug in the controller, when a read is completed, all the words are byte
     swapped in the scatterlist buffers.

     The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY

     A write is slightly different in that the bytes to write are read from the scatterlist
     into a dma memory buffer (this is in case the source buffer should be read only). The
     entire write buffer is then done from this single dma memory buffer.

     The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY

   GET RO
     Gets the status of the write protect pin, if available.
*/

#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>

#include <linux/mmc/host.h>
#include <linux/mmc/protocol.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/mmc.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91rm9200_mci.h>
#include <asm/arch/at91rm9200_pdc.h>

#define DRIVER_NAME "at91_mci"

#undef	SUPPORT_4WIRE

static struct clk *mci_clk;

#define FL_SENT_COMMAND (1 << 0)
#define FL_SENT_STOP (1 << 1)



/*
 * Read from a MCI register.
 */
static inline unsigned long at91_mci_read(unsigned int reg)
{
	void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;

	return __raw_readl(mci_base + reg);
}

/*
 * Write to a MCI register.
 */
static inline void at91_mci_write(unsigned int reg, unsigned long value)
{
        void __iomem *mci_base = (void __iomem *)AT91_VA_BASE_MCI;

        __raw_writel(value, mci_base + reg);
}

/*
 * Low level type for this driver
 */
struct at91mci_host
{
	struct mmc_host *mmc;
	struct mmc_command *cmd;
	struct mmc_request *request;

	struct at91_mmc_data *board;
	int present;

	/*
	 * Flag indicating when the command has been sent. This is used to
	 * work out whether or not to send the stop
	 */
	unsigned int flags;
	/* flag for current bus settings */
	u32 bus_mode;

	/* DMA buffer used for transmitting */
	unsigned int* buffer;
	dma_addr_t physical_address;
	unsigned int total_length;

	/* Latest in the scatterlist that has been enabled for transfer, but not freed */
	int in_use_index;

	/* Latest in the scatterlist that has been enabled for transfer */
	int transfer_index;
};

/*
 * Copy from sg to a dma block - used for transfers
 */
static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
{
	unsigned int len, i, size;
	unsigned *dmabuf = host->buffer;

	size = host->total_length;
	len = data->sg_len;

	/*
	 * Just loop through all entries. Size might not
	 * be the entire list though so make sure that
	 * we do not transfer too much.
	 */
	for (i = 0; i < len; i++) {
		struct scatterlist *sg;
		int amount;
		int index;
		unsigned int *sgbuffer;

		sg = &data->sg[i];

		sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
		amount = min(size, sg->length);
		size -= amount;
		amount /= 4;

		for (index = 0; index < amount; index++)
			*dmabuf++ = swab32(sgbuffer[index]);

		kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);

		if (size == 0)
			break;
	}

	/*
	 * Check that we didn't get a request to transfer
	 * more data than can fit into the SG list.
	 */
	BUG_ON(size != 0);
}

/*
 * Prepare a dma read
 */
static void at91mci_pre_dma_read(struct at91mci_host *host)
{
	int i;
	struct scatterlist *sg;
	struct mmc_command *cmd;
	struct mmc_data *data;

	pr_debug("pre dma read\n");

	cmd = host->cmd;
	if (!cmd) {
		pr_debug("no command\n");
		return;
	}

	data = cmd->data;
	if (!data) {
		pr_debug("no data\n");
		return;
	}

	for (i = 0; i < 2; i++) {
		/* nothing left to transfer */
		if (host->transfer_index >= data->sg_len) {
			pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index);
			break;
		}

		/* Check to see if this needs filling */
		if (i == 0) {
			if (at91_mci_read(AT91_PDC_RCR) != 0) {
				pr_debug("Transfer active in current\n");
				continue;
			}
		}
		else {
			if (at91_mci_read(AT91_PDC_RNCR) != 0) {
				pr_debug("Transfer active in next\n");
				continue;
			}
		}

		/* Setup the next transfer */
		pr_debug("Using transfer index %d\n", host->transfer_index);

		sg = &data->sg[host->transfer_index++];
		pr_debug("sg = %p\n", sg);

		sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);

		pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);

		if (i == 0) {
			at91_mci_write(AT91_PDC_RPR, sg->dma_address);
			at91_mci_write(AT91_PDC_RCR, sg->length / 4);
		}
		else {
			at91_mci_write(AT91_PDC_RNPR, sg->dma_address);
			at91_mci_write(AT91_PDC_RNCR, sg->length / 4);
		}
	}

	pr_debug("pre dma read done\n");
}

/*
 * Handle after a dma read
 */
static void at91mci_post_dma_read(struct at91mci_host *host)
{
	struct mmc_command *cmd;
	struct mmc_data *data;

	pr_debug("post dma read\n");

	cmd = host->cmd;
	if (!cmd) {
		pr_debug("no command\n");
		return;
	}

	data = cmd->data;
	if (!data) {
		pr_debug("no data\n");
		return;
	}

	while (host->in_use_index < host->transfer_index) {
		unsigned int *buffer;
		int index;
		int len;

		struct scatterlist *sg;

		pr_debug("finishing index %d\n", host->in_use_index);

		sg = &data->sg[host->in_use_index++];

		pr_debug("Unmapping page %08X\n", sg->dma_address);

		dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE);

		/* Swap the contents of the buffer */
		buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
		pr_debug("buffer = %p, length = %d\n", buffer, sg->length);

		data->bytes_xfered += sg->length;

		len = sg->length / 4;

		for (index = 0; index < len; index++) {
			buffer[index] = swab32(buffer[index]);
		}
		kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
		flush_dcache_page(sg->page);
	}

	/* Is there another transfer to trigger? */
	if (host->transfer_index < data->sg_len)
		at91mci_pre_dma_read(host);
	else {
		at91_mci_write(AT91_MCI_IER, AT91_MCI_RXBUFF);
		at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);
	}

	pr_debug("post dma read done\n");
}

/*
 * Handle transmitted data
 */
static void at91_mci_handle_transmitted(struct at91mci_host *host)
{
	struct mmc_command *cmd;
	struct mmc_data *data;

	pr_debug("Handling the transmit\n");

	/* Disable the transfer */
	at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);

	/* Now wait for cmd ready */
	at91_mci_write(AT91_MCI_IDR, AT91_MCI_TXBUFE);
	at91_mci_write(AT91_MCI_IER, AT91_MCI_NOTBUSY);

	cmd = host->cmd;
	if (!cmd) return;

	data = cmd->data;
	if (!data) return;

	data->bytes_xfered = host->total_length;
}

/*
 * Enable the controller
 */
static void at91_mci_enable(void)
{
	at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);
	at91_mci_write(AT91_MCI_IDR, 0xFFFFFFFF);
	at91_mci_write(AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
	at91_mci_write(AT91_MCI_MR, 0x834A);
	at91_mci_write(AT91_MCI_SDCR, 0x0);
}

/*
 * Disable the controller
 */
static void at91_mci_disable(void)
{
	at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
}

/*
 * Send a command
 * return the interrupts to enable
 */
static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
{
	unsigned int cmdr, mr;
	unsigned int block_length;
	struct mmc_data *data = cmd->data;

	unsigned int blocks;
	unsigned int ier = 0;

	host->cmd = cmd;

	/* Not sure if this is needed */
#if 0
	if ((at91_mci_read(AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
		pr_debug("Clearing timeout\n");
		at91_mci_write(AT91_MCI_ARGR, 0);
		at91_mci_write(AT91_MCI_CMDR, AT91_MCI_OPDCMD);
		while (!(at91_mci_read(AT91_MCI_SR) & AT91_MCI_CMDRDY)) {
			/* spin */
			pr_debug("Clearing: SR = %08X\n", at91_mci_read(AT91_MCI_SR));
		}
	}
#endif
	cmdr = cmd->opcode;

	if (mmc_resp_type(cmd) == MMC_RSP_NONE)
		cmdr |= AT91_MCI_RSPTYP_NONE;
	else {
		/* if a response is expected then allow maximum response latancy */
		cmdr |= AT91_MCI_MAXLAT;
		/* set 136 bit response for R2, 48 bit response otherwise */
		if (mmc_resp_type(cmd) == MMC_RSP_R2)
			cmdr |= AT91_MCI_RSPTYP_136;
		else
			cmdr |= AT91_MCI_RSPTYP_48;
	}

	if (data) {
		block_length = data->blksz;
		blocks = data->blocks;

		/* always set data start - also set direction flag for read */
		if (data->flags & MMC_DATA_READ)
			cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);
		else if (data->flags & MMC_DATA_WRITE)
			cmdr |= AT91_MCI_TRCMD_START;

		if (data->flags & MMC_DATA_STREAM)
			cmdr |= AT91_MCI_TRTYP_STREAM;
		if (data->flags & MMC_DATA_MULTI)
			cmdr |= AT91_MCI_TRTYP_MULTIPLE;
	}
	else {
		block_length = 0;
		blocks = 0;
	}

	if (cmd->opcode == MMC_STOP_TRANSMISSION)
		cmdr |= AT91_MCI_TRCMD_STOP;

	if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
		cmdr |= AT91_MCI_OPDCMD;

	/*
	 * Set the arguments and send the command
	 */
	pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08lX)\n",
		cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(AT91_MCI_MR));

	if (!data) {
		at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS);
		at91_mci_write(AT91_PDC_RPR, 0);
		at91_mci_write(AT91_PDC_RCR, 0);
		at91_mci_write(AT91_PDC_RNPR, 0);
		at91_mci_write(AT91_PDC_RNCR, 0);
		at91_mci_write(AT91_PDC_TPR, 0);
		at91_mci_write(AT91_PDC_TCR, 0);
		at91_mci_write(AT91_PDC_TNPR, 0);
		at91_mci_write(AT91_PDC_TNCR, 0);

		at91_mci_write(AT91_MCI_ARGR, cmd->arg);
		at91_mci_write(AT91_MCI_CMDR, cmdr);
		return AT91_MCI_CMDRDY;
	}

	mr = at91_mci_read(AT91_MCI_MR) & 0x7fff;	/* zero block length and PDC mode */
	at91_mci_write(AT91_MCI_MR, mr | (block_length << 16) | AT91_MCI_PDCMODE);

	/*
	 * Disable the PDC controller
	 */
	at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS);

	if (cmdr & AT91_MCI_TRCMD_START) {
		data->bytes_xfered = 0;
		host->transfer_index = 0;
		host->in_use_index = 0;
		if (cmdr & AT91_MCI_TRDIR) {
			/*
			 * Handle a read
			 */
			host->buffer = NULL;
			host->total_length = 0;

			at91mci_pre_dma_read(host);
			ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
		}
		else {
			/*
			 * Handle a write
			 */
			host->total_length = block_length * blocks;
			host->buffer = dma_alloc_coherent(NULL,
						  host->total_length,
						  &host->physical_address, GFP_KERNEL);

			at91mci_sg_to_dma(host, data);

			pr_debug("Transmitting %d bytes\n", host->total_length);

			at91_mci_write(AT91_PDC_TPR, host->physical_address);
			at91_mci_write(AT91_PDC_TCR, host->total_length / 4);
			ier = AT91_MCI_TXBUFE;
		}
	}

	/*
	 * Send the command and then enable the PDC - not the other way round as
	 * the data sheet says
	 */

	at91_mci_write(AT91_MCI_ARGR, cmd->arg);
	at91_mci_write(AT91_MCI_CMDR, cmdr);

	if (cmdr & AT91_MCI_TRCMD_START) {
		if (cmdr & AT91_MCI_TRDIR)
			at91_mci_write(AT91_PDC_PTCR, AT91_PDC_RXTEN);
		else
			at91_mci_write(AT91_PDC_PTCR, AT91_PDC_TXTEN);
	}
	return ier;
}

/*
 * Wait for a command to complete
 */
static void at91mci_process_command(struct at91mci_host *host, struct mmc_command *cmd)
{
	unsigned int ier;

	ier = at91_mci_send_command(host, cmd);

	pr_debug("setting ier to %08X\n", ier);

	/* Stop on errors or the required value */
	at91_mci_write(AT91_MCI_IER, 0xffff0000 | ier);
}

/*
 * Process the next step in the request
 */
static void at91mci_process_next(struct at91mci_host *host)
{
	if (!(host->flags & FL_SENT_COMMAND)) {
		host->flags |= FL_SENT_COMMAND;
		at91mci_process_command(host, host->request->cmd);
	}
	else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
		host->flags |= FL_SENT_STOP;
		at91mci_process_command(host, host->request->stop);
	}
	else
		mmc_request_done(host->mmc, host->request);
}

/*
 * Handle a command that has been completed
 */
static void at91mci_completed_command(struct at91mci_host *host)
{
	struct mmc_command *cmd = host->cmd;
	unsigned int status;

	at91_mci_write(AT91_MCI_IDR, 0xffffffff);

	cmd->resp[0] = at91_mci_read(AT91_MCI_RSPR(0));
	cmd->resp[1] = at91_mci_read(AT91_MCI_RSPR(1));
	cmd->resp[2] = at91_mci_read(AT91_MCI_RSPR(2));
	cmd->resp[3] = at91_mci_read(AT91_MCI_RSPR(3));

	if (host->buffer) {
		dma_free_coherent(NULL, host->total_length, host->buffer, host->physical_address);
		host->buffer = NULL;
	}

	status = at91_mci_read(AT91_MCI_SR);

	pr_debug("Status = %08X [%08X %08X %08X %08X]\n",
		 status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	if (status & (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE |
			AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
			AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
		if ((status & AT91_MCI_RCRCE) &&
			((cmd->opcode == MMC_SEND_OP_COND) || (cmd->opcode == SD_APP_OP_COND))) {
			cmd->error = MMC_ERR_NONE;
		}
		else {
			if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
				cmd->error = MMC_ERR_TIMEOUT;
			else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
				cmd->error = MMC_ERR_BADCRC;
			else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))
				cmd->error = MMC_ERR_FIFO;
			else
				cmd->error = MMC_ERR_FAILED;

			pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n",
				 cmd->error, cmd->opcode, cmd->retries);
		}
	}
	else
		cmd->error = MMC_ERR_NONE;

	at91mci_process_next(host);
}

/*
 * Handle an MMC request
 */
static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct at91mci_host *host = mmc_priv(mmc);
	host->request = mrq;
	host->flags = 0;

	at91mci_process_next(host);
}

/*
 * Set the IOS
 */
static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	int clkdiv;
	struct at91mci_host *host = mmc_priv(mmc);
	unsigned long at91_master_clock = clk_get_rate(mci_clk);

	host->bus_mode = ios->bus_mode;

	if (ios->clock == 0) {
		/* Disable the MCI controller */
		at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIDIS);
		clkdiv = 0;
	}
	else {
		/* Enable the MCI controller */
		at91_mci_write(AT91_MCI_CR, AT91_MCI_MCIEN);

		if ((at91_master_clock % (ios->clock * 2)) == 0)
			clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
		else
			clkdiv = (at91_master_clock / ios->clock) / 2;

		pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv,
			at91_master_clock / (2 * (clkdiv + 1)));
	}
	if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {
		pr_debug("MMC: Setting controller bus width to 4\n");
		at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) | AT91_MCI_SDCBUS);
	}
	else {
		pr_debug("MMC: Setting controller bus width to 1\n");
		at91_mci_write(AT91_MCI_SDCR, at91_mci_read(AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
	}

	/* Set the clock divider */
	at91_mci_write(AT91_MCI_MR, (at91_mci_read(AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);

	/* maybe switch power to the card */
	if (host->board->vcc_pin) {
		switch (ios->power_mode) {
			case MMC_POWER_OFF:
				at91_set_gpio_output(host->board->vcc_pin, 0);
				break;
			case MMC_POWER_UP:
			case MMC_POWER_ON:
				at91_set_gpio_output(host->board->vcc_pin, 1);
				break;
		}
	}
}

/*
 * Handle an interrupt
 */
static irqreturn_t at91_mci_irq(int irq, void *devid, struct pt_regs *regs)
{
	struct at91mci_host *host = devid;
	int completed = 0;

	unsigned int int_status;

	int_status = at91_mci_read(AT91_MCI_SR);
	pr_debug("MCI irq: status = %08X, %08lX, %08lX\n", int_status, at91_mci_read(AT91_MCI_IMR),
		int_status & at91_mci_read(AT91_MCI_IMR));

	if ((int_status & at91_mci_read(AT91_MCI_IMR)) & 0xffff0000)
		completed = 1;

	int_status &= at91_mci_read(AT91_MCI_IMR);

	if (int_status & AT91_MCI_UNRE)
		pr_debug("MMC: Underrun error\n");
	if (int_status & AT91_MCI_OVRE)
		pr_debug("MMC: Overrun error\n");
	if (int_status & AT91_MCI_DTOE)
		pr_debug("MMC: Data timeout\n");
	if (int_status & AT91_MCI_DCRCE)
		pr_debug("MMC: CRC error in data\n");
	if (int_status & AT91_MCI_RTOE)
		pr_debug("MMC: Response timeout\n");
	if (int_status & AT91_MCI_RENDE)
		pr_debug("MMC: Response end bit error\n");
	if (int_status & AT91_MCI_RCRCE)
		pr_debug("MMC: Response CRC error\n");
	if (int_status & AT91_MCI_RDIRE)
		pr_debug("MMC: Response direction error\n");
	if (int_status & AT91_MCI_RINDE)
		pr_debug("MMC: Response index error\n");

	/* Only continue processing if no errors */
	if (!completed) {
		if (int_status & AT91_MCI_TXBUFE) {
			pr_debug("TX buffer empty\n");
			at91_mci_handle_transmitted(host);
		}

		if (int_status & AT91_MCI_RXBUFF) {
			pr_debug("RX buffer full\n");
			at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);
		}

		if (int_status & AT91_MCI_ENDTX) {
			pr_debug("Transmit has ended\n");
		}

		if (int_status & AT91_MCI_ENDRX) {
			pr_debug("Receive has ended\n");
			at91mci_post_dma_read(host);
		}

		if (int_status & AT91_MCI_NOTBUSY) {
			pr_debug("Card is ready\n");
			at91_mci_write(AT91_MCI_IER, AT91_MCI_CMDRDY);
		}

		if (int_status & AT91_MCI_DTIP) {
			pr_debug("Data transfer in progress\n");
		}

		if (int_status & AT91_MCI_BLKE) {
			pr_debug("Block transfer has ended\n");
		}

		if (int_status & AT91_MCI_TXRDY) {
			pr_debug("Ready to transmit\n");
		}

		if (int_status & AT91_MCI_RXRDY) {
			pr_debug("Ready to receive\n");
		}

		if (int_status & AT91_MCI_CMDRDY) {
			pr_debug("Command ready\n");
			completed = 1;
		}
	}
	at91_mci_write(AT91_MCI_IDR, int_status);

	if (completed) {
		pr_debug("Completed command\n");
		at91_mci_write(AT91_MCI_IDR, 0xffffffff);
		at91mci_completed_command(host);
	}

	return IRQ_HANDLED;
}

static irqreturn_t at91_mmc_det_irq(int irq, void *_host, struct pt_regs *regs)
{
	struct at91mci_host *host = _host;
	int present = !at91_get_gpio_value(irq);

	/*
	 * we expect this irq on both insert and remove,
	 * and use a short delay to debounce.
	 */
	if (present != host->present) {
		host->present = present;
		pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
			present ? "insert" : "remove");
		if (!present) {
			pr_debug("****** Resetting SD-card bus width ******\n");
			at91_mci_write(AT91_MCI_SDCR, 0);
		}
		mmc_detect_change(host->mmc, msecs_to_jiffies(100));
	}
	return IRQ_HANDLED;
}

int at91_mci_get_ro(struct mmc_host *mmc)
{
	int read_only = 0;
	struct at91mci_host *host = mmc_priv(mmc);

	if (host->board->wp_pin) {
		read_only = at91_get_gpio_value(host->board->wp_pin);
		printk(KERN_WARNING "%s: card is %s\n", mmc_hostname(mmc),
				(read_only ? "read-only" : "read-write") );
	}
	else {
		printk(KERN_WARNING "%s: host does not support reading read-only "
				"switch.  Assuming write-enable.\n", mmc_hostname(mmc));
	}
	return read_only;
}

static struct mmc_host_ops at91_mci_ops = {
	.request	= at91_mci_request,
	.set_ios	= at91_mci_set_ios,
	.get_ro		= at91_mci_get_ro,
};

/*
 * Probe for the device
 */
static int at91_mci_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct at91mci_host *host;
	int ret;

	pr_debug("Probe MCI devices\n");
	at91_mci_disable();
	at91_mci_enable();

	mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
	if (!mmc) {
		pr_debug("Failed to allocate mmc host\n");
		return -ENOMEM;
	}

	mmc->ops = &at91_mci_ops;
	mmc->f_min = 375000;
	mmc->f_max = 25000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->buffer = NULL;
	host->bus_mode = 0;
	host->board = pdev->dev.platform_data;
	if (host->board->wire4) {
#ifdef SUPPORT_4WIRE
		mmc->caps |= MMC_CAP_4_BIT_DATA;
#else
		printk("MMC: 4 wire bus mode not supported by this driver - using 1 wire\n");
#endif
	}

	/*
	 * Get Clock
	 */
	mci_clk = clk_get(&pdev->dev, "mci_clk");
	if (IS_ERR(mci_clk)) {
		printk(KERN_ERR "AT91 MMC: no clock defined.\n");
		mmc_free_host(mmc);
		return -ENODEV;
	}
	clk_enable(mci_clk);			/* Enable the peripheral clock */

	/*
	 * Allocate the MCI interrupt
	 */
	ret = request_irq(AT91_ID_MCI, at91_mci_irq, SA_SHIRQ, DRIVER_NAME, host);
	if (ret) {
		printk(KERN_ERR "Failed to request MCI interrupt\n");
		clk_disable(mci_clk);
		clk_put(mci_clk);
		mmc_free_host(mmc);
		return ret;
	}

	platform_set_drvdata(pdev, mmc);

	/*
	 * Add host to MMC layer
	 */
	if (host->board->det_pin)
		host->present = !at91_get_gpio_value(host->board->det_pin);
	else
		host->present = -1;

	mmc_add_host(mmc);

	/*
	 * monitor card insertion/removal if we can
	 */
	if (host->board->det_pin) {
		ret = request_irq(host->board->det_pin, at91_mmc_det_irq,
				0, DRIVER_NAME, host);
		if (ret)
			printk(KERN_ERR "couldn't allocate MMC detect irq\n");
	}

	pr_debug(KERN_INFO "Added MCI driver\n");

	return 0;
}

/*
 * Remove a device
 */
static int at91_mci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct at91mci_host *host;

	if (!mmc)
		return -1;

	host = mmc_priv(mmc);

	if (host->present != -1) {
		free_irq(host->board->det_pin, host);
		cancel_delayed_work(&host->mmc->detect);
	}

	mmc_remove_host(mmc);
	at91_mci_disable();
	free_irq(AT91_ID_MCI, host);
	mmc_free_host(mmc);

	clk_disable(mci_clk);				/* Disable the peripheral clock */
	clk_put(mci_clk);

	platform_set_drvdata(pdev, NULL);

	pr_debug("MCI Removed\n");

	return 0;
}

#ifdef CONFIG_PM
static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	int ret = 0;

	if (mmc)
		ret = mmc_suspend_host(mmc, state);

	return ret;
}

static int at91_mci_resume(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	int ret = 0;

	if (mmc)
		ret = mmc_resume_host(mmc);

	return ret;
}
#else
#define at91_mci_suspend	NULL
#define at91_mci_resume		NULL
#endif

static struct platform_driver at91_mci_driver = {
	.probe		= at91_mci_probe,
	.remove		= at91_mci_remove,
	.suspend	= at91_mci_suspend,
	.resume		= at91_mci_resume,
	.driver		= {
		.name	= DRIVER_NAME,
		.owner	= THIS_MODULE,
	},
};

static int __init at91_mci_init(void)
{
	return platform_driver_register(&at91_mci_driver);
}

static void __exit at91_mci_exit(void)
{
	platform_driver_unregister(&at91_mci_driver);
}

module_init(at91_mci_init);
module_exit(at91_mci_exit);

MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
MODULE_AUTHOR("Nick Randell");
MODULE_LICENSE("GPL");
