diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc.h | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-of-esdhc.c | 17 |
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, |