/*
 *  linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver
 *
 *  Copyright (C) 2005-2006 Pierre Ossman, All Rights Reserved.
 *
 * 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.
 */

 /*
  * Note that PIO transfer is rather crappy atm. The buffer full/empty
  * interrupts aren't reliable so we currently transfer the entire buffer
  * directly. Patches to solve the problem are welcome.
  */

#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>

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

#include <asm/scatterlist.h>

#include "sdhci.h"

#define DRIVER_NAME "sdhci"
#define DRIVER_VERSION "0.11"

#define BUGMAIL "<sdhci-devel@list.drzeus.cx>"

#define DBG(f, x...) \
	pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)

static const struct pci_device_id pci_ids[] __devinitdata = {
	/* handle any SD host controller */
	{PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)},
	{ /* end: all zeroes */ },
};

MODULE_DEVICE_TABLE(pci, pci_ids);

static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
static void sdhci_finish_data(struct sdhci_host *);

static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
static void sdhci_finish_command(struct sdhci_host *);

static void sdhci_dumpregs(struct sdhci_host *host)
{
	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");

	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
		readl(host->ioaddr + SDHCI_DMA_ADDRESS),
		readw(host->ioaddr + SDHCI_HOST_VERSION));
	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
		readw(host->ioaddr + SDHCI_BLOCK_SIZE),
		readw(host->ioaddr + SDHCI_BLOCK_COUNT));
	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
		readl(host->ioaddr + SDHCI_ARGUMENT),
		readw(host->ioaddr + SDHCI_TRANSFER_MODE));
	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
		readl(host->ioaddr + SDHCI_PRESENT_STATE),
		readb(host->ioaddr + SDHCI_HOST_CONTROL));
	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
		readb(host->ioaddr + SDHCI_POWER_CONTROL),
		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
		readb(host->ioaddr + SDHCI_WALK_UP_CONTROL),
		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
		readl(host->ioaddr + SDHCI_INT_STATUS));
	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
		readl(host->ioaddr + SDHCI_INT_ENABLE),
		readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
		readw(host->ioaddr + SDHCI_ACMD12_ERR),
		readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
		readl(host->ioaddr + SDHCI_CAPABILITIES),
		readl(host->ioaddr + SDHCI_MAX_CURRENT));

	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
}

/*****************************************************************************\
 *                                                                           *
 * Low level functions                                                       *
 *                                                                           *
\*****************************************************************************/

static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);

	if (mask & SDHCI_RESET_ALL) {
		host->clock = 0;

		mdelay(50);
	}
}

static void sdhci_init(struct sdhci_host *host)
{
	u32 intmask;

	sdhci_reset(host, SDHCI_RESET_ALL);

	intmask = ~(SDHCI_INT_CARD_INT | SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL);

	writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
	writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);

	/* This is unknown magic. */
	writeb(0xE, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
}

static void sdhci_activate_led(struct sdhci_host *host)
{
	u8 ctrl;

	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
	ctrl |= SDHCI_CTRL_LED;
	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
}

static void sdhci_deactivate_led(struct sdhci_host *host)
{
	u8 ctrl;

	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
	ctrl &= ~SDHCI_CTRL_LED;
	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
}

/*****************************************************************************\
 *                                                                           *
 * Core functions                                                            *
 *                                                                           *
\*****************************************************************************/

static inline char* sdhci_kmap_sg(struct sdhci_host* host)
{
	host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ);
	return host->mapped_sg + host->cur_sg->offset;
}

static inline void sdhci_kunmap_sg(struct sdhci_host* host)
{
	kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
}

static inline int sdhci_next_sg(struct sdhci_host* host)
{
	/*
	 * Skip to next SG entry.
	 */
	host->cur_sg++;
	host->num_sg--;

	/*
	 * Any entries left?
	 */
	if (host->num_sg > 0) {
		host->offset = 0;
		host->remain = host->cur_sg->length;
	}

	return host->num_sg;
}

static void sdhci_transfer_pio(struct sdhci_host *host)
{
	char *buffer;
	u32 mask;
	int bytes, size;
	unsigned long max_jiffies;

	BUG_ON(!host->data);

	if (host->num_sg == 0)
		return;

	bytes = 0;
	if (host->data->flags & MMC_DATA_READ)
		mask = SDHCI_DATA_AVAILABLE;
	else
		mask = SDHCI_SPACE_AVAILABLE;

	buffer = sdhci_kmap_sg(host) + host->offset;

	/* Transfer shouldn't take more than 5 s */
	max_jiffies = jiffies + HZ * 5;

	while (host->size > 0) {
		if (time_after(jiffies, max_jiffies)) {
			printk(KERN_ERR "%s: PIO transfer stalled. "
				"Please report this to "
				BUGMAIL ".\n", mmc_hostname(host->mmc));
			sdhci_dumpregs(host);

			sdhci_kunmap_sg(host);

			host->data->error = MMC_ERR_FAILED;
			sdhci_finish_data(host);
			return;
		}

		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask))
			continue;

		size = min(host->size, host->remain);

		if (size >= 4) {
			if (host->data->flags & MMC_DATA_READ)
				*(u32*)buffer = readl(host->ioaddr + SDHCI_BUFFER);
			else
				writel(*(u32*)buffer, host->ioaddr + SDHCI_BUFFER);
			size = 4;
		} else if (size >= 2) {
			if (host->data->flags & MMC_DATA_READ)
				*(u16*)buffer = readw(host->ioaddr + SDHCI_BUFFER);
			else
				writew(*(u16*)buffer, host->ioaddr + SDHCI_BUFFER);
			size = 2;
		} else {
			if (host->data->flags & MMC_DATA_READ)
				*(u8*)buffer = readb(host->ioaddr + SDHCI_BUFFER);
			else
				writeb(*(u8*)buffer, host->ioaddr + SDHCI_BUFFER);
			size = 1;
		}

		buffer += size;
		host->offset += size;
		host->remain -= size;

		bytes += size;
		host->size -= size;

		if (host->remain == 0) {
			sdhci_kunmap_sg(host);
			if (sdhci_next_sg(host) == 0) {
				DBG("PIO transfer: %d bytes\n", bytes);
				return;
			}
			buffer = sdhci_kmap_sg(host);
		}
	}

	sdhci_kunmap_sg(host);

	DBG("PIO transfer: %d bytes\n", bytes);
}

static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
{
	u16 mode;

	WARN_ON(host->data);

	if (data == NULL) {
		writew(0, host->ioaddr + SDHCI_TRANSFER_MODE);
		return;
	}

	DBG("blksz %04x blks %04x flags %08x\n",
		data->blksz, data->blocks, data->flags);
	DBG("tsac %d ms nsac %d clk\n",
		data->timeout_ns / 1000000, data->timeout_clks);

	mode = SDHCI_TRNS_BLK_CNT_EN;
	if (data->blocks > 1)
		mode |= SDHCI_TRNS_MULTI;
	if (data->flags & MMC_DATA_READ)
		mode |= SDHCI_TRNS_READ;
	if (host->flags & SDHCI_USE_DMA)
		mode |= SDHCI_TRNS_DMA;

	writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);

	writew(data->blksz, host->ioaddr + SDHCI_BLOCK_SIZE);
	writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);

	if (host->flags & SDHCI_USE_DMA) {
		int count;

		count = pci_map_sg(host->chip->pdev, data->sg, data->sg_len,
			(data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE);
		BUG_ON(count != 1);

		writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS);
	} else {
		host->size = data->blksz * data->blocks;

		host->cur_sg = data->sg;
		host->num_sg = data->sg_len;

		host->offset = 0;
		host->remain = host->cur_sg->length;
	}
}

static void sdhci_finish_data(struct sdhci_host *host)
{
	struct mmc_data *data;
	u32 intmask;
	u16 blocks;

	BUG_ON(!host->data);

	data = host->data;
	host->data = NULL;

	if (host->flags & SDHCI_USE_DMA) {
		pci_unmap_sg(host->chip->pdev, data->sg, data->sg_len,
			(data->flags & MMC_DATA_READ)?PCI_DMA_FROMDEVICE:PCI_DMA_TODEVICE);
	} else {
		intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE);
		intmask &= ~(SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL);
		writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);

		intmask = readl(host->ioaddr + SDHCI_INT_ENABLE);
		intmask &= ~(SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL);
		writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
	}

	/*
	 * Controller doesn't count down when in single block mode.
	 */
	if ((data->blocks == 1) && (data->error == MMC_ERR_NONE))
		blocks = 0;
	else
		blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT);
	data->bytes_xfered = data->blksz * (data->blocks - blocks);

	if ((data->error == MMC_ERR_NONE) && blocks) {
		printk(KERN_ERR "%s: Controller signalled completion even "
			"though there were blocks left. Please report this "
			"to " BUGMAIL ".\n", mmc_hostname(host->mmc));
		data->error = MMC_ERR_FAILED;
	}

	if (host->size != 0) {
		printk(KERN_ERR "%s: %d bytes were left untransferred. "
			"Please report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc), host->size);
		data->error = MMC_ERR_FAILED;
	}

	DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered);

	if (data->stop) {
		/*
		 * The controller needs a reset of internal state machines
		 * upon error conditions.
		 */
		if (data->error != MMC_ERR_NONE) {
			sdhci_reset(host, SDHCI_RESET_CMD);
			sdhci_reset(host, SDHCI_RESET_DATA);
		}

		sdhci_send_command(host, data->stop);
	} else
		tasklet_schedule(&host->finish_tasklet);
}

static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
{
	int flags;
	u32 present;
	unsigned long max_jiffies;

	WARN_ON(host->cmd);

	DBG("Sending cmd (%x)\n", cmd->opcode);

	/* Wait max 10 ms */
	max_jiffies = jiffies + (HZ + 99)/100;
	do {
		if (time_after(jiffies, max_jiffies)) {
			printk(KERN_ERR "%s: Controller never released "
				"inhibit bits. Please report this to "
				BUGMAIL ".\n", mmc_hostname(host->mmc));
			sdhci_dumpregs(host);
			cmd->error = MMC_ERR_FAILED;
			tasklet_schedule(&host->finish_tasklet);
			return;
		}
		present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
	} while (present & (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT));

	mod_timer(&host->timer, jiffies + 10 * HZ);

	host->cmd = cmd;

	sdhci_prepare_data(host, cmd->data);

	writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);

	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
		printk(KERN_ERR "%s: Unsupported response type! "
			"Please report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		cmd->error = MMC_ERR_INVALID;
		tasklet_schedule(&host->finish_tasklet);
		return;
	}

	if (!(cmd->flags & MMC_RSP_PRESENT))
		flags = SDHCI_CMD_RESP_NONE;
	else if (cmd->flags & MMC_RSP_136)
		flags = SDHCI_CMD_RESP_LONG;
	else if (cmd->flags & MMC_RSP_BUSY)
		flags = SDHCI_CMD_RESP_SHORT_BUSY;
	else
		flags = SDHCI_CMD_RESP_SHORT;

	if (cmd->flags & MMC_RSP_CRC)
		flags |= SDHCI_CMD_CRC;
	if (cmd->flags & MMC_RSP_OPCODE)
		flags |= SDHCI_CMD_INDEX;
	if (cmd->data)
		flags |= SDHCI_CMD_DATA;

	writel(SDHCI_MAKE_CMD(cmd->opcode, flags),
		host->ioaddr + SDHCI_COMMAND);
}

static void sdhci_finish_command(struct sdhci_host *host)
{
	int i;

	BUG_ON(host->cmd == NULL);

	if (host->cmd->flags & MMC_RSP_PRESENT) {
		if (host->cmd->flags & MMC_RSP_136) {
			/* CRC is stripped so we need to do some shifting. */
			for (i = 0;i < 4;i++) {
				host->cmd->resp[i] = readl(host->ioaddr +
					SDHCI_RESPONSE + (3-i)*4) << 8;
				if (i != 3)
					host->cmd->resp[i] |=
						readb(host->ioaddr +
						SDHCI_RESPONSE + (3-i)*4-1);
			}
		} else {
			host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
		}
	}

	host->cmd->error = MMC_ERR_NONE;

	DBG("Ending cmd (%x)\n", host->cmd->opcode);

	if (host->cmd->data) {
		u32 intmask;

		host->data = host->cmd->data;

		if (!(host->flags & SDHCI_USE_DMA)) {
			/*
			 * Don't enable the interrupts until now to make sure we
			 * get stable handling of the FIFO.
			 */
			intmask = readl(host->ioaddr + SDHCI_INT_ENABLE);
			intmask |= SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL;
			writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);

			intmask = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE);
			intmask |= SDHCI_INT_BUF_EMPTY | SDHCI_INT_BUF_FULL;
			writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);

			/*
			 * The buffer interrupts are to unreliable so we
			 * start the transfer immediatly.
			 */
			sdhci_transfer_pio(host);
		}
	} else
		tasklet_schedule(&host->finish_tasklet);

	host->cmd = NULL;
}

static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
	int div;
	u16 clk;
	unsigned long max_jiffies;

	if (clock == host->clock)
		return;

	writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);

	if (clock == 0)
		goto out;

	for (div = 1;div < 256;div *= 2) {
		if ((host->max_clk / div) <= clock)
			break;
	}
	div >>= 1;

	clk = div << SDHCI_DIVIDER_SHIFT;
	clk |= SDHCI_CLOCK_INT_EN;
	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);

	/* Wait max 10 ms */
	max_jiffies = jiffies + (HZ + 99)/100;
	do {
		if (time_after(jiffies, max_jiffies)) {
			printk(KERN_ERR "%s: Internal clock never stabilised. "
				"Please report this to " BUGMAIL ".\n",
				mmc_hostname(host->mmc));
			sdhci_dumpregs(host);
			return;
		}
		clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL);
	} while (!(clk & SDHCI_CLOCK_INT_STABLE));

	clk |= SDHCI_CLOCK_CARD_EN;
	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);

out:
	host->clock = clock;
}

/*****************************************************************************\
 *                                                                           *
 * MMC callbacks                                                             *
 *                                                                           *
\*****************************************************************************/

static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct sdhci_host *host;
	unsigned long flags;

	host = mmc_priv(mmc);

	spin_lock_irqsave(&host->lock, flags);

	WARN_ON(host->mrq != NULL);

	sdhci_activate_led(host);

	host->mrq = mrq;

	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
		host->mrq->cmd->error = MMC_ERR_TIMEOUT;
		tasklet_schedule(&host->finish_tasklet);
	} else
		sdhci_send_command(host, mrq->cmd);

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

static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct sdhci_host *host;
	unsigned long flags;
	u8 ctrl;

	host = mmc_priv(mmc);

	spin_lock_irqsave(&host->lock, flags);

	/*
	 * Reset the chip on each power off.
	 * Should clear out any weird states.
	 */
	if (ios->power_mode == MMC_POWER_OFF) {
		writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
		spin_unlock_irqrestore(&host->lock, flags);
		sdhci_init(host);
		spin_lock_irqsave(&host->lock, flags);
	}

	sdhci_set_clock(host, ios->clock);

	if (ios->power_mode == MMC_POWER_OFF)
		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
	else
		writeb(0xFF, host->ioaddr + SDHCI_POWER_CONTROL);

	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
	if (ios->bus_width == MMC_BUS_WIDTH_4)
		ctrl |= SDHCI_CTRL_4BITBUS;
	else
		ctrl &= ~SDHCI_CTRL_4BITBUS;
	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);

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

static int sdhci_get_ro(struct mmc_host *mmc)
{
	struct sdhci_host *host;
	unsigned long flags;
	int present;

	host = mmc_priv(mmc);

	spin_lock_irqsave(&host->lock, flags);

	present = readl(host->ioaddr + SDHCI_PRESENT_STATE);

	spin_unlock_irqrestore(&host->lock, flags);

	return !(present & SDHCI_WRITE_PROTECT);
}

static struct mmc_host_ops sdhci_ops = {
	.request	= sdhci_request,
	.set_ios	= sdhci_set_ios,
	.get_ro		= sdhci_get_ro,
};

/*****************************************************************************\
 *                                                                           *
 * Tasklets                                                                  *
 *                                                                           *
\*****************************************************************************/

static void sdhci_tasklet_card(unsigned long param)
{
	struct sdhci_host *host;
	unsigned long flags;

	host = (struct sdhci_host*)param;

	spin_lock_irqsave(&host->lock, flags);

	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
		if (host->mrq) {
			printk(KERN_ERR "%s: Card removed during transfer!\n",
				mmc_hostname(host->mmc));
			printk(KERN_ERR "%s: Resetting controller.\n",
				mmc_hostname(host->mmc));

			sdhci_reset(host, SDHCI_RESET_CMD);
			sdhci_reset(host, SDHCI_RESET_DATA);

			host->mrq->cmd->error = MMC_ERR_FAILED;
			tasklet_schedule(&host->finish_tasklet);
		}
	}

	spin_unlock_irqrestore(&host->lock, flags);

	mmc_detect_change(host->mmc, msecs_to_jiffies(500));
}

static void sdhci_tasklet_finish(unsigned long param)
{
	struct sdhci_host *host;
	unsigned long flags;
	struct mmc_request *mrq;

	host = (struct sdhci_host*)param;

	spin_lock_irqsave(&host->lock, flags);

	del_timer(&host->timer);

	mrq = host->mrq;

	DBG("Ending request, cmd (%x)\n", mrq->cmd->opcode);

	/*
	 * The controller needs a reset of internal state machines
	 * upon error conditions.
	 */
	if ((mrq->cmd->error != MMC_ERR_NONE) ||
		(mrq->data && ((mrq->data->error != MMC_ERR_NONE) ||
		(mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) {
		sdhci_reset(host, SDHCI_RESET_CMD);
		sdhci_reset(host, SDHCI_RESET_DATA);
	}

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

	sdhci_deactivate_led(host);

	spin_unlock_irqrestore(&host->lock, flags);

	mmc_request_done(host->mmc, mrq);
}

static void sdhci_timeout_timer(unsigned long data)
{
	struct sdhci_host *host;
	unsigned long flags;

	host = (struct sdhci_host*)data;

	spin_lock_irqsave(&host->lock, flags);

	if (host->mrq) {
		printk(KERN_ERR "%s: Timeout waiting for hardware interrupt. "
			"Please report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);

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

			tasklet_schedule(&host->finish_tasklet);
		}
	}

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

/*****************************************************************************\
 *                                                                           *
 * Interrupt handling                                                        *
 *                                                                           *
\*****************************************************************************/

static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
{
	BUG_ON(intmask == 0);

	if (!host->cmd) {
		printk(KERN_ERR "%s: Got command interrupt even though no "
			"command operation was in progress.\n",
			mmc_hostname(host->mmc));
		printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);
		return;
	}

	if (intmask & SDHCI_INT_RESPONSE)
		sdhci_finish_command(host);
	else {
		if (intmask & SDHCI_INT_TIMEOUT)
			host->cmd->error = MMC_ERR_TIMEOUT;
		else if (intmask & SDHCI_INT_CRC)
			host->cmd->error = MMC_ERR_BADCRC;
		else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX))
			host->cmd->error = MMC_ERR_FAILED;
		else
			host->cmd->error = MMC_ERR_INVALID;

		tasklet_schedule(&host->finish_tasklet);
	}
}

static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{
	BUG_ON(intmask == 0);

	if (!host->data) {
		/*
		 * A data end interrupt is sent together with the response
		 * for the stop command.
		 */
		if (intmask & SDHCI_INT_DATA_END)
			return;

		printk(KERN_ERR "%s: Got data interrupt even though no "
			"data operation was in progress.\n",
			mmc_hostname(host->mmc));
		printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);

		return;
	}

	if (intmask & SDHCI_INT_DATA_TIMEOUT)
		host->data->error = MMC_ERR_TIMEOUT;
	else if (intmask & SDHCI_INT_DATA_CRC)
		host->data->error = MMC_ERR_BADCRC;
	else if (intmask & SDHCI_INT_DATA_END_BIT)
		host->data->error = MMC_ERR_FAILED;

	if (host->data->error != MMC_ERR_NONE)
		sdhci_finish_data(host);
	else {
		if (intmask & (SDHCI_INT_BUF_FULL | SDHCI_INT_BUF_EMPTY))
			sdhci_transfer_pio(host);

		if (intmask & SDHCI_INT_DATA_END)
			sdhci_finish_data(host);
	}
}

static irqreturn_t sdhci_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	irqreturn_t result;
	struct sdhci_host* host = dev_id;
	u32 intmask;

	spin_lock(&host->lock);

	intmask = readl(host->ioaddr + SDHCI_INT_STATUS);

	if (!intmask) {
		result = IRQ_NONE;
		goto out;
	}

	DBG("*** %s got interrupt: 0x%08x\n", host->slot_descr, intmask);

	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE))
		tasklet_schedule(&host->card_tasklet);

	if (intmask & SDHCI_INT_CMD_MASK) {
		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);

		writel(intmask & SDHCI_INT_CMD_MASK,
			host->ioaddr + SDHCI_INT_STATUS);
	}

	if (intmask & SDHCI_INT_DATA_MASK) {
		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);

		writel(intmask & SDHCI_INT_DATA_MASK,
			host->ioaddr + SDHCI_INT_STATUS);
	}

	intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);

	if (intmask & SDHCI_INT_CARD_INT) {
		printk(KERN_ERR "%s: Unexpected card interrupt. Please "
			"report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);
	}

	if (intmask & SDHCI_INT_BUS_POWER) {
		printk(KERN_ERR "%s: Unexpected bus power interrupt. Please "
			"report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);
	}

	if (intmask & SDHCI_INT_ACMD12ERR) {
		printk(KERN_ERR "%s: Unexpected auto CMD12 error. Please "
			"report this to " BUGMAIL ".\n",
			mmc_hostname(host->mmc));
		sdhci_dumpregs(host);

		writew(~0, host->ioaddr + SDHCI_ACMD12_ERR);
	}

	if (intmask)
		writel(intmask, host->ioaddr + SDHCI_INT_STATUS);

	result = IRQ_HANDLED;

out:
	spin_unlock(&host->lock);

	return result;
}

/*****************************************************************************\
 *                                                                           *
 * Suspend/resume                                                            *
 *                                                                           *
\*****************************************************************************/

#ifdef CONFIG_PM

static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state)
{
	struct sdhci_chip *chip;
	int i, ret;

	chip = pci_get_drvdata(pdev);
	if (!chip)
		return 0;

	DBG("Suspending...\n");

	for (i = 0;i < chip->num_slots;i++) {
		if (!chip->hosts[i])
			continue;
		ret = mmc_suspend_host(chip->hosts[i]->mmc, state);
		if (ret) {
			for (i--;i >= 0;i--)
				mmc_resume_host(chip->hosts[i]->mmc);
			return ret;
		}
	}

	pci_save_state(pdev);
	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, pci_choose_state(pdev, state));

	return 0;
}

static int sdhci_resume (struct pci_dev *pdev)
{
	struct sdhci_chip *chip;
	int i, ret;

	chip = pci_get_drvdata(pdev);
	if (!chip)
		return 0;

	DBG("Resuming...\n");

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);
	pci_enable_device(pdev);

	for (i = 0;i < chip->num_slots;i++) {
		if (!chip->hosts[i])
			continue;
		if (chip->hosts[i]->flags & SDHCI_USE_DMA)
			pci_set_master(pdev);
		sdhci_init(chip->hosts[i]);
		ret = mmc_resume_host(chip->hosts[i]->mmc);
		if (ret)
			return ret;
	}

	return 0;
}

#else /* CONFIG_PM */

#define sdhci_suspend NULL
#define sdhci_resume NULL

#endif /* CONFIG_PM */

/*****************************************************************************\
 *                                                                           *
 * Device probing/removal                                                    *
 *                                                                           *
\*****************************************************************************/

static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
{
	int ret;
	struct sdhci_chip *chip;
	struct mmc_host *mmc;
	struct sdhci_host *host;

	u8 first_bar;
	unsigned int caps;

	chip = pci_get_drvdata(pdev);
	BUG_ON(!chip);

	ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
	if (ret)
		return ret;

	first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;

	if (first_bar > 5) {
		printk(KERN_ERR DRIVER_NAME ": Invalid first BAR. Aborting.\n");
		return -ENODEV;
	}

	if (!(pci_resource_flags(pdev, first_bar + slot) & IORESOURCE_MEM)) {
		printk(KERN_ERR DRIVER_NAME ": BAR is not iomem. Aborting.\n");
		return -ENODEV;
	}

	if (pci_resource_len(pdev, first_bar + slot) != 0x100) {
		printk(KERN_ERR DRIVER_NAME ": Invalid iomem size. Aborting.\n");
		return -ENODEV;
	}

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

	host = mmc_priv(mmc);
	host->mmc = mmc;

	host->bar = first_bar + slot;

	host->addr = pci_resource_start(pdev, host->bar);
	host->irq = pdev->irq;

	DBG("slot %d at 0x%08lx, irq %d\n", slot, host->addr, host->irq);

	snprintf(host->slot_descr, 20, "sdhci:slot%d", slot);

	ret = pci_request_region(pdev, host->bar, host->slot_descr);
	if (ret)
		goto free;

	host->ioaddr = ioremap_nocache(host->addr,
		pci_resource_len(pdev, host->bar));
	if (!host->ioaddr) {
		ret = -ENOMEM;
		goto release;
	}

	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);

	if ((caps & SDHCI_CAN_DO_DMA) && ((pdev->class & 0x0000FF) == 0x01))
		host->flags |= SDHCI_USE_DMA;

	if (host->flags & SDHCI_USE_DMA) {
		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
			printk(KERN_WARNING "%s: No suitable DMA available. "
				"Falling back to PIO.\n", host->slot_descr);
			host->flags &= ~SDHCI_USE_DMA;
		}
	}

	if (host->flags & SDHCI_USE_DMA)
		pci_set_master(pdev);
	else /* XXX: Hack to get MMC layer to avoid highmem */
		pdev->dma_mask = 0;

	host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
	host->max_clk *= 1000000;

	/*
	 * Set host parameters.
	 */
	mmc->ops = &sdhci_ops;
	mmc->f_min = host->max_clk / 256;
	mmc->f_max = host->max_clk;
	mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA;

	spin_lock_init(&host->lock);

	/*
	 * Maximum number of segments. Hardware cannot do scatter lists.
	 */
	if (host->flags & SDHCI_USE_DMA)
		mmc->max_hw_segs = 1;
	else
		mmc->max_hw_segs = 16;
	mmc->max_phys_segs = 16;

	/*
	 * Maximum number of sectors in one transfer. Limited by sector
	 * count register.
	 */
	mmc->max_sectors = 0x3FFF;

	/*
	 * Maximum segment size. Could be one segment with the maximum number
	 * of sectors.
	 */
	mmc->max_seg_size = mmc->max_sectors * 512;

	/*
	 * Init tasklets.
	 */
	tasklet_init(&host->card_tasklet,
		sdhci_tasklet_card, (unsigned long)host);
	tasklet_init(&host->finish_tasklet,
		sdhci_tasklet_finish, (unsigned long)host);

	setup_timer(&host->timer, sdhci_timeout_timer, (long)host);

	ret = request_irq(host->irq, sdhci_irq, SA_SHIRQ,
		host->slot_descr, host);
	if (ret)
		goto unmap;

	sdhci_init(host);

#ifdef CONFIG_MMC_DEBUG
	sdhci_dumpregs(host);
#endif

	host->chip = chip;
	chip->hosts[slot] = host;

	mmc_add_host(mmc);

	printk(KERN_INFO "%s: SDHCI at 0x%08lx irq %d %s\n", mmc_hostname(mmc),
		host->addr, host->irq,
		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");

	return 0;

unmap:
	tasklet_kill(&host->card_tasklet);
	tasklet_kill(&host->finish_tasklet);

	iounmap(host->ioaddr);
release:
	pci_release_region(pdev, host->bar);
free:
	mmc_free_host(mmc);

	return ret;
}

static void sdhci_remove_slot(struct pci_dev *pdev, int slot)
{
	struct sdhci_chip *chip;
	struct mmc_host *mmc;
	struct sdhci_host *host;

	chip = pci_get_drvdata(pdev);
	host = chip->hosts[slot];
	mmc = host->mmc;

	chip->hosts[slot] = NULL;

	mmc_remove_host(mmc);

	sdhci_reset(host, SDHCI_RESET_ALL);

	free_irq(host->irq, host);

	del_timer_sync(&host->timer);

	tasklet_kill(&host->card_tasklet);
	tasklet_kill(&host->finish_tasklet);

	iounmap(host->ioaddr);

	pci_release_region(pdev, host->bar);

	mmc_free_host(mmc);
}

static int __devinit sdhci_probe(struct pci_dev *pdev,
	const struct pci_device_id *ent)
{
	int ret, i;
	u8 slots;
	struct sdhci_chip *chip;

	BUG_ON(pdev == NULL);
	BUG_ON(ent == NULL);

	DBG("found at %s\n", pci_name(pdev));

	ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
	if (ret)
		return ret;

	slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
	DBG("found %d slot(s)\n", slots);
	if (slots == 0)
		return -ENODEV;

	ret = pci_enable_device(pdev);
	if (ret)
		return ret;

	chip = kzalloc(sizeof(struct sdhci_chip) +
		sizeof(struct sdhci_host*) * slots, GFP_KERNEL);
	if (!chip) {
		ret = -ENOMEM;
		goto err;
	}

	chip->pdev = pdev;

	chip->num_slots = slots;
	pci_set_drvdata(pdev, chip);

	for (i = 0;i < slots;i++) {
		ret = sdhci_probe_slot(pdev, i);
		if (ret) {
			for (i--;i >= 0;i--)
				sdhci_remove_slot(pdev, i);
			goto free;
		}
	}

	return 0;

free:
	pci_set_drvdata(pdev, NULL);
	kfree(chip);

err:
	pci_disable_device(pdev);
	return ret;
}

static void __devexit sdhci_remove(struct pci_dev *pdev)
{
	int i;
	struct sdhci_chip *chip;

	chip = pci_get_drvdata(pdev);

	if (chip) {
		for (i = 0;i < chip->num_slots;i++)
			sdhci_remove_slot(pdev, i);

		pci_set_drvdata(pdev, NULL);

		kfree(chip);
	}

	pci_disable_device(pdev);
}

static struct pci_driver sdhci_driver = {
	.name = 	DRIVER_NAME,
	.id_table =	pci_ids,
	.probe = 	sdhci_probe,
	.remove =	__devexit_p(sdhci_remove),
	.suspend =	sdhci_suspend,
	.resume	=	sdhci_resume,
};

/*****************************************************************************\
 *                                                                           *
 * Driver init/exit                                                          *
 *                                                                           *
\*****************************************************************************/

static int __init sdhci_drv_init(void)
{
	printk(KERN_INFO DRIVER_NAME
		": Secure Digital Host Controller Interface driver, "
		DRIVER_VERSION "\n");
	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");

	return pci_register_driver(&sdhci_driver);
}

static void __exit sdhci_drv_exit(void)
{
	DBG("Exiting\n");

	pci_unregister_driver(&sdhci_driver);
}

module_init(sdhci_drv_init);
module_exit(sdhci_drv_exit);

MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
