>From d6a6ca1fe489ef4ad66f108bb14ad89c6dc8c0d1 Mon Sep 17 00:00:00 2001
From: Chuanxiao Dong <[email protected]>
Date: Thu, 28 Oct 2010 11:38:19 +0800
Subject: [PATCH 3/3] mmc: implemented the real reset eMMC card part in sdhci 
host
 controller driver

the hardware reset need host controller to trigger a RST_n signal,
and driver needs to pull up/down the relavent GPIO to implement
this

Signed-off-by: Chuanxiao Dong <[email protected]>
---
 drivers/mmc/host/sdhci-pci.c |   64 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 8ae6733..ce32aff 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -17,6 +17,7 @@
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/gpio.h>
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -629,8 +630,41 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host)
        return 0;
 }
 
+/*
+ * HW reset eMMC4.4 card callback
+ * In this function, driver need to trigger RST_n signal
+ * as eMMC4.4 standard says.
+ * 0: reset emmc successfully
+ * 1: reset emmc failed
+ */
+static int sdhci_pci_reset_emmc(struct sdhci_host *host)
+{
+       /* trigger a RST_n signal */
+       struct sdhci_pci_slot *slot;
+       struct pci_dev *pdev;
+       unsigned gpio;
+       int ret = 1;
+
+       slot = sdhci_priv(host);
+       pdev = slot->chip->pdev;
+
+       if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC0)
+               gpio = 117;
+       else if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC1)
+               gpio = 118;
+       else
+               return ret;
+
+       __gpio_set_value(gpio, 1);
+       udelay(300);
+       __gpio_set_value(gpio, 0);
+
+       return 0;
+}
+
 static struct sdhci_ops sdhci_pci_ops = {
        .enable_dma     = sdhci_pci_enable_dma,
+       .reset_emmc = sdhci_pci_reset_emmc,
 };
 
 /*****************************************************************************\
@@ -885,6 +919,20 @@ static struct sdhci_pci_slot * __devinit 
sdhci_pci_probe_slot(
        if (ret)
                goto remove;
 
+       if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC0) {
+               /* request gp_core_21 for eMMC0 */
+               gpio_request(117, "eMMC0");
+               /* set to be output and to be low state */
+               gpio_direction_output(117, 0);
+       }
+
+       if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC1) {
+               /* request gp_core_22 for eMMC1 */
+               gpio_request(118, "eMMC1");
+               /* set to be output and to be low state */
+               gpio_direction_output(118, 0);
+       }
+
        return slot;
 
 remove:
@@ -907,12 +955,28 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot 
*slot)
 {
        int dead;
        u32 scratch;
+       struct pci_dev *pdev;
 
        dead = 0;
        scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
        if (scratch == (u32)-1)
                dead = 1;
 
+       pdev = slot->chip->pdev;
+       if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC0) {
+               /* set to be output and to be low state */
+               gpio_direction_output(117, 0);
+               /* free gp_core_21 for eMMC0 */
+               gpio_free(117);
+       }
+
+       if (pdev->device == PCI_DEVICE_ID_INTEL_MFD_EMMC1) {
+               /* set to be output and to be low state */
+               gpio_direction_output(118, 0);
+               /* free gp_core_22 for eMMC1 */
+               gpio_free(118);
+       }
+
        sdhci_remove_host(slot->host, dead);
 
        if (slot->chip->fixes && slot->chip->fixes->remove_slot)
-- 
1.6.6.1

Attachment: 0003-mmc-implemented-the-real-reset-eMMC-card-part-in-sdh.patch
Description: 0003-mmc-implemented-the-real-reset-eMMC-card-part-in-sdh.patch

_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to