// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  linux/drivers/mmc/host/wbsd.c - Winbond W83L51xD SD/MMC driver
 *
 *  Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved.
 *
 * Warning!
 *
 * Changes to the FIFO system should be done with extreme care since
 * the hardware is full of bugs related to the FIFO. Known issues are:
 *
 * - FIFO size field in FSR is always zero.
 *
 * - FIFO interrupts tend not to work as they should. Interrupts are
 *   triggered only for full/empty events, not for threshold values.
 *
 * - On APIC systems the FIFO empty interrupt is sometimes lost.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/pnp.h>
#include <linux/highmem.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>

#include <asm/io.h>
#include <asm/dma.h>

#include "wbsd.h"

#define DRIVER_NAME "wbsd"

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

/*
 * Device resources
 */

#ifdef CONFIG_PNP

static const struct pnp_device_id pnp_dev_table[] = {
	{ "WEC0517", 0 },
	{ "WEC0518", 0 },
	{ "", 0 },
};

MODULE_DEVICE_TABLE(pnp, pnp_dev_table);

#endif /* CONFIG_PNP */

static const int config_ports[] = { 0x2E, 0x4E };
static const int unlock_codes[] = { 0x83, 0x87 };

static const int valid_ids[] = {
	0x7112,
};

#ifdef CONFIG_PNP
static unsigned int param_nopnp = 0;
#else
static const unsigned int param_nopnp = 1;
#endif
static unsigned int param_io = 0x248;
static unsigned int param_irq = 6;
static int param_dma = 2;

/*
 * Basic functions
 */

static inline void wbsd_unlock_config(struct wbsd_host *host)
{
	BUG_ON(host->config == 0);

	outb(host->unlock_code, host->config);
	outb(host->unlock_code, host->config);
}

static inline void wbsd_lock_config(struct wbsd_host *host)
{
	BUG_ON(host->config == 0);

	outb(LOCK_CODE, host->config);
}

static inline void wbsd_write_config(struct wbsd_host *host, u8 reg, u8 value)
{
	BUG_ON(host->config == 0);

	outb(reg, host->config);
	outb(value, host->config + 1);
}

static inline u8 wbsd_read_config(struct wbsd_host *host, u8 reg)
{
	BUG_ON(host->config == 0);

	outb(reg, host->config);
	return inb(host->config + 1);
}

static inline void wbsd_write_index(struct wbsd_host *host, u8 index, u8 value)
{
	outb(index, host->base + WBSD_IDXR);
	outb(value, host->base + WBSD_DATAR);
}

static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index)
{
	outb(index, host->base + WBSD_IDXR);
	return inb(host->base + WBSD_DATAR);
}

/*
 * Common routines
 */

static void wbsd_init_device(struct wbsd_host *host)
{
	u8 setup, ier;

	/*
	 * Reset chip (SD/MMC part) and fifo.
	 */
	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
	setup |= WBSD_FIFO_RESET | WBSD_SOFT_RESET;
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);

	/*
	 * Set DAT3 to input
	 */
	setup &= ~WBSD_DAT3_H;
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
	host->flags &= ~WBSD_FIGNORE_DETECT;

	/*
	 * Read back default clock.
	 */
	host->clk = wbsd_read_index(host, WBSD_IDX_CLK);

	/*
	 * Power down port.
	 */
	outb(WBSD_POWER_N, host->base + WBSD_CSR);

	/*
	 * Set maximum timeout.
	 */
	wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F);

	/*
	 * Test for card presence
	 */
	if (inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT)
		host->flags |= WBSD_FCARD_PRESENT;
	else
		host->flags &= ~WBSD_FCARD_PRESENT;

	/*
	 * Enable interesting interrupts.
	 */
	ier = 0;
	ier |= WBSD_EINT_CARD;
	ier |= WBSD_EINT_FIFO_THRE;
	ier |= WBSD_EINT_CRC;
	ier |= WBSD_EINT_TIMEOUT;
	ier |= WBSD_EINT_TC;

	outb(ier, host->base + WBSD_EIR);

	/*
	 * Clear interrupts.
	 */
	inb(host->base + WBSD_ISR);
}

static void wbsd_reset(struct wbsd_host *host)
{
	u8 setup;

	pr_err("%s: Resetting chip\n", mmc_hostname(host->mmc));

	/*
	 * Soft reset of chip (SD/MMC part).
	 */
	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
	setup |= WBSD_SOFT_RESET;
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
}

static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq)
{
	unsigned long dmaflags;

	if (host->dma >= 0) {
		/*
		 * Release ISA DMA controller.
		 */
		dmaflags = claim_dma_lock();
		disable_dma(host->dma);
		clear_dma_ff(host->dma);
		release_dma_lock(dmaflags);

		/*
		 * Disable DMA on host.
		 */
		wbsd_write_index(host, WBSD_IDX_DMA, 0);
	}

	host->mrq = NULL;

	/*
	 * MMC layer might call back into the driver so first unlock.
	 */
	spin_unlock(&host->lock);
	mmc_request_done(host->mmc, mrq);
	spin_lock(&host->lock);
}

/*
 * Scatter/gather functions
 */

static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data)
{
	/*
	 * Get info. about SG list from data structure.
	 */
	host->cur_sg = data->sg;
	host->num_sg = data->sg_len;

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

static inline int wbsd_next_sg(struct wbsd_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 inline char *wbsd_map_sg(struct wbsd_host *host)
{
	return kmap_local_page(sg_page(host->cur_sg)) + host->cur_sg->offset;
}

static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
{
	size_t len = 0;
	int i;

	for (i = 0; i < data->sg_len; i++)
		len += data->sg[i].length;
	sg_copy_to_buffer(data->sg, data->sg_len, host->dma_buffer, len);
}

static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
{
	size_t len = 0;
	int i;

	for (i = 0; i < data->sg_len; i++)
		len += data->sg[i].length;
	sg_copy_from_buffer(data->sg, data->sg_len, host->dma_buffer, len);
}

/*
 * Command handling
 */

static inline void wbsd_get_short_reply(struct wbsd_host *host,
					struct mmc_command *cmd)
{
	/*
	 * Correct response type?
	 */
	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) {
		cmd->error = -EILSEQ;
		return;
	}

	cmd->resp[0]  = wbsd_read_index(host, WBSD_IDX_RESP12) << 24;
	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP13) << 16;
	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP14) << 8;
	cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP15) << 0;
	cmd->resp[1]  = wbsd_read_index(host, WBSD_IDX_RESP16) << 24;
}

static inline void wbsd_get_long_reply(struct wbsd_host *host,
	struct mmc_command *cmd)
{
	int i;

	/*
	 * Correct response type?
	 */
	if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) {
		cmd->error = -EILSEQ;
		return;
	}

	for (i = 0; i < 4; i++) {
		cmd->resp[i] =
			wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24;
		cmd->resp[i] |=
			wbsd_read_index(host, WBSD_IDX_RESP2 + i * 4) << 16;
		cmd->resp[i] |=
			wbsd_read_index(host, WBSD_IDX_RESP3 + i * 4) << 8;
		cmd->resp[i] |=
			wbsd_read_index(host, WBSD_IDX_RESP4 + i * 4) << 0;
	}
}

static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
{
	int i;
	u8 status, isr;

	/*
	 * Clear accumulated ISR. The interrupt routine
	 * will fill this one with events that occur during
	 * transfer.
	 */
	host->isr = 0;

	/*
	 * Send the command (CRC calculated by host).
	 */
	outb(cmd->opcode, host->base + WBSD_CMDR);
	for (i = 3; i >= 0; i--)
		outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);

	cmd->error = 0;

	/*
	 * Wait for the request to complete.
	 */
	do {
		status = wbsd_read_index(host, WBSD_IDX_STATUS);
	} while (status & WBSD_CARDTRAFFIC);

	/*
	 * Do we expect a reply?
	 */
	if (cmd->flags & MMC_RSP_PRESENT) {
		/*
		 * Read back status.
		 */
		isr = host->isr;

		/* Card removed? */
		if (isr & WBSD_INT_CARD)
			cmd->error = -ENOMEDIUM;
		/* Timeout? */
		else if (isr & WBSD_INT_TIMEOUT)
			cmd->error = -ETIMEDOUT;
		/* CRC? */
		else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
			cmd->error = -EILSEQ;
		/* All ok */
		else {
			if (cmd->flags & MMC_RSP_136)
				wbsd_get_long_reply(host, cmd);
			else
				wbsd_get_short_reply(host, cmd);
		}
	}
}

/*
 * Data functions
 */

static void wbsd_empty_fifo(struct wbsd_host *host)
{
	struct mmc_data *data = host->mrq->cmd->data;
	char *buffer;
	int i, idx, fsr, fifo;

	/*
	 * Handle excessive data.
	 */
	if (host->num_sg == 0)
		return;

	buffer = wbsd_map_sg(host) + host->offset;
	idx = 0;

	/*
	 * Drain the fifo. This has a tendency to loop longer
	 * than the FIFO length (usually one block).
	 */
	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) {
		/*
		 * The size field in the FSR is broken so we have to
		 * do some guessing.
		 */
		if (fsr & WBSD_FIFO_FULL)
			fifo = 16;
		else if (fsr & WBSD_FIFO_FUTHRE)
			fifo = 8;
		else
			fifo = 1;

		for (i = 0; i < fifo; i++) {
			buffer[idx++] = inb(host->base + WBSD_DFR);
			host->offset++;
			host->remain--;

			data->bytes_xfered++;

			/*
			 * End of scatter list entry?
			 */
			if (host->remain == 0) {
				kunmap_local(buffer);
				/*
				 * Get next entry. Check if last.
				 */
				if (!wbsd_next_sg(host))
					return;

				buffer = wbsd_map_sg(host);
				idx = 0;
			}
		}
	}
	kunmap_local(buffer);

	/*
	 * This is a very dirty hack to solve a
	 * hardware problem. The chip doesn't trigger
	 * FIFO threshold interrupts properly.
	 */
	if ((data->blocks * data->blksz - data->bytes_xfered) < 16)
		tasklet_schedule(&host->fifo_tasklet);
}

static void wbsd_fill_fifo(struct wbsd_host *host)
{
	struct mmc_data *data = host->mrq->cmd->data;
	char *buffer;
	int i, idx, fsr, fifo;

	/*
	 * Check that we aren't being called after the
	 * entire buffer has been transferred.
	 */
	if (host->num_sg == 0)
		return;

	buffer = wbsd_map_sg(host) + host->offset;
	idx = 0;

	/*
	 * Fill the fifo. This has a tendency to loop longer
	 * than the FIFO length (usually one block).
	 */
	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) {
		/*
		 * The size field in the FSR is broken so we have to
		 * do some guessing.
		 */
		if (fsr & WBSD_FIFO_EMPTY)
			fifo = 0;
		else if (fsr & WBSD_FIFO_EMTHRE)
			fifo = 8;
		else
			fifo = 15;

		for (i = 16; i > fifo; i--) {
			outb(buffer[idx], host->base + WBSD_DFR);
			host->offset++;
			host->remain--;

			data->bytes_xfered++;

			/*
			 * End of scatter list entry?
			 */
			if (host->remain == 0) {
				kunmap_local(buffer);
				/*
				 * Get next entry. Check if last.
				 */
				if (!wbsd_next_sg(host))
					return;

				buffer = wbsd_map_sg(host);
				idx = 0;
			}
		}
	}
	kunmap_local(buffer);

	/*
	 * The controller stops sending interrupts for
	 * 'FIFO empty' under certain conditions. So we
	 * need to be a bit more pro-active.
	 */
	tasklet_schedule(&host->fifo_tasklet);
}

static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
{
	u16 blksize;
	u8 setup;
	unsigned long dmaflags;
	unsigned int size;

	/*
	 * Calculate size.
	 */
	size = data->blocks * data->blksz;

	/*
	 * Check timeout values for overflow.
	 * (Yes, some cards cause this value to overflow).
	 */
	if (data->timeout_ns > 127000000)
		wbsd_write_index(host, WBSD_IDX_TAAC, 127);
	else {
		wbsd_write_index(host, WBSD_IDX_TAAC,
			data->timeout_ns / 1000000);
	}

	if (data->timeout_clks > 255)
		wbsd_write_index(host, WBSD_IDX_NSAC, 255);
	else
		wbsd_write_index(host, WBSD_IDX_NSAC, data->timeout_clks);

	/*
	 * Inform the chip of how large blocks will be
	 * sent. It needs this to determine when to
	 * calculate CRC.
	 *
	 * Space for CRC must be included in the size.
	 * Two bytes are needed for each data line.
	 */
	if (host->bus_width == MMC_BUS_WIDTH_1) {
		blksize = data->blksz + 2;

		wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
		wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
	} else if (host->bus_width == MMC_BUS_WIDTH_4) {
		blksize = data->blksz + 2 * 4;

		wbsd_write_index(host, WBSD_IDX_PBSMSB,
			((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
		wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
	} else {
		data->error = -EINVAL;
		return;
	}

	/*
	 * Clear the FIFO. This is needed even for DMA
	 * transfers since the chip still uses the FIFO
	 * internally.
	 */
	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
	setup |= WBSD_FIFO_RESET;
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);

	/*
	 * DMA transfer?
	 */
	if (host->dma >= 0) {
		/*
		 * The buffer for DMA is only 64 kB.
		 */
		BUG_ON(size > 0x10000);
		if (size > 0x10000) {
			data->error = -EINVAL;
			return;
		}

		/*
		 * Transfer data from the SG list to
		 * the DMA buffer.
		 */
		if (data->flags & MMC_DATA_WRITE)
			wbsd_sg_to_dma(host, data);

		/*
		 * Initialise the ISA DMA controller.
		 */
		dmaflags = claim_dma_lock();
		disable_dma(host->dma);
		clear_dma_ff(host->dma);
		if (data->flags & MMC_DATA_READ)
			set_dma_mode(host->dma, DMA_MODE_READ & ~0x40);
		else
			set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40);
		set_dma_addr(host->dma, host->dma_addr);
		set_dma_count(host->dma, size);

		enable_dma(host->dma);
		release_dma_lock(dmaflags);

		/*
		 * Enable DMA on the host.
		 */
		wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE);
	} else {
		/*
		 * This flag is used to keep printk
		 * output to a minimum.
		 */
		host->firsterr = 1;

		/*
		 * Initialise the SG list.
		 */
		wbsd_init_sg(host, data);

		/*
		 * Turn off DMA.
		 */
		wbsd_write_index(host, WBSD_IDX_DMA, 0);

		/*
		 * Set up FIFO threshold levels (and fill
		 * buffer if doing a write).
		 */
		if (data->flags & MMC_DATA_READ) {
			wbsd_write_index(host, WBSD_IDX_FIFOEN,
				WBSD_FIFOEN_FULL | 8);
		} else {
			wbsd_write_index(host, WBSD_IDX_FIFOEN,
				WBSD_FIFOEN_EMPTY | 8);
			wbsd_fill_fifo(host);
		}
	}

	data->error = 0;
}

static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
{
	unsigned long dmaflags;
	int count;
	u8 status;

	WARN_ON(host->mrq == NULL);

	/*
	 * Send a stop command if needed.
	 */
	if (data->stop)
		wbsd_send_command(host, data->stop);

	/*
	 * Wait for the controller to leave data
	 * transfer state.
	 */
	do {
		status = wbsd_read_index(host, WBSD_IDX_STATUS);
	} while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE));

	/*
	 * DMA transfer?
	 */
	if (host->dma >= 0) {
		/*
		 * Disable DMA on the host.
		 */
		wbsd_write_index(host, WBSD_IDX_DMA, 0);

		/*
		 * Turn of ISA DMA controller.
		 */
		dmaflags = claim_dma_lock();
		disable_dma(host->dma);
		clear_dma_ff(host->dma);
		count = get_dma_residue(host->dma);
		release_dma_lock(dmaflags);

		data->bytes_xfered = host->mrq->data->blocks *
			host->mrq->data->blksz - count;
		data->bytes_xfered -= data->bytes_xfered % data->blksz;

		/*
		 * Any leftover data?
		 */
		if (count) {
			pr_err("%s: Incomplete DMA transfer. "
				"%d bytes left.\n",
				mmc_hostname(host->mmc), count);

			if (!data->error)
				data->error = -EIO;
		} else {
			/*
			 * Transfer data from DMA buffer to
			 * SG list.
			 */
			if (data->flags & MMC_DATA_READ)
				wbsd_dma_to_sg(host, data);
		}

		if (data->error) {
			if (data->bytes_xfered)
				data->bytes_xfered -= data->blksz;
		}
	}

	wbsd_request_end(host, host->mrq);
}

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

static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct wbsd_host *host = mmc_priv(mmc);
	struct mmc_command *cmd;

	/*
	 * Disable tasklets to avoid a deadlock.
	 */
	spin_lock_bh(&host->lock);

	BUG_ON(host->mrq != NULL);

	cmd = mrq->cmd;

	host->mrq = mrq;

	/*
	 * Check that there is actually a card in the slot.
	 */
	if (!(host->flags & WBSD_FCARD_PRESENT)) {
		cmd->error = -ENOMEDIUM;
		goto done;
	}

	if (cmd->data) {
		/*
		 * The hardware is so delightfully stupid that it has a list
		 * of "data" commands. If a command isn't on this list, it'll
		 * just go back to the idle state and won't send any data
		 * interrupts.
		 */
		switch (cmd->opcode) {
		case SD_SWITCH_VOLTAGE:
		case MMC_READ_SINGLE_BLOCK:
		case MMC_READ_MULTIPLE_BLOCK:
		case MMC_WRITE_DAT_UNTIL_STOP:
		case MMC_WRITE_BLOCK:
		case MMC_WRITE_MULTIPLE_BLOCK:
		case MMC_PROGRAM_CID:
		case MMC_PROGRAM_CSD:
		case MMC_SEND_WRITE_PROT:
		case MMC_LOCK_UNLOCK:
		case MMC_GEN_CMD:
			break;

		/* ACMDs. We don't keep track of state, so we just treat them
		 * like any other command. */
		case SD_APP_SEND_SCR:
			break;

		default:
			pr_warn("%s: Data command %d is not supported by this controller\n",
				mmc_hostname(host->mmc), cmd->opcode);
			cmd->error = -EINVAL;

			goto done;
		}
	}

	/*
	 * Does the request include data?
	 */
	if (cmd->data) {
		wbsd_prepare_data(host, cmd->data);

		if (cmd->data->error)
			goto done;
	}

	wbsd_send_command(host, cmd);

	/*
	 * If this is a data transfer the request
	 * will be finished after the data has
	 * transferred.
	 */
	if (cmd->data && !cmd->error) {
		/*
		 * Dirty fix for hardware bug.
		 */
		if (host->dma == -1)
			tasklet_schedule(&host->fifo_tasklet);

		spin_unlock_bh(&host->lock);

		return;
	}

done:
	wbsd_request_end(host, mrq);

	spin_unlock_bh(&host->lock);
}

static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct wbsd_host *host = mmc_priv(mmc);
	u8 clk, setup, pwr;

	spin_lock_bh(&host->lock);

	/*
	 * Reset the chip on each power off.
	 * Should clear out any weird states.
	 */
	if (ios->power_mode == MMC_POWER_OFF)
		wbsd_init_device(host);

	if (ios->clock >= 24000000)
		clk = WBSD_CLK_24M;
	else if (ios->clock >= 16000000)
		clk = WBSD_CLK_16M;
	else if (ios->clock >= 12000000)
		clk = WBSD_CLK_12M;
	else
		clk = WBSD_CLK_375K;

	/*
	 * Only write to the clock register when
	 * there is an actual change.
	 */
	if (clk != host->clk) {
		wbsd_write_index(host, WBSD_IDX_CLK, clk);
		host->clk = clk;
	}

	/*
	 * Power up card.
	 */
	if (ios->power_mode != MMC_POWER_OFF) {
		pwr = inb(host->base + WBSD_CSR);
		pwr &= ~WBSD_POWER_N;
		outb(pwr, host->base + WBSD_CSR);
	}

	/*
	 * MMC cards need to have pin 1 high during init.
	 * It wreaks havoc with the card detection though so
	 * that needs to be disabled.
	 */
	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
	if (ios->chip_select == MMC_CS_HIGH) {
		BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1);
		setup |= WBSD_DAT3_H;
		host->flags |= WBSD_FIGNORE_DETECT;
	} else {
		if (setup & WBSD_DAT3_H) {
			setup &= ~WBSD_DAT3_H;

			/*
			 * We cannot resume card detection immediately
			 * because of capacitance and delays in the chip.
			 */
			mod_timer(&host->ignore_timer, jiffies + HZ / 100);
		}
	}
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);

	/*
	 * Store bus width for later. Will be used when
	 * setting up the data transfer.
	 */
	host->bus_width = ios->bus_width;

	spin_unlock_bh(&host->lock);
}

static int wbsd_get_ro(struct mmc_host *mmc)
{
	struct wbsd_host *host = mmc_priv(mmc);
	u8 csr;

	spin_lock_bh(&host->lock);

	csr = inb(host->base + WBSD_CSR);
	csr |= WBSD_MSLED;
	outb(csr, host->base + WBSD_CSR);

	mdelay(1);

	csr = inb(host->base + WBSD_CSR);
	csr &= ~WBSD_MSLED;
	outb(csr, host->base + WBSD_CSR);

	spin_unlock_bh(&host->lock);

	return !!(csr & WBSD_WRPT);
}

static const struct mmc_host_ops wbsd_ops = {
	.request	= wbsd_request,
	.set_ios	= wbsd_set_ios,
	.get_ro		= wbsd_get_ro,
};

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

/*
 * Helper function to reset detection ignore
 */

static void wbsd_reset_ignore(struct timer_list *t)
{
	struct wbsd_host *host = from_timer(host, t, ignore_timer);

	BUG_ON(host == NULL);

	DBG("Resetting card detection ignore\n");

	spin_lock_bh(&host->lock);

	host->flags &= ~WBSD_FIGNORE_DETECT;

	/*
	 * Card status might have changed during the
	 * blackout.
	 */
	tasklet_schedule(&host->card_tasklet);

	spin_unlock_bh(&host->lock);
}

/*
 * Tasklets
 */

static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host)
{
	WARN_ON(!host->mrq);
	if (!host->mrq)
		return NULL;

	WARN_ON(!host->mrq->cmd);
	if (!host->mrq->cmd)
		return NULL;

	WARN_ON(!host->mrq->cmd->data);
	if (!host->mrq->cmd->data)
		return NULL;

	return host->mrq->cmd->data;
}

static void wbsd_tasklet_card(struct tasklet_struct *t)
{
	struct wbsd_host *host = from_tasklet(host, t, card_tasklet);
	u8 csr;
	int delay = -1;

	spin_lock(&host->lock);

	if (host->flags & WBSD_FIGNORE_DETECT) {
		spin_unlock(&host->lock);
		return;
	}

	csr = inb(host->base + WBSD_CSR);
	WARN_ON(csr == 0xff);

	if (csr & WBSD_CARDPRESENT) {
		if (!(host->flags & WBSD_FCARD_PRESENT)) {
			DBG("Card inserted\n");
			host->flags |= WBSD_FCARD_PRESENT;

			delay = 500;
		}
	} else if (host->flags & WBSD_FCARD_PRESENT) {
		DBG("Card removed\n");
		host->flags &= ~WBSD_FCARD_PRESENT;

		if (host->mrq) {
			pr_err("%s: Card removed during transfer!\n",
				mmc_hostname(host->mmc));
			wbsd_reset(host);

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

		delay = 0;
	}

	/*
	 * Unlock first since we might get a call back.
	 */

	spin_unlock(&host->lock);

	if (delay != -1)
		mmc_detect_change(host->mmc, msecs_to_jiffies(delay));
}

static void wbsd_tasklet_fifo(struct tasklet_struct *t)
{
	struct wbsd_host *host = from_tasklet(host, t, fifo_tasklet);
	struct mmc_data *data;

	spin_lock(&host->lock);

	if (!host->mrq)
		goto end;

	data = wbsd_get_data(host);
	if (!data)
		goto end;

	if (data->flags & MMC_DATA_WRITE)
		wbsd_fill_fifo(host);
	else
		wbsd_empty_fifo(host);

	/*
	 * Done?
	 */
	if (host->num_sg == 0) {
		wbsd_write_index(host, WBSD_IDX_FIFOEN, 0);
		tasklet_schedule(&host->finish_tasklet);
	}

end:
	spin_unlock(&host->lock);
}

static void wbsd_tasklet_crc(struct tasklet_struct *t)
{
	struct wbsd_host *host = from_tasklet(host, t, crc_tasklet);
	struct mmc_data *data;

	spin_lock(&host->lock);

	if (!host->mrq)
		goto end;

	data = wbsd_get_data(host);
	if (!data)
		goto end;

	DBGF("CRC error\n");

	data->error = -EILSEQ;

	tasklet_schedule(&host->finish_tasklet);

end:
	spin_unlock(&host->lock);
}

static void wbsd_tasklet_timeout(struct tasklet_struct *t)
{
	struct wbsd_host *host = from_tasklet(host, t, timeout_tasklet);
	struct mmc_data *data;

	spin_lock(&host->lock);

	if (!host->mrq)
		goto end;

	data = wbsd_get_data(host);
	if (!data)
		goto end;

	DBGF("Timeout\n");

	data->error = -ETIMEDOUT;

	tasklet_schedule(&host->finish_tasklet);

end:
	spin_unlock(&host->lock);
}

static void wbsd_tasklet_finish(struct tasklet_struct *t)
{
	struct wbsd_host *host = from_tasklet(host, t, finish_tasklet);
	struct mmc_data *data;

	spin_lock(&host->lock);

	WARN_ON(!host->mrq);
	if (!host->mrq)
		goto end;

	data = wbsd_get_data(host);
	if (!data)
		goto end;

	wbsd_finish_data(host, data);

end:
	spin_unlock(&host->lock);
}

/*
 * Interrupt handling
 */

static irqreturn_t wbsd_irq(int irq, void *dev_id)
{
	struct wbsd_host *host = dev_id;
	int isr;

	isr = inb(host->base + WBSD_ISR);

	/*
	 * Was it actually our hardware that caused the interrupt?
	 */
	if (isr == 0xff || isr == 0x00)
		return IRQ_NONE;

	host->isr |= isr;

	/*
	 * Schedule tasklets as needed.
	 */
	if (isr & WBSD_INT_CARD)
		tasklet_schedule(&host->card_tasklet);
	if (isr & WBSD_INT_FIFO_THRE)
		tasklet_schedule(&host->fifo_tasklet);
	if (isr & WBSD_INT_CRC)
		tasklet_hi_schedule(&host->crc_tasklet);
	if (isr & WBSD_INT_TIMEOUT)
		tasklet_hi_schedule(&host->timeout_tasklet);
	if (isr & WBSD_INT_TC)
		tasklet_schedule(&host->finish_tasklet);

	return IRQ_HANDLED;
}

/*****************************************************************************\
 *                                                                           *
 * Device initialisation and shutdown                                        *
 *                                                                           *
\*****************************************************************************/

/*
 * Allocate/free MMC structure.
 */

static int wbsd_alloc_mmc(struct device *dev)
{
	struct mmc_host *mmc;
	struct wbsd_host *host;

	/*
	 * Allocate MMC structure.
	 */
	mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev);
	if (!mmc)
		return -ENOMEM;

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

	host->dma = -1;

	/*
	 * Set host parameters.
	 */
	mmc->ops = &wbsd_ops;
	mmc->f_min = 375000;
	mmc->f_max = 24000000;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA;

	spin_lock_init(&host->lock);

	/*
	 * Set up timers
	 */
	timer_setup(&host->ignore_timer, wbsd_reset_ignore, 0);

	/*
	 * Maximum number of segments. Worst case is one sector per segment
	 * so this will be 64kB/512.
	 */
	mmc->max_segs = 128;

	/*
	 * Maximum request size. Also limited by 64KiB buffer.
	 */
	mmc->max_req_size = 65536;

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

	/*
	 * Maximum block size. We have 12 bits (= 4095) but have to subtract
	 * space for CRC. So the maximum is 4095 - 4*2 = 4087.
	 */
	mmc->max_blk_size = 4087;

	/*
	 * Maximum block count. There is no real limit so the maximum
	 * request size will be the only restriction.
	 */
	mmc->max_blk_count = mmc->max_req_size;

	dev_set_drvdata(dev, mmc);

	return 0;
}

static void wbsd_free_mmc(struct device *dev)
{
	struct mmc_host *mmc;
	struct wbsd_host *host;

	mmc = dev_get_drvdata(dev);
	if (!mmc)
		return;

	host = mmc_priv(mmc);
	BUG_ON(host == NULL);

	del_timer_sync(&host->ignore_timer);

	mmc_free_host(mmc);
}

/*
 * Scan for known chip id:s
 */

static int wbsd_scan(struct wbsd_host *host)
{
	int i, j, k;
	int id;

	/*
	 * Iterate through all ports, all codes to
	 * find hardware that is in our known list.
	 */
	for (i = 0; i < ARRAY_SIZE(config_ports); i++) {
		if (!request_region(config_ports[i], 2, DRIVER_NAME))
			continue;

		for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) {
			host->config = config_ports[i];
			host->unlock_code = unlock_codes[j];

			wbsd_unlock_config(host);

			outb(WBSD_CONF_ID_HI, config_ports[i]);
			id = inb(config_ports[i] + 1) << 8;

			outb(WBSD_CONF_ID_LO, config_ports[i]);
			id |= inb(config_ports[i] + 1);

			wbsd_lock_config(host);

			for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
				if (id == valid_ids[k]) {
					host->chip_id = id;

					return 0;
				}
			}

			if (id != 0xFFFF) {
				DBG("Unknown hardware (id %x) found at %x\n",
					id, config_ports[i]);
			}
		}

		release_region(config_ports[i], 2);
	}

	host->config = 0;
	host->unlock_code = 0;

	return -ENODEV;
}

/*
 * Allocate/free io port ranges
 */

static int wbsd_request_region(struct wbsd_host *host, int base)
{
	if (base & 0x7)
		return -EINVAL;

	if (!request_region(base, 8, DRIVER_NAME))
		return -EIO;

	host->base = base;

	return 0;
}

static void wbsd_release_regions(struct wbsd_host *host)
{
	if (host->base)
		release_region(host->base, 8);

	host->base = 0;

	if (host->config)
		release_region(host->config, 2);

	host->config = 0;
}

/*
 * Allocate/free DMA port and buffer
 */

static void wbsd_request_dma(struct wbsd_host *host, int dma)
{
	if (dma < 0)
		return;

	if (request_dma(dma, DRIVER_NAME))
		goto err;

	/*
	 * We need to allocate a special buffer in
	 * order for ISA to be able to DMA to it.
	 */
	host->dma_buffer = kmalloc(WBSD_DMA_SIZE,
		GFP_NOIO | GFP_DMA | __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
	if (!host->dma_buffer)
		goto free;

	/*
	 * Translate the address to a physical address.
	 */
	host->dma_addr = dma_map_single(mmc_dev(host->mmc), host->dma_buffer,
		WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
	if (dma_mapping_error(mmc_dev(host->mmc), host->dma_addr))
		goto kfree;

	/*
	 * ISA DMA must be aligned on a 64k basis.
	 */
	if ((host->dma_addr & 0xffff) != 0)
		goto unmap;
	/*
	 * ISA cannot access memory above 16 MB.
	 */
	else if (host->dma_addr >= 0x1000000)
		goto unmap;

	host->dma = dma;

	return;

unmap:
	/*
	 * If we've gotten here then there is some kind of alignment bug
	 */
	BUG_ON(1);

	dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
		WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
	host->dma_addr = 0;

kfree:
	kfree(host->dma_buffer);
	host->dma_buffer = NULL;

free:
	free_dma(dma);

err:
	pr_warn(DRIVER_NAME ": Unable to allocate DMA %d - falling back on FIFO\n",
		dma);
}

static void wbsd_release_dma(struct wbsd_host *host)
{
	/*
	 * host->dma_addr is valid here iff host->dma_buffer is not NULL.
	 */
	if (host->dma_buffer) {
		dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
			WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
		kfree(host->dma_buffer);
	}
	if (host->dma >= 0)
		free_dma(host->dma);

	host->dma = -1;
	host->dma_buffer = NULL;
	host->dma_addr = 0;
}

/*
 * Allocate/free IRQ.
 */

static int wbsd_request_irq(struct wbsd_host *host, int irq)
{
	int ret;

	/*
	 * Set up tasklets. Must be done before requesting interrupt.
	 */
	tasklet_setup(&host->card_tasklet, wbsd_tasklet_card);
	tasklet_setup(&host->fifo_tasklet, wbsd_tasklet_fifo);
	tasklet_setup(&host->crc_tasklet, wbsd_tasklet_crc);
	tasklet_setup(&host->timeout_tasklet, wbsd_tasklet_timeout);
	tasklet_setup(&host->finish_tasklet, wbsd_tasklet_finish);

	/*
	 * Allocate interrupt.
	 */
	ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host);
	if (ret)
		return ret;

	host->irq = irq;

	return 0;
}

static void  wbsd_release_irq(struct wbsd_host *host)
{
	if (!host->irq)
		return;

	free_irq(host->irq, host);

	host->irq = 0;

	tasklet_kill(&host->card_tasklet);
	tasklet_kill(&host->fifo_tasklet);
	tasklet_kill(&host->crc_tasklet);
	tasklet_kill(&host->timeout_tasklet);
	tasklet_kill(&host->finish_tasklet);
}

/*
 * Allocate all resources for the host.
 */

static int wbsd_request_resources(struct wbsd_host *host,
	int base, int irq, int dma)
{
	int ret;

	/*
	 * Allocate I/O ports.
	 */
	ret = wbsd_request_region(host, base);
	if (ret)
		return ret;

	/*
	 * Allocate interrupt.
	 */
	ret = wbsd_request_irq(host, irq);
	if (ret)
		return ret;

	/*
	 * Allocate DMA.
	 */
	wbsd_request_dma(host, dma);

	return 0;
}

/*
 * Release all resources for the host.
 */

static void wbsd_release_resources(struct wbsd_host *host)
{
	wbsd_release_dma(host);
	wbsd_release_irq(host);
	wbsd_release_regions(host);
}

/*
 * Configure the resources the chip should use.
 */

static void wbsd_chip_config(struct wbsd_host *host)
{
	wbsd_unlock_config(host);

	/*
	 * Reset the chip.
	 */
	wbsd_write_config(host, WBSD_CONF_SWRST, 1);
	wbsd_write_config(host, WBSD_CONF_SWRST, 0);

	/*
	 * Select SD/MMC function.
	 */
	wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);

	/*
	 * Set up card detection.
	 */
	wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11);

	/*
	 * Configure chip
	 */
	wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8);
	wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff);

	wbsd_write_config(host, WBSD_CONF_IRQ, host->irq);

	if (host->dma >= 0)
		wbsd_write_config(host, WBSD_CONF_DRQ, host->dma);

	/*
	 * Enable and power up chip.
	 */
	wbsd_write_config(host, WBSD_CONF_ENABLE, 1);
	wbsd_write_config(host, WBSD_CONF_POWER, 0x20);

	wbsd_lock_config(host);
}

/*
 * Check that configured resources are correct.
 */

static int wbsd_chip_validate(struct wbsd_host *host)
{
	int base, irq, dma;

	wbsd_unlock_config(host);

	/*
	 * Select SD/MMC function.
	 */
	wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);

	/*
	 * Read configuration.
	 */
	base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8;
	base |= wbsd_read_config(host, WBSD_CONF_PORT_LO);

	irq = wbsd_read_config(host, WBSD_CONF_IRQ);

	dma = wbsd_read_config(host, WBSD_CONF_DRQ);

	wbsd_lock_config(host);

	/*
	 * Validate against given configuration.
	 */
	if (base != host->base)
		return 0;
	if (irq != host->irq)
		return 0;
	if ((dma != host->dma) && (host->dma != -1))
		return 0;

	return 1;
}

/*
 * Powers down the SD function
 */

static void wbsd_chip_poweroff(struct wbsd_host *host)
{
	wbsd_unlock_config(host);

	wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD);
	wbsd_write_config(host, WBSD_CONF_ENABLE, 0);

	wbsd_lock_config(host);
}

/*****************************************************************************\
 *                                                                           *
 * Devices setup and shutdown                                                *
 *                                                                           *
\*****************************************************************************/

static int wbsd_init(struct device *dev, int base, int irq, int dma,
	int pnp)
{
	struct wbsd_host *host = NULL;
	struct mmc_host *mmc = NULL;
	int ret;

	ret = wbsd_alloc_mmc(dev);
	if (ret)
		return ret;

	mmc = dev_get_drvdata(dev);
	host = mmc_priv(mmc);

	/*
	 * Scan for hardware.
	 */
	ret = wbsd_scan(host);
	if (ret) {
		if (pnp && (ret == -ENODEV)) {
			pr_warn(DRIVER_NAME ": Unable to confirm device presence - you may experience lock-ups\n");
		} else {
			wbsd_free_mmc(dev);
			return ret;
		}
	}

	/*
	 * Request resources.
	 */
	ret = wbsd_request_resources(host, base, irq, dma);
	if (ret) {
		wbsd_release_resources(host);
		wbsd_free_mmc(dev);
		return ret;
	}

	/*
	 * See if chip needs to be configured.
	 */
	if (pnp) {
		if ((host->config != 0) && !wbsd_chip_validate(host)) {
			pr_warn(DRIVER_NAME ": PnP active but chip not configured! You probably have a buggy BIOS. Configuring chip manually.\n");
			wbsd_chip_config(host);
		}
	} else
		wbsd_chip_config(host);

	/*
	 * Power Management stuff. No idea how this works.
	 * Not tested.
	 */
#ifdef CONFIG_PM
	if (host->config) {
		wbsd_unlock_config(host);
		wbsd_write_config(host, WBSD_CONF_PME, 0xA0);
		wbsd_lock_config(host);
	}
#endif
	/*
	 * Allow device to initialise itself properly.
	 */
	mdelay(5);

	/*
	 * Reset the chip into a known state.
	 */
	wbsd_init_device(host);

	ret = mmc_add_host(mmc);
	if (ret) {
		if (!pnp)
			wbsd_chip_poweroff(host);

		wbsd_release_resources(host);
		wbsd_free_mmc(dev);
		return ret;
	}

	pr_info("%s: W83L51xD", mmc_hostname(mmc));
	if (host->chip_id != 0)
		printk(" id %x", (int)host->chip_id);
	printk(" at 0x%x irq %d", (int)host->base, (int)host->irq);
	if (host->dma >= 0)
		printk(" dma %d", (int)host->dma);
	else
		printk(" FIFO");
	if (pnp)
		printk(" PnP");
	printk("\n");

	return 0;
}

static void wbsd_shutdown(struct device *dev, int pnp)
{
	struct mmc_host *mmc = dev_get_drvdata(dev);
	struct wbsd_host *host;

	if (!mmc)
		return;

	host = mmc_priv(mmc);

	mmc_remove_host(mmc);

	/*
	 * Power down the SD/MMC function.
	 */
	if (!pnp)
		wbsd_chip_poweroff(host);

	wbsd_release_resources(host);

	wbsd_free_mmc(dev);
}

/*
 * Non-PnP
 */

static int wbsd_probe(struct platform_device *dev)
{
	/* Use the module parameters for resources */
	return wbsd_init(&dev->dev, param_io, param_irq, param_dma, 0);
}

static void wbsd_remove(struct platform_device *dev)
{
	wbsd_shutdown(&dev->dev, 0);
}

/*
 * PnP
 */

#ifdef CONFIG_PNP

static int
wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id)
{
	int io, irq, dma;

	/*
	 * Get resources from PnP layer.
	 */
	io = pnp_port_start(pnpdev, 0);
	irq = pnp_irq(pnpdev, 0);
	if (pnp_dma_valid(pnpdev, 0))
		dma = pnp_dma(pnpdev, 0);
	else
		dma = -1;

	DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma);

	return wbsd_init(&pnpdev->dev, io, irq, dma, 1);
}

static void wbsd_pnp_remove(struct pnp_dev *dev)
{
	wbsd_shutdown(&dev->dev, 1);
}

#endif /* CONFIG_PNP */

/*
 * Power management
 */

#ifdef CONFIG_PM

static int wbsd_platform_suspend(struct platform_device *dev,
				 pm_message_t state)
{
	struct mmc_host *mmc = platform_get_drvdata(dev);
	struct wbsd_host *host;

	if (mmc == NULL)
		return 0;

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

	host = mmc_priv(mmc);

	wbsd_chip_poweroff(host);
	return 0;
}

static int wbsd_platform_resume(struct platform_device *dev)
{
	struct mmc_host *mmc = platform_get_drvdata(dev);
	struct wbsd_host *host;

	if (mmc == NULL)
		return 0;

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

	host = mmc_priv(mmc);

	wbsd_chip_config(host);

	/*
	 * Allow device to initialise itself properly.
	 */
	mdelay(5);

	wbsd_init_device(host);
	return 0;
}

#ifdef CONFIG_PNP

static int wbsd_pnp_suspend(struct pnp_dev *pnp_dev, pm_message_t state)
{
	struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);

	if (mmc == NULL)
		return 0;

	DBGF("Suspending...\n");
	return 0;
}

static int wbsd_pnp_resume(struct pnp_dev *pnp_dev)
{
	struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev);
	struct wbsd_host *host;

	if (mmc == NULL)
		return 0;

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

	host = mmc_priv(mmc);

	/*
	 * See if chip needs to be configured.
	 */
	if (host->config != 0) {
		if (!wbsd_chip_validate(host)) {
			pr_warn(DRIVER_NAME ": PnP active but chip not configured! You probably have a buggy BIOS. Configuring chip manually.\n");
			wbsd_chip_config(host);
		}
	}

	/*
	 * Allow device to initialise itself properly.
	 */
	mdelay(5);

	wbsd_init_device(host);
	return 0;
}

#endif /* CONFIG_PNP */

#else /* CONFIG_PM */

#define wbsd_platform_suspend NULL
#define wbsd_platform_resume NULL

#define wbsd_pnp_suspend NULL
#define wbsd_pnp_resume NULL

#endif /* CONFIG_PM */

static struct platform_device *wbsd_device;

static struct platform_driver wbsd_driver = {
	.probe		= wbsd_probe,
	.remove_new	= wbsd_remove,
	.suspend	= wbsd_platform_suspend,
	.resume		= wbsd_platform_resume,
	.driver		= {
		.name	= DRIVER_NAME,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};

#ifdef CONFIG_PNP

static struct pnp_driver wbsd_pnp_driver = {
	.name		= DRIVER_NAME,
	.id_table	= pnp_dev_table,
	.probe		= wbsd_pnp_probe,
	.remove		= wbsd_pnp_remove,

	.suspend	= wbsd_pnp_suspend,
	.resume		= wbsd_pnp_resume,
};

#endif /* CONFIG_PNP */

/*
 * Module loading/unloading
 */

static int __init wbsd_drv_init(void)
{
	int result;

	pr_info(DRIVER_NAME
		": Winbond W83L51xD SD/MMC card interface driver\n");
	pr_info(DRIVER_NAME ": Copyright(c) Pierre Ossman\n");

#ifdef CONFIG_PNP

	if (!param_nopnp) {
		result = pnp_register_driver(&wbsd_pnp_driver);
		if (result < 0)
			return result;
	}
#endif /* CONFIG_PNP */

	if (param_nopnp) {
		result = platform_driver_register(&wbsd_driver);
		if (result < 0)
			return result;

		wbsd_device = platform_device_alloc(DRIVER_NAME, -1);
		if (!wbsd_device) {
			platform_driver_unregister(&wbsd_driver);
			return -ENOMEM;
		}

		result = platform_device_add(wbsd_device);
		if (result) {
			platform_device_put(wbsd_device);
			platform_driver_unregister(&wbsd_driver);
			return result;
		}
	}

	return 0;
}

static void __exit wbsd_drv_exit(void)
{
#ifdef CONFIG_PNP

	if (!param_nopnp)
		pnp_unregister_driver(&wbsd_pnp_driver);

#endif /* CONFIG_PNP */

	if (param_nopnp) {
		platform_device_unregister(wbsd_device);

		platform_driver_unregister(&wbsd_driver);
	}

	DBG("unloaded\n");
}

module_init(wbsd_drv_init);
module_exit(wbsd_drv_exit);
#ifdef CONFIG_PNP
module_param_hw_named(nopnp, param_nopnp, uint, other, 0444);
#endif
module_param_hw_named(io, param_io, uint, ioport, 0444);
module_param_hw_named(irq, param_irq, uint, irq, 0444);
module_param_hw_named(dma, param_dma, int, dma, 0444);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");

#ifdef CONFIG_PNP
MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)");
#endif
MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)");
MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)");
MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)");
