summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
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,