[ARM] pxa: factor pxamci gpio handling

Several boards use always the same pattern with pxamci :
request gpio, request irq for that gpio to detect MMC card
insertion, request gpio for read-only mode detection, etc
...

Now that pxamci provides platform_data to describe simple
gpio management of the MMC external controls, use it.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Acked-by: Mike Rapoport <mike@compulab.co.il>
Acked-by: Philipp Zabel <philipp.zabel@gmail.com>
Acked-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: rpurdie@rpsys.net
Cc: drwyrm@gmail.com
Cc: sakoman@gmail.com
Cc: marek.vasut@gmail.com
Cc: s.hauer@pengutronix.de
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index 1d2cec2..5929218 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -271,56 +271,12 @@
 #endif
 
 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
-static int cmx270_mci_init(struct device *dev,
-			   irq_handler_t cmx270_detect_int,
-			   void *data)
-{
-	int err;
-
-	err = gpio_request(GPIO105_MMC_POWER, "MMC/SD power");
-	if (err) {
-		dev_warn(dev, "power gpio unavailable\n");
-		return err;
-	}
-
-	gpio_direction_output(GPIO105_MMC_POWER, 0);
-
-	err = request_irq(CMX270_MMC_IRQ, cmx270_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err) {
-		gpio_free(GPIO105_MMC_POWER);
-		dev_err(dev, "cmx270_mci_init: MMC/SD: can't"
-			" request MMC card detect IRQ\n");
-	}
-
-	return err;
-}
-
-static void cmx270_mci_setpower(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-
-	if ((1 << vdd) & p_d->ocr_mask) {
-		dev_dbg(dev, "power on\n");
-		gpio_set_value(GPIO105_MMC_POWER, 0);
-	} else {
-		gpio_set_value(GPIO105_MMC_POWER, 1);
-		dev_dbg(dev, "power off\n");
-	}
-}
-
-static void cmx270_mci_exit(struct device *dev, void *data)
-{
-	free_irq(CMX270_MMC_IRQ, data);
-	gpio_free(GPIO105_MMC_POWER);
-}
-
 static struct pxamci_platform_data cmx270_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= cmx270_mci_init,
-	.setpower 	= cmx270_mci_setpower,
-	.exit		= cmx270_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO83_MMC_IRQ,
+	.gpio_card_ro		= -1,
+	.gpio_power		= GPIO105_MMC_POWER,
+	.gpio_power_invert	= 1,
 };
 
 static void __init cmx270_init_mmc(void)
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 465da26..aac2cda 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -306,68 +306,21 @@
 }
 
 static struct pxamci_platform_data cm_x300_mci_platform_data = {
-	.detect_delay	= 20,
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= cm_x300_mci_init,
-	.exit		= cm_x300_mci_exit,
+	.detect_delay		= 20,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 			= cm_x300_mci_init,
+	.exit			= cm_x300_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
-static int cm_x300_mci2_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO85_MMC2_WP);
-}
-
-static int cm_x300_mci2_init(struct device *dev,
-			     irq_handler_t cm_x300_detect_int,
-			     void *data)
-{
-	int err;
-
-	/*
-	 * setup GPIO for CM-X300 MMC controller
-	 */
-	err = gpio_request(GPIO82_MMC2_IRQ, "mmc card detect");
-	if (err)
-		goto err_request_cd;
-	gpio_direction_input(GPIO82_MMC2_IRQ);
-
-	err = gpio_request(GPIO85_MMC2_WP, "mmc write protect");
-	if (err)
-		goto err_request_wp;
-	gpio_direction_input(GPIO85_MMC2_WP);
-
-	err = request_irq(CM_X300_MMC2_IRQ, cm_x300_detect_int,
-			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: MMC/SD/SDIO: "
-				"can't request card detect IRQ\n", __func__);
-		goto err_request_irq;
-	}
-
-	return 0;
-
-err_request_irq:
-	gpio_free(GPIO85_MMC2_WP);
-err_request_wp:
-	gpio_free(GPIO82_MMC2_IRQ);
-err_request_cd:
-	return err;
-}
-
-static void cm_x300_mci2_exit(struct device *dev, void *data)
-{
-	free_irq(CM_X300_MMC2_IRQ, data);
-	gpio_free(GPIO82_MMC2_IRQ);
-	gpio_free(GPIO85_MMC2_WP);
-}
-
 static struct pxamci_platform_data cm_x300_mci2_platform_data = {
-	.detect_delay	= 20,
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= cm_x300_mci2_init,
-	.exit		= cm_x300_mci2_exit,
-	.get_ro		= cm_x300_mci2_ro,
+	.detect_delay		= 20,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO82_MMC2_IRQ,
+	.gpio_card_ro		= GPIO85_MMC2_WP,
+	.gpio_power		= -1,
 };
 
 static void __init cm_x300_init_mmc(void)
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index ea34e34..2c846bb 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -95,10 +95,13 @@
 }
 
 static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
-	.detect_delay	= 20,
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.init		= colibri_pxa3xx_mci_init,
-	.exit		= colibri_pxa3xx_mci_exit,
+	.detect_delay		= 20,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.init			= colibri_pxa3xx_mci_init,
+	.exit			= colibri_pxa3xx_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 void __init colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin)
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 5363e1a..39a9458 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -307,77 +307,11 @@
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert/eject.
  */
-static struct pxamci_platform_data corgi_mci_platform_data;
-
-static int corgi_mci_init(struct device *dev, irq_handler_t corgi_detect_int, void *data)
-{
-	int err;
-
-	err = gpio_request(CORGI_GPIO_nSD_DETECT, "nSD_DETECT");
-	if (err)
-		goto err_out;
-
-	err = gpio_request(CORGI_GPIO_nSD_WP, "nSD_WP");
-	if (err)
-		goto err_free_1;
-
-	err = gpio_request(CORGI_GPIO_SD_PWR, "SD_PWR");
-	if (err)
-		goto err_free_2;
-
-	gpio_direction_input(CORGI_GPIO_nSD_DETECT);
-	gpio_direction_input(CORGI_GPIO_nSD_WP);
-	gpio_direction_output(CORGI_GPIO_SD_PWR, 0);
-
-	corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
-
-	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
-				IRQF_DISABLED | IRQF_TRIGGER_RISING |
-				IRQF_TRIGGER_FALLING,
-				"MMC card detect", data);
-	if (err) {
-		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
-				__func__);
-		goto err_free_3;
-	}
-	return 0;
-
-err_free_3:
-	gpio_free(CORGI_GPIO_SD_PWR);
-err_free_2:
-	gpio_free(CORGI_GPIO_nSD_WP);
-err_free_1:
-	gpio_free(CORGI_GPIO_nSD_DETECT);
-err_out:
-	return err;
-}
-
-static void corgi_mci_setpower(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data* p_d = dev->platform_data;
-
-	gpio_set_value(CORGI_GPIO_SD_PWR, ((1 << vdd) & p_d->ocr_mask));
-}
-
-static int corgi_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(CORGI_GPIO_nSD_WP);
-}
-
-static void corgi_mci_exit(struct device *dev, void *data)
-{
-	free_irq(CORGI_IRQ_GPIO_nSD_DETECT, data);
-	gpio_free(CORGI_GPIO_SD_PWR);
-	gpio_free(CORGI_GPIO_nSD_WP);
-	gpio_free(CORGI_GPIO_nSD_DETECT);
-}
-
 static struct pxamci_platform_data corgi_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= corgi_mci_init,
-	.get_ro		= corgi_mci_get_ro,
-	.setpower 	= corgi_mci_setpower,
-	.exit		= corgi_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= CORGI_GPIO_nSD_WP,
+	.gpio_power		= CORGI_GPIO_SD_PWR,
 };
 
 
@@ -636,6 +570,7 @@
 	corgi_init_spi();
 
  	pxa_set_udc_info(&udc_info);
+	corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&corgi_mci_platform_data);
 	pxa_set_ficp_info(&corgi_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 7d3e1b4..79141f8 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -130,61 +130,17 @@
 static int csb726_mci_init(struct device *dev,
 		irq_handler_t detect, void *data)
 {
-	int err;
-
 	csb726_mci_data.detect_delay = msecs_to_jiffies(500);
-
-	err = gpio_request(CSB726_GPIO_MMC_DETECT, "MMC detect");
-	if (err)
-		goto err_det_req;
-
-	err = gpio_direction_input(CSB726_GPIO_MMC_DETECT);
-	if (err)
-		goto err_det_dir;
-
-	err = gpio_request(CSB726_GPIO_MMC_RO, "MMC ro");
-	if (err)
-		goto err_ro_req;
-
-	err = gpio_direction_input(CSB726_GPIO_MMC_RO);
-	if (err)
-		goto err_ro_dir;
-
-	err = request_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), detect,
-			IRQF_DISABLED, "MMC card detect", data);
-	if (err)
-		goto err_irq;
-
 	return 0;
-
-err_irq:
-err_ro_dir:
-	gpio_free(CSB726_GPIO_MMC_RO);
-err_ro_req:
-err_det_dir:
-	gpio_free(CSB726_GPIO_MMC_DETECT);
-err_det_req:
-	return err;
-}
-
-static int csb726_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(CSB726_GPIO_MMC_RO);
-}
-
-static void csb726_mci_exit(struct device *dev, void *data)
-{
-	free_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), data);
-	gpio_free(CSB726_GPIO_MMC_RO);
-	gpio_free(CSB726_GPIO_MMC_DETECT);
 }
 
 static struct pxamci_platform_data csb726_mci = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init		= csb726_mci_init,
-	.get_ro		= csb726_mci_get_ro,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init			= csb726_mci_init,
 	/* FIXME setpower */
-	.exit		= csb726_mci_exit,
+	.gpio_card_detect	= CSB726_GPIO_MMC_DETECT,
+	.gpio_card_ro		= CSB726_GPIO_MMC_RO,
+	.gpio_power		= -1,
 };
 
 static struct pxaohci_platform_data csb726_ohci_platform_data = {
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 9cd0946..e0121f4 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -646,13 +646,16 @@
 }
 
 static struct pxamci_platform_data em_x270_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
-			  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
-			  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
-			  MMC_VDD_30_31|MMC_VDD_31_32,
-	.init 		= em_x270_mci_init,
-	.setpower 	= em_x270_mci_setpower,
-	.exit		= em_x270_mci_exit,
+	.ocr_mask		= MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
+				  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
+				  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
+				  MMC_VDD_30_31|MMC_VDD_31_32,
+	.init 			= em_x270_mci_init,
+	.setpower 		= em_x270_mci_setpower,
+	.exit			= em_x270_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static void __init em_x270_init_mmc(void)
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index ca9912e..1708c01 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -88,7 +88,10 @@
 
 #ifdef CONFIG_MMC_PXA
 static struct pxamci_platform_data gumstix_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect 	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static void __init gumstix_mmc_init(void)
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index b6243b5..b6486ef 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -168,7 +168,10 @@
 };
 
 static struct pxamci_platform_data idp_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static void __init idp_init(void)
diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c
index 961807d..2a4945d 100644
--- a/arch/arm/mach-pxa/imote2.c
+++ b/arch/arm/mach-pxa/imote2.c
@@ -389,6 +389,9 @@
 static struct pxamci_platform_data imote2_mci_platform_data = {
 	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */
 	.get_ro = imote2_mci_get_ro,
+	.gpio_card_detect = -1,
+	.gpio_card_ro	= -1,
+	.gpio_power = -1,
 };
 
 static struct mtd_partition imote2flash_partitions[] = {
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index f04c833..1785cc9 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -482,11 +482,14 @@
 }
 
 static struct pxamci_platform_data lubbock_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.detect_delay	= 1,
-	.init 		= lubbock_mci_init,
-	.get_ro		= lubbock_mci_get_ro,
-	.exit 		= lubbock_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.detect_delay		= 1,
+	.init 			= lubbock_mci_init,
+	.get_ro			= lubbock_mci_get_ro,
+	.exit 			= lubbock_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index ca39669..0daba43 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -651,55 +651,24 @@
 static int magician_mci_init(struct device *dev,
 				irq_handler_t detect_irq, void *data)
 {
-	int err;
-
-	err = request_irq(IRQ_MAGICIAN_SD, detect_irq,
+	return request_irq(IRQ_MAGICIAN_SD, detect_irq,
 				IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
-				"MMC card detect", data);
-	if (err)
-		goto err_request_irq;
-	err = gpio_request(EGPIO_MAGICIAN_SD_POWER, "SD_POWER");
-	if (err)
-		goto err_request_power;
-	err = gpio_request(EGPIO_MAGICIAN_nSD_READONLY, "nSD_READONLY");
-	if (err)
-		goto err_request_readonly;
-
-	return 0;
-
-err_request_readonly:
-	gpio_free(EGPIO_MAGICIAN_SD_POWER);
-err_request_power:
-	free_irq(IRQ_MAGICIAN_SD, data);
-err_request_irq:
-	return err;
-}
-
-static void magician_mci_setpower(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *pdata = dev->platform_data;
-
-	gpio_set_value(EGPIO_MAGICIAN_SD_POWER, (1 << vdd) & pdata->ocr_mask);
-}
-
-static int magician_mci_get_ro(struct device *dev)
-{
-	return (!gpio_get_value(EGPIO_MAGICIAN_nSD_READONLY));
+				"mmc card detect", data);
 }
 
 static void magician_mci_exit(struct device *dev, void *data)
 {
-	gpio_free(EGPIO_MAGICIAN_nSD_READONLY);
-	gpio_free(EGPIO_MAGICIAN_SD_POWER);
 	free_irq(IRQ_MAGICIAN_SD, data);
 }
 
 static struct pxamci_platform_data magician_mci_info = {
-	.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
-	.init     = magician_mci_init,
-	.get_ro   = magician_mci_get_ro,
-	.setpower = magician_mci_setpower,
-	.exit     = magician_mci_exit,
+	.ocr_mask 		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init     		= magician_mci_init,
+	.exit     		= magician_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= EGPIO_MAGICIAN_nSD_READONLY,
+	.gpio_card_ro_invert	= 1,
+	.gpio_power		= EGPIO_MAGICIAN_SD_POWER,
 };
 
 
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index f4dabf0..f7dc230 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -450,10 +450,13 @@
 }
 
 static struct pxamci_platform_data mainstone_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= mainstone_mci_init,
-	.setpower 	= mainstone_mci_setpower,
-	.exit		= mainstone_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 			= mainstone_mci_init,
+	.setpower 		= mainstone_mci_setpower,
+	.exit			= mainstone_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 2d28132..a8122ec 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -434,72 +434,15 @@
 /*
  * SDIO/MMC Card controller
  */
-static void mci_setpower(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-
-	if ((1 << vdd) & p_d->ocr_mask)
-		gpio_set_value(GPIO91_SDIO_EN, 1);	/* enable SDIO power */
-	else
-		gpio_set_value(GPIO91_SDIO_EN, 0);	/* disable SDIO power */
-}
-
-static int mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO78_SDIO_RO);
-}
-
-struct gpio_ress mci_gpios[] = {
-	MIO_GPIO_IN(GPIO78_SDIO_RO, 	"SDIO readonly detect"),
-	MIO_GPIO_IN(GPIO15_SDIO_INSERT,	"SDIO insertion detect"),
-	MIO_GPIO_OUT(GPIO91_SDIO_EN, 0,	"SDIO power enable")
-};
-
-static void mci_exit(struct device *dev, void *data)
-{
-	mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
-	free_irq(gpio_to_irq(GPIO15_SDIO_INSERT), data);
-}
-
-static struct pxamci_platform_data mioa701_mci_info;
-
 /**
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert/eject.
  */
-static int mci_init(struct device *dev, irq_handler_t detect_int, void *data)
-{
-	int rc;
-	int irq = gpio_to_irq(GPIO15_SDIO_INSERT);
-
-	rc = mio_gpio_request(ARRAY_AND_SIZE(mci_gpios));
-	if (rc)
-		goto err_gpio;
-	/* enable RE/FE interrupt on card insertion and removal */
-	rc = request_irq(irq, detect_int,
-			 IRQF_DISABLED | IRQF_TRIGGER_RISING |
-			 IRQF_TRIGGER_FALLING,
-			 "MMC card detect", data);
-	if (rc)
-		goto err_irq;
-
-	mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
-	return 0;
-
-err_irq:
-	dev_err(dev, "mioa701_mci_init: MMC/SD:"
-		" can't request MMC card detect IRQ\n");
-	mio_gpio_free(ARRAY_AND_SIZE(mci_gpios));
-err_gpio:
-	return rc;
-}
-
 static struct pxamci_platform_data mioa701_mci_info = {
-	.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
-	.init	  = mci_init,
-	.get_ro	  = mci_get_ro,
-	.setpower = mci_setpower,
-	.exit	  = mci_exit,
+	.ocr_mask 		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO15_SDIO_INSERT,
+	.gpio_card_ro		= GPIO78_SDIO_RO,
+	.gpio_power		= GPIO91_SDIO_EN,
 };
 
 /* FlashRAM */
@@ -841,7 +784,7 @@
 static struct gpio_ress global_gpios[] = {
 	MIO_GPIO_OUT(GPIO9_CHARGE_EN, 1, "Charger enable"),
 	MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"),
-	MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power")
+	MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power"),
 };
 
 static void __init mioa701_machine_init(void)
@@ -855,6 +798,7 @@
 	mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
 	bootstrap_init();
 	set_pxa_fb_info(&mioa701_pxafb_info);
+	mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&mioa701_mci_info);
 	pxa_set_keypad_info(&mioa701_keypad_info);
 	wm97xx_bat_set_pdata(&mioa701_battery_data);
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 169fcc1..4457491 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -143,83 +143,11 @@
 /******************************************************************************
  * SD/MMC card controller
  ******************************************************************************/
-static int palmld_mci_init(struct device *dev, irq_handler_t palmld_detect_int,
-				void *data)
-{
-	int err = 0;
-
-	/* Setup an interrupt for detecting card insert/remove events */
-	err = gpio_request(GPIO_NR_PALMLD_SD_DETECT_N, "SD IRQ");
-	if (err)
-		goto err;
-	err = gpio_direction_input(GPIO_NR_PALMLD_SD_DETECT_N);
-	if (err)
-		goto err2;
-	err = request_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N),
-			palmld_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"SD/MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
-				__func__);
-		goto err2;
-	}
-
-	err = gpio_request(GPIO_NR_PALMLD_SD_POWER, "SD_POWER");
-	if (err)
-		goto err3;
-	err = gpio_direction_output(GPIO_NR_PALMLD_SD_POWER, 0);
-	if (err)
-		goto err4;
-
-	err = gpio_request(GPIO_NR_PALMLD_SD_READONLY, "SD_READONLY");
-	if (err)
-		goto err4;
-	err = gpio_direction_input(GPIO_NR_PALMLD_SD_READONLY);
-	if (err)
-		goto err5;
-
-	printk(KERN_DEBUG "%s: irq registered\n", __func__);
-
-	return 0;
-
-err5:
-	gpio_free(GPIO_NR_PALMLD_SD_READONLY);
-err4:
-	gpio_free(GPIO_NR_PALMLD_SD_POWER);
-err3:
-	free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
-err2:
-	gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
-err:
-	return err;
-}
-
-static void palmld_mci_exit(struct device *dev, void *data)
-{
-	gpio_free(GPIO_NR_PALMLD_SD_READONLY);
-	gpio_free(GPIO_NR_PALMLD_SD_POWER);
-	free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
-	gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
-}
-
-static void palmld_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-	gpio_set_value(GPIO_NR_PALMLD_SD_POWER, p_d->ocr_mask & (1 << vdd));
-}
-
-static int palmld_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO_NR_PALMLD_SD_READONLY);
-}
-
 static struct pxamci_platform_data palmld_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.setpower	= palmld_mci_power,
-	.get_ro		= palmld_mci_get_ro,
-	.init 		= palmld_mci_init,
-	.exit		= palmld_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_PALMLD_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_PALMLD_SD_READONLY,
+	.gpio_power		= GPIO_NR_PALMLD_SD_POWER,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 33f726f..42d0528 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -124,83 +124,11 @@
 /******************************************************************************
  * SD/MMC card controller
  ******************************************************************************/
-static int palmt5_mci_init(struct device *dev, irq_handler_t palmt5_detect_int,
-				void *data)
-{
-	int err = 0;
-
-	/* Setup an interrupt for detecting card insert/remove events */
-	err = gpio_request(GPIO_NR_PALMT5_SD_DETECT_N, "SD IRQ");
-	if (err)
-		goto err;
-	err = gpio_direction_input(GPIO_NR_PALMT5_SD_DETECT_N);
-	if (err)
-		goto err2;
-	err = request_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N),
-			palmt5_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"SD/MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
-				__func__);
-		goto err2;
-	}
-
-	err = gpio_request(GPIO_NR_PALMT5_SD_POWER, "SD_POWER");
-	if (err)
-		goto err3;
-	err = gpio_direction_output(GPIO_NR_PALMT5_SD_POWER, 0);
-	if (err)
-		goto err4;
-
-	err = gpio_request(GPIO_NR_PALMT5_SD_READONLY, "SD_READONLY");
-	if (err)
-		goto err4;
-	err = gpio_direction_input(GPIO_NR_PALMT5_SD_READONLY);
-	if (err)
-		goto err5;
-
-	printk(KERN_DEBUG "%s: irq registered\n", __func__);
-
-	return 0;
-
-err5:
-	gpio_free(GPIO_NR_PALMT5_SD_READONLY);
-err4:
-	gpio_free(GPIO_NR_PALMT5_SD_POWER);
-err3:
-	free_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N), data);
-err2:
-	gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
-err:
-	return err;
-}
-
-static void palmt5_mci_exit(struct device *dev, void *data)
-{
-	gpio_free(GPIO_NR_PALMT5_SD_READONLY);
-	gpio_free(GPIO_NR_PALMT5_SD_POWER);
-	free_irq(IRQ_GPIO_PALMT5_SD_DETECT_N, data);
-	gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
-}
-
-static void palmt5_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-	gpio_set_value(GPIO_NR_PALMT5_SD_POWER, p_d->ocr_mask & (1 << vdd));
-}
-
-static int palmt5_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO_NR_PALMT5_SD_READONLY);
-}
-
 static struct pxamci_platform_data palmt5_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.setpower	= palmt5_mci_power,
-	.get_ro		= palmt5_mci_get_ro,
-	.init 		= palmt5_mci_init,
-	.exit		= palmt5_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_PALMT5_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_PALMT5_SD_READONLY,
+	.gpio_power		= GPIO_NR_PALMT5_SD_POWER,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index d823b09..d9ef76c 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -117,83 +117,11 @@
 /******************************************************************************
  * SD/MMC card controller
  ******************************************************************************/
-static int palmte2_mci_init(struct device *dev,
-				irq_handler_t palmte2_detect_int, void *data)
-{
-	int err = 0;
-
-	/* Setup an interrupt for detecting card insert/remove events */
-	err = gpio_request(GPIO_NR_PALMTE2_SD_DETECT_N, "SD IRQ");
-	if (err)
-		goto err;
-	err = gpio_direction_input(GPIO_NR_PALMTE2_SD_DETECT_N);
-	if (err)
-		goto err2;
-	err = request_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N),
-			palmte2_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"SD/MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
-				__func__);
-		goto err2;
-	}
-
-	err = gpio_request(GPIO_NR_PALMTE2_SD_POWER, "SD_POWER");
-	if (err)
-		goto err3;
-	err = gpio_direction_output(GPIO_NR_PALMTE2_SD_POWER, 0);
-	if (err)
-		goto err4;
-
-	err = gpio_request(GPIO_NR_PALMTE2_SD_READONLY, "SD_READONLY");
-	if (err)
-		goto err4;
-	err = gpio_direction_input(GPIO_NR_PALMTE2_SD_READONLY);
-	if (err)
-		goto err5;
-
-	printk(KERN_DEBUG "%s: irq registered\n", __func__);
-
-	return 0;
-
-err5:
-	gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
-err4:
-	gpio_free(GPIO_NR_PALMTE2_SD_POWER);
-err3:
-	free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
-err2:
-	gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
-err:
-	return err;
-}
-
-static void palmte2_mci_exit(struct device *dev, void *data)
-{
-	gpio_free(GPIO_NR_PALMTE2_SD_READONLY);
-	gpio_free(GPIO_NR_PALMTE2_SD_POWER);
-	free_irq(gpio_to_irq(GPIO_NR_PALMTE2_SD_DETECT_N), data);
-	gpio_free(GPIO_NR_PALMTE2_SD_DETECT_N);
-}
-
-static void palmte2_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-	gpio_set_value(GPIO_NR_PALMTE2_SD_POWER, p_d->ocr_mask & (1 << vdd));
-}
-
-static int palmte2_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO_NR_PALMTE2_SD_READONLY);
-}
-
 static struct pxamci_platform_data palmte2_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.setpower	= palmte2_mci_power,
-	.get_ro		= palmte2_mci_get_ro,
-	.init 		= palmte2_mci_init,
-	.exit		= palmte2_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_PALMTE2_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_PALMTE2_SD_READONLY,
+	.gpio_power		= GPIO_NR_PALMTE2_SD_POWER,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 83d0208..4a9ca71 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -140,83 +140,11 @@
 /******************************************************************************
  * SD/MMC card controller
  ******************************************************************************/
-static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int,
-				void *data)
-{
-	int err = 0;
-
-	/* Setup an interrupt for detecting card insert/remove events */
-	err = gpio_request(GPIO_NR_PALMTX_SD_DETECT_N, "SD IRQ");
-	if (err)
-		goto err;
-	err = gpio_direction_input(GPIO_NR_PALMTX_SD_DETECT_N);
-	if (err)
-		goto err2;
-	err = request_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N),
-			palmtx_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"SD/MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
-				__func__);
-		goto err2;
-	}
-
-	err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER");
-	if (err)
-		goto err3;
-	err = gpio_direction_output(GPIO_NR_PALMTX_SD_POWER, 0);
-	if (err)
-		goto err4;
-
-	err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY");
-	if (err)
-		goto err4;
-	err = gpio_direction_input(GPIO_NR_PALMTX_SD_READONLY);
-	if (err)
-		goto err5;
-
-	printk(KERN_DEBUG "%s: irq registered\n", __func__);
-
-	return 0;
-
-err5:
-	gpio_free(GPIO_NR_PALMTX_SD_READONLY);
-err4:
-	gpio_free(GPIO_NR_PALMTX_SD_POWER);
-err3:
-	free_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N), data);
-err2:
-	gpio_free(GPIO_NR_PALMTX_SD_DETECT_N);
-err:
-	return err;
-}
-
-static void palmtx_mci_exit(struct device *dev, void *data)
-{
-	gpio_free(GPIO_NR_PALMTX_SD_READONLY);
-	gpio_free(GPIO_NR_PALMTX_SD_POWER);
-	free_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N), data);
-	gpio_free(GPIO_NR_PALMTX_SD_DETECT_N);
-}
-
-static void palmtx_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-	gpio_set_value(GPIO_NR_PALMTX_SD_POWER, p_d->ocr_mask & (1 << vdd));
-}
-
-static int palmtx_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO_NR_PALMTX_SD_READONLY);
-}
-
 static struct pxamci_platform_data palmtx_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.setpower	= palmtx_mci_power,
-	.get_ro		= palmtx_mci_get_ro,
-	.init 		= palmtx_mci_init,
-	.exit		= palmtx_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_PALMTX_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_PALMTX_SD_READONLY,
+	.gpio_power		= GPIO_NR_PALMTX_SD_POWER,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index c3645aa..d8fa53c 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -129,88 +129,14 @@
 /******************************************************************************
  * SD/MMC card controller
  ******************************************************************************/
-static int palmz72_mci_init(struct device *dev,
-				irq_handler_t palmz72_detect_int, void *data)
-{
-	int err = 0;
-
-	/* Setup an interrupt for detecting card insert/remove events */
-	err = gpio_request(GPIO_NR_PALMZ72_SD_DETECT_N, "SD IRQ");
-	if (err)
-		goto err;
-	err = gpio_direction_input(GPIO_NR_PALMZ72_SD_DETECT_N);
-	if (err)
-		goto err2;
-	err = request_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N),
-			palmz72_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
-			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			"SD/MMC card detect", data);
-	if (err) {
-		printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
-				__func__);
-		goto err2;
-	}
-
-	/* SD_POWER is not actually power, but it is more like chip
-	 * select, i.e. it is inverted */
-
-	err = gpio_request(GPIO_NR_PALMZ72_SD_POWER_N, "SD_POWER");
-	if (err)
-		goto err3;
-	err = gpio_direction_output(GPIO_NR_PALMZ72_SD_POWER_N, 0);
-	if (err)
-		goto err4;
-	err = gpio_request(GPIO_NR_PALMZ72_SD_RO, "SD_RO");
-	if (err)
-		goto err4;
-	err = gpio_direction_input(GPIO_NR_PALMZ72_SD_RO);
-	if (err)
-		goto err5;
-
-	printk(KERN_DEBUG "%s: irq registered\n", __func__);
-
-	return 0;
-
-err5:
-	gpio_free(GPIO_NR_PALMZ72_SD_RO);
-err4:
-	gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
-err3:
-	free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
-err2:
-	gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
-err:
-	return err;
-}
-
-static void palmz72_mci_exit(struct device *dev, void *data)
-{
-	gpio_free(GPIO_NR_PALMZ72_SD_POWER_N);
-	free_irq(gpio_to_irq(GPIO_NR_PALMZ72_SD_DETECT_N), data);
-	gpio_free(GPIO_NR_PALMZ72_SD_DETECT_N);
-	gpio_free(GPIO_NR_PALMZ72_SD_RO);
-}
-
-static void palmz72_mci_power(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data *p_d = dev->platform_data;
-	if (p_d->ocr_mask & (1 << vdd))
-		gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 0);
-	else
-		gpio_set_value(GPIO_NR_PALMZ72_SD_POWER_N, 1);
-}
-
-static int palmz72_mci_ro(struct device *dev)
-{
-	return gpio_get_value(GPIO_NR_PALMZ72_SD_RO);
-}
-
+/* SD_POWER is not actually power, but it is more like chip
+ * select, i.e. it is inverted */
 static struct pxamci_platform_data palmz72_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.setpower	= palmz72_mci_power,
-	.get_ro		= palmz72_mci_ro,
-	.init 		= palmz72_mci_init,
-	.exit		= palmz72_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.gpio_card_detect	= GPIO_NR_PALMZ72_SD_DETECT_N,
+	.gpio_card_ro		= GPIO_NR_PALMZ72_SD_RO,
+	.gpio_power		= GPIO_NR_PALMZ72_SD_POWER_N,
+	.gpio_power_invert	= 1,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 01791d7..e211633 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -321,11 +321,14 @@
 #define MSECS_PER_JIFFY (1000/HZ)
 
 static struct pxamci_platform_data pcm990_mci_platform_data = {
-	.detect_delay	= 250 / MSECS_PER_JIFFY,
-	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
-	.init 		= pcm990_mci_init,
-	.setpower 	= pcm990_mci_setpower,
-	.exit		= pcm990_mci_exit,
+	.detect_delay		= 250 / MSECS_PER_JIFFY,
+	.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.init 			= pcm990_mci_init,
+	.setpower 		= pcm990_mci_setpower,
+	.exit			= pcm990_mci_exit,
+	.gpio_card_detect	= -1,
+	.gpio_card_ro		= -1,
+	.gpio_power		= -1,
 };
 
 static struct pxaohci_platform_data pcm990_ohci_platform_data = {
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 9352d4a..333b1dc 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -245,20 +245,10 @@
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert/eject.
  */
-static struct pxamci_platform_data poodle_mci_platform_data;
-
 static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
 {
 	int err;
 
-	err = gpio_request(POODLE_GPIO_nSD_DETECT, "nSD_DETECT");
-	if (err)
-		goto err_out;
-
-	err = gpio_request(POODLE_GPIO_nSD_WP, "nSD_WP");
-	if (err)
-		goto err_free_1;
-
 	err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
 	if (err)
 		goto err_free_2;
@@ -267,34 +257,14 @@
 	if (err)
 		goto err_free_3;
 
-	gpio_direction_input(POODLE_GPIO_nSD_DETECT);
-	gpio_direction_input(POODLE_GPIO_nSD_WP);
-
 	gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
 	gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);
 
-	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
-
-	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err) {
-		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
-				__func__);
-		goto err_free_4;
-	}
-
 	return 0;
 
-err_free_4:
-	gpio_free(POODLE_GPIO_SD_PWR1);
 err_free_3:
 	gpio_free(POODLE_GPIO_SD_PWR);
 err_free_2:
-	gpio_free(POODLE_GPIO_nSD_WP);
-err_free_1:
-	gpio_free(POODLE_GPIO_nSD_DETECT);
-err_out:
 	return err;
 }
 
@@ -312,28 +282,20 @@
 	}
 }
 
-static int poodle_mci_get_ro(struct device *dev)
-{
-	return !!gpio_get_value(POODLE_GPIO_nSD_WP);
-	return GPLR(POODLE_GPIO_nSD_WP) & GPIO_bit(POODLE_GPIO_nSD_WP);
-}
-
-
 static void poodle_mci_exit(struct device *dev, void *data)
 {
-	free_irq(POODLE_IRQ_GPIO_nSD_DETECT, data);
 	gpio_free(POODLE_GPIO_SD_PWR1);
 	gpio_free(POODLE_GPIO_SD_PWR);
-	gpio_free(POODLE_GPIO_nSD_WP);
-	gpio_free(POODLE_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data poodle_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= poodle_mci_init,
-	.get_ro		= poodle_mci_get_ro,
-	.setpower 	= poodle_mci_setpower,
-	.exit		= poodle_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 			= poodle_mci_init,
+	.setpower 		= poodle_mci_setpower,
+	.exit			= poodle_mci_exit,
+	.gpio_card_detect	= POODLE_IRQ_GPIO_nSD_DETECT,
+	.gpio_card_ro		= POODLE_GPIO_nSD_WP,
+	.gpio_power		= -1,
 };
 
 
@@ -521,6 +483,7 @@
 	set_pxa_fb_parent(&poodle_locomo_device.dev);
 	set_pxa_fb_info(&poodle_fb_info);
 	pxa_set_udc_info(&udc_info);
+	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&poodle_mci_platform_data);
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index dda310f..da85327 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -378,45 +378,6 @@
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert/eject.
  */
-
-static struct pxamci_platform_data spitz_mci_platform_data;
-
-static int spitz_mci_init(struct device *dev, irq_handler_t spitz_detect_int, void *data)
-{
-	int err;
-
-	err = gpio_request(SPITZ_GPIO_nSD_DETECT, "nSD_DETECT");
-	if (err)
-		goto err_out;
-
-	err = gpio_request(SPITZ_GPIO_nSD_WP, "nSD_WP");
-	if (err)
-		goto err_free_1;
-
-	gpio_direction_input(SPITZ_GPIO_nSD_DETECT);
-	gpio_direction_input(SPITZ_GPIO_nSD_WP);
-
-	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
-
-	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING |
-			  IRQF_TRIGGER_FALLING,
-			  "MMC card detect", data);
-	if (err) {
-		pr_err("%s: MMC/SD: can't request MMC card detect IRQ\n",
-				__func__);
-		goto err_free_2;
-	}
-	return 0;
-
-err_free_2:
-	gpio_free(SPITZ_GPIO_nSD_WP);
-err_free_1:
-	gpio_free(SPITZ_GPIO_nSD_DETECT);
-err_out:
-	return err;
-}
-
 static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
 {
 	struct pxamci_platform_data* p_d = dev->platform_data;
@@ -427,24 +388,12 @@
 		spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000);
 }
 
-static int spitz_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(SPITZ_GPIO_nSD_WP);
-}
-
-static void spitz_mci_exit(struct device *dev, void *data)
-{
-	free_irq(SPITZ_IRQ_GPIO_nSD_DETECT, data);
-	gpio_free(SPITZ_GPIO_nSD_WP);
-	gpio_free(SPITZ_GPIO_nSD_DETECT);
-}
-
 static struct pxamci_platform_data spitz_mci_platform_data = {
-	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init 		= spitz_mci_init,
-	.get_ro		= spitz_mci_get_ro,
-	.setpower 	= spitz_mci_setpower,
-	.exit		= spitz_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.setpower 		= spitz_mci_setpower,
+	.gpio_card_detect	= SPITZ_GPIO_nSD_DETECT,
+	.gpio_card_ro		= SPITZ_GPIO_nSD_WP,
+	.gpio_power		= -1,
 };
 
 
@@ -695,6 +644,7 @@
 	spitz_init_spi();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
+	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&spitz_mci_platform_data);
 	pxa_set_ohci_info(&spitz_ohci_platform_data);
 	pxa_set_ficp_info(&spitz_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 117ad59..b56cc56 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -247,49 +247,10 @@
 /*
  * MMC/SD Device
  */
-static struct pxamci_platform_data tosa_mci_platform_data;
-
 static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
 {
 	int err;
 
-	tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
-
-	err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect");
-	if (err) {
-		printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n");
-		goto err_gpio_detect;
-	}
-	err = gpio_direction_input(TOSA_GPIO_nSD_DETECT);
-	if (err)
-		goto err_gpio_detect_dir;
-
-	err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int,
-			  IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				"MMC/SD card detect", data);
-	if (err) {
-		printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
-		goto err_irq;
-	}
-
-	err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect");
-	if (err) {
-		printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n");
-		goto err_gpio_wp;
-	}
-	err = gpio_direction_input(TOSA_GPIO_SD_WP);
-	if (err)
-		goto err_gpio_wp_dir;
-
-	err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power");
-	if (err) {
-		printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
-		goto err_gpio_pwr;
-	}
-	err = gpio_direction_output(TOSA_GPIO_PWR_ON, 0);
-	if (err)
-		goto err_gpio_pwr_dir;
-
 	err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int");
 	if (err) {
 		printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
@@ -304,51 +265,21 @@
 err_gpio_int_dir:
 	gpio_free(TOSA_GPIO_nSD_INT);
 err_gpio_int:
-err_gpio_pwr_dir:
-	gpio_free(TOSA_GPIO_PWR_ON);
-err_gpio_pwr:
-err_gpio_wp_dir:
-	gpio_free(TOSA_GPIO_SD_WP);
-err_gpio_wp:
-	free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
-err_irq:
-err_gpio_detect_dir:
-	gpio_free(TOSA_GPIO_nSD_DETECT);
-err_gpio_detect:
 	return err;
 }
 
-static void tosa_mci_setpower(struct device *dev, unsigned int vdd)
-{
-	struct pxamci_platform_data* p_d = dev->platform_data;
-
-	if (( 1 << vdd) & p_d->ocr_mask) {
-		gpio_set_value(TOSA_GPIO_PWR_ON, 1);
-	} else {
-		gpio_set_value(TOSA_GPIO_PWR_ON, 0);
-	}
-}
-
-static int tosa_mci_get_ro(struct device *dev)
-{
-	return gpio_get_value(TOSA_GPIO_SD_WP);
-}
-
 static void tosa_mci_exit(struct device *dev, void *data)
 {
 	gpio_free(TOSA_GPIO_nSD_INT);
-	gpio_free(TOSA_GPIO_PWR_ON);
-	gpio_free(TOSA_GPIO_SD_WP);
-	free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data);
-	gpio_free(TOSA_GPIO_nSD_DETECT);
 }
 
 static struct pxamci_platform_data tosa_mci_platform_data = {
-	.ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-	.init           = tosa_mci_init,
-	.get_ro		= tosa_mci_get_ro,
-	.setpower       = tosa_mci_setpower,
-	.exit           = tosa_mci_exit,
+	.ocr_mask       	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init           	= tosa_mci_init,
+	.exit           	= tosa_mci_exit,
+	.gpio_card_detect	= TOSA_GPIO_nSD_DETECT,
+	.gpio_card_ro		= TOSA_GPIO_SD_WP,
+	.gpio_power		= TOSA_GPIO_PWR_ON,
 };
 
 /*
@@ -910,6 +841,7 @@
 	dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
 	dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 
+	tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 	pxa_set_mci_info(&tosa_mci_platform_data);
 	pxa_set_udc_info(&udc_info);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 825f540..3229986 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -367,6 +367,9 @@
 	.exit		= trizeps4_mci_exit,
 	.get_ro		= NULL,	/* write-protection not supported */
 	.setpower 	= NULL,	/* power-switching not supported */
+	.gpio_card_detect = -1,
+	.gpio_card_ro	= -1,
+	.gpio_power	= -1,
 };
 
 /****************************************************************************
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 218d200..09784d3 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -290,6 +290,9 @@
 	.init 		= zylonite_mci_init,
 	.exit		= zylonite_mci_exit,
 	.get_ro		= zylonite_mci_ro,
+	.gpio_card_detect = -1,
+	.gpio_card_ro	= -1,
+	.gpio_power	= -1,
 };
 
 static struct pxamci_platform_data zylonite_mci2_platform_data = {