// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018 Oleksij Rempel <linux@rempel-privat.de>
 *
 * Driver for Alcor Micro AU6601 and AU6621 controllers
 */

/* Note: this driver was created without any documentation. Based
 * on sniffing, testing and in some cases mimic of original driver.
 * As soon as some one with documentation or more experience in SD/MMC, or
 * reverse engineering then me, please review this driver and question every
 * thing what I did. 2018 Oleksij Rempel <linux@rempel-privat.de>
 */

#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/pm.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>

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

#include <linux/alcor_pci.h>

enum alcor_cookie {
	COOKIE_UNMAPPED,
	COOKIE_PRE_MAPPED,
	COOKIE_MAPPED,
};

struct alcor_pll_conf {
	unsigned int clk_src_freq;
	unsigned int clk_src_reg;
	unsigned int min_div;
	unsigned int max_div;
};

struct alcor_sdmmc_host {
	struct  device *dev;
	struct alcor_pci_priv *alcor_pci;

	struct mmc_request *mrq;
	struct mmc_command *cmd;
	struct mmc_data *data;
	unsigned int dma_on:1;

	struct mutex cmd_mutex;

	struct delayed_work timeout_work;

	struct sg_mapping_iter sg_miter;	/* SG state for PIO */
	struct scatterlist *sg;
	unsigned int blocks;		/* remaining PIO blocks */
	int sg_count;

	u32			irq_status_sd;
	unsigned char		cur_power_mode;
};

static const struct alcor_pll_conf alcor_pll_cfg[] = {
	/* MHZ,		CLK src,		max div, min div */
	{ 31250000,	AU6601_CLK_31_25_MHZ,	1,	511},
	{ 48000000,	AU6601_CLK_48_MHZ,	1,	511},
	{125000000,	AU6601_CLK_125_MHZ,	1,	511},
	{384000000,	AU6601_CLK_384_MHZ,	1,	511},
};

static inline void alcor_rmw8(struct alcor_sdmmc_host *host, unsigned int addr,
			       u8 clear, u8 set)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	u32 var;

	var = alcor_read8(priv, addr);
	var &= ~clear;
	var |= set;
	alcor_write8(priv, var, addr);
}

/* As soon as irqs are masked, some status updates may be missed.
 * Use this with care.
 */
static inline void alcor_mask_sd_irqs(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;

	alcor_write32(priv, 0, AU6601_REG_INT_ENABLE);
}

static inline void alcor_unmask_sd_irqs(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;

	alcor_write32(priv, AU6601_INT_CMD_MASK | AU6601_INT_DATA_MASK |
		  AU6601_INT_CARD_INSERT | AU6601_INT_CARD_REMOVE |
		  AU6601_INT_OVER_CURRENT_ERR,
		  AU6601_REG_INT_ENABLE);
}

static void alcor_reset(struct alcor_sdmmc_host *host, u8 val)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	int i;

	alcor_write8(priv, val | AU6601_BUF_CTRL_RESET,
		      AU6601_REG_SW_RESET);
	for (i = 0; i < 100; i++) {
		if (!(alcor_read8(priv, AU6601_REG_SW_RESET) & val))
			return;
		udelay(50);
	}
	dev_err(host->dev, "%s: timeout\n", __func__);
}

/*
 * Perform DMA I/O of a single page.
 */
static void alcor_data_set_dma(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	u32 addr;

	if (!host->sg_count)
		return;

	if (!host->sg) {
		dev_err(host->dev, "have blocks, but no SG\n");
		return;
	}

	if (!sg_dma_len(host->sg)) {
		dev_err(host->dev, "DMA SG len == 0\n");
		return;
	}


	addr = (u32)sg_dma_address(host->sg);

	alcor_write32(priv, addr, AU6601_REG_SDMA_ADDR);
	host->sg = sg_next(host->sg);
	host->sg_count--;
}

static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	struct mmc_data *data = host->data;
	u8 ctrl = 0;

	if (data->flags & MMC_DATA_WRITE)
		ctrl |= AU6601_DATA_WRITE;

	if (data->host_cookie == COOKIE_MAPPED) {
		/*
		 * For DMA transfers, this function is called just once,
		 * at the start of the operation. The hardware can only
		 * perform DMA I/O on a single page at a time, so here
		 * we kick off the transfer with the first page, and expect
		 * subsequent pages to be transferred upon IRQ events
		 * indicating that the single-page DMA was completed.
		 */
		alcor_data_set_dma(host);
		ctrl |= AU6601_DATA_DMA_MODE;
		host->dma_on = 1;
		alcor_write32(priv, data->sg_count * 0x1000,
			       AU6601_REG_BLOCK_SIZE);
	} else {
		/*
		 * For PIO transfers, we break down each operation
		 * into several sector-sized transfers. When one sector has
		 * complete, the IRQ handler will call this function again
		 * to kick off the transfer of the next sector.
		 */
		alcor_write32(priv, data->blksz, AU6601_REG_BLOCK_SIZE);
	}

	alcor_write8(priv, ctrl | AU6601_DATA_START_XFER,
		      AU6601_DATA_XFER_CTRL);
}

static void alcor_trf_block_pio(struct alcor_sdmmc_host *host, bool read)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	size_t blksize, len;
	u8 *buf;

	if (!host->blocks)
		return;

	if (host->dma_on) {
		dev_err(host->dev, "configured DMA but got PIO request.\n");
		return;
	}

	if (!!(host->data->flags & MMC_DATA_READ) != read) {
		dev_err(host->dev, "got unexpected direction %i != %i\n",
			!!(host->data->flags & MMC_DATA_READ), read);
	}

	if (!sg_miter_next(&host->sg_miter))
		return;

	blksize = host->data->blksz;
	len = min(host->sg_miter.length, blksize);

	dev_dbg(host->dev, "PIO, %s block size: 0x%zx\n",
		read ? "read" : "write", blksize);

	host->sg_miter.consumed = len;
	host->blocks--;

	buf = host->sg_miter.addr;

	if (read)
		ioread32_rep(priv->iobase + AU6601_REG_BUFFER, buf, len >> 2);
	else
		iowrite32_rep(priv->iobase + AU6601_REG_BUFFER, buf, len >> 2);

	sg_miter_stop(&host->sg_miter);
}

static void alcor_prepare_sg_miter(struct alcor_sdmmc_host *host)
{
	unsigned int flags = SG_MITER_ATOMIC;
	struct mmc_data *data = host->data;

	if (data->flags & MMC_DATA_READ)
		flags |= SG_MITER_TO_SG;
	else
		flags |= SG_MITER_FROM_SG;
	sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags);
}

static void alcor_prepare_data(struct alcor_sdmmc_host *host,
			       struct mmc_command *cmd)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	struct mmc_data *data = cmd->data;

	if (!data)
		return;


	host->data = data;
	host->data->bytes_xfered = 0;
	host->blocks = data->blocks;
	host->sg = data->sg;
	host->sg_count = data->sg_count;
	dev_dbg(host->dev, "prepare DATA: sg %i, blocks: %i\n",
			host->sg_count, host->blocks);

	if (data->host_cookie != COOKIE_MAPPED)
		alcor_prepare_sg_miter(host);

	alcor_write8(priv, 0, AU6601_DATA_XFER_CTRL);
}

static void alcor_send_cmd(struct alcor_sdmmc_host *host,
			   struct mmc_command *cmd, bool set_timeout)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	unsigned long timeout = 0;
	u8 ctrl = 0;

	host->cmd = cmd;
	alcor_prepare_data(host, cmd);

	dev_dbg(host->dev, "send CMD. opcode: 0x%02x, arg; 0x%08x\n",
		cmd->opcode, cmd->arg);
	alcor_write8(priv, cmd->opcode | 0x40, AU6601_REG_CMD_OPCODE);
	alcor_write32be(priv, cmd->arg, AU6601_REG_CMD_ARG);

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		ctrl = AU6601_CMD_NO_RESP;
		break;
	case MMC_RSP_R1:
		ctrl = AU6601_CMD_6_BYTE_CRC;
		break;
	case MMC_RSP_R1B:
		ctrl = AU6601_CMD_6_BYTE_CRC | AU6601_CMD_STOP_WAIT_RDY;
		break;
	case MMC_RSP_R2:
		ctrl = AU6601_CMD_17_BYTE_CRC;
		break;
	case MMC_RSP_R3:
		ctrl = AU6601_CMD_6_BYTE_WO_CRC;
		break;
	default:
		dev_err(host->dev, "%s: cmd->flag (0x%02x) is not valid\n",
			mmc_hostname(mmc_from_priv(host)), mmc_resp_type(cmd));
		break;
	}

	if (set_timeout) {
		if (!cmd->data && cmd->busy_timeout)
			timeout = cmd->busy_timeout;
		else
			timeout = 10000;

		schedule_delayed_work(&host->timeout_work,
				      msecs_to_jiffies(timeout));
	}

	dev_dbg(host->dev, "xfer ctrl: 0x%02x; timeout: %lu\n", ctrl, timeout);
	alcor_write8(priv, ctrl | AU6601_CMD_START_XFER,
				 AU6601_CMD_XFER_CTRL);
}

static void alcor_request_complete(struct alcor_sdmmc_host *host,
				   bool cancel_timeout)
{
	struct mmc_request *mrq;

	/*
	 * If this work gets rescheduled while running, it will
	 * be run again afterwards but without any active request.
	 */
	if (!host->mrq)
		return;

	if (cancel_timeout)
		cancel_delayed_work(&host->timeout_work);

	mrq = host->mrq;

	host->mrq = NULL;
	host->cmd = NULL;
	host->data = NULL;
	host->dma_on = 0;

	mmc_request_done(mmc_from_priv(host), mrq);
}

static void alcor_finish_data(struct alcor_sdmmc_host *host)
{
	struct mmc_data *data;

	data = host->data;
	host->data = NULL;
	host->dma_on = 0;

	/*
	 * The specification states that the block count register must
	 * be updated, but it does not specify at what point in the
	 * data flow. That makes the register entirely useless to read
	 * back so we have to assume that nothing made it to the card
	 * in the event of an error.
	 */
	if (data->error)
		data->bytes_xfered = 0;
	else
		data->bytes_xfered = data->blksz * data->blocks;

	/*
	 * Need to send CMD12 if -
	 * a) open-ended multiblock transfer (no CMD23)
	 * b) error in multiblock transfer
	 */
	if (data->stop &&
	    (data->error ||
	     !host->mrq->sbc)) {

		/*
		 * The controller needs a reset of internal state machines
		 * upon error conditions.
		 */
		if (data->error)
			alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA);

		alcor_unmask_sd_irqs(host);
		alcor_send_cmd(host, data->stop, false);
		return;
	}

	alcor_request_complete(host, 1);
}

static void alcor_err_irq(struct alcor_sdmmc_host *host, u32 intmask)
{
	dev_dbg(host->dev, "ERR IRQ %x\n", intmask);

	if (host->cmd) {
		if (intmask & AU6601_INT_CMD_TIMEOUT_ERR)
			host->cmd->error = -ETIMEDOUT;
		else
			host->cmd->error = -EILSEQ;
	}

	if (host->data) {
		if (intmask & AU6601_INT_DATA_TIMEOUT_ERR)
			host->data->error = -ETIMEDOUT;
		else
			host->data->error = -EILSEQ;

		host->data->bytes_xfered = 0;
	}

	alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA);
	alcor_request_complete(host, 1);
}

static int alcor_cmd_irq_done(struct alcor_sdmmc_host *host, u32 intmask)
{
	struct alcor_pci_priv *priv = host->alcor_pci;

	intmask &= AU6601_INT_CMD_END;

	if (!intmask)
		return true;

	/* got CMD_END but no CMD is in progress, wake thread an process the
	 * error
	 */
	if (!host->cmd)
		return false;

	if (host->cmd->flags & MMC_RSP_PRESENT) {
		struct mmc_command *cmd = host->cmd;

		cmd->resp[0] = alcor_read32be(priv, AU6601_REG_CMD_RSP0);
		dev_dbg(host->dev, "RSP0: 0x%04x\n", cmd->resp[0]);
		if (host->cmd->flags & MMC_RSP_136) {
			cmd->resp[1] =
				alcor_read32be(priv, AU6601_REG_CMD_RSP1);
			cmd->resp[2] =
				alcor_read32be(priv, AU6601_REG_CMD_RSP2);
			cmd->resp[3] =
				alcor_read32be(priv, AU6601_REG_CMD_RSP3);
			dev_dbg(host->dev, "RSP1,2,3: 0x%04x 0x%04x 0x%04x\n",
				cmd->resp[1], cmd->resp[2], cmd->resp[3]);
		}

	}

	host->cmd->error = 0;

	/* Processed actual command. */
	if (!host->data)
		return false;

	alcor_trigger_data_transfer(host);
	host->cmd = NULL;
	return true;
}

static void alcor_cmd_irq_thread(struct alcor_sdmmc_host *host, u32 intmask)
{
	intmask &= AU6601_INT_CMD_END;

	if (!intmask)
		return;

	if (!host->cmd && intmask & AU6601_INT_CMD_END) {
		dev_dbg(host->dev, "Got command interrupt 0x%08x even though no command operation was in progress.\n",
			intmask);
	}

	/* Processed actual command. */
	if (!host->data)
		alcor_request_complete(host, 1);
	else
		alcor_trigger_data_transfer(host);
	host->cmd = NULL;
}

static int alcor_data_irq_done(struct alcor_sdmmc_host *host, u32 intmask)
{
	u32 tmp;

	intmask &= AU6601_INT_DATA_MASK;

	/* nothing here to do */
	if (!intmask)
		return 1;

	/* we was too fast and got DATA_END after it was processed?
	 * lets ignore it for now.
	 */
	if (!host->data && intmask == AU6601_INT_DATA_END)
		return 1;

	/* looks like an error, so lets handle it. */
	if (!host->data)
		return 0;

	tmp = intmask & (AU6601_INT_READ_BUF_RDY | AU6601_INT_WRITE_BUF_RDY
			 | AU6601_INT_DMA_END);
	switch (tmp) {
	case 0:
		break;
	case AU6601_INT_READ_BUF_RDY:
		alcor_trf_block_pio(host, true);
		return 1;
	case AU6601_INT_WRITE_BUF_RDY:
		alcor_trf_block_pio(host, false);
		return 1;
	case AU6601_INT_DMA_END:
		if (!host->sg_count)
			break;

		alcor_data_set_dma(host);
		break;
	default:
		dev_err(host->dev, "Got READ_BUF_RDY and WRITE_BUF_RDY at same time\n");
		break;
	}

	if (intmask & AU6601_INT_DATA_END) {
		if (!host->dma_on && host->blocks) {
			alcor_trigger_data_transfer(host);
			return 1;
		} else {
			return 0;
		}
	}

	return 1;
}

static void alcor_data_irq_thread(struct alcor_sdmmc_host *host, u32 intmask)
{
	intmask &= AU6601_INT_DATA_MASK;

	if (!intmask)
		return;

	if (!host->data) {
		dev_dbg(host->dev, "Got data interrupt 0x%08x even though no data operation was in progress.\n",
			intmask);
		alcor_reset(host, AU6601_RESET_DATA);
		return;
	}

	if (alcor_data_irq_done(host, intmask))
		return;

	if ((intmask & AU6601_INT_DATA_END) || !host->blocks ||
	    (host->dma_on && !host->sg_count))
		alcor_finish_data(host);
}

static void alcor_cd_irq(struct alcor_sdmmc_host *host, u32 intmask)
{
	dev_dbg(host->dev, "card %s\n",
		intmask & AU6601_INT_CARD_REMOVE ? "removed" : "inserted");

	if (host->mrq) {
		dev_dbg(host->dev, "cancel all pending tasks.\n");

		if (host->data)
			host->data->error = -ENOMEDIUM;

		if (host->cmd)
			host->cmd->error = -ENOMEDIUM;
		else
			host->mrq->cmd->error = -ENOMEDIUM;

		alcor_request_complete(host, 1);
	}

	mmc_detect_change(mmc_from_priv(host), msecs_to_jiffies(1));
}

static irqreturn_t alcor_irq_thread(int irq, void *d)
{
	struct alcor_sdmmc_host *host = d;
	irqreturn_t ret = IRQ_HANDLED;
	u32 intmask, tmp;

	mutex_lock(&host->cmd_mutex);

	intmask = host->irq_status_sd;

	/* some thing bad */
	if (unlikely(!intmask || AU6601_INT_ALL_MASK == intmask)) {
		dev_dbg(host->dev, "unexpected IRQ: 0x%04x\n", intmask);
		ret = IRQ_NONE;
		goto exit;
	}

	tmp = intmask & (AU6601_INT_CMD_MASK | AU6601_INT_DATA_MASK);
	if (tmp) {
		if (tmp & AU6601_INT_ERROR_MASK)
			alcor_err_irq(host, tmp);
		else {
			alcor_cmd_irq_thread(host, tmp);
			alcor_data_irq_thread(host, tmp);
		}
		intmask &= ~(AU6601_INT_CMD_MASK | AU6601_INT_DATA_MASK);
	}

	if (intmask & (AU6601_INT_CARD_INSERT | AU6601_INT_CARD_REMOVE)) {
		alcor_cd_irq(host, intmask);
		intmask &= ~(AU6601_INT_CARD_INSERT | AU6601_INT_CARD_REMOVE);
	}

	if (intmask & AU6601_INT_OVER_CURRENT_ERR) {
		dev_warn(host->dev,
			 "warning: over current detected!\n");
		intmask &= ~AU6601_INT_OVER_CURRENT_ERR;
	}

	if (intmask)
		dev_dbg(host->dev, "got not handled IRQ: 0x%04x\n", intmask);

exit:
	mutex_unlock(&host->cmd_mutex);
	alcor_unmask_sd_irqs(host);
	return ret;
}


static irqreturn_t alcor_irq(int irq, void *d)
{
	struct alcor_sdmmc_host *host = d;
	struct alcor_pci_priv *priv = host->alcor_pci;
	u32 status, tmp;
	irqreturn_t ret;
	int cmd_done, data_done;

	status = alcor_read32(priv, AU6601_REG_INT_STATUS);
	if (!status)
		return IRQ_NONE;

	alcor_write32(priv, status, AU6601_REG_INT_STATUS);

	tmp = status & (AU6601_INT_READ_BUF_RDY | AU6601_INT_WRITE_BUF_RDY
			| AU6601_INT_DATA_END | AU6601_INT_DMA_END
			| AU6601_INT_CMD_END);
	if (tmp == status) {
		cmd_done = alcor_cmd_irq_done(host, tmp);
		data_done = alcor_data_irq_done(host, tmp);
		/* use fast path for simple tasks */
		if (cmd_done && data_done) {
			ret = IRQ_HANDLED;
			goto alcor_irq_done;
		}
	}

	host->irq_status_sd = status;
	ret = IRQ_WAKE_THREAD;
	alcor_mask_sd_irqs(host);
alcor_irq_done:
	return ret;
}

static void alcor_set_clock(struct alcor_sdmmc_host *host, unsigned int clock)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	int i, diff = 0x7fffffff, tmp_clock = 0;
	u16 clk_src = 0;
	u8 clk_div = 0;

	if (clock == 0) {
		alcor_write16(priv, 0, AU6601_CLK_SELECT);
		return;
	}

	for (i = 0; i < ARRAY_SIZE(alcor_pll_cfg); i++) {
		unsigned int tmp_div, tmp_diff;
		const struct alcor_pll_conf *cfg = &alcor_pll_cfg[i];

		tmp_div = DIV_ROUND_UP(cfg->clk_src_freq, clock);
		if (cfg->min_div > tmp_div || tmp_div > cfg->max_div)
			continue;

		tmp_clock = DIV_ROUND_UP(cfg->clk_src_freq, tmp_div);
		tmp_diff = abs(clock - tmp_clock);

		if (tmp_diff >= 0 && tmp_diff < diff) {
			diff = tmp_diff;
			clk_src = cfg->clk_src_reg;
			clk_div = tmp_div;
		}
	}

	clk_src |= ((clk_div - 1) << 8);
	clk_src |= AU6601_CLK_ENABLE;

	dev_dbg(host->dev, "set freq %d cal freq %d, use div %d, mod %x\n",
			clock, tmp_clock, clk_div, clk_src);

	alcor_write16(priv, clk_src, AU6601_CLK_SELECT);

}

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

	if (ios->timing == MMC_TIMING_LEGACY) {
		alcor_rmw8(host, AU6601_CLK_DELAY,
			    AU6601_CLK_POSITIVE_EDGE_ALL, 0);
	} else {
		alcor_rmw8(host, AU6601_CLK_DELAY,
			    0, AU6601_CLK_POSITIVE_EDGE_ALL);
	}
}

static void alcor_set_bus_width(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct alcor_pci_priv *priv = host->alcor_pci;

	if (ios->bus_width == MMC_BUS_WIDTH_1) {
		alcor_write8(priv, 0, AU6601_REG_BUS_CTRL);
	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
		alcor_write8(priv, AU6601_BUS_WIDTH_4BIT,
			      AU6601_REG_BUS_CTRL);
	} else
		dev_err(host->dev, "Unknown BUS mode\n");

}

static int alcor_card_busy(struct mmc_host *mmc)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct alcor_pci_priv *priv = host->alcor_pci;
	u8 status;

	/* Check whether dat[0:3] low */
	status = alcor_read8(priv, AU6601_DATA_PIN_STATE);

	return !(status & AU6601_BUS_STAT_DAT_MASK);
}

static int alcor_get_cd(struct mmc_host *mmc)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct alcor_pci_priv *priv = host->alcor_pci;
	u8 detect;

	detect = alcor_read8(priv, AU6601_DETECT_STATUS)
		& AU6601_DETECT_STATUS_M;
	/* check if card is present then send command and data */
	return (detect == AU6601_SD_DETECTED);
}

static int alcor_get_ro(struct mmc_host *mmc)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct alcor_pci_priv *priv = host->alcor_pci;
	u8 status;

	/* get write protect pin status */
	status = alcor_read8(priv, AU6601_INTERFACE_MODE_CTRL);

	return !!(status & AU6601_SD_CARD_WP);
}

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

	mutex_lock(&host->cmd_mutex);

	host->mrq = mrq;

	/* check if card is present then send command and data */
	if (alcor_get_cd(mmc))
		alcor_send_cmd(host, mrq->cmd, true);
	else {
		mrq->cmd->error = -ENOMEDIUM;
		alcor_request_complete(host, 1);
	}

	mutex_unlock(&host->cmd_mutex);
}

static void alcor_pre_req(struct mmc_host *mmc,
			   struct mmc_request *mrq)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct mmc_data *data = mrq->data;
	struct mmc_command *cmd = mrq->cmd;
	struct scatterlist *sg;
	unsigned int i, sg_len;

	if (!data || !cmd)
		return;

	data->host_cookie = COOKIE_UNMAPPED;

	/* FIXME: looks like the DMA engine works only with CMD18 */
	if (cmd->opcode != MMC_READ_MULTIPLE_BLOCK
			&& cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK)
		return;
	/*
	 * We don't do DMA on "complex" transfers, i.e. with
	 * non-word-aligned buffers or lengths. A future improvement
	 * could be made to use temporary DMA bounce-buffers when these
	 * requirements are not met.
	 *
	 * Also, we don't bother with all the DMA setup overhead for
	 * short transfers.
	 */
	if (data->blocks * data->blksz < AU6601_MAX_DMA_BLOCK_SIZE)
		return;

	if (data->blksz & 3)
		return;

	for_each_sg(data->sg, sg, data->sg_len, i) {
		if (sg->length != AU6601_MAX_DMA_BLOCK_SIZE)
			return;
		if (sg->offset != 0)
			return;
	}

	/* This data might be unmapped at this time */

	sg_len = dma_map_sg(host->dev, data->sg, data->sg_len,
			    mmc_get_dma_dir(data));
	if (sg_len)
		data->host_cookie = COOKIE_MAPPED;

	data->sg_count = sg_len;
}

static void alcor_post_req(struct mmc_host *mmc,
			    struct mmc_request *mrq,
			    int err)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct mmc_data *data = mrq->data;

	if (!data)
		return;

	if (data->host_cookie == COOKIE_MAPPED) {
		dma_unmap_sg(host->dev,
			     data->sg,
			     data->sg_len,
			     mmc_get_dma_dir(data));
	}

	data->host_cookie = COOKIE_UNMAPPED;
}

static void alcor_set_power_mode(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);
	struct alcor_pci_priv *priv = host->alcor_pci;

	switch (ios->power_mode) {
	case MMC_POWER_OFF:
		alcor_set_clock(host, ios->clock);
		/* set all pins to input */
		alcor_write8(priv, 0, AU6601_OUTPUT_ENABLE);
		/* turn of VDD */
		alcor_write8(priv, 0, AU6601_POWER_CONTROL);
		break;
	case MMC_POWER_UP:
		break;
	case MMC_POWER_ON:
		/* This is most trickiest part. The order and timings of
		 * instructions seems to play important role. Any changes may
		 * confuse internal state engine if this HW.
		 * FIXME: If we will ever get access to documentation, then this
		 * part should be reviewed again.
		 */

		/* enable SD card mode */
		alcor_write8(priv, AU6601_SD_CARD,
			      AU6601_ACTIVE_CTRL);
		/* set signal voltage to 3.3V */
		alcor_write8(priv, 0, AU6601_OPT);
		/* no documentation about clk delay, for now just try to mimic
		 * original driver.
		 */
		alcor_write8(priv, 0x20, AU6601_CLK_DELAY);
		/* set BUS width to 1 bit */
		alcor_write8(priv, 0, AU6601_REG_BUS_CTRL);
		/* set CLK first time */
		alcor_set_clock(host, ios->clock);
		/* power on VDD */
		alcor_write8(priv, AU6601_SD_CARD,
			      AU6601_POWER_CONTROL);
		/* wait until the CLK will get stable */
		mdelay(20);
		/* set CLK again, mimic original driver. */
		alcor_set_clock(host, ios->clock);

		/* enable output */
		alcor_write8(priv, AU6601_SD_CARD,
			      AU6601_OUTPUT_ENABLE);
		/* The clk will not work on au6621. We need to trigger data
		 * transfer.
		 */
		alcor_write8(priv, AU6601_DATA_WRITE,
			      AU6601_DATA_XFER_CTRL);
		/* configure timeout. Not clear what exactly it means. */
		alcor_write8(priv, 0x7d, AU6601_TIME_OUT_CTRL);
		mdelay(100);
		break;
	default:
		dev_err(host->dev, "Unknown power parameter\n");
	}
}

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

	mutex_lock(&host->cmd_mutex);

	dev_dbg(host->dev, "set ios. bus width: %x, power mode: %x\n",
		ios->bus_width, ios->power_mode);

	if (ios->power_mode != host->cur_power_mode) {
		alcor_set_power_mode(mmc, ios);
		host->cur_power_mode = ios->power_mode;
	} else {
		alcor_set_timing(mmc, ios);
		alcor_set_bus_width(mmc, ios);
		alcor_set_clock(host, ios->clock);
	}

	mutex_unlock(&host->cmd_mutex);
}

static int alcor_signal_voltage_switch(struct mmc_host *mmc,
				       struct mmc_ios *ios)
{
	struct alcor_sdmmc_host *host = mmc_priv(mmc);

	mutex_lock(&host->cmd_mutex);

	switch (ios->signal_voltage) {
	case MMC_SIGNAL_VOLTAGE_330:
		alcor_rmw8(host, AU6601_OPT, AU6601_OPT_SD_18V, 0);
		break;
	case MMC_SIGNAL_VOLTAGE_180:
		alcor_rmw8(host, AU6601_OPT, 0, AU6601_OPT_SD_18V);
		break;
	default:
		/* No signal voltage switch required */
		break;
	}

	mutex_unlock(&host->cmd_mutex);
	return 0;
}

static const struct mmc_host_ops alcor_sdc_ops = {
	.card_busy	= alcor_card_busy,
	.get_cd		= alcor_get_cd,
	.get_ro		= alcor_get_ro,
	.post_req	= alcor_post_req,
	.pre_req	= alcor_pre_req,
	.request	= alcor_request,
	.set_ios	= alcor_set_ios,
	.start_signal_voltage_switch = alcor_signal_voltage_switch,
};

static void alcor_timeout_timer(struct work_struct *work)
{
	struct delayed_work *d = to_delayed_work(work);
	struct alcor_sdmmc_host *host = container_of(d, struct alcor_sdmmc_host,
						timeout_work);
	mutex_lock(&host->cmd_mutex);

	dev_dbg(host->dev, "triggered timeout\n");
	if (host->mrq) {
		dev_err(host->dev, "Timeout waiting for hardware interrupt.\n");

		if (host->data) {
			host->data->error = -ETIMEDOUT;
		} else {
			if (host->cmd)
				host->cmd->error = -ETIMEDOUT;
			else
				host->mrq->cmd->error = -ETIMEDOUT;
		}

		alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA);
		alcor_request_complete(host, 0);
	}

	mutex_unlock(&host->cmd_mutex);
}

static void alcor_hw_init(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;
	struct alcor_dev_cfg *cfg = priv->cfg;

	/* FIXME: This part is a mimics HW init of original driver.
	 * If we will ever get access to documentation, then this part
	 * should be reviewed again.
	 */

	/* reset command state engine */
	alcor_reset(host, AU6601_RESET_CMD);

	alcor_write8(priv, 0, AU6601_DMA_BOUNDARY);
	/* enable sd card mode */
	alcor_write8(priv, AU6601_SD_CARD, AU6601_ACTIVE_CTRL);

	/* set BUS width to 1 bit */
	alcor_write8(priv, 0, AU6601_REG_BUS_CTRL);

	/* reset data state engine */
	alcor_reset(host, AU6601_RESET_DATA);
	/* Not sure if a voodoo with AU6601_DMA_BOUNDARY is really needed */
	alcor_write8(priv, 0, AU6601_DMA_BOUNDARY);

	alcor_write8(priv, 0, AU6601_INTERFACE_MODE_CTRL);
	/* not clear what we are doing here. */
	alcor_write8(priv, 0x44, AU6601_PAD_DRIVE0);
	alcor_write8(priv, 0x44, AU6601_PAD_DRIVE1);
	alcor_write8(priv, 0x00, AU6601_PAD_DRIVE2);

	/* for 6601 - dma_boundary; for 6621 - dma_page_cnt
	 * exact meaning of this register is not clear.
	 */
	alcor_write8(priv, cfg->dma, AU6601_DMA_BOUNDARY);

	/* make sure all pins are set to input and VDD is off */
	alcor_write8(priv, 0, AU6601_OUTPUT_ENABLE);
	alcor_write8(priv, 0, AU6601_POWER_CONTROL);

	alcor_write8(priv, AU6601_DETECT_EN, AU6601_DETECT_STATUS);
	/* now we should be safe to enable IRQs */
	alcor_unmask_sd_irqs(host);
}

static void alcor_hw_uninit(struct alcor_sdmmc_host *host)
{
	struct alcor_pci_priv *priv = host->alcor_pci;

	alcor_mask_sd_irqs(host);
	alcor_reset(host, AU6601_RESET_CMD | AU6601_RESET_DATA);

	alcor_write8(priv, 0, AU6601_DETECT_STATUS);

	alcor_write8(priv, 0, AU6601_OUTPUT_ENABLE);
	alcor_write8(priv, 0, AU6601_POWER_CONTROL);

	alcor_write8(priv, 0, AU6601_OPT);
}

static void alcor_init_mmc(struct alcor_sdmmc_host *host)
{
	struct mmc_host *mmc = mmc_from_priv(host);

	mmc->f_min = AU6601_MIN_CLOCK;
	mmc->f_max = AU6601_MAX_CLOCK;
	mmc->ocr_avail = MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED
		| MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50
		| MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50;
	mmc->caps2 = MMC_CAP2_NO_SDIO;
	mmc->ops = &alcor_sdc_ops;

	/* The hardware does DMA data transfer of 4096 bytes to/from a single
	 * buffer address. Scatterlists are not supported at the hardware
	 * level, however we can work with them at the driver level,
	 * provided that each segment is exactly 4096 bytes in size.
	 * Upon DMA completion of a single segment (signalled via IRQ), we
	 * immediately proceed to transfer the next segment from the
	 * scatterlist.
	 *
	 * The overall request is limited to 240 sectors, matching the
	 * original vendor driver.
	 */
	mmc->max_segs = AU6601_MAX_DMA_SEGMENTS;
	mmc->max_seg_size = AU6601_MAX_DMA_BLOCK_SIZE;
	mmc->max_blk_count = 240;
	mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size;
	dma_set_max_seg_size(host->dev, mmc->max_seg_size);
}

static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
{
	struct alcor_pci_priv *priv = pdev->dev.platform_data;
	struct mmc_host *mmc;
	struct alcor_sdmmc_host *host;
	int ret;

	mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
	if (!mmc) {
		dev_err(&pdev->dev, "Can't allocate MMC\n");
		return -ENOMEM;
	}

	host = mmc_priv(mmc);
	host->dev = &pdev->dev;
	host->cur_power_mode = MMC_POWER_UNDEFINED;
	host->alcor_pci = priv;

	/* make sure irqs are disabled */
	alcor_write32(priv, 0, AU6601_REG_INT_ENABLE);
	alcor_write32(priv, 0, AU6601_MS_INT_ENABLE);

	ret = devm_request_threaded_irq(&pdev->dev, priv->irq,
			alcor_irq, alcor_irq_thread, IRQF_SHARED,
			DRV_NAME_ALCOR_PCI_SDMMC, host);

	if (ret) {
		dev_err(&pdev->dev, "Failed to get irq for data line\n");
		return ret;
	}

	mutex_init(&host->cmd_mutex);
	INIT_DELAYED_WORK(&host->timeout_work, alcor_timeout_timer);

	alcor_init_mmc(host);
	alcor_hw_init(host);

	dev_set_drvdata(&pdev->dev, host);
	mmc_add_host(mmc);
	return 0;
}

static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev)
{
	struct alcor_sdmmc_host *host = dev_get_drvdata(&pdev->dev);
	struct mmc_host *mmc = mmc_from_priv(host);

	if (cancel_delayed_work_sync(&host->timeout_work))
		alcor_request_complete(host, 0);

	alcor_hw_uninit(host);
	mmc_remove_host(mmc);
	mmc_free_host(mmc);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int alcor_pci_sdmmc_suspend(struct device *dev)
{
	struct alcor_sdmmc_host *host = dev_get_drvdata(dev);

	if (cancel_delayed_work_sync(&host->timeout_work))
		alcor_request_complete(host, 0);

	alcor_hw_uninit(host);

	return 0;
}

static int alcor_pci_sdmmc_resume(struct device *dev)
{
	struct alcor_sdmmc_host *host = dev_get_drvdata(dev);

	alcor_hw_init(host);

	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static SIMPLE_DEV_PM_OPS(alcor_mmc_pm_ops, alcor_pci_sdmmc_suspend,
			 alcor_pci_sdmmc_resume);

static const struct platform_device_id alcor_pci_sdmmc_ids[] = {
	{
		.name = DRV_NAME_ALCOR_PCI_SDMMC,
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, alcor_pci_sdmmc_ids);

static struct platform_driver alcor_pci_sdmmc_driver = {
	.probe		= alcor_pci_sdmmc_drv_probe,
	.remove		= alcor_pci_sdmmc_drv_remove,
	.id_table	= alcor_pci_sdmmc_ids,
	.driver		= {
		.name	= DRV_NAME_ALCOR_PCI_SDMMC,
		.pm	= &alcor_mmc_pm_ops
	},
};
module_platform_driver(alcor_pci_sdmmc_driver);

MODULE_AUTHOR("Oleksij Rempel <linux@rempel-privat.de>");
MODULE_DESCRIPTION("PCI driver for Alcor Micro AU6601 Secure Digital Host Controller Interface");
MODULE_LICENSE("GPL");
