/*
 *  linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
 *
 *  This is a driver for the SDHC controller found in Freescale MX2/MX3
 *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
 *  Unlike the hardware found on MX1, this hardware just works and does
 *  not need all the quirks found in imxmmc.c, hence the separate driver.
 *
 *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
 *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
 *
 *  derived from pxamci.c by Russell King
 *
 * 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/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/dmaengine.h>
#include <linux/types.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/of_gpio.h>
#include <linux/mmc/slot-gpio.h>

#include <asm/dma.h>
#include <asm/irq.h>
#include <linux/platform_data/mmc-mxcmmc.h>

#include <linux/platform_data/dma-imx.h>

#define DRIVER_NAME "mxc-mmc"
#define MXCMCI_TIMEOUT_MS 10000

#define MMC_REG_STR_STP_CLK		0x00
#define MMC_REG_STATUS			0x04
#define MMC_REG_CLK_RATE		0x08
#define MMC_REG_CMD_DAT_CONT		0x0C
#define MMC_REG_RES_TO			0x10
#define MMC_REG_READ_TO			0x14
#define MMC_REG_BLK_LEN			0x18
#define MMC_REG_NOB			0x1C
#define MMC_REG_REV_NO			0x20
#define MMC_REG_INT_CNTR		0x24
#define MMC_REG_CMD			0x28
#define MMC_REG_ARG			0x2C
#define MMC_REG_RES_FIFO		0x34
#define MMC_REG_BUFFER_ACCESS		0x38

#define STR_STP_CLK_RESET               (1 << 3)
#define STR_STP_CLK_START_CLK           (1 << 1)
#define STR_STP_CLK_STOP_CLK            (1 << 0)

#define STATUS_CARD_INSERTION		(1 << 31)
#define STATUS_CARD_REMOVAL		(1 << 30)
#define STATUS_YBUF_EMPTY		(1 << 29)
#define STATUS_XBUF_EMPTY		(1 << 28)
#define STATUS_YBUF_FULL		(1 << 27)
#define STATUS_XBUF_FULL		(1 << 26)
#define STATUS_BUF_UND_RUN		(1 << 25)
#define STATUS_BUF_OVFL			(1 << 24)
#define STATUS_SDIO_INT_ACTIVE		(1 << 14)
#define STATUS_END_CMD_RESP		(1 << 13)
#define STATUS_WRITE_OP_DONE		(1 << 12)
#define STATUS_DATA_TRANS_DONE		(1 << 11)
#define STATUS_READ_OP_DONE		(1 << 11)
#define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
#define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
#define STATUS_BUF_READ_RDY		(1 << 7)
#define STATUS_BUF_WRITE_RDY		(1 << 6)
#define STATUS_RESP_CRC_ERR		(1 << 5)
#define STATUS_CRC_READ_ERR		(1 << 3)
#define STATUS_CRC_WRITE_ERR		(1 << 2)
#define STATUS_TIME_OUT_RESP		(1 << 1)
#define STATUS_TIME_OUT_READ		(1 << 0)
#define STATUS_ERR_MASK			0x2f

#define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
#define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
#define CMD_DAT_CONT_START_READWAIT	(1 << 10)
#define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
#define CMD_DAT_CONT_INIT		(1 << 7)
#define CMD_DAT_CONT_WRITE		(1 << 4)
#define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
#define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
#define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
#define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)

#define INT_SDIO_INT_WKP_EN		(1 << 18)
#define INT_CARD_INSERTION_WKP_EN	(1 << 17)
#define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
#define INT_CARD_INSERTION_EN		(1 << 15)
#define INT_CARD_REMOVAL_EN		(1 << 14)
#define INT_SDIO_IRQ_EN			(1 << 13)
#define INT_DAT0_EN			(1 << 12)
#define INT_BUF_READ_EN			(1 << 4)
#define INT_BUF_WRITE_EN		(1 << 3)
#define INT_END_CMD_RES_EN		(1 << 2)
#define INT_WRITE_OP_DONE_EN		(1 << 1)
#define INT_READ_OP_EN			(1 << 0)

enum mxcmci_type {
	IMX21_MMC,
	IMX31_MMC,
	MPC512X_MMC,
};

struct mxcmci_host {
	struct mmc_host		*mmc;
	struct resource		*res;
	void __iomem		*base;
	int			irq;
	int			detect_irq;
	struct dma_chan		*dma;
	struct dma_async_tx_descriptor *desc;
	int			do_dma;
	int			default_irq_mask;
	int			use_sdio;
	unsigned int		power_mode;
	struct imxmmc_platform_data *pdata;

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

	unsigned int		datasize;
	unsigned int		dma_dir;

	u16			rev_no;
	unsigned int		cmdat;

	struct clk		*clk_ipg;
	struct clk		*clk_per;

	int			clock;

	struct work_struct	datawork;
	spinlock_t		lock;

	struct regulator	*vcc;

	int			burstlen;
	int			dmareq;
	struct dma_slave_config dma_slave_config;
	struct imx_dma_data	dma_data;

	struct timer_list	watchdog;
	enum mxcmci_type	devtype;
};

static const struct platform_device_id mxcmci_devtype[] = {
	{
		.name = "imx21-mmc",
		.driver_data = IMX21_MMC,
	}, {
		.name = "imx31-mmc",
		.driver_data = IMX31_MMC,
	}, {
		.name = "mpc512x-sdhc",
		.driver_data = MPC512X_MMC,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, mxcmci_devtype);

static const struct of_device_id mxcmci_of_match[] = {
	{
		.compatible = "fsl,imx21-mmc",
		.data = &mxcmci_devtype[IMX21_MMC],
	}, {
		.compatible = "fsl,imx31-mmc",
		.data = &mxcmci_devtype[IMX31_MMC],
	}, {
		.compatible = "fsl,mpc5121-sdhc",
		.data = &mxcmci_devtype[MPC512X_MMC],
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, mxcmci_of_match);

static inline int is_imx31_mmc(struct mxcmci_host *host)
{
	return host->devtype == IMX31_MMC;
}

static inline int is_mpc512x_mmc(struct mxcmci_host *host)
{
	return host->devtype == MPC512X_MMC;
}

static inline u32 mxcmci_readl(struct mxcmci_host *host, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		return ioread32be(host->base + reg);
	else
		return readl(host->base + reg);
}

static inline void mxcmci_writel(struct mxcmci_host *host, u32 val, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		iowrite32be(val, host->base + reg);
	else
		writel(val, host->base + reg);
}

static inline u16 mxcmci_readw(struct mxcmci_host *host, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		return ioread32be(host->base + reg);
	else
		return readw(host->base + reg);
}

static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		iowrite32be(val, host->base + reg);
	else
		writew(val, host->base + reg);
}

static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);

static inline void mxcmci_init_ocr(struct mxcmci_host *host)
{
	host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc");

	if (IS_ERR(host->vcc)) {
		host->vcc = NULL;
	} else {
		host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc);
		if (host->pdata && host->pdata->ocr_avail)
			dev_warn(mmc_dev(host->mmc),
				"pdata->ocr_avail will not be used\n");
	}

	if (host->vcc == NULL) {
		/* fall-back to platform data */
		if (host->pdata && host->pdata->ocr_avail)
			host->mmc->ocr_avail = host->pdata->ocr_avail;
		else
			host->mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
	}
}

static inline void mxcmci_set_power(struct mxcmci_host *host,
				    unsigned char power_mode,
				    unsigned int vdd)
{
	if (host->vcc) {
		if (power_mode == MMC_POWER_UP)
			mmc_regulator_set_ocr(host->mmc, host->vcc, vdd);
		else if (power_mode == MMC_POWER_OFF)
			mmc_regulator_set_ocr(host->mmc, host->vcc, 0);
	}

	if (host->pdata && host->pdata->setpower)
		host->pdata->setpower(mmc_dev(host->mmc), vdd);
}

static inline int mxcmci_use_dma(struct mxcmci_host *host)
{
	return host->do_dma;
}

static void mxcmci_softreset(struct mxcmci_host *host)
{
	int i;

	dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");

	/* reset sequence */
	mxcmci_writew(host, STR_STP_CLK_RESET, MMC_REG_STR_STP_CLK);
	mxcmci_writew(host, STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
			MMC_REG_STR_STP_CLK);

	for (i = 0; i < 8; i++)
		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);

	mxcmci_writew(host, 0xff, MMC_REG_RES_TO);
}
static int mxcmci_setup_dma(struct mmc_host *mmc);

#if IS_ENABLED(CONFIG_PPC_MPC512x)
static inline void buffer_swap32(u32 *buf, int len)
{
	int i;

	for (i = 0; i < ((len + 3) / 4); i++) {
		st_le32(buf, *buf);
		buf++;
	}
}

static void mxcmci_swap_buffers(struct mmc_data *data)
{
	struct scatterlist *sg;
	int i;

	for_each_sg(data->sg, sg, data->sg_len, i)
		buffer_swap32(sg_virt(sg), sg->length);
}
#else
static inline void mxcmci_swap_buffers(struct mmc_data *data) {}
#endif

static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
{
	unsigned int nob = data->blocks;
	unsigned int blksz = data->blksz;
	unsigned int datasize = nob * blksz;
	struct scatterlist *sg;
	enum dma_transfer_direction slave_dirn;
	int i, nents;

	if (data->flags & MMC_DATA_STREAM)
		nob = 0xffff;

	host->data = data;
	data->bytes_xfered = 0;

	mxcmci_writew(host, nob, MMC_REG_NOB);
	mxcmci_writew(host, blksz, MMC_REG_BLK_LEN);
	host->datasize = datasize;

	if (!mxcmci_use_dma(host))
		return 0;

	for_each_sg(data->sg, sg, data->sg_len, i) {
		if (sg->offset & 3 || sg->length & 3 || sg->length < 512) {
			host->do_dma = 0;
			return 0;
		}
	}

	if (data->flags & MMC_DATA_READ) {
		host->dma_dir = DMA_FROM_DEVICE;
		slave_dirn = DMA_DEV_TO_MEM;
	} else {
		host->dma_dir = DMA_TO_DEVICE;
		slave_dirn = DMA_MEM_TO_DEV;

		mxcmci_swap_buffers(data);
	}

	nents = dma_map_sg(host->dma->device->dev, data->sg,
				     data->sg_len,  host->dma_dir);
	if (nents != data->sg_len)
		return -EINVAL;

	host->desc = dmaengine_prep_slave_sg(host->dma,
		data->sg, data->sg_len, slave_dirn,
		DMA_PREP_INTERRUPT | DMA_CTRL_ACK);

	if (!host->desc) {
		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
				host->dma_dir);
		host->do_dma = 0;
		return 0; /* Fall back to PIO */
	}
	wmb();

	dmaengine_submit(host->desc);
	dma_async_issue_pending(host->dma);

	mod_timer(&host->watchdog, jiffies + msecs_to_jiffies(MXCMCI_TIMEOUT_MS));

	return 0;
}

static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat);
static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat);

static void mxcmci_dma_callback(void *data)
{
	struct mxcmci_host *host = data;
	u32 stat;

	del_timer(&host->watchdog);

	stat = mxcmci_readl(host, MMC_REG_STATUS);
	mxcmci_writel(host, stat & ~STATUS_DATA_TRANS_DONE, MMC_REG_STATUS);

	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);

	if (stat & STATUS_READ_OP_DONE)
		mxcmci_writel(host, STATUS_READ_OP_DONE, MMC_REG_STATUS);

	mxcmci_data_done(host, stat);
}

static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
		unsigned int cmdat)
{
	u32 int_cntr = host->default_irq_mask;
	unsigned long flags;

	WARN_ON(host->cmd != NULL);
	host->cmd = cmd;

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_R1: /* short CRC, OPCODE */
	case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
		break;
	case MMC_RSP_R2: /* long 136 bit + CRC */
		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
		break;
	case MMC_RSP_R3: /* short */
		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
		break;
	case MMC_RSP_NONE:
		break;
	default:
		dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
				mmc_resp_type(cmd));
		cmd->error = -EINVAL;
		return -EINVAL;
	}

	int_cntr = INT_END_CMD_RES_EN;

	if (mxcmci_use_dma(host)) {
		if (host->dma_dir == DMA_FROM_DEVICE) {
			host->desc->callback = mxcmci_dma_callback;
			host->desc->callback_param = host;
		} else {
			int_cntr |= INT_WRITE_OP_DONE_EN;
		}
	}

	spin_lock_irqsave(&host->lock, flags);
	if (host->use_sdio)
		int_cntr |= INT_SDIO_IRQ_EN;
	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
	spin_unlock_irqrestore(&host->lock, flags);

	mxcmci_writew(host, cmd->opcode, MMC_REG_CMD);
	mxcmci_writel(host, cmd->arg, MMC_REG_ARG);
	mxcmci_writew(host, cmdat, MMC_REG_CMD_DAT_CONT);

	return 0;
}

static void mxcmci_finish_request(struct mxcmci_host *host,
		struct mmc_request *req)
{
	u32 int_cntr = host->default_irq_mask;
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
	if (host->use_sdio)
		int_cntr |= INT_SDIO_IRQ_EN;
	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
	spin_unlock_irqrestore(&host->lock, flags);

	host->req = NULL;
	host->cmd = NULL;
	host->data = NULL;

	mmc_request_done(host->mmc, req);
}

static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
{
	struct mmc_data *data = host->data;
	int data_error;

	if (mxcmci_use_dma(host)) {
		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
				host->dma_dir);
		mxcmci_swap_buffers(data);
	}

	if (stat & STATUS_ERR_MASK) {
		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
				stat);
		if (stat & STATUS_CRC_READ_ERR) {
			dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
			data->error = -EILSEQ;
		} else if (stat & STATUS_CRC_WRITE_ERR) {
			u32 err_code = (stat >> 9) & 0x3;
			if (err_code == 2) { /* No CRC response */
				dev_err(mmc_dev(host->mmc),
					"%s: No CRC -ETIMEDOUT\n", __func__);
				data->error = -ETIMEDOUT;
			} else {
				dev_err(mmc_dev(host->mmc),
					"%s: -EILSEQ\n", __func__);
				data->error = -EILSEQ;
			}
		} else if (stat & STATUS_TIME_OUT_READ) {
			dev_err(mmc_dev(host->mmc),
				"%s: read -ETIMEDOUT\n", __func__);
			data->error = -ETIMEDOUT;
		} else {
			dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
			data->error = -EIO;
		}
	} else {
		data->bytes_xfered = host->datasize;
	}

	data_error = data->error;

	host->data = NULL;

	return data_error;
}

static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
{
	struct mmc_command *cmd = host->cmd;
	int i;
	u32 a, b, c;

	if (!cmd)
		return;

	if (stat & STATUS_TIME_OUT_RESP) {
		dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
		cmd->error = -ETIMEDOUT;
	} else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
		dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
		cmd->error = -EILSEQ;
	}

	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136) {
			for (i = 0; i < 4; i++) {
				a = mxcmci_readw(host, MMC_REG_RES_FIFO);
				b = mxcmci_readw(host, MMC_REG_RES_FIFO);
				cmd->resp[i] = a << 16 | b;
			}
		} else {
			a = mxcmci_readw(host, MMC_REG_RES_FIFO);
			b = mxcmci_readw(host, MMC_REG_RES_FIFO);
			c = mxcmci_readw(host, MMC_REG_RES_FIFO);
			cmd->resp[0] = a << 24 | b << 8 | c >> 8;
		}
	}
}

static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
{
	u32 stat;
	unsigned long timeout = jiffies + HZ;

	do {
		stat = mxcmci_readl(host, MMC_REG_STATUS);
		if (stat & STATUS_ERR_MASK)
			return stat;
		if (time_after(jiffies, timeout)) {
			mxcmci_softreset(host);
			mxcmci_set_clk_rate(host, host->clock);
			return STATUS_TIME_OUT_READ;
		}
		if (stat & mask)
			return 0;
		cpu_relax();
	} while (1);
}

static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
{
	unsigned int stat;
	u32 *buf = _buf;

	while (bytes > 3) {
		stat = mxcmci_poll_status(host,
				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
		if (stat)
			return stat;
		*buf++ = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
		bytes -= 4;
	}

	if (bytes) {
		u8 *b = (u8 *)buf;
		u32 tmp;

		stat = mxcmci_poll_status(host,
				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
		if (stat)
			return stat;
		tmp = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
		memcpy(b, &tmp, bytes);
	}

	return 0;
}

static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
{
	unsigned int stat;
	u32 *buf = _buf;

	while (bytes > 3) {
		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
		if (stat)
			return stat;
		mxcmci_writel(host, cpu_to_le32(*buf++), MMC_REG_BUFFER_ACCESS);
		bytes -= 4;
	}

	if (bytes) {
		u8 *b = (u8 *)buf;
		u32 tmp;

		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
		if (stat)
			return stat;

		memcpy(&tmp, b, bytes);
		mxcmci_writel(host, cpu_to_le32(tmp), MMC_REG_BUFFER_ACCESS);
	}

	stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
	if (stat)
		return stat;

	return 0;
}

static int mxcmci_transfer_data(struct mxcmci_host *host)
{
	struct mmc_data *data = host->req->data;
	struct scatterlist *sg;
	int stat, i;

	host->data = data;
	host->datasize = 0;

	if (data->flags & MMC_DATA_READ) {
		for_each_sg(data->sg, sg, data->sg_len, i) {
			stat = mxcmci_pull(host, sg_virt(sg), sg->length);
			if (stat)
				return stat;
			host->datasize += sg->length;
		}
	} else {
		for_each_sg(data->sg, sg, data->sg_len, i) {
			stat = mxcmci_push(host, sg_virt(sg), sg->length);
			if (stat)
				return stat;
			host->datasize += sg->length;
		}
		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
		if (stat)
			return stat;
	}
	return 0;
}

static void mxcmci_datawork(struct work_struct *work)
{
	struct mxcmci_host *host = container_of(work, struct mxcmci_host,
						  datawork);
	int datastat = mxcmci_transfer_data(host);

	mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
		MMC_REG_STATUS);
	mxcmci_finish_data(host, datastat);

	if (host->req->stop) {
		if (mxcmci_start_cmd(host, host->req->stop, 0)) {
			mxcmci_finish_request(host, host->req);
			return;
		}
	} else {
		mxcmci_finish_request(host, host->req);
	}
}

static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
{
	struct mmc_request *req;
	int data_error;
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);

	if (!host->data) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	if (!host->req) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	req = host->req;
	if (!req->stop)
		host->req = NULL; /* we will handle finish req below */

	data_error = mxcmci_finish_data(host, stat);

	spin_unlock_irqrestore(&host->lock, flags);

	mxcmci_read_response(host, stat);
	host->cmd = NULL;

	if (req->stop) {
		if (mxcmci_start_cmd(host, req->stop, 0)) {
			mxcmci_finish_request(host, req);
			return;
		}
	} else {
		mxcmci_finish_request(host, req);
	}
}

static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
{
	mxcmci_read_response(host, stat);
	host->cmd = NULL;

	if (!host->data && host->req) {
		mxcmci_finish_request(host, host->req);
		return;
	}

	/* For the DMA case the DMA engine handles the data transfer
	 * automatically. For non DMA we have to do it ourselves.
	 * Don't do it in interrupt context though.
	 */
	if (!mxcmci_use_dma(host) && host->data)
		schedule_work(&host->datawork);

}

static irqreturn_t mxcmci_irq(int irq, void *devid)
{
	struct mxcmci_host *host = devid;
	unsigned long flags;
	bool sdio_irq;
	u32 stat;

	stat = mxcmci_readl(host, MMC_REG_STATUS);
	mxcmci_writel(host,
		stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE |
			 STATUS_WRITE_OP_DONE),
		MMC_REG_STATUS);

	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);

	spin_lock_irqsave(&host->lock, flags);
	sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio;
	spin_unlock_irqrestore(&host->lock, flags);

	if (mxcmci_use_dma(host) &&
	    (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE)))
		mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
			MMC_REG_STATUS);

	if (sdio_irq) {
		mxcmci_writel(host, STATUS_SDIO_INT_ACTIVE, MMC_REG_STATUS);
		mmc_signal_sdio_irq(host->mmc);
	}

	if (stat & STATUS_END_CMD_RESP)
		mxcmci_cmd_done(host, stat);

	if (mxcmci_use_dma(host) &&
		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) {
		del_timer(&host->watchdog);
		mxcmci_data_done(host, stat);
	}

	if (host->default_irq_mask &&
		  (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
		mmc_detect_change(host->mmc, msecs_to_jiffies(200));

	return IRQ_HANDLED;
}

static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	unsigned int cmdat = host->cmdat;
	int error;

	WARN_ON(host->req != NULL);

	host->req = req;
	host->cmdat &= ~CMD_DAT_CONT_INIT;

	if (host->dma)
		host->do_dma = 1;

	if (req->data) {
		error = mxcmci_setup_data(host, req->data);
		if (error) {
			req->cmd->error = error;
			goto out;
		}


		cmdat |= CMD_DAT_CONT_DATA_ENABLE;

		if (req->data->flags & MMC_DATA_WRITE)
			cmdat |= CMD_DAT_CONT_WRITE;
	}

	error = mxcmci_start_cmd(host, req->cmd, cmdat);

out:
	if (error)
		mxcmci_finish_request(host, req);
}

static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
{
	unsigned int divider;
	int prescaler = 0;
	unsigned int clk_in = clk_get_rate(host->clk_per);

	while (prescaler <= 0x800) {
		for (divider = 1; divider <= 0xF; divider++) {
			int x;

			x = (clk_in / (divider + 1));

			if (prescaler)
				x /= (prescaler * 2);

			if (x <= clk_ios)
				break;
		}
		if (divider < 0x10)
			break;

		if (prescaler == 0)
			prescaler = 1;
		else
			prescaler <<= 1;
	}

	mxcmci_writew(host, (prescaler << 4) | divider, MMC_REG_CLK_RATE);

	dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
			prescaler, divider, clk_in, clk_ios);
}

static int mxcmci_setup_dma(struct mmc_host *mmc)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	struct dma_slave_config *config = &host->dma_slave_config;

	config->dst_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
	config->src_addr = host->res->start + MMC_REG_BUFFER_ACCESS;
	config->dst_addr_width = 4;
	config->src_addr_width = 4;
	config->dst_maxburst = host->burstlen;
	config->src_maxburst = host->burstlen;
	config->device_fc = false;

	return dmaengine_slave_config(host->dma, config);
}

static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	int burstlen, ret;

	/*
	 * use burstlen of 64 (16 words) in 4 bit mode (--> reg value  0)
	 * use burstlen of 16 (4 words) in 1 bit mode (--> reg value 16)
	 */
	if (ios->bus_width == MMC_BUS_WIDTH_4)
		burstlen = 16;
	else
		burstlen = 4;

	if (mxcmci_use_dma(host) && burstlen != host->burstlen) {
		host->burstlen = burstlen;
		ret = mxcmci_setup_dma(mmc);
		if (ret) {
			dev_err(mmc_dev(host->mmc),
				"failed to config DMA channel. Falling back to PIO\n");
			dma_release_channel(host->dma);
			host->do_dma = 0;
			host->dma = NULL;
		}
	}

	if (ios->bus_width == MMC_BUS_WIDTH_4)
		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
	else
		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;

	if (host->power_mode != ios->power_mode) {
		mxcmci_set_power(host, ios->power_mode, ios->vdd);
		host->power_mode = ios->power_mode;

		if (ios->power_mode == MMC_POWER_ON)
			host->cmdat |= CMD_DAT_CONT_INIT;
	}

	if (ios->clock) {
		mxcmci_set_clk_rate(host, ios->clock);
		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);
	} else {
		mxcmci_writew(host, STR_STP_CLK_STOP_CLK, MMC_REG_STR_STP_CLK);
	}

	host->clock = ios->clock;
}

static irqreturn_t mxcmci_detect_irq(int irq, void *data)
{
	struct mmc_host *mmc = data;

	dev_dbg(mmc_dev(mmc), "%s\n", __func__);

	mmc_detect_change(mmc, msecs_to_jiffies(250));
	return IRQ_HANDLED;
}

static int mxcmci_get_ro(struct mmc_host *mmc)
{
	struct mxcmci_host *host = mmc_priv(mmc);

	if (host->pdata && host->pdata->get_ro)
		return !!host->pdata->get_ro(mmc_dev(mmc));
	/*
	 * If board doesn't support read only detection (no mmc_gpio
	 * context or gpio is invalid), then let the mmc core decide
	 * what to do.
	 */
	return mmc_gpio_get_ro(mmc);
}

static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	unsigned long flags;
	u32 int_cntr;

	spin_lock_irqsave(&host->lock, flags);
	host->use_sdio = enable;
	int_cntr = mxcmci_readl(host, MMC_REG_INT_CNTR);

	if (enable)
		int_cntr |= INT_SDIO_IRQ_EN;
	else
		int_cntr &= ~INT_SDIO_IRQ_EN;

	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
	spin_unlock_irqrestore(&host->lock, flags);
}

static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
{
	struct mxcmci_host *mxcmci = mmc_priv(host);

	/*
	 * MX3 SoCs have a silicon bug which corrupts CRC calculation of
	 * multi-block transfers when connected SDIO peripheral doesn't
	 * drive the BUSY line as required by the specs.
	 * One way to prevent this is to only allow 1-bit transfers.
	 */

	if (is_imx31_mmc(mxcmci) && card->type == MMC_TYPE_SDIO)
		host->caps &= ~MMC_CAP_4_BIT_DATA;
	else
		host->caps |= MMC_CAP_4_BIT_DATA;
}

static bool filter(struct dma_chan *chan, void *param)
{
	struct mxcmci_host *host = param;

	if (!imx_dma_is_general_purpose(chan))
		return false;

	chan->private = &host->dma_data;

	return true;
}

static void mxcmci_watchdog(unsigned long data)
{
	struct mmc_host *mmc = (struct mmc_host *)data;
	struct mxcmci_host *host = mmc_priv(mmc);
	struct mmc_request *req = host->req;
	unsigned int stat = mxcmci_readl(host, MMC_REG_STATUS);

	if (host->dma_dir == DMA_FROM_DEVICE) {
		dmaengine_terminate_all(host->dma);
		dev_err(mmc_dev(host->mmc),
			"%s: read time out (status = 0x%08x)\n",
			__func__, stat);
	} else {
		dev_err(mmc_dev(host->mmc),
			"%s: write time out (status = 0x%08x)\n",
			__func__, stat);
		mxcmci_softreset(host);
	}

	/* Mark transfer as erroneus and inform the upper layers */

	if (host->data)
		host->data->error = -ETIMEDOUT;
	host->req = NULL;
	host->cmd = NULL;
	host->data = NULL;
	mmc_request_done(host->mmc, req);
}

static const struct mmc_host_ops mxcmci_ops = {
	.request		= mxcmci_request,
	.set_ios		= mxcmci_set_ios,
	.get_ro			= mxcmci_get_ro,
	.enable_sdio_irq	= mxcmci_enable_sdio_irq,
	.init_card		= mxcmci_init_card,
};

static int mxcmci_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
	struct mxcmci_host *host = NULL;
	struct resource *iores, *r;
	int ret = 0, irq;
	bool dat3_card_detect = false;
	dma_cap_mask_t mask;
	const struct of_device_id *of_id;
	struct imxmmc_platform_data *pdata = pdev->dev.platform_data;

	pr_info("i.MX/MPC512x SDHC driver\n");

	of_id = of_match_device(mxcmci_of_match, &pdev->dev);

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);
	if (!iores || irq < 0)
		return -EINVAL;

	r = request_mem_region(iores->start, resource_size(iores), pdev->name);
	if (!r)
		return -EBUSY;

	mmc = mmc_alloc_host(sizeof(struct mxcmci_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto out_release_mem;
	}

	mmc_of_parse(mmc);
	mmc->ops = &mxcmci_ops;

	/* For devicetree parsing, the bus width is read from devicetree */
	if (pdata)
		mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
	else
		mmc->caps |= MMC_CAP_SDIO_IRQ;

	/* MMC core transfer sizes tunable parameters */
	mmc->max_blk_size = 2048;
	mmc->max_blk_count = 65535;
	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
	mmc->max_seg_size = mmc->max_req_size;

	host = mmc_priv(mmc);
	host->base = ioremap(r->start, resource_size(r));
	if (!host->base) {
		ret = -ENOMEM;
		goto out_free;
	}

	if (of_id) {
		const struct platform_device_id *id_entry = of_id->data;
		host->devtype = id_entry->driver_data;
	} else {
		host->devtype = pdev->id_entry->driver_data;
	}

	/* adjust max_segs after devtype detection */
	if (!is_mpc512x_mmc(host))
		mmc->max_segs = 64;

	host->mmc = mmc;
	host->pdata = pdata;
	spin_lock_init(&host->lock);

	if (pdata)
		dat3_card_detect = pdata->dat3_card_detect;
	else if (!(mmc->caps & MMC_CAP_NONREMOVABLE)
			&& !of_property_read_bool(pdev->dev.of_node, "cd-gpios"))
		dat3_card_detect = true;

	mxcmci_init_ocr(host);

	if (dat3_card_detect)
		host->default_irq_mask =
			INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN;
	else
		host->default_irq_mask = 0;

	host->res = r;
	host->irq = irq;

	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(host->clk_ipg)) {
		ret = PTR_ERR(host->clk_ipg);
		goto out_iounmap;
	}

	host->clk_per = devm_clk_get(&pdev->dev, "per");
	if (IS_ERR(host->clk_per)) {
		ret = PTR_ERR(host->clk_per);
		goto out_iounmap;
	}

	clk_prepare_enable(host->clk_per);
	clk_prepare_enable(host->clk_ipg);

	mxcmci_softreset(host);

	host->rev_no = mxcmci_readw(host, MMC_REG_REV_NO);
	if (host->rev_no != 0x400) {
		ret = -ENODEV;
		dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
			host->rev_no);
		goto out_clk_put;
	}

	mmc->f_min = clk_get_rate(host->clk_per) >> 16;
	mmc->f_max = clk_get_rate(host->clk_per) >> 1;

	/* recommended in data sheet */
	mxcmci_writew(host, 0x2db4, MMC_REG_READ_TO);

	mxcmci_writel(host, host->default_irq_mask, MMC_REG_INT_CNTR);

	if (!host->pdata) {
		host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx");
	} else {
		r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
		if (r) {
			host->dmareq = r->start;
			host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
			host->dma_data.priority = DMA_PRIO_LOW;
			host->dma_data.dma_request = host->dmareq;
			dma_cap_zero(mask);
			dma_cap_set(DMA_SLAVE, mask);
			host->dma = dma_request_channel(mask, filter, host);
		}
	}
	if (host->dma)
		mmc->max_seg_size = dma_get_max_seg_size(
				host->dma->device->dev);
	else
		dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n");

	INIT_WORK(&host->datawork, mxcmci_datawork);

	ret = request_irq(host->irq, mxcmci_irq, 0, DRIVER_NAME, host);
	if (ret)
		goto out_free_dma;

	platform_set_drvdata(pdev, mmc);

	if (host->pdata && host->pdata->init) {
		ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
				host->mmc);
		if (ret)
			goto out_free_irq;
	}

	init_timer(&host->watchdog);
	host->watchdog.function = &mxcmci_watchdog;
	host->watchdog.data = (unsigned long)mmc;

	mmc_add_host(mmc);

	return 0;

out_free_irq:
	free_irq(host->irq, host);
out_free_dma:
	if (host->dma)
		dma_release_channel(host->dma);
out_clk_put:
	clk_disable_unprepare(host->clk_per);
	clk_disable_unprepare(host->clk_ipg);
out_iounmap:
	iounmap(host->base);
out_free:
	mmc_free_host(mmc);
out_release_mem:
	release_mem_region(iores->start, resource_size(iores));
	return ret;
}

static int mxcmci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct mxcmci_host *host = mmc_priv(mmc);

	platform_set_drvdata(pdev, NULL);

	mmc_remove_host(mmc);

	if (host->vcc)
		regulator_put(host->vcc);

	if (host->pdata && host->pdata->exit)
		host->pdata->exit(&pdev->dev, mmc);

	free_irq(host->irq, host);
	iounmap(host->base);

	if (host->dma)
		dma_release_channel(host->dma);

	clk_disable_unprepare(host->clk_per);
	clk_disable_unprepare(host->clk_ipg);

	release_mem_region(host->res->start, resource_size(host->res));

	mmc_free_host(mmc);

	return 0;
}

#ifdef CONFIG_PM
static int mxcmci_suspend(struct device *dev)
{
	struct mmc_host *mmc = dev_get_drvdata(dev);
	struct mxcmci_host *host = mmc_priv(mmc);
	int ret = 0;

	if (mmc)
		ret = mmc_suspend_host(mmc);
	clk_disable_unprepare(host->clk_per);
	clk_disable_unprepare(host->clk_ipg);

	return ret;
}

static int mxcmci_resume(struct device *dev)
{
	struct mmc_host *mmc = dev_get_drvdata(dev);
	struct mxcmci_host *host = mmc_priv(mmc);
	int ret = 0;

	clk_prepare_enable(host->clk_per);
	clk_prepare_enable(host->clk_ipg);
	if (mmc)
		ret = mmc_resume_host(mmc);

	return ret;
}

static const struct dev_pm_ops mxcmci_pm_ops = {
	.suspend	= mxcmci_suspend,
	.resume		= mxcmci_resume,
};
#endif

static struct platform_driver mxcmci_driver = {
	.probe		= mxcmci_probe,
	.remove		= mxcmci_remove,
	.id_table	= mxcmci_devtype,
	.driver		= {
		.name		= DRIVER_NAME,
		.owner		= THIS_MODULE,
#ifdef CONFIG_PM
		.pm	= &mxcmci_pm_ops,
#endif
		.of_match_table	= mxcmci_of_match,
	}
};

module_platform_driver(mxcmci_driver);

MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mxc-mmc");
