[PATCH 1/2] add-force-sdhci-rescan.patch

Andy Green andy at openmoko.com
Sat Dec 6 00:21:36 CET 2008


This provides a way for code to force a mmc rescan by using the s3c hsmmc
platform device as a handle.  It solves the issue of 6410 having two
card detect signals mutually exclusive on one physical ball.

Ben Dooks told he might implement this another way but we need this on GTA03
right now and can migrate it to any official way that turns up.

Signed-off-by: Andy Green <andy at openmoko.com>
---

 arch/arm/plat-s3c/include/plat/sdhci.h |    4 ++++
 drivers/mmc/host/sdhci-s3c.c           |   17 +++++++++++++++++
 drivers/mmc/host/sdhci.c               |    7 ++++---
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-s3c/include/plat/sdhci.h b/arch/arm/plat-s3c/include/plat/sdhci.h
index c4ca392..04613f0 100644
--- a/arch/arm/plat-s3c/include/plat/sdhci.h
+++ b/arch/arm/plat-s3c/include/plat/sdhci.h
@@ -29,6 +29,7 @@ struct mmc_ios;
  *            is necessary the controllers and/or GPIO blocks require the
  *	      changing of driver-strength and other controls dependant on
  *	      the card and speed of operation.
+ * sdhci_host: Pointer kept during init, allows presence change notification
  *
  * Initialisation data specific to either the machine or the platform
  * for the device driver to use or call-back when configuring gpio or
@@ -45,8 +46,11 @@ struct s3c_sdhci_platdata {
 			    void __iomem *regbase,
 			    struct mmc_ios *ios,
 			    struct mmc_card *card);
+	struct sdhci_host * sdhci_host;
 };
 
+extern void sdhci_s3c_force_presence_change(struct platform_device *pdev);
+
 /**
  * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
  * @pd: Platform data to register to device.
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index b8f2044..b9c9fd7 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -197,6 +197,21 @@ static struct sdhci_ops sdhci_s3c_ops = {
 	.set_ios		= sdhci_s3c_set_ios,
 };
 
+/*
+ * call this when you need sd stack to recognize insertion or removal of card
+ * that can't be told by SDHCI regs
+ */
+
+void sdhci_s3c_force_presence_change(struct platform_device *pdev)
+{
+	struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
+
+	dev_info(&pdev->dev, "sdhci_s3c_force_presence_change called\n");
+	mmc_detect_change(pdata->sdhci_host->mmc, msecs_to_jiffies(200));
+}
+EXPORT_SYMBOL_GPL(sdhci_s3c_force_presence_change);
+
+
 static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 {
 	struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
@@ -229,6 +244,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 		return PTR_ERR(host);
 	}
 
+	pdata->sdhci_host = host;
+
 	sc = sdhci_priv(host);
 
 	sc->host = host;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ed2c892..c769ae5 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1030,12 +1030,13 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 #endif
 
 	host->mrq = mrq;
-
+/*
 	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
 		|| (host->flags & SDHCI_DEVICE_DEAD)) {
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	} else
+*/
 		sdhci_send_command(host, mrq->cmd);
 
 	mmiowb();
@@ -1170,7 +1171,7 @@ static void sdhci_tasklet_card(unsigned long param)
 	host = (struct sdhci_host*)param;
 
 	spin_lock_irqsave(&host->lock, flags);
-
+/*
 	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
 		if (host->mrq) {
 			printk(KERN_ERR "%s: Card removed during transfer!\n",
@@ -1185,7 +1186,7 @@ static void sdhci_tasklet_card(unsigned long param)
 			tasklet_schedule(&host->finish_tasklet);
 		}
 	}
-
+*/
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	mmc_detect_change(host->mmc, msecs_to_jiffies(200));




More information about the openmoko-kernel mailing list