>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
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
