[RFT] au1xmmc: remove board-specific code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I received a new Au1200 based toy on which the current driver-implemented
SD card-detect scheme doesn't work.  However since this toy does have a 
dedicated SD carddetect IRQ and card status bits, I took the opportunity
to get rid of the DB1200 specific parts in the driver and added callbacks
for platform/board-specific carddetect and voltage setting methods.

What I need is feedback from testers with access to db1200/pb1200 boards:
The patch below (+ boardstuff) works on my board but I'm not sure if
I got the carddetect poll timer for the db1200 right.

Please test and comment!

Thanks!
	Manuel Lauss

--- 

>From fd0021032494ad61f36558f1760391f715c05e97 Mon Sep 17 00:00:00 2001
From: Manuel Lauss <mano@xxxxxxxxxxxxx>
Date: Tue, 6 May 2008 20:03:24 +0200
Subject: [PATCH] au1xmmc updates

- export get_au1x00_speed() for modules
- move DB/PB1200 specific functions out of the driver to the board code,
  wrap them in a structure and pass them to the driver via platform_data.
- code style changes
- hook up the SDIO irq
---
 arch/mips/au1000/common/clocks.c          |    2 +-
 arch/mips/au1000/common/platform.c        |   32 --
 arch/mips/au1000/pb1200/platform.c        |  127 +++++++-
 drivers/mmc/host/au1xmmc.c                |  573 +++++++++++++++++------------
 drivers/mmc/host/au1xmmc.h                |   96 -----
 include/asm-mips/mach-au1x00/au1100_mmc.h |   43 ++-
 6 files changed, 501 insertions(+), 372 deletions(-)
 delete mode 100644 drivers/mmc/host/au1xmmc.h

diff --git a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c
index 3ce6cac..6dbc87a 100644
--- a/arch/mips/au1000/common/clocks.c
+++ b/arch/mips/au1000/common/clocks.c
@@ -46,7 +46,7 @@ unsigned int get_au1x00_speed(void)
 {
 	return au1x00_clock;
 }
-
+EXPORT_SYMBOL(get_au1x00_speed);
 
 
 /*
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 31d2a22..08a5900 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -162,24 +162,6 @@ static struct resource au1xxx_usb_gdt_resources[] = {
 	},
 };
 
-static struct resource au1xxx_mmc_resources[] = {
-	[0] = {
-		.start          = SD0_PHYS_ADDR,
-		.end            = SD0_PHYS_ADDR + 0x40,
-		.flags          = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= SD1_PHYS_ADDR,
-		.end 		= SD1_PHYS_ADDR + 0x40,
-		.flags		= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start          = AU1200_SD_INT,
-		.end            = AU1200_SD_INT,
-		.flags          = IORESOURCE_IRQ,
-	}
-};
-
 static u64 udc_dmamask = ~(u32)0;
 
 static struct platform_device au1xxx_usb_gdt_device = {
@@ -245,19 +227,6 @@ static struct platform_device au1200_lcd_device = {
 	.num_resources  = ARRAY_SIZE(au1200_lcd_resources),
 	.resource       = au1200_lcd_resources,
 };
-
-static u64 au1xxx_mmc_dmamask =  ~(u32)0;
-
-static struct platform_device au1xxx_mmc_device = {
-	.name = "au1xxx-mmc",
-	.id = 0,
-	.dev = {
-		.dma_mask               = &au1xxx_mmc_dmamask,
-		.coherent_dma_mask      = 0xffffffff,
-	},
-	.num_resources  = ARRAY_SIZE(au1xxx_mmc_resources),
-	.resource       = au1xxx_mmc_resources,
-};
 #endif /* #ifdef CONFIG_SOC_AU1200 */
 
 static struct platform_device au1x00_pcmcia_device = {
@@ -295,7 +264,6 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = {
 	&au1xxx_usb_gdt_device,
 	&au1xxx_usb_otg_device,
 	&au1200_lcd_device,
-	&au1xxx_mmc_device,
 #endif
 #ifdef SMBUS_PSC_BASE
 	&pbdb_smbus_device,
diff --git a/arch/mips/au1000/pb1200/platform.c b/arch/mips/au1000/pb1200/platform.c
index 5930110..bee2bf7 100644
--- a/arch/mips/au1000/pb1200/platform.c
+++ b/arch/mips/au1000/pb1200/platform.c
@@ -20,8 +20,17 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/mmc/host.h>
 
 #include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+
+#if defined(CONFIG_MIPS_PB1200)
+#include <asm/mach-pb1x00/pb1200.h>
+#elif defined(CONFIG_MIPS_DB1200)
+#include <asm/mach-db1x00/db1200.h>
+#endif
 
 static struct resource ide_resources[] = {
 	[0] = {
@@ -70,9 +79,125 @@ static struct platform_device smc91c111_device = {
 	.resource	= smc91c111_resources
 };
 
+
+static const struct {
+	u16 bcsrpwr;
+	u16 bcsrstatus;
+	u16 wpstatus;
+} au1xmmc_card_table[] = {
+	{ BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
+#ifndef CONFIG_MIPS_DB1200
+	{ BCSR_BOARD_SD1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
+#endif
+};
+
+static void pb1200mmc_set_power(void *mmc_host, int state)
+{
+	struct au1xmmc_host *host = mmc_priv((struct mmc_host *)mmc_host);
+	u32 val = au1xmmc_card_table[host->id].bcsrpwr;
+
+	bcsr->board &= ~val;
+	if (state)
+		bcsr->board |= val;
+
+	au_sync_delay(1);
+}
+
+static int pb1200mmc_card_readonly(void *mmc_host)
+{
+	struct au1xmmc_host *host = mmc_priv((struct mmc_host *)mmc_host);
+	return (bcsr->status & au1xmmc_card_table[host->id].wpstatus) ? 1 : 0;
+}
+
+static int pb1200mmc_card_inserted(void *mmc_host)
+{
+	struct au1xmmc_host *host = mmc_priv((struct mmc_host *)mmc_host);
+	return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus)
+		? 1 : 0;
+}
+
+static struct au1xmmc_platdata db1xmmcpd = {
+	.set_power	= pb1200mmc_set_power,
+	.card_inserted	= pb1200mmc_card_inserted,
+	.card_readonly	= pb1200mmc_card_readonly,
+	.cd_setup	= NULL,		/* use poll-timer in driver */
+};
+
+static u64 au1xxx_mmc_dmamask =  ~(u32)0;
+
+struct resource au1200sd0_res[] = {
+	[0] = {
+		.start	= CPHYSADDR(SD0_BASE),
+		.end	= CPHYSADDR(SD0_BASE) + 0x40,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= AU1200_SD_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= DSCR_CMD0_SDMS_TX0,
+		.flags	= IORESOURCE_DMA,
+	},
+	[4] = {
+		.start	= DSCR_CMD0_SDMS_RX0,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device au1xxx_sd0_device = {
+	.name = "au1xxx-mmc",
+	.id = 0,	/* index into au1xmmc_card_table[] */
+	.dev = {
+		.dma_mask               = &au1xxx_mmc_dmamask,
+		.coherent_dma_mask      = 0xffffffff,
+		.platform_data		= &db1xmmcpd,
+	},
+	.num_resources  = ARRAY_SIZE(au1200sd0_res),
+	.resource       = au1200sd0_res,
+};
+
+#ifndef CONFIG_MIPS_DB1200
+struct resource au1200sd1_res[] = {
+	[0] = {
+		.start	= CPHYSADDR(SD1_BASE),
+		.end	= CPHYSADDR(SD1_BASE) + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= AU1200_SD_INT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= DSCR_CMD0_SDMS_TX1,
+		.flags	= IORESOURCE_DMA,
+	},
+	[4] = {
+		.start	= DSCR_CMD0_SDMS_RX1,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device au1xxx_sd1_device = {
+	.name = "au1xxx-mmc",
+	.id = 1,	/* index into au1xmmc_card_table[] */
+	.dev = {
+		.dma_mask               = &au1xxx_mmc_dmamask,
+		.coherent_dma_mask      = 0xffffffff,
+		.platform_data		= &db1xmmcpd,
+	},
+	.num_resources  = ARRAY_SIZE(au1200sd1_res),
+	.resource       = au1200sd1_res,
+};
+#endif
+
 static struct platform_device *board_platform_devices[] __initdata = {
 	&ide_device,
-	&smc91c111_device
+	&smc91c111_device,
+	&au1xxx_sd0_device,
+#ifndef CONFIG_MIPS_DB1200
+	&au1xxx_sd1_device,
+#endif
 };
 
 static int __init board_register_devices(void)
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index cc5f7bc..da62bd2 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -49,7 +49,6 @@
 #include <asm/mach-au1x00/au1100_mmc.h>
 
 #include <au1xxx.h>
-#include "au1xmmc.h"
 
 #define DRIVER_NAME "au1xxx-mmc"
 
@@ -61,31 +60,71 @@
 #define DBG(fmt, idx, args...)
 #endif
 
-const struct {
-	u32 iobase;
-	u32 tx_devid, rx_devid;
-	u16 bcsrpwr;
-	u16 bcsrstatus;
-	u16 wpstatus;
-} au1xmmc_card_table[] = {
-	{ SD0_BASE, DSCR_CMD0_SDMS_TX0, DSCR_CMD0_SDMS_RX0,
-	  BCSR_BOARD_SD0PWR, BCSR_INT_SD0INSERT, BCSR_STATUS_SD0WP },
-#ifndef CONFIG_MIPS_DB1200
-	{ SD1_BASE, DSCR_CMD0_SDMS_TX1, DSCR_CMD0_SDMS_RX1,
-	  BCSR_BOARD_DS1PWR, BCSR_INT_SD1INSERT, BCSR_STATUS_SD1WP }
+#define AU1XMMC_DESCRIPTOR_COUNT 1
+#define AU1XMMC_DESCRIPTOR_SIZE  2048
+
+#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30  | \
+		      MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33  | \
+		      MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)
+
+/* Easy access macros */
+
+#define HOST_STATUS(h)	((h)->iobase + SD_STATUS)
+#define HOST_CONFIG(h)	((h)->iobase + SD_CONFIG)
+#define HOST_ENABLE(h)	((h)->iobase + SD_ENABLE)
+#define HOST_TXPORT(h)	((h)->iobase + SD_TXPORT)
+#define HOST_RXPORT(h)	((h)->iobase + SD_RXPORT)
+#define HOST_CMDARG(h)	((h)->iobase + SD_CMDARG)
+#define HOST_BLKSIZE(h)	((h)->iobase + SD_BLKSIZE)
+#define HOST_CMD(h)	((h)->iobase + SD_CMD)
+#define HOST_CONFIG2(h)	((h)->iobase + SD_CONFIG2)
+#define HOST_TIMEOUT(h)	((h)->iobase + SD_TIMEOUT)
+#define HOST_DEBUG(h)	((h)->iobase + SD_DEBUG)
+
+#define DMA_CHANNEL(h) \
+	( ((h)->flags & HOST_F_XMIT) ? (h)->dma.tx_chan : (h)->dma.rx_chan)
+
+/* This gives us a hard value for the stop command that we can write directly
+ * to the command register
+ */
+
+#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO)
+
+/* This is the set of interrupts that we configure by default */
+
+#if 0
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \
+		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
 #endif
-};
 
-#define AU1XMMC_CONTROLLER_COUNT (ARRAY_SIZE(au1xmmc_card_table))
+#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \
+		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
+/* The poll event (looking for insert/remove events runs twice a second */
+#define AU1XMMC_DETECT_TIMEOUT (HZ/2)
+
+/* Status flags used by the host structure */
+#define HOST_F_XMIT   0x0001
+#define HOST_F_RECV   0x0002
+#define HOST_F_DMA    0x0010
+#define HOST_F_ACTIVE 0x0100
+#define HOST_F_STOP   0x1000
+
+#define HOST_S_IDLE   0x0001
+#define HOST_S_CMD    0x0002
+#define HOST_S_DATA   0x0003
+#define HOST_S_STOP   0x0004
 
-/* This array stores pointers for the hosts (used by the IRQ handler) */
-struct au1xmmc_host *au1xmmc_hosts[AU1XMMC_CONTROLLER_COUNT];
 static int dma = 1;
 
-#ifdef MODULE
 module_param(dma, bool, 0);
 MODULE_PARM_DESC(dma, "Use DMA engine for data transfers (0 = disabled)");
-#endif
+
+/* 8bit memory device */
+static dbdev_tab_t au1xmmc_mem_dbdev = {
+	DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
+};
+static int memid = 0;
+
 
 static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
 {
@@ -119,14 +158,13 @@ static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask)
 
 static inline void SEND_STOP(struct au1xmmc_host *host)
 {
-
-	/* We know the value of CONFIG2, so avoid a read we don't need */
-	u32 mask = SD_CONFIG2_EN;
+	u32 config2;
 
 	WARN_ON(host->status != HOST_S_DATA);
 	host->status = HOST_S_STOP;
 
-	au_writel(mask | SD_CONFIG2_DF, HOST_CONFIG2(host));
+	config2 = au_readl(HOST_CONFIG2(host));
+	au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host));
 	au_sync();
 
 	/* Send the stop commmand */
@@ -135,31 +173,37 @@ static inline void SEND_STOP(struct au1xmmc_host *host)
 
 static void au1xmmc_set_power(struct au1xmmc_host *host, int state)
 {
-
-	u32 val = au1xmmc_card_table[host->id].bcsrpwr;
-
-	bcsr->board &= ~val;
-	if (state) bcsr->board |= val;
-
-	au_sync_delay(1);
+	if (host->platdata && host->platdata->set_power)
+		host->platdata->set_power(host->mmc, state);
 }
 
-static inline int au1xmmc_card_inserted(struct au1xmmc_host *host)
+static int au1xmmc_card_inserted(struct au1xmmc_host *host)
 {
-	return (bcsr->sig_status & au1xmmc_card_table[host->id].bcsrstatus)
-		? 1 : 0;
+	int ret;
+
+	if (host->platdata && host->platdata->card_inserted)
+		ret = host->platdata->card_readonly(host->mmc);
+	else
+		ret = 1;	/* assume there is a card */
+
+	return ret;
 }
 
 static int au1xmmc_card_readonly(struct mmc_host *mmc)
 {
 	struct au1xmmc_host *host = mmc_priv(mmc);
-	return (bcsr->status & au1xmmc_card_table[host->id].wpstatus)
-		? 1 : 0;
+	int ret;
+
+	if (host->platdata && host->platdata->card_readonly)
+		ret = host->platdata->card_readonly(mmc);
+	else
+		ret = 1;	/* assume card is read-only */
+
+	return ret;
 }
 
 static void au1xmmc_finish_request(struct au1xmmc_host *host)
 {
-
 	struct mmc_request *mrq = host->mrq;
 
 	host->mrq = NULL;
@@ -174,14 +218,12 @@ static void au1xmmc_finish_request(struct au1xmmc_host *host)
 
 	host->status = HOST_S_IDLE;
 
-	bcsr->disk_leds |= (1 << 8);
-
 	mmc_request_done(host->mmc, mrq);
 }
 
 static void au1xmmc_tasklet_finish(unsigned long param)
 {
-	struct au1xmmc_host *host = (struct au1xmmc_host *) param;
+	struct au1xmmc_host *host = (struct au1xmmc_host *)param;
 	au1xmmc_finish_request(host);
 }
 
@@ -235,18 +277,16 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 	au_sync();
 
 	/* Wait for the command to go on the line */
-
-	while(1) {
+	while (1) {
 		if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
 			break;
 	}
 
 	/* Wait for the command to come back */
-
 	if (wait) {
 		u32 status = au_readl(HOST_STATUS(host));
 
-		while(!(status & SD_STATUS_CR))
+		while (!(status & SD_STATUS_CR))
 			status = au_readl(HOST_STATUS(host));
 
 		/* Clear the CR status */
@@ -260,7 +300,6 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
 
 static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
 {
-
 	struct mmc_request *mrq = host->mrq;
 	struct mmc_data *data;
 	u32 crc;
@@ -276,15 +315,13 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
 		status = au_readl(HOST_STATUS(host));
 
 	/* The transaction is really over when the SD_STATUS_DB bit is clear */
-
-	while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
+	while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
 		status = au_readl(HOST_STATUS(host));
 
 	data->error = 0;
 	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
 
         /* Process any errors */
-
 	crc = (status & (SD_STATUS_WC | SD_STATUS_RC));
 	if (host->flags & HOST_F_XMIT)
 		crc |= ((status & 0x07) == 0x02) ? 0 : 1;
@@ -304,8 +341,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
 			chan_tab_t *c = *((chan_tab_t **) chan);
 			au1x_dma_chan_t *cp = c->chan_ptr;
 			data->bytes_xfered = cp->ddma_bytecnt;
-		}
-		else
+		} else
 			data->bytes_xfered =
 				(data->blocks * data->blksz) -
 				host->pio.len;
@@ -326,10 +362,9 @@ static void au1xmmc_tasklet_data(unsigned long param)
 
 static void au1xmmc_send_pio(struct au1xmmc_host *host)
 {
-
 	struct mmc_data *data = 0;
 	int sg_len, max, count = 0;
-	unsigned char *sg_ptr;
+	unsigned char *sg_ptr, val;
 	u32 status = 0;
 	struct scatterlist *sg;
 
@@ -350,11 +385,8 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 	max = (sg_len > host->pio.len) ? host->pio.len : sg_len;
 	if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER;
 
-	for(count = 0; count < max; count++ ) {
-		unsigned char val;
-
+	for (count = 0; count < max; count++ ) {
 		status = au_readl(HOST_STATUS(host));
-
 		if (!(status & SD_STATUS_TH))
 			break;
 
@@ -384,7 +416,6 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
 
 static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 {
-
 	struct mmc_data *data = 0;
 	int sg_len = 0, max = 0, count = 0;
 	unsigned char *sg_ptr = 0;
@@ -412,7 +443,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 	if (max > AU1XMMC_MAX_TRANSFER)
 		max = AU1XMMC_MAX_TRANSFER;
 
-	for(count = 0; count < max; count++ ) {
+	for (count = 0; count < max; count++ ) {
 		u32 val;
 		status = au_readl(HOST_STATUS(host));
 
@@ -468,7 +499,6 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
 
 static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
 {
-
 	struct mmc_request *mrq = host->mrq;
 	struct mmc_command *cmd;
 	int trans;
@@ -493,7 +523,6 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
 			 * we only got 120 bytes, but the engine expects
 			 * 128 bits, so we have to shift things up
 			 */
-
 			for(i = 0; i < 4; i++) {
 				cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8;
 				if (i != 3)
@@ -512,14 +541,12 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
 	}
 
         /* Figure out errors */
-
 	if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
 		cmd->error = -EILSEQ;
 
 	trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
 
 	if (!trans || cmd->error) {
-
 		IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
 		tasklet_schedule(&host->finish_task);
 		return;
@@ -531,21 +558,18 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
 		u32 channel = DMA_CHANNEL(host);
 
 		/* Start the DMA as soon as the buffer gets something in it */
-
 		if (host->flags & HOST_F_RECV) {
 			u32 mask = SD_STATUS_DB | SD_STATUS_NE;
 
-			while((status & mask) != mask)
+			while ((status & mask) != mask)
 				status = au_readl(HOST_STATUS(host));
 		}
-
 		au1xxx_dbdma_start(channel);
 	}
 }
 
 static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
 {
-
 	unsigned int pbus = get_au1x00_speed();
 	unsigned int divisor;
 	u32 config;
@@ -571,7 +595,6 @@ static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate)
 static int
 au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 {
-
 	int datalen = data->blocks * data->blksz;
 
 	if (dma != 0)
@@ -646,10 +669,6 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 	return -ETIMEDOUT;
 }
 
-/* static void au1xmmc_request
-   This actually starts a command or data transaction
-*/
-
 static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 {
 
@@ -663,8 +682,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 	host->mrq = mrq;
 	host->status = HOST_S_CMD;
 
-	bcsr->disk_leds &= ~(1 << 8);
-
 	if (mrq->data) {
 		FLUSH_FIFO(host);
 		flags = mrq->data->flags;
@@ -682,7 +699,6 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 
 static void au1xmmc_reset_controller(struct au1xmmc_host *host)
 {
-
 	/* Apply the clock */
 	au_writel(SD_ENABLE_CE, HOST_ENABLE(host));
         au_sync_delay(1);
@@ -711,10 +727,10 @@ static void au1xmmc_reset_controller(struct au1xmmc_host *host)
 	au_sync();
 }
 
-
-static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
+static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct au1xmmc_host *host = mmc_priv(mmc);
+	u32 config;
 
 	if (ios->power_mode == MMC_POWER_OFF)
 		au1xmmc_set_power(host, 0);
@@ -726,14 +742,25 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
 		au1xmmc_set_clock(host, ios->clock);
 		host->clock = ios->clock;
 	}
+
+	config = au_readl(HOST_CONFIG2(host));
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_4:
+		config |= (1 << 8);
+		break;
+	case MMC_BUS_WIDTH_1:
+		config &= ~(1 << 8);
+		break;
+	}
+	au_writel(config, HOST_CONFIG2(host));
+	au_sync();
 }
 
 static void au1xmmc_dma_callback(int irq, void *dev_id)
 {
-	struct au1xmmc_host *host = (struct au1xmmc_host *) dev_id;
+	struct au1xmmc_host *host = (struct au1xmmc_host *)dev_id;
 
 	/* Avoid spurious interrupts */
-
 	if (!host->mrq)
 		return;
 
@@ -749,118 +776,90 @@ static void au1xmmc_dma_callback(int irq, void *dev_id)
 
 static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
 {
-
+	struct au1xmmc_host *host = dev_id;
 	u32 status;
-	int i, ret = 0;
 
-	disable_irq(AU1100_SD_IRQ);
+	status = au_readl(HOST_STATUS(host));
 
-	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
-		struct au1xmmc_host * host = au1xmmc_hosts[i];
-		u32 handled = 1;
+	if (!(status & (1<<15)))
+		return IRQ_NONE;	/* not ours */
 
-		status = au_readl(HOST_STATUS(host));
-
-		if (host->mrq && (status & STATUS_TIMEOUT)) {
-			if (status & SD_STATUS_RAT)
-				host->mrq->cmd->error = -ETIMEDOUT;
-
-			else if (status & SD_STATUS_DT)
-				host->mrq->data->error = -ETIMEDOUT;
+	if (host->mrq && (status & STATUS_TIMEOUT)) {
+		if (status & SD_STATUS_RAT)
+			host->mrq->cmd->error = -ETIMEDOUT;
+		else if (status & SD_STATUS_DT)
+			host->mrq->data->error = -ETIMEDOUT;
 
-			/* In PIO mode, interrupts might still be enabled */
-			IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
+		/* In PIO mode, interrupts might still be enabled */
+		IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
 
-			//IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF);
-			tasklet_schedule(&host->finish_task);
-		}
+		//IRQ_OFF(host, SD_CONFIG_TH|SD_CONFIG_RA|SD_CONFIG_RF);
+		tasklet_schedule(&host->finish_task);
+	}
 #if 0
-		else if (status & SD_STATUS_DD) {
-
-			/* Sometimes we get a DD before a NE in PIO mode */
-
-			if (!(host->flags & HOST_F_DMA) &&
-					(status & SD_STATUS_NE))
-				au1xmmc_receive_pio(host);
-			else {
-				au1xmmc_data_complete(host, status);
-				//tasklet_schedule(&host->data_task);
-			}
+	else if (status & SD_STATUS_DD) {
+		/* Sometimes we get a DD before a NE in PIO mode */
+		if (!(host->flags & HOST_F_DMA) && (status & SD_STATUS_NE))
+			au1xmmc_receive_pio(host);
+		else {
+			au1xmmc_data_complete(host, status);
+			//tasklet_schedule(&host->data_task);
 		}
+	}
 #endif
-		else if (status & (SD_STATUS_CR)) {
-			if (host->status == HOST_S_CMD)
-				au1xmmc_cmd_complete(host,status);
-		}
-		else if (!(host->flags & HOST_F_DMA)) {
-			if ((host->flags & HOST_F_XMIT) &&
-			    (status & STATUS_DATA_OUT))
-				au1xmmc_send_pio(host);
-			else if ((host->flags & HOST_F_RECV) &&
-			    (status & STATUS_DATA_IN))
-				au1xmmc_receive_pio(host);
-		}
-		else if (status & 0x203FBC70) {
-			DBG("Unhandled status %8.8x\n", host->id, status);
-			handled = 0;
-		}
-
-		au_writel(status, HOST_STATUS(host));
-		au_sync();
+	else if (status & (SD_STATUS_CR)) {
+		if (host->status == HOST_S_CMD)
+			au1xmmc_cmd_complete(host,status);
 
-		ret |= handled;
-	}
+	} else if (!(host->flags & HOST_F_DMA)) {
+		if ((host->flags & HOST_F_XMIT) && (status & STATUS_DATA_OUT))
+			au1xmmc_send_pio(host);
+		else if ((host->flags & HOST_F_RECV) && (status & STATUS_DATA_IN))
+			au1xmmc_receive_pio(host);
 
-	enable_irq(AU1100_SD_IRQ);
-	return ret;
-}
+	} else if (status & 0x80000000) {
+		mmc_signal_sdio_irq(host->mmc);
 
-static void au1xmmc_poll_event(unsigned long arg)
-{
-	struct au1xmmc_host *host = (struct au1xmmc_host *) arg;
-
-	int card = au1xmmc_card_inserted(host);
-        int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
-
-	if (card != controller) {
-		host->flags &= ~HOST_F_ACTIVE;
-		if (card) host->flags |= HOST_F_ACTIVE;
-		mmc_detect_change(host->mmc, 0);
+	} else if (status & 0x203FBC70) {
+			DBG("Unhandled status %8.8x\n", host->id, status);
 	}
 
-	if (host->mrq != NULL) {
-		u32 status = au_readl(HOST_STATUS(host));
-		DBG("PENDING - %8.8x\n", host->id, status);
-	}
+	au_writel(status, HOST_STATUS(host));
+	au_sync();
 
-	mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
+	return IRQ_HANDLED;
 }
 
-static dbdev_tab_t au1xmmc_mem_dbdev =
+static int au1xmmc_init_dma(struct au1xmmc_host *host)
 {
-	DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 8, 0x00000000, 0, 0
-};
-
-static void au1xmmc_init_dma(struct au1xmmc_host *host)
-{
-
+	struct resource *res;
 	u32 rxchan, txchan;
+	int txid, rxid;
 
-	int txid = au1xmmc_card_table[host->id].tx_devid;
-	int rxid = au1xmmc_card_table[host->id].rx_devid;
+	res = platform_get_resource(host->pdev, IORESOURCE_DMA, 0);
+	if (!res)
+		return -ENODEV;
+	txid = res->start;
 
-	/* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
-	   of 8 bits.  And since devices are shared, we need to create
-	   our own to avoid freaking out other devices
-	*/
-
-	int memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
+	res = platform_get_resource(host->pdev, IORESOURCE_DMA, 1);
+	if (!res)
+		return -ENODEV;
+	rxid = res->start;
 
 	txchan = au1xxx_dbdma_chan_alloc(memid, txid,
-					 au1xmmc_dma_callback, (void *) host);
+				au1xmmc_dma_callback, (void *)host);
+	if (!txchan) {
+		dev_err(&host->pdev->dev, "cannot allocate TX DMA\n");
+		return -ENODEV;
+	}
 
 	rxchan = au1xxx_dbdma_chan_alloc(rxid, memid,
-					 au1xmmc_dma_callback, (void *) host);
+				au1xmmc_dma_callback, (void *)host);
+	if (!rxchan) {
+		dev_err(&host->pdev->dev, "cannot allocate RX DMA\n");
+		au1xxx_dbdma_chan_free(txchan);
+		return -ENODEV;
+	}
 
 	au1xxx_dbdma_set_devwidth(txchan, 8);
 	au1xxx_dbdma_set_devwidth(rxchan, 8);
@@ -868,126 +867,219 @@ static void au1xmmc_init_dma(struct au1xmmc_host *host)
 	au1xxx_dbdma_ring_alloc(txchan, AU1XMMC_DESCRIPTOR_COUNT);
 	au1xxx_dbdma_ring_alloc(rxchan, AU1XMMC_DESCRIPTOR_COUNT);
 
-	host->tx_chan = txchan;
-	host->rx_chan = rxchan;
+	host->dma.tx_chan = txchan;
+	host->dma.rx_chan = rxchan;
+
+	return 0;
+}
+
+static void au1xmmc_enable_sdio_irq(struct mmc_host *mmc, int en)
+{
+	struct au1xmmc_host *host = mmc_priv(mmc);
+
+	if (en)
+		IRQ_ON(host, (1<<31));
+	else
+		IRQ_OFF(host, (1<<31));
 }
 
 static const struct mmc_host_ops au1xmmc_ops = {
 	.request	= au1xmmc_request,
 	.set_ios	= au1xmmc_set_ios,
 	.get_ro		= au1xmmc_card_readonly,
+	.enable_sdio_irq= au1xmmc_enable_sdio_irq,
 };
 
-static int __devinit au1xmmc_probe(struct platform_device *pdev)
+static void au1xmmc_poll_event(unsigned long arg)
 {
+	struct au1xmmc_host *host = (struct au1xmmc_host *)arg;
+	u32 status;
 
-	int i, ret = 0;
+	int card = au1xmmc_card_inserted(host);
+        int controller = (host->flags & HOST_F_ACTIVE) ? 1 : 0;
 
-	/* THe interrupt is shared among all controllers */
-	ret = request_irq(AU1100_SD_IRQ, au1xmmc_irq, IRQF_DISABLED, "MMC", 0);
+	if (card != controller) {
+		host->flags &= ~HOST_F_ACTIVE;
+		if (card)
+			host->flags |= HOST_F_ACTIVE;
+		mmc_detect_change(host->mmc, 0);
+	}
 
-	if (ret) {
-		printk(DRIVER_NAME "ERROR: Couldn't get int %d: %d\n",
-				AU1100_SD_IRQ, ret);
-		return -ENXIO;
+	if (host->mrq != NULL) {
+		status = au_readl(HOST_STATUS(host));
+		DBG("PENDING - %8.8x\n", host->id, status);
 	}
 
-	disable_irq(AU1100_SD_IRQ);
+	mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
+}
 
-	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
-		struct mmc_host *mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
-		struct au1xmmc_host *host = 0;
+static void au1xmmc_init_cd_poll_timer(struct au1xmmc_host *host)
+{
+	init_timer(&host->timer);
+	host->timer.function = au1xmmc_poll_event;
+	host->timer.data = (unsigned long)host;
+	host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
+	add_timer(&host->timer);
+}
 
-		if (!mmc) {
-			printk(DRIVER_NAME "ERROR: no mem for host %d\n", i);
-			au1xmmc_hosts[i] = 0;
-			continue;
-		}
+static int __devinit au1xmmc_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc;
+	struct au1xmmc_host *host;
+	struct resource *r;
+	int ret;
+
+	mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
+	if (!mmc) {
+		dev_err(&pdev->dev, "no memory for mmc host\n");
+		ret = -ENOMEM;
+		goto out0;
+	}
 
-		mmc->ops = &au1xmmc_ops;
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->platdata = pdev->dev.platform_data;
+	host->pdev = pdev;
 
-		mmc->f_min =   450000;
-		mmc->f_max = 24000000;
+	ret = -ENODEV;
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		dev_err(&pdev->dev, "no mmio defined\n");
+		goto out1;
+	}
+	host->iobase = (unsigned long)ioremap(r->start, 0xff);
+	if (!host->iobase) {
+		dev_err(&pdev->dev, "cannot remap mmio\n");
+		goto out1;
+	}
 
-		mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
-		mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!r) {
+		dev_err(&pdev->dev, "no IRQ defined\n");
+		goto out2;
+	}
 
-		mmc->max_blk_size = 2048;
-		mmc->max_blk_count = 512;
+	host->irq = r->start;
+	/* IRQ is shared among both SD controllers */
+	ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED,
+			  DRIVER_NAME, host);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot grab IRQ\n");
+		goto out2;
+	}
 
-		mmc->ocr_avail = AU1XMMC_OCR;
+	mmc->ops = &au1xmmc_ops;
 
-		host = mmc_priv(mmc);
-		host->mmc = mmc;
+	mmc->f_min =   450000;
+	mmc->f_max = 24000000;
 
-		host->id = i;
-		host->iobase = au1xmmc_card_table[host->id].iobase;
-		host->clock = 0;
-		host->power_mode = MMC_POWER_OFF;
+	mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE;
+	mmc->max_phys_segs = AU1XMMC_DESCRIPTOR_COUNT;
 
-		host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0;
-		host->status = HOST_S_IDLE;
+	mmc->max_blk_size = 2048;
+	mmc->max_blk_count = 512;
 
-		init_timer(&host->timer);
+	mmc->ocr_avail = AU1XMMC_OCR;
+	mmc->caps = MMC_CAP_SDIO_IRQ /* | MMC_CAP_4_BIT_DATA borked */;
 
-		host->timer.function = au1xmmc_poll_event;
-		host->timer.data = (unsigned long) host;
-		host->timer.expires = jiffies + AU1XMMC_DETECT_TIMEOUT;
+	host->clock = 0;
+	host->id = pdev->id;
+	host->status = HOST_S_IDLE;
 
-		tasklet_init(&host->data_task, au1xmmc_tasklet_data,
-				(unsigned long) host);
+	/* board-specific carddetect setup, if any */
+	if (host->platdata && host->platdata->cd_setup) {
+		ret = host->platdata->cd_setup(mmc, 1);
+		if (ret) {
+			dev_err(&pdev->dev, "board CD setup failed\n");
+			goto out3;
+		}
+	} else {
+		/* poll the board-specific card-is-in-socket method */
+		au1xmmc_init_cd_poll_timer(host);
+		host->flags = au1xmmc_card_inserted(host) ? HOST_F_ACTIVE : 0;
+	}
 
-		tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
-				(unsigned long) host);
+	tasklet_init(&host->data_task, au1xmmc_tasklet_data,
+			(unsigned long)host);
 
-		spin_lock_init(&host->lock);
+	tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
+			(unsigned long)host);
 
-		if (dma != 0)
-			au1xmmc_init_dma(host);
+	if (dma) {
+		ret = au1xmmc_init_dma(host);
+		if (ret)
+			goto out4;
+	}
 
-		au1xmmc_reset_controller(host);
+	au1xmmc_reset_controller(host);
 
-		mmc_add_host(mmc);
-		au1xmmc_hosts[i] = host;
+	ret = mmc_add_host(mmc);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot add mmc host\n");
+		goto out5;
+	}
 
-		add_timer(&host->timer);
+	platform_set_drvdata(pdev, mmc);
 
-		printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n",
-		       host->id, host->iobase, dma ? "dma" : "pio");
-	}
+	printk(KERN_INFO DRIVER_NAME ": MMC Controller %d set up at %8.8X (mode=%s)\n",
+		       pdev->id, host->iobase, dma ? "dma" : "pio");
 
-	enable_irq(AU1100_SD_IRQ);
+	return 0;	/* all ok */
 
-	return 0;
+out5:
+	if (dma) {
+		au1xxx_dbdma_chan_free(host->dma.tx_chan);
+		au1xxx_dbdma_chan_free(host->dma.rx_chan);
+	}
+out4:
+	tasklet_kill(&host->data_task);
+	tasklet_kill(&host->finish_task);
+
+	if (host->platdata && host->platdata->cd_setup)
+		host->platdata->cd_setup(mmc, 0);
+	else
+		del_timer_sync(&host->timer);
+out3:
+	free_irq(host->irq, host);
+out2:
+	iounmap((void *)host->iobase);
+out1:
+	mmc_free_host(mmc);
+out0:
+	return ret;
 }
 
 static int __devexit au1xmmc_remove(struct platform_device *pdev)
 {
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+	struct au1xmmc_host *host;
 
-	int i;
-
-	disable_irq(AU1100_SD_IRQ);
+	if (mmc) {
+		host  = mmc_priv(mmc);
 
-	for(i = 0; i < AU1XMMC_CONTROLLER_COUNT; i++) {
-		struct au1xmmc_host *host = au1xmmc_hosts[i];
-		if (!host) continue;
+		au_writel(0, HOST_ENABLE(host));
+		au_writel(0, HOST_CONFIG(host));
+		au_sync();
 
 		tasklet_kill(&host->data_task);
 		tasklet_kill(&host->finish_task);
 
-		del_timer_sync(&host->timer);
+		if (host->platdata && host->platdata->cd_setup)
+			host->platdata->cd_setup(mmc, 0);
+		else
+			del_timer_sync(&host->timer);
+
 		au1xmmc_set_power(host, 0);
 
-		mmc_remove_host(host->mmc);
+		free_irq(host->irq, host);
 
-		au1xxx_dbdma_chan_free(host->tx_chan);
-		au1xxx_dbdma_chan_free(host->rx_chan);
+		mmc_remove_host(host->mmc);
 
-		au_writel(0x0, HOST_ENABLE(host));
-		au_sync();
+		if (dma) {
+			au1xxx_dbdma_chan_free(host->dma.tx_chan);
+			au1xxx_dbdma_chan_free(host->dma.rx_chan);
+		}
 	}
-
-	free_irq(AU1100_SD_IRQ, 0);
 	return 0;
 }
 
@@ -1004,6 +1096,18 @@ static struct platform_driver au1xmmc_driver = {
 
 static int __init au1xmmc_init(void)
 {
+	if (dma) {
+		/* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
+		   of 8 bits.  And since devices are shared, we need to create
+		   our own to avoid freaking out other devices
+		 */
+		if (!memid)
+			memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
+		if (!memid) {
+			printk(KERN_ERR "au1xmmc: cannot add memory dma dev\n");
+			return -ENODEV;
+		}
+	}
 	return platform_driver_register(&au1xmmc_driver);
 }
 
@@ -1015,10 +1119,7 @@ static void __exit au1xmmc_exit(void)
 module_init(au1xmmc_init);
 module_exit(au1xmmc_exit);
 
-#ifdef MODULE
 MODULE_AUTHOR("Advanced Micro Devices, Inc");
 MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:au1xxx-mmc");
-#endif
-
diff --git a/drivers/mmc/host/au1xmmc.h b/drivers/mmc/host/au1xmmc.h
deleted file mode 100644
index 341cbdf..0000000
--- a/drivers/mmc/host/au1xmmc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-#ifndef _AU1XMMC_H_
-#define _AU1XMMC_H_
-
-/* Hardware definitions */
-
-#define AU1XMMC_DESCRIPTOR_COUNT 1
-#define AU1XMMC_DESCRIPTOR_SIZE  2048
-
-#define AU1XMMC_OCR ( MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30  | \
-		      MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33  | \
-		      MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36)
-
-/* Easy access macros */
-
-#define HOST_STATUS(h)	((h)->iobase + SD_STATUS)
-#define HOST_CONFIG(h)	((h)->iobase + SD_CONFIG)
-#define HOST_ENABLE(h)	((h)->iobase + SD_ENABLE)
-#define HOST_TXPORT(h)	((h)->iobase + SD_TXPORT)
-#define HOST_RXPORT(h)	((h)->iobase + SD_RXPORT)
-#define HOST_CMDARG(h)	((h)->iobase + SD_CMDARG)
-#define HOST_BLKSIZE(h)	((h)->iobase + SD_BLKSIZE)
-#define HOST_CMD(h)	((h)->iobase + SD_CMD)
-#define HOST_CONFIG2(h)	((h)->iobase + SD_CONFIG2)
-#define HOST_TIMEOUT(h)	((h)->iobase + SD_TIMEOUT)
-#define HOST_DEBUG(h)	((h)->iobase + SD_DEBUG)
-
-#define DMA_CHANNEL(h) \
-	( ((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)
-
-/* This gives us a hard value for the stop command that we can write directly
- * to the command register
- */
-
-#define STOP_CMD (SD_CMD_RT_1B|SD_CMD_CT_7|(0xC << SD_CMD_CI_SHIFT)|SD_CMD_GO)
-
-/* This is the set of interrupts that we configure by default */
-
-#if 0
-#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | SD_CONFIG_DD | \
-		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
-#endif
-
-#define AU1XMMC_INTERRUPTS (SD_CONFIG_SC | SD_CONFIG_DT | \
-		SD_CONFIG_RAT | SD_CONFIG_CR | SD_CONFIG_I)
-/* The poll event (looking for insert/remove events runs twice a second */
-#define AU1XMMC_DETECT_TIMEOUT (HZ/2)
-
-struct au1xmmc_host {
-  struct mmc_host *mmc;
-  struct mmc_request *mrq;
-
-  u32 id;
-
-  u32 flags;
-  u32 iobase;
-  u32 clock;
-  u32 bus_width;
-  u32 power_mode;
-
-  int status;
-
-   struct {
-	   int len;
-	   int dir;
-  } dma;
-
-   struct {
-	   int index;
-	   int offset;
-	   int len;
-  } pio;
-
-  u32 tx_chan;
-  u32 rx_chan;
-
-  struct timer_list timer;
-  struct tasklet_struct finish_task;
-  struct tasklet_struct data_task;
-
-  spinlock_t lock;
-};
-
-/* Status flags used by the host structure */
-
-#define HOST_F_XMIT   0x0001
-#define HOST_F_RECV   0x0002
-#define HOST_F_DMA    0x0010
-#define HOST_F_ACTIVE 0x0100
-#define HOST_F_STOP   0x1000
-
-#define HOST_S_IDLE   0x0001
-#define HOST_S_CMD    0x0002
-#define HOST_S_DATA   0x0003
-#define HOST_S_STOP   0x0004
-
-#endif
diff --git a/include/asm-mips/mach-au1x00/au1100_mmc.h b/include/asm-mips/mach-au1x00/au1100_mmc.h
index 9e0028f..6474fac 100644
--- a/include/asm-mips/mach-au1x00/au1100_mmc.h
+++ b/include/asm-mips/mach-au1x00/au1100_mmc.h
@@ -38,15 +38,46 @@
 #ifndef __ASM_AU1100_MMC_H
 #define __ASM_AU1100_MMC_H
 
-
-#define NUM_AU1100_MMC_CONTROLLERS	2
-
-#if defined(CONFIG_SOC_AU1100)
-#define AU1100_SD_IRQ	AU1100_SD_INT
-#elif defined(CONFIG_SOC_AU1200)
-#define AU1100_SD_IRQ	AU1200_SD_INT
-#endif
-
+struct au1xmmc_platdata {
+	int(*cd_setup)(void *mmc_host, int on);
+	int(*card_inserted)(void *mmc_host);
+	int(*card_readonly)(void *mmc_host);
+	void(*set_power)(void *mmc_host, int state);
+};
+
+struct au1xmmc_host {
+	struct mmc_host *mmc;
+	struct mmc_request *mrq;
+
+	u32 id;
+
+	u32 flags;
+	u32 iobase;
+	u32 clock;
+
+	int status;
+
+	struct {
+		int len;
+		int dir;
+		u32 tx_chan;
+		u32 rx_chan;
+	} dma;
+
+	struct {
+		int index;
+		int offset;
+		int len;
+	} pio;
+
+	struct timer_list timer;
+	struct tasklet_struct finish_task;
+	struct tasklet_struct data_task;
+
+	struct platform_device *pdev;
+	struct au1xmmc_platdata *platdata;
+	int irq;
+};
 
 #define SD0_BASE	0xB0600000
 #define SD1_BASE	0xB0680000
-- 
1.5.5.1




[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux