This patch adds platform data support to the s3mci driver.  This allows
flexible board-specific configuration of set_power, card detect and read only
pins.
---
 drivers/mmc/s3cmci.c               |   31 	30 +	1 -	0 !
 include/asm-arm/arch-s3c2410/mmc.h |    4 	4 +	0 -	0 !
 2 files changed, 34 insertions(+), 1 deletion(-)

Index: linux-2.6/drivers/mmc/s3cmci.c
===================================================================
--- linux-2.6.orig/drivers/mmc/s3cmci.c	2007-05-01 21:41:42.000000000 +0200
+++ linux-2.6/drivers/mmc/s3cmci.c	2007-05-02 00:20:38.000000000 +0200
@@ -1007,6 +1007,9 @@ static void s3cmci_set_ios(struct mmc_ho
 			s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2);
 			s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3);
 
+			if (host->pdata->set_power)
+				host->pdata->set_power(ios->power_mode, ios->vdd);
+
 			if (!host->is2440)
 				mci_con|=S3C2410_SDICON_FIFORESET;
 
@@ -1017,6 +1020,9 @@ static void s3cmci_set_ios(struct mmc_ho
 			s3c2410_gpio_setpin(S3C2410_GPE5, 0);
 			s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_OUTP);
 
+			if (host->pdata->set_power)
+				host->pdata->set_power(ios->power_mode, ios->vdd);
+
 			if (host->is2440)
 				mci_con|=S3C2440_SDICON_SDRESET;
 
@@ -1070,13 +1076,26 @@ static void s3cmci_reset(struct s3cmci_h
 	writel(con, host->base + S3C2410_SDICON);
 }
 
+static int s3cmci_get_ro(struct mmc_host *mmc)
+{
+	struct s3cmci_host *host = mmc_priv(mmc);
+
+	if (host->pdata->gpio_wprotect == 0)
+		return 0;
+
+	return s3c2410_gpio_getpin(host->pdata->gpio_wprotect);
+}
+
 static struct mmc_host_ops s3cmci_ops = {
 	.request	= s3cmci_request,
 	.set_ios	= s3cmci_set_ios,
+	.get_ro		= s3cmci_get_ro,
 };
 
 static struct s3c24xx_mmc_platdata s3c2410_mmc_defplat = {
 	.gpio_detect	= S3C2410_GPF2,
+	.set_power	= NULL,
+	.ocr_avail	= MMC_VDD_32_33,
 };
 
 static int s3cmci_probe(struct platform_device *pdev, int is2440)
@@ -1097,6 +1116,12 @@ static int s3cmci_probe(struct platform_
 	host->mmc 	= mmc;
 	host->pdev	= pdev;
 
+	host->pdata = pdev->dev.platform_data;
+	if (!host->pdata) {
+		pdev->dev.platform_data = &s3c2410_mmc_defplat;
+		host->pdata = &s3c2410_mmc_defplat;
+	}
+
 	spin_lock_init(&host->complete_lock);
 	tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
 	if (is2440) {
@@ -1176,6 +1201,10 @@ static int s3cmci_probe(struct platform_
 		goto probe_free_irq;
 	}
 
+	if (host->pdata->gpio_wprotect)
+		s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
+				    S3C2410_GPIO_INPUT);
+
 	if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL)) {
 		dev_err(&pdev->dev, "unable to get DMA channel.\n");
 		ret = -EBUSY;
@@ -1198,7 +1227,7 @@ static int s3cmci_probe(struct platform_
 	host->clk_rate = clk_get_rate(host->clk);
 
 	mmc->ops 	= &s3cmci_ops;
-	mmc->ocr_avail	= MMC_VDD_32_33;
+	mmc->ocr_avail	= host->pdata->ocr_avail;
 	mmc->caps	= MMC_CAP_4_BIT_DATA;
 	mmc->f_min 	= host->clk_rate / (host->clk_div * 256);
 	mmc->f_max 	= host->clk_rate / host->clk_div;
Index: linux-2.6/include/asm-arm/arch-s3c2410/mmc.h
===================================================================
--- linux-2.6.orig/include/asm-arm/arch-s3c2410/mmc.h	2007-05-01 18:49:08.000000000 +0200
+++ linux-2.6/include/asm-arm/arch-s3c2410/mmc.h	2007-05-02 00:15:11.000000000 +0200
@@ -17,6 +17,10 @@
 
 struct s3c24xx_mmc_platdata {
 	unsigned int	gpio_detect;
+	unsigned int	gpio_wprotect;
+	unsigned long	ocr_avail;
+	void		(*set_power)(unsigned char power_mode,
+				     unsigned short vdd);
 };
 
 extern void __init s3c24xx_sdi_set_platdata(struct s3c24xx_mmc_platdata *pd);
