/*
 *  linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver
 *
 *  Copyright (C) 2004-2005 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.
 *
 *
 * 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/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/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/protocol.h>

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

#include "wbsd.h"

#define DRIVER_NAME "wbsd"
#define DRIVER_VERSION "1.2"

#ifdef CONFIG_MMC_DEBUG
#define DBG(x...) \
	printk(KERN_DEBUG DRIVER_NAME ": " x)
#define DBGF(f, x...) \
	printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x)
#else
#define DBG(x...)	do { } while (0)
#define DBGF(x...)	do { } while (0)
#endif

/*
 * 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 nopnp = 0;
#else
static const unsigned int nopnp = 1;
#endif
static unsigned int io = 0x248;
static unsigned int irq = 6;
static int 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_CCRC;
	ier |= WBSD_EINT_TIMEOUT;
	ier |= WBSD_EINT_CRC;
	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;
	
	printk(KERN_ERR DRIVER_NAME ": Resetting chip\n");
	
	/*
	 * 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;
	
	DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode);
	
	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_kmap_sg(struct wbsd_host* host)
{
	host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
		host->cur_sg->offset;
	return host->mapped_sg;
}

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

static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
{
	unsigned int len, i, size;
	struct scatterlist* sg;
	char* dmabuf = host->dma_buffer;
	char* sgbuf;
	
	size = host->size;
	
	sg = data->sg;
	len = data->sg_len;
	
	/*
	 * Just loop through all entries. Size might not
	 * be the entire list though so make sure that
	 * we do not transfer too much.
	 */
	for (i = 0;i < len;i++)
	{
		sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
		if (size < sg[i].length)
			memcpy(dmabuf, sgbuf, size);
		else
			memcpy(dmabuf, sgbuf, sg[i].length);
		kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
		dmabuf += sg[i].length;
		
		if (size < sg[i].length)
			size = 0;
		else
			size -= sg[i].length;
	
		if (size == 0)
			break;
	}
	
	/*
	 * Check that we didn't get a request to transfer
	 * more data than can fit into the SG list.
	 */
	
	BUG_ON(size != 0);
	
	host->size -= size;
}

static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
{
	unsigned int len, i, size;
	struct scatterlist* sg;
	char* dmabuf = host->dma_buffer;
	char* sgbuf;
	
	size = host->size;
	
	sg = data->sg;
	len = data->sg_len;
	
	/*
	 * Just loop through all entries. Size might not
	 * be the entire list though so make sure that
	 * we do not transfer too much.
	 */
	for (i = 0;i < len;i++)
	{
		sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
		if (size < sg[i].length)
			memcpy(sgbuf, dmabuf, size);
		else
			memcpy(sgbuf, dmabuf, sg[i].length);
		kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
		dmabuf += sg[i].length;
		
		if (size < sg[i].length)
			size = 0;
		else
			size -= sg[i].length;
		
		if (size == 0)
			break;
	}
	
	/*
	 * Check that we didn't get a request to transfer
	 * more data than can fit into the SG list.
	 */
	
	BUG_ON(size != 0);
	
	host->size -= size;
}

/*
 * 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 = MMC_ERR_INVALID;
		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 = MMC_ERR_INVALID;
		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;
	
	DBGF("Sending cmd (%x)\n", cmd->opcode);

	/*
	 * 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 = MMC_ERR_NONE;
	
	/*
	 * 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_MASK) != MMC_RSP_NONE)
	{
		/*
		 * Read back status.
		 */
		isr = host->isr;
		
		/* Card removed? */
		if (isr & WBSD_INT_CARD)
			cmd->error = MMC_ERR_TIMEOUT;
		/* Timeout? */
		else if (isr & WBSD_INT_TIMEOUT)
			cmd->error = MMC_ERR_TIMEOUT;
		/* CRC? */
		else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
			cmd->error = MMC_ERR_BADCRC;
		/* All ok */
		else
		{
			if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT)
				wbsd_get_short_reply(host, cmd);
			else
				wbsd_get_long_reply(host, cmd);
		}
	}

	DBGF("Sent cmd (%x), res %d\n", cmd->opcode, cmd->error);
}

/*
 * Data functions
 */

static void wbsd_empty_fifo(struct wbsd_host* host)
{
	struct mmc_data* data = host->mrq->cmd->data;
	char* buffer;
	int i, fsr, fifo;
	
	/*
	 * Handle excessive data.
	 */
	if (data->bytes_xfered == host->size)
		return;
	
	buffer = wbsd_kmap_sg(host) + host->offset;

	/*
	 * 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 = inb(host->base + WBSD_DFR);
			buffer++;
			host->offset++;
			host->remain--;

			data->bytes_xfered++;
			
			/*
			 * Transfer done?
			 */
			if (data->bytes_xfered == host->size)
			{
				wbsd_kunmap_sg(host);				
				return;
			}
			
			/*
			 * End of scatter list entry?
			 */
			if (host->remain == 0)
			{
				wbsd_kunmap_sg(host);
				
				/*
				 * Get next entry. Check if last.
				 */
				if (!wbsd_next_sg(host))
				{
					/*
					 * We should never reach this point.
					 * It means that we're trying to
					 * transfer more blocks than can fit
					 * into the scatter list.
					 */
					BUG_ON(1);
					
					host->size = data->bytes_xfered;
					
					return;
				}
				
				buffer = wbsd_kmap_sg(host);
			}
		}
	}
	
	wbsd_kunmap_sg(host);

	/*
	 * This is a very dirty hack to solve a
	 * hardware problem. The chip doesn't trigger
	 * FIFO threshold interrupts properly.
	 */
	if ((host->size - 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, fsr, fifo;
	
	/*
	 * Check that we aren't being called after the
	 * entire buffer has been transfered.
	 */
	if (data->bytes_xfered == host->size)
		return;

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

	/*
	 * 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, host->base + WBSD_DFR);
			buffer++;
			host->offset++;
			host->remain--;
			
			data->bytes_xfered++;
			
			/*
			 * Transfer done?
			 */
			if (data->bytes_xfered == host->size)
			{
				wbsd_kunmap_sg(host);
				return;
			}

			/*
			 * End of scatter list entry?
			 */
			if (host->remain == 0)
			{
				wbsd_kunmap_sg(host);
				
				/*
				 * Get next entry. Check if last.
				 */
				if (!wbsd_next_sg(host))
				{
					/*
					 * We should never reach this point.
					 * It means that we're trying to
					 * transfer more blocks than can fit
					 * into the scatter list.
					 */
					BUG_ON(1);
					
					host->size = data->bytes_xfered;
					
					return;
				}
				
				buffer = wbsd_kmap_sg(host);
			}
		}
	}
	
	wbsd_kunmap_sg(host);
	
	/*
	 * 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;

	DBGF("blksz %04x blks %04x flags %08x\n",
		1 << data->blksz_bits, data->blocks, data->flags);
	DBGF("tsac %d ms nsac %d clk\n",
		data->timeout_ns / 1000000, data->timeout_clks);
	
	/*
	 * Calculate size.
	 */
	host->size = data->blocks << data->blksz_bits;

	/*
	 * 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.
	 */
	blksize = (1 << data->blksz_bits) + 2;
	
	wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
	wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);

	/*
	 * 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(host->size > 0x10000);
		if (host->size > 0x10000)
		{
			data->error = MMC_ERR_INVALID;
			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, host->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 = MMC_ERR_NONE;
}

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);
		
		/*
		 * Any leftover data?
		 */
		if (count)
		{
			printk(KERN_ERR DRIVER_NAME ": Incomplete DMA "
				"transfer. %d bytes left.\n", count);
			
			data->error = MMC_ERR_FAILED;
		}
		else
		{
			/*
			 * Transfer data from DMA buffer to
			 * SG list.
			 */
			if (data->flags & MMC_DATA_READ)
				wbsd_dma_to_sg(host, data);
			
			data->bytes_xfered = host->size;
		}
	}
	
	DBGF("Ending data transfer (%d bytes)\n", data->bytes_xfered);
	
	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;
	
	/*
	 * If there is no card in the slot then
	 * timeout immediatly.
	 */
	if (!(host->flags & WBSD_FCARD_PRESENT))
	{
		cmd->error = MMC_ERR_TIMEOUT;
		goto done;
	}

	/*
	 * Does the request include data?
	 */
	if (cmd->data)
	{
		wbsd_prepare_data(host, cmd->data);
		
		if (cmd->data->error != MMC_ERR_NONE)
			goto done;
	}
	
	wbsd_send_command(host, cmd);

	/*
	 * If this is a data transfer the request
	 * will be finished after the data has
	 * transfered.
	 */	
	if (cmd->data && (cmd->error == MMC_ERR_NONE))
	{
		/*
		 * 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;
	
	DBGF("clock %uHz busmode %u powermode %u Vdd %u\n",
		ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);

	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.
	 * Init time corresponds rather nicely with the bus mode.
	 * It wreaks havoc with the card detection though so
	 * that needs to be disabed.
	 */
	setup = wbsd_read_index(host, WBSD_IDX_SETUP);
	if ((ios->power_mode == MMC_POWER_ON) &&
		(ios->bus_mode == MMC_BUSMODE_OPENDRAIN))
	{
		setup |= WBSD_DAT3_H;
		host->flags |= WBSD_FIGNORE_DETECT;
	}
	else
	{
		setup &= ~WBSD_DAT3_H;
		host->flags &= ~WBSD_FIGNORE_DETECT;
	}
	wbsd_write_index(host, WBSD_IDX_SETUP, setup);
	
	spin_unlock_bh(&host->lock);
}

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

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

/*
 * Helper function for card detection
 */
static void wbsd_detect_card(unsigned long data)
{
	struct wbsd_host *host = (struct wbsd_host*)data;
	
	BUG_ON(host == NULL);
	
	DBG("Executing card detection\n");
	
	mmc_detect_change(host->mmc);	
}

/*
 * 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(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	u8 csr;
	
	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 card detection to allow electrical connections
			 * to stabilise.
			 */
			mod_timer(&host->timer, jiffies + HZ/2);
		}
		
		spin_unlock(&host->lock);
	}
	else if (host->flags & WBSD_FCARD_PRESENT)
	{
		DBG("Card removed\n");
		host->flags &= ~WBSD_FCARD_PRESENT;
		
		if (host->mrq)
		{
			printk(KERN_ERR DRIVER_NAME
				": Card removed during transfer!\n");
			wbsd_reset(host);
			
			host->mrq->cmd->error = MMC_ERR_FAILED;
			tasklet_schedule(&host->finish_tasklet);
		}
		
		/*
		 * Unlock first since we might get a call back.
		 */
		spin_unlock(&host->lock);

		mmc_detect_change(host->mmc);
	}
}

static void wbsd_tasklet_fifo(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	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->size == data->bytes_xfered)
	{
		wbsd_write_index(host, WBSD_IDX_FIFOEN, 0);
		tasklet_schedule(&host->finish_tasklet);
	}

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

static void wbsd_tasklet_crc(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	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 = MMC_ERR_BADCRC;
	
	tasklet_schedule(&host->finish_tasklet);

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

static void wbsd_tasklet_timeout(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	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 = MMC_ERR_TIMEOUT;
	
	tasklet_schedule(&host->finish_tasklet);

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

static void wbsd_tasklet_finish(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	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);
}

static void wbsd_tasklet_block(unsigned long param)
{
	struct wbsd_host* host = (struct wbsd_host*)param;
	struct mmc_data* data;
	
	spin_lock(&host->lock);

	if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) !=
		WBSD_CRC_OK)
	{
		data = wbsd_get_data(host);
		if (!data)
			goto end;
		
		DBGF("CRC error\n");

		data->error = MMC_ERR_BADCRC;
	
		tasklet_schedule(&host->finish_tasklet);
	}

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

/*
 * Interrupt handling
 */

static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
{
	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_BUSYEND)
		tasklet_hi_schedule(&host->block_tasklet);
	if (isr & WBSD_INT_TC)
		tasklet_schedule(&host->finish_tasklet);
	
	return IRQ_HANDLED;
}

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

/*
 * Allocate/free MMC structure.
 */

static int __devinit 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;
	
	spin_lock_init(&host->lock);
	
	/*
	 * Set up detection timer
	 */
	init_timer(&host->timer);
	host->timer.data = (unsigned long)host;
	host->timer.function = wbsd_detect_card;
	
	/*
	 * Maximum number of segments. Worst case is one sector per segment
	 * so this will be 64kB/512.
	 */
	mmc->max_hw_segs = 128;
	mmc->max_phys_segs = 128;
	
	/*
	 * Maximum number of sectors in one transfer. Also limited by 64kB
	 * buffer.
	 */
	mmc->max_sectors = 128;
	
	/*
	 * Maximum segment size. Could be one segment with the maximum number
	 * of segments.
	 */
	mmc->max_seg_size = mmc->max_sectors * 512;
	
	dev_set_drvdata(dev, mmc);
	
	return 0;
}

static void __devexit 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->timer);
	
	mmc_free_host(mmc);
	
	dev_set_drvdata(dev, NULL);
}

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

static int __devinit 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 < sizeof(config_ports)/sizeof(int);i++)
	{
		if (!request_region(config_ports[i], 2, DRIVER_NAME))
			continue;
			
		for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++)
		{
			id = 0xFFFF;
			
			outb(unlock_codes[j], config_ports[i]);
			outb(unlock_codes[j], config_ports[i]);
			
			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);
			
			for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
			{
				if (id == valid_ids[k])
				{				
					host->chip_id = id;
					host->config = config_ports[i];
					host->unlock_code = unlock_codes[i];
				
					return 0;
				}
			}
			
			if (id != 0xFFFF)
			{
				DBG("Unknown hardware (id %x) found at %x\n",
					id, config_ports[i]);
			}

			outb(LOCK_CODE, config_ports[i]);
		}
		
		release_region(config_ports[i], 2);
	}
	
	return -ENODEV;
}

/*
 * Allocate/free io port ranges
 */

static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
{
	if (io & 0x7)
		return -EINVAL;
	
	if (!request_region(base, 8, DRIVER_NAME))
		return -EIO;
	
	host->base = io;
		
	return 0;
}

static void __devexit 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 __devinit 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_REPEAT | __GFP_NOWARN);
	if (!host->dma_buffer)
		goto free;

	/*
	 * Translate the address to a physical address.
	 */
	host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer,
		WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
			
	/*
	 * ISA DMA must be aligned on a 64k basis.
	 */
	if ((host->dma_addr & 0xffff) != 0)
		goto kfree;
	/*
	 * ISA cannot access memory above 16 MB.
	 */
	else if (host->dma_addr >= 0x1000000)
		goto kfree;

	host->dma = dma;
	
	return;
	
kfree:
	/*
	 * If we've gotten here then there is some kind of alignment bug
	 */
	BUG_ON(1);
	
	dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
		DMA_BIDIRECTIONAL);
	host->dma_addr = (dma_addr_t)NULL;
	
	kfree(host->dma_buffer);
	host->dma_buffer = NULL;

free:
	free_dma(dma);

err:
	printk(KERN_WARNING DRIVER_NAME ": Unable to allocate DMA %d. "
		"Falling back on FIFO.\n", dma);
}

static void __devexit wbsd_release_dma(struct wbsd_host* host)
{
	if (host->dma_addr)
		dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
			DMA_BIDIRECTIONAL);
	if (host->dma_buffer)
		kfree(host->dma_buffer);
	if (host->dma >= 0)
		free_dma(host->dma);
	
	host->dma = -1;
	host->dma_buffer = NULL;
	host->dma_addr = (dma_addr_t)NULL;
}

/*
 * Allocate/free IRQ.
 */

static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
{
	int ret;
	
	/*
	 * Allocate interrupt.
	 */

	ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
	if (ret)
		return ret;
	
	host->irq = irq;

	/*
	 * Set up tasklets.
	 */
	tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host);
	tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host);
	tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host);
	tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host);
	tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host);
	tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host);
	
	return 0;
}

static void __devexit 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);
	tasklet_kill(&host->block_tasklet);
}

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

static int __devinit 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 __devexit 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 __devinit wbsd_chip_config(struct wbsd_host* 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);
}

/*
 * Check that configured resources are correct.
 */
 
static int __devinit wbsd_chip_validate(struct wbsd_host* host)
{
	int base, irq, dma;
	
	/*
	 * 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);
	
	/*
	 * 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;
}

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

static int __devinit 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))
		{
			printk(KERN_WARNING 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, io, irq, dma);
	if (ret)
	{
		wbsd_release_resources(host);
		wbsd_free_mmc(dev);
		return ret;
	}
	
	/*
	 * See if chip needs to be configured.
	 */
	if (pnp && (host->config != 0))
	{
		if (!wbsd_chip_validate(host))
		{
			printk(KERN_WARNING 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_write_config(host, WBSD_CONF_PME, 0xA0);
#endif
	/*
	 * Allow device to initialise itself properly.
	 */
	mdelay(5);

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

	printk(KERN_INFO "%s: W83L51xD", mmc->host_name);
	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 __devexit 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);

	if (!pnp)
	{
		/*
		 * Power down the SD/MMC function.
		 */
		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);
	}
	
	wbsd_release_resources(host);
	
	wbsd_free_mmc(dev);
}

/*
 * Non-PnP
 */

static int __devinit wbsd_probe(struct device* dev)
{
	return wbsd_init(dev, io, irq, dma, 0);
}

static int __devexit wbsd_remove(struct device* dev)
{
	wbsd_shutdown(dev, 0);

	return 0;
}

/*
 * PnP
 */

#ifdef CONFIG_PNP

static int __devinit
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 __devexit wbsd_pnp_remove(struct pnp_dev * dev)
{
	wbsd_shutdown(&dev->dev, 1);
}

#endif /* CONFIG_PNP */

/*
 * Power management
 */

#ifdef CONFIG_PM
static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level)
{
	DBGF("Not yet supported\n");

	return 0;
}

static int wbsd_resume(struct device *dev, u32 level)
{
	DBGF("Not yet supported\n");

	return 0;
}
#else
#define wbsd_suspend NULL
#define wbsd_resume NULL
#endif

static struct platform_device *wbsd_device;

static struct device_driver wbsd_driver = {
	.name		= DRIVER_NAME,
	.bus		= &platform_bus_type,
	.probe		= wbsd_probe,
	.remove		= wbsd_remove,
	
	.suspend	= wbsd_suspend,
	.resume		= wbsd_resume,
};

#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,
};

#endif /* CONFIG_PNP */

/*
 * Module loading/unloading
 */

static int __init wbsd_drv_init(void)
{
	int result;
	
	printk(KERN_INFO DRIVER_NAME
		": Winbond W83L51xD SD/MMC card interface driver, "
		DRIVER_VERSION "\n");
	printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");

#ifdef CONFIG_PNP

	if (!nopnp)
	{
		result = pnp_register_driver(&wbsd_pnp_driver);
		if (result < 0)
			return result;
	}

#endif /* CONFIG_PNP */	
	
	if (nopnp)
	{
		result = driver_register(&wbsd_driver);
		if (result < 0)
			return result;

		wbsd_device = platform_device_register_simple(DRIVER_NAME, -1,
			NULL, 0);
		if (IS_ERR(wbsd_device))
			return PTR_ERR(wbsd_device);
	}

	return 0;
}

static void __exit wbsd_drv_exit(void)
{
#ifdef CONFIG_PNP

	if (!nopnp)
		pnp_unregister_driver(&wbsd_pnp_driver);
	
#endif /* CONFIG_PNP */	

	if (nopnp)
	{
		platform_device_unregister(wbsd_device);
	
		driver_unregister(&wbsd_driver);
	}

	DBG("unloaded\n");
}

module_init(wbsd_drv_init);
module_exit(wbsd_drv_exit);
#ifdef CONFIG_PNP
module_param(nopnp, uint, 0444);
#endif
module_param(io, uint, 0444);
module_param(irq, uint, 0444);
module_param(dma, int, 0444);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
MODULE_VERSION(DRIVER_VERSION);

#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)");
