/*
 *  cb710/mmc.c
 *
 *  Copyright by Michał Mirosław, 2008-2009
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include "cb710-mmc.h"

static const u8 cb710_clock_divider_log2[8] = {
/*	1, 2, 4, 8, 16, 32, 128, 512 */
	0, 1, 2, 3,  4,  5,   7,   9
};
#define CB710_MAX_DIVIDER_IDX	\
	(ARRAY_SIZE(cb710_clock_divider_log2) - 1)

static const u8 cb710_src_freq_mhz[16] = {
	33, 10, 20, 25, 30, 35, 40, 45,
	50, 55, 60, 65, 70, 75, 80, 85
};

static void cb710_mmc_set_clock(struct mmc_host *mmc, int hz)
{
	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
	struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev;
	u32 src_freq_idx;
	u32 divider_idx;
	int src_hz;

	/* this is magic, unverifiable for me, unless I get
	 * MMC card with cables connected to bus signals */
	pci_read_config_dword(pdev, 0x48, &src_freq_idx);
	src_freq_idx = (src_freq_idx >> 16) & 0xF;
	src_hz = cb710_src_freq_mhz[src_freq_idx] * 1000000;

	for (divider_idx = 0; divider_idx < CB710_MAX_DIVIDER_IDX; ++divider_idx) {
		if (hz >= src_hz >> cb710_clock_divider_log2[divider_idx])
			break;
	}

	if (src_freq_idx)
		divider_idx |= 0x8;

	cb710_pci_update_config_reg(pdev, 0x40, ~0xF0000000, divider_idx << 28);

	dev_dbg(cb710_slot_dev(slot),
		"clock set to %d Hz, wanted %d Hz; flag = %d\n",
		src_hz >> cb710_clock_divider_log2[divider_idx & 7],
		hz, (divider_idx & 8) != 0);
}

static void __cb710_mmc_enable_irq(struct cb710_slot *slot,
	unsigned short enable, unsigned short mask)
{
	/* clear global IE
	 * - it gets set later if any interrupt sources are enabled */
	mask |= CB710_MMC_IE_IRQ_ENABLE;

	/* look like interrupt is fired whenever
	 * WORD[0x0C] & WORD[0x10] != 0;
	 * -> bit 15 port 0x0C seems to be global interrupt enable
	 */

	enable = (cb710_read_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT)
		& ~mask) | enable;

	if (enable)
		enable |= CB710_MMC_IE_IRQ_ENABLE;

	cb710_write_port_16(slot, CB710_MMC_IRQ_ENABLE_PORT, enable);
}

static void cb710_mmc_enable_irq(struct cb710_slot *slot,
	unsigned short enable, unsigned short mask)
{
	struct cb710_mmc_reader *reader = mmc_priv(cb710_slot_to_mmc(slot));
	unsigned long flags;

	spin_lock_irqsave(&reader->irq_lock, flags);
	/* this is the only thing irq_lock protects */
	__cb710_mmc_enable_irq(slot, enable, mask);
	spin_unlock_irqrestore(&reader->irq_lock, flags);
}

static void cb710_mmc_reset_events(struct cb710_slot *slot)
{
	cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, 0xFF);
	cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, 0xFF);
	cb710_write_port_8(slot, CB710_MMC_STATUS2_PORT, 0xFF);
}

static int cb710_mmc_is_card_inserted(struct cb710_slot *slot)
{
	return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
		& CB710_MMC_S3_CARD_DETECTED;
}

static void cb710_mmc_enable_4bit_data(struct cb710_slot *slot, int enable)
{
	dev_dbg(cb710_slot_dev(slot), "configuring %d-data-line%s mode\n",
		enable ? 4 : 1, enable ? "s" : "");
	if (enable)
		cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
			CB710_MMC_C1_4BIT_DATA_BUS, 0);
	else
		cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT,
			0, CB710_MMC_C1_4BIT_DATA_BUS);
}

static int cb710_check_event(struct cb710_slot *slot, u8 what)
{
	u16 status;

	status = cb710_read_port_16(slot, CB710_MMC_STATUS_PORT);

	if (status & CB710_MMC_S0_FIFO_UNDERFLOW) {
		/* it is just a guess, so log it */
		dev_dbg(cb710_slot_dev(slot),
			"CHECK : ignoring bit 6 in status %04X\n", status);
		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
			CB710_MMC_S0_FIFO_UNDERFLOW);
		status &= ~CB710_MMC_S0_FIFO_UNDERFLOW;
	}

	if (status & CB710_MMC_STATUS_ERROR_EVENTS) {
		dev_dbg(cb710_slot_dev(slot),
			"CHECK : returning EIO on status %04X\n", status);
		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT, status & 0xFF);
		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
			CB710_MMC_S1_RESET);
		return -EIO;
	}

	/* 'what' is a bit in MMC_STATUS1 */
	if ((status >> 8) & what) {
		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT, what);
		return 1;
	}

	return 0;
}

static int cb710_wait_for_event(struct cb710_slot *slot, u8 what)
{
	int err = 0;
	unsigned limit = 2000000;	/* FIXME: real timeout */

#ifdef CONFIG_CB710_DEBUG
	u32 e, x;
	e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
#endif

	while (!(err = cb710_check_event(slot, what))) {
		if (!--limit) {
			cb710_dump_regs(cb710_slot_to_chip(slot),
				CB710_DUMP_REGS_MMC);
			err = -ETIMEDOUT;
			break;
		}
		udelay(1);
	}

#ifdef CONFIG_CB710_DEBUG
	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);

	limit = 2000000 - limit;
	if (limit > 100)
		dev_dbg(cb710_slot_dev(slot),
			"WAIT10: waited %d loops, what %d, entry val %08X, exit val %08X\n",
			limit, what, e, x);
#endif
	return err < 0 ? err : 0;
}


static int cb710_wait_while_busy(struct cb710_slot *slot, uint8_t mask)
{
	unsigned limit = 500000;	/* FIXME: real timeout */
	int err = 0;

#ifdef CONFIG_CB710_DEBUG
	u32 e, x;
	e = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
#endif

	while (cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & mask) {
		if (!--limit) {
			cb710_dump_regs(cb710_slot_to_chip(slot),
				CB710_DUMP_REGS_MMC);
			err = -ETIMEDOUT;
			break;
		}
		udelay(1);
	}

#ifdef CONFIG_CB710_DEBUG
	x = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);

	limit = 500000 - limit;
	if (limit > 100)
		dev_dbg(cb710_slot_dev(slot),
			"WAIT12: waited %d loops, mask %02X, entry val %08X, exit val %08X\n",
			limit, mask, e, x);
#endif
	return 0;
}

static void cb710_mmc_set_transfer_size(struct cb710_slot *slot,
	size_t count, size_t blocksize)
{
	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	cb710_write_port_32(slot, CB710_MMC_TRANSFER_SIZE_PORT,
		((count - 1) << 16)|(blocksize - 1));

	dev_vdbg(cb710_slot_dev(slot), "set up for %zu block%s of %zu bytes\n",
		count, count == 1 ? "" : "s", blocksize);
}

static void cb710_mmc_fifo_hack(struct cb710_slot *slot)
{
	/* without this, received data is prepended with 8-bytes of zeroes */
	u32 r1, r2;
	int ok = 0;

	r1 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
	r2 = cb710_read_port_32(slot, CB710_MMC_DATA_PORT);
	if (cb710_read_port_8(slot, CB710_MMC_STATUS0_PORT)
	    & CB710_MMC_S0_FIFO_UNDERFLOW) {
		cb710_write_port_8(slot, CB710_MMC_STATUS0_PORT,
			CB710_MMC_S0_FIFO_UNDERFLOW);
		ok = 1;
	}

	dev_dbg(cb710_slot_dev(slot),
		"FIFO-read-hack: expected STATUS0 bit was %s\n",
		ok ? "set." : "NOT SET!");
	dev_dbg(cb710_slot_dev(slot),
		"FIFO-read-hack: dwords ignored: %08X %08X - %s\n",
		r1, r2, (r1|r2) ? "BAD (NOT ZERO)!" : "ok");
}

static int cb710_mmc_receive_pio(struct cb710_slot *slot,
	struct sg_mapping_iter *miter, size_t dw_count)
{
	if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT) & CB710_MMC_S2_FIFO_READY)) {
		int err = cb710_wait_for_event(slot,
			CB710_MMC_S1_PIO_TRANSFER_DONE);
		if (err)
			return err;
	}

	cb710_sg_dwiter_write_from_io(miter,
		slot->iobase + CB710_MMC_DATA_PORT, dw_count);

	return 0;
}

static bool cb710_is_transfer_size_supported(struct mmc_data *data)
{
	return !(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8));
}

static int cb710_mmc_receive(struct cb710_slot *slot, struct mmc_data *data)
{
	struct sg_mapping_iter miter;
	size_t len, blocks = data->blocks;
	int err = 0;

	/* TODO: I don't know how/if the hardware handles non-16B-boundary blocks
	 * except single 8B block */
	if (unlikely(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8)))
		return -EINVAL;

	sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_TO_SG);

	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
		15, CB710_MMC_C2_READ_PIO_SIZE_MASK);

	cb710_mmc_fifo_hack(slot);

	while (blocks-- > 0) {
		len = data->blksz;

		while (len >= 16) {
			err = cb710_mmc_receive_pio(slot, &miter, 4);
			if (err)
				goto out;
			len -= 16;
		}

		if (!len)
			continue;

		cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
			len - 1, CB710_MMC_C2_READ_PIO_SIZE_MASK);

		len = (len >= 8) ? 4 : 2;
		err = cb710_mmc_receive_pio(slot, &miter, len);
		if (err)
			goto out;
	}
out:
	sg_miter_stop(&miter);
	return err;
}

static int cb710_mmc_send(struct cb710_slot *slot, struct mmc_data *data)
{
	struct sg_mapping_iter miter;
	size_t len, blocks = data->blocks;
	int err = 0;

	/* TODO: I don't know how/if the hardware handles multiple
	 * non-16B-boundary blocks */
	if (unlikely(data->blocks > 1 && data->blksz & 15))
		return -EINVAL;

	sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_FROM_SG);

	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT,
		0, CB710_MMC_C2_READ_PIO_SIZE_MASK);

	while (blocks-- > 0) {
		len = (data->blksz + 15) >> 4;
		do {
			if (!(cb710_read_port_8(slot, CB710_MMC_STATUS2_PORT)
			    & CB710_MMC_S2_FIFO_EMPTY)) {
				err = cb710_wait_for_event(slot,
					CB710_MMC_S1_PIO_TRANSFER_DONE);
				if (err)
					goto out;
			}
			cb710_sg_dwiter_read_to_io(&miter,
				slot->iobase + CB710_MMC_DATA_PORT, 4);
		} while (--len);
	}
out:
	sg_miter_stop(&miter);
	return err;
}

static u16 cb710_encode_cmd_flags(struct cb710_mmc_reader *reader,
	struct mmc_command *cmd)
{
	unsigned int flags = cmd->flags;
	u16 cb_flags = 0;

	/* Windows driver returned 0 for commands for which no response
	 * is expected. It happened that there were only two such commands
	 * used: MMC_GO_IDLE_STATE and MMC_GO_INACTIVE_STATE so it might
	 * as well be a bug in that driver.
	 *
	 * Original driver set bit 14 for MMC/SD application
	 * commands. There's no difference 'on the wire' and
	 * it apparently works without it anyway.
	 */

	switch (flags & MMC_CMD_MASK) {
	case MMC_CMD_AC:	cb_flags = CB710_MMC_CMD_AC;	break;
	case MMC_CMD_ADTC:	cb_flags = CB710_MMC_CMD_ADTC;	break;
	case MMC_CMD_BC:	cb_flags = CB710_MMC_CMD_BC;	break;
	case MMC_CMD_BCR:	cb_flags = CB710_MMC_CMD_BCR;	break;
	}

	if (flags & MMC_RSP_BUSY)
		cb_flags |= CB710_MMC_RSP_BUSY;

	cb_flags |= cmd->opcode << CB710_MMC_CMD_CODE_SHIFT;

	if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
		cb_flags |= CB710_MMC_DATA_READ;

	if (flags & MMC_RSP_PRESENT) {
		/* Windows driver set 01 at bits 4,3 except for
		 * MMC_SET_BLOCKLEN where it set 10. Maybe the
		 * hardware can do something special about this
		 * command? The original driver looks buggy/incomplete
		 * anyway so we ignore this for now.
		 *
		 * I assume that 00 here means no response is expected.
		 */
		cb_flags |= CB710_MMC_RSP_PRESENT;

		if (flags & MMC_RSP_136)
			cb_flags |= CB710_MMC_RSP_136;
		if (!(flags & MMC_RSP_CRC))
			cb_flags |= CB710_MMC_RSP_NO_CRC;
	}

	return cb_flags;
}

static void cb710_receive_response(struct cb710_slot *slot,
	struct mmc_command *cmd)
{
	unsigned rsp_opcode, wanted_opcode;

	/* Looks like final byte with CRC is always stripped (same as SDHCI) */
	if (cmd->flags & MMC_RSP_136) {
		u32 resp[4];

		resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE3_PORT);
		resp[1] = cb710_read_port_32(slot, CB710_MMC_RESPONSE2_PORT);
		resp[2] = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT);
		resp[3] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
		rsp_opcode = resp[0] >> 24;

		cmd->resp[0] = (resp[0] << 8)|(resp[1] >> 24);
		cmd->resp[1] = (resp[1] << 8)|(resp[2] >> 24);
		cmd->resp[2] = (resp[2] << 8)|(resp[3] >> 24);
		cmd->resp[3] = (resp[3] << 8);
	} else {
		rsp_opcode = cb710_read_port_32(slot, CB710_MMC_RESPONSE1_PORT) & 0x3F;
		cmd->resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT);
	}

	wanted_opcode = (cmd->flags & MMC_RSP_OPCODE) ? cmd->opcode : 0x3F;
	if (rsp_opcode != wanted_opcode)
		cmd->error = -EILSEQ;
}

static int cb710_mmc_transfer_data(struct cb710_slot *slot,
	struct mmc_data *data)
{
	int error, to;

	if (data->flags & MMC_DATA_READ)
		error = cb710_mmc_receive(slot, data);
	else
		error = cb710_mmc_send(slot, data);

	to = cb710_wait_for_event(slot, CB710_MMC_S1_DATA_TRANSFER_DONE);
	if (!error)
		error = to;

	if (!error)
		data->bytes_xfered = data->blksz * data->blocks;
	return error;
}

static int cb710_mmc_command(struct mmc_host *mmc, struct mmc_command *cmd)
{
	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
	struct cb710_mmc_reader *reader = mmc_priv(mmc);
	struct mmc_data *data = cmd->data;

	u16 cb_cmd = cb710_encode_cmd_flags(reader, cmd);
	dev_dbg(cb710_slot_dev(slot), "cmd request: 0x%04X\n", cb_cmd);

	if (data) {
		if (!cb710_is_transfer_size_supported(data)) {
			data->error = -EINVAL;
			return -1;
		}
		cb710_mmc_set_transfer_size(slot, data->blocks, data->blksz);
	}

	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20|CB710_MMC_S2_BUSY_10);
	cb710_write_port_16(slot, CB710_MMC_CMD_TYPE_PORT, cb_cmd);
	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	cb710_write_port_32(slot, CB710_MMC_CMD_PARAM_PORT, cmd->arg);
	cb710_mmc_reset_events(slot);
	cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x01, 0);

	cmd->error = cb710_wait_for_event(slot, CB710_MMC_S1_COMMAND_SENT);
	if (cmd->error)
		return -1;

	if (cmd->flags & MMC_RSP_PRESENT) {
		cb710_receive_response(slot, cmd);
		if (cmd->error)
			return -1;
	}

	if (data)
		data->error = cb710_mmc_transfer_data(slot, data);
	return 0;
}

static void cb710_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
	struct cb710_mmc_reader *reader = mmc_priv(mmc);

	WARN_ON(reader->mrq != NULL);

	reader->mrq = mrq;
	cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);

	if (cb710_mmc_is_card_inserted(slot)) {
		if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop)
			cb710_mmc_command(mmc, mrq->stop);
		mdelay(1);
	} else {
		mrq->cmd->error = -ENOMEDIUM;
	}

	tasklet_schedule(&reader->finish_req_tasklet);
}

static int cb710_mmc_powerup(struct cb710_slot *slot)
{
#ifdef CONFIG_CB710_DEBUG
	struct cb710_chip *chip = cb710_slot_to_chip(slot);
#endif
	int err;

	/* a lot of magic; see comment in cb710_mmc_set_clock() */
	dev_dbg(cb710_slot_dev(slot), "bus powerup\n");
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	if (unlikely(err))
		return err;
	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x80, 0);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x80, 0);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	mdelay(1);
	dev_dbg(cb710_slot_dev(slot), "after delay 1\n");
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	if (unlikely(err))
		return err;
	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x09, 0);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	mdelay(1);
	dev_dbg(cb710_slot_dev(slot), "after delay 2\n");
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	if (unlikely(err))
		return err;
	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x08);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	mdelay(2);
	dev_dbg(cb710_slot_dev(slot), "after delay 3\n");
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0x70, 0);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG2_PORT, 0x80, 0);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0x03, 0);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	err = cb710_wait_while_busy(slot, CB710_MMC_S2_BUSY_20);
	if (unlikely(err))
		return err;
	/* This port behaves weird: quick byte reads of 0x08,0x09 return
	 * 0xFF,0x00 after writing 0xFFFF to 0x08; it works correctly when
	 * read/written from userspace...  What am I missing here?
	 * (it doesn't depend on write-to-read delay) */
	cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0xFFFF);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG0_PORT, 0x06, 0);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);
	dev_dbg(cb710_slot_dev(slot), "bus powerup finished\n");

	return cb710_check_event(slot, 0);
}

static void cb710_mmc_powerdown(struct cb710_slot *slot)
{
	cb710_modify_port_8(slot, CB710_MMC_CONFIG1_PORT, 0, 0x81);
	cb710_modify_port_8(slot, CB710_MMC_CONFIG3_PORT, 0, 0x80);
}

static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);
	struct cb710_mmc_reader *reader = mmc_priv(mmc);
	int err;

	cb710_mmc_set_clock(mmc, ios->clock);

	if (!cb710_mmc_is_card_inserted(slot)) {
		dev_dbg(cb710_slot_dev(slot),
			"no card inserted - ignoring bus powerup request\n");
		ios->power_mode = MMC_POWER_OFF;
	}

	if (ios->power_mode != reader->last_power_mode)
	switch (ios->power_mode) {
	case MMC_POWER_ON:
		err = cb710_mmc_powerup(slot);
		if (err) {
			dev_warn(cb710_slot_dev(slot),
				"powerup failed (%d)- retrying\n", err);
			cb710_mmc_powerdown(slot);
			udelay(1);
			err = cb710_mmc_powerup(slot);
			if (err)
				dev_warn(cb710_slot_dev(slot),
					"powerup retry failed (%d) - expect errors\n",
					err);
		}
		reader->last_power_mode = MMC_POWER_ON;
		break;
	case MMC_POWER_OFF:
		cb710_mmc_powerdown(slot);
		reader->last_power_mode = MMC_POWER_OFF;
		break;
	case MMC_POWER_UP:
	default:
		/* ignore */;
	}

	cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1);

	cb710_mmc_enable_irq(slot, CB710_MMC_IE_TEST_MASK, 0);
}

static int cb710_mmc_get_ro(struct mmc_host *mmc)
{
	struct cb710_slot *slot = cb710_mmc_to_slot(mmc);

	return cb710_read_port_8(slot, CB710_MMC_STATUS3_PORT)
		& CB710_MMC_S3_WRITE_PROTECTED;
}

static int cb710_mmc_irq_handler(struct cb710_slot *slot)
{
	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
	struct cb710_mmc_reader *reader = mmc_priv(mmc);
	u32 status, config1, config2, irqen;

	status = cb710_read_port_32(slot, CB710_MMC_STATUS_PORT);
	irqen = cb710_read_port_32(slot, CB710_MMC_IRQ_ENABLE_PORT);
	config2 = cb710_read_port_32(slot, CB710_MMC_CONFIGB_PORT);
	config1 = cb710_read_port_32(slot, CB710_MMC_CONFIG_PORT);

	dev_dbg(cb710_slot_dev(slot), "interrupt; status: %08X, "
		"ie: %08X, c2: %08X, c1: %08X\n",
		status, irqen, config2, config1);

	if (status & (CB710_MMC_S1_CARD_CHANGED << 8)) {
		/* ack the event */
		cb710_write_port_8(slot, CB710_MMC_STATUS1_PORT,
			CB710_MMC_S1_CARD_CHANGED);
		if ((irqen & CB710_MMC_IE_CISTATUS_MASK)
		    == CB710_MMC_IE_CISTATUS_MASK)
			mmc_detect_change(mmc, HZ/5);
	} else {
		dev_dbg(cb710_slot_dev(slot), "unknown interrupt (test)\n");
		spin_lock(&reader->irq_lock);
		__cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_TEST_MASK);
		spin_unlock(&reader->irq_lock);
	}

	return 1;
}

static void cb710_mmc_finish_request_tasklet(unsigned long data)
{
	struct mmc_host *mmc = (void *)data;
	struct cb710_mmc_reader *reader = mmc_priv(mmc);
	struct mmc_request *mrq = reader->mrq;

	reader->mrq = NULL;
	mmc_request_done(mmc, mrq);
}

static const struct mmc_host_ops cb710_mmc_host = {
	.request = cb710_mmc_request,
	.set_ios = cb710_mmc_set_ios,
	.get_ro = cb710_mmc_get_ro
};

#ifdef CONFIG_PM

static int cb710_mmc_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
	int err;

	err = mmc_suspend_host(mmc, state);
	if (err)
		return err;

	cb710_mmc_enable_irq(slot, 0, ~0);
	return 0;
}

static int cb710_mmc_resume(struct platform_device *pdev)
{
	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
	struct mmc_host *mmc = cb710_slot_to_mmc(slot);

	cb710_mmc_enable_irq(slot, 0, ~0);

	return mmc_resume_host(mmc);
}

#endif /* CONFIG_PM */

static int __devinit cb710_mmc_init(struct platform_device *pdev)
{
	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
	struct cb710_chip *chip = cb710_slot_to_chip(slot);
	struct mmc_host *mmc;
	struct cb710_mmc_reader *reader;
	int err;
	u32 val;

	mmc = mmc_alloc_host(sizeof(*reader), cb710_slot_dev(slot));
	if (!mmc)
		return -ENOMEM;

	dev_set_drvdata(&pdev->dev, mmc);

	/* harmless (maybe) magic */
	pci_read_config_dword(chip->pdev, 0x48, &val);
	val = cb710_src_freq_mhz[(val >> 16) & 0xF];
	dev_dbg(cb710_slot_dev(slot), "source frequency: %dMHz\n", val);
	val *= 1000000;

	mmc->ops = &cb710_mmc_host;
	mmc->f_max = val;
	mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX];
	mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA;

	reader = mmc_priv(mmc);

	tasklet_init(&reader->finish_req_tasklet,
		cb710_mmc_finish_request_tasklet, (unsigned long)mmc);
	spin_lock_init(&reader->irq_lock);
	cb710_dump_regs(chip, CB710_DUMP_REGS_MMC);

	cb710_mmc_enable_irq(slot, 0, ~0);
	cb710_set_irq_handler(slot, cb710_mmc_irq_handler);

	err = mmc_add_host(mmc);
	if (unlikely(err))
		goto err_free_mmc;

	dev_dbg(cb710_slot_dev(slot), "mmc_hostname is %s\n",
		mmc_hostname(mmc));

	cb710_mmc_enable_irq(slot, CB710_MMC_IE_CARD_INSERTION_STATUS, 0);

	return 0;

err_free_mmc:
	dev_dbg(cb710_slot_dev(slot), "mmc_add_host() failed: %d\n", err);

	mmc_free_host(mmc);
	return err;
}

static int __devexit cb710_mmc_exit(struct platform_device *pdev)
{
	struct cb710_slot *slot = cb710_pdev_to_slot(pdev);
	struct mmc_host *mmc = cb710_slot_to_mmc(slot);
	struct cb710_mmc_reader *reader = mmc_priv(mmc);

	cb710_mmc_enable_irq(slot, 0, CB710_MMC_IE_CARD_INSERTION_STATUS);

	mmc_remove_host(mmc);

	/* IRQs should be disabled now, but let's stay on the safe side */
	cb710_mmc_enable_irq(slot, 0, ~0);
	cb710_set_irq_handler(slot, NULL);

	/* clear config ports - just in case */
	cb710_write_port_32(slot, CB710_MMC_CONFIG_PORT, 0);
	cb710_write_port_16(slot, CB710_MMC_CONFIGB_PORT, 0);

	tasklet_kill(&reader->finish_req_tasklet);

	mmc_free_host(mmc);
	return 0;
}

static struct platform_driver cb710_mmc_driver = {
	.driver.name = "cb710-mmc",
	.probe = cb710_mmc_init,
	.remove = __devexit_p(cb710_mmc_exit),
#ifdef CONFIG_PM
	.suspend = cb710_mmc_suspend,
	.resume = cb710_mmc_resume,
#endif
};

static int __init cb710_mmc_init_module(void)
{
	return platform_driver_register(&cb710_mmc_driver);
}

static void __exit cb710_mmc_cleanup_module(void)
{
	platform_driver_unregister(&cb710_mmc_driver);
}

module_init(cb710_mmc_init_module);
module_exit(cb710_mmc_cleanup_module);

MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:cb710-mmc");
