summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorHaijun Zhang <Haijun.Zhang@freescale.com>2013-12-19 03:09:03 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-01-10 20:28:09 (GMT)
commit70eae713045cb894a1fd9604e04ba6481bef7ef2 (patch)
tree8eaa111aec15108830acb028f042d57537028cef /drivers/mmc
parent42c9c60fd22a63be120a361b2ea7b5504ce267e3 (diff)
downloadlinux-fsl-qoriq-70eae713045cb894a1fd9604e04ba6481bef7ef2.tar.xz
esdhc: Enable DMA err bit for eSDHC host
eSDHC host had bit eSDHC_IRQSTAT[3] to indicate that DMA (SDMA or ADMA) transfer has failed. So enable this bit detecting and its interrupt. Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com> Change-Id: If2abc2718d4bf0d020077848804a9ac59d5c2010 Reviewed-on: http://git.am.freescale.net:8181/5927 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Xiaobo Xie <X.Xie@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h2
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c17
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index e5f1a17..3abd1e7 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -35,6 +35,7 @@
#define ESDHC_CLOCK_HCKEN 0x00000002
#define ESDHC_CLOCK_IPGEN 0x00000001
+
#define ESDHCI_PRESENT_STATE 0x24
#define ESDHC_CLK_STABLE 0x00000008
@@ -51,6 +52,7 @@
/* OF-specific */
#define ESDHC_DMA_SYSCTL 0x40c
#define ESDHC_DMA_SNOOP 0x00000040
+#define ESDHC_INT_DMA_ERROR 0x10000000
#define ESDHC_HOST_CONTROL_RES 0x01
#define ESDHC_VOL_SEL 0x04
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index a5c1a3ea..3af4587 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -499,6 +499,21 @@ static int esdhc_of_get_cd(struct sdhci_host *host)
return !!present;
}
+static void esdhc_get_pltfm_irq(struct sdhci_host *host, u32 *irq)
+{
+ *irq |= ESDHC_INT_DMA_ERROR;
+}
+
+static void esdhc_pltfm_irq_handler(struct sdhci_host *host, u32 intmask)
+{
+ if (intmask & (ESDHC_INT_DMA_ERROR | SDHCI_INT_ADMA_ERROR)) {
+ host->data->error = -EIO;
+ pr_err("%s: ADMA error\n", mmc_hostname(host->mmc));
+ sdhci_show_adma_error(host);
+ esdhci_of_adma_workaround(host, intmask);
+ }
+}
+
static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
{
u32 ctrl;
@@ -534,6 +549,8 @@ static const struct sdhci_ops sdhci_esdhc_ops = {
.enable_dma = esdhc_of_enable_dma,
.get_max_clock = esdhc_of_get_max_clock,
.get_min_clock = esdhc_of_get_min_clock,
+ .get_platform_irq = esdhc_get_pltfm_irq,
+ .handle_platform_irq = esdhc_pltfm_irq_handler,
.platform_reset_enter = esdhc_of_platform_reset_enter,
.platform_reset_exit = esdhc_of_platform_reset_exit,
.platform_init = esdhc_of_platform_init,