* [PATCH 2/2] mmc:esdhc: Enable DMA err bit for eSDHC host @ 2013-09-17 5:28 Haijun Zhang 2013-09-17 5:28 ` [PATCH 1/2] mmc:sdhc: Add vendor specific interrupt and handle routine Haijun Zhang 0 siblings, 1 reply; 3+ messages in thread From: Haijun Zhang @ 2013-09-17 5:28 UTC (permalink / raw) To: linux-mmc; +Cc: cbouatmailru, cjb, scottwood, X.Xie, ulf.hansson, Haijun Zhang 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> --- drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index e328252..86809c0 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -24,6 +24,9 @@ #define VENDOR_V_22 0x12 #define VENDOR_V_23 0x13 + +#define ESDHC_INT_DMA_ERROR 0x10000000 + static u32 esdhc_readl(struct sdhci_host *host, int reg) { u32 ret; @@ -238,6 +241,21 @@ static void esdhc_of_platform_init(struct sdhci_host *host) host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; } +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; @@ -273,6 +291,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_init = esdhc_of_platform_init, #ifdef CONFIG_PM .platform_suspend = esdhc_of_suspend, -- 1.8.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 1/2] mmc:sdhc: Add vendor specific interrupt and handle routine 2013-09-17 5:28 [PATCH 2/2] mmc:esdhc: Enable DMA err bit for eSDHC host Haijun Zhang @ 2013-09-17 5:28 ` Haijun Zhang 2013-10-21 9:20 ` Zhang Haijun 0 siblings, 1 reply; 3+ messages in thread From: Haijun Zhang @ 2013-09-17 5:28 UTC (permalink / raw) To: linux-mmc; +Cc: cbouatmailru, cjb, scottwood, X.Xie, ulf.hansson, Haijun Zhang As spec detailed: Error Interrupt Status Register(Offset 032h)[15-12] Error Interrupt Status Enable Register (Offset 036h)[15-12] Error Interrupt Signal Enable Register (Offset 03Ah)[15-12] Bits above are specified by vendor itself. So add interface to handle this requirememt. Also share sdhci_dma_show in sdhc.h for platform usr. Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com> --- drivers/mmc/host/sdhci.c | 25 +++++++++++++++++++------ drivers/mmc/host/sdhci.h | 5 +++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b4d7f27..2ba9c6d 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -238,16 +238,25 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); static void sdhci_init(struct sdhci_host *host, int soft) { + u32 pltm_irq = 0, irq = 0; + if (soft) sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); else sdhci_reset(host, SDHCI_RESET_ALL); - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | + irq = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); + SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; + /* Vendor Specific Error Status, Status enable and Signal Enable */ + if (host->ops->get_platform_irq) + host->ops->get_platform_irq(host, &pltm_irq); + + if (pltm_irq) + irq |= pltm_irq; + + sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, irq); if (soft) { /* force clock reconfiguration */ @@ -2241,6 +2250,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) SDHCI_INT_INDEX)) host->cmd->error = -EILSEQ; + if (host->ops->handle_platform_irq) + host->ops->handle_platform_irq(host, intmask); + if (host->cmd->error) { tasklet_schedule(&host->finish_tasklet); return; @@ -2273,7 +2285,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) } #ifdef CONFIG_MMC_DEBUG -static void sdhci_show_adma_error(struct sdhci_host *host) +void sdhci_show_adma_error(struct sdhci_host *host) { const char *name = mmc_hostname(host->mmc); u8 *desc = host->adma_desc; @@ -2350,10 +2362,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); sdhci_show_adma_error(host); host->data->error = -EIO; - if (host->ops->adma_workaround) - host->ops->adma_workaround(host, intmask); } + if (host->ops->handle_platform_irq) + host->ops->handle_platform_irq(host, intmask); + if (host->data->error) sdhci_finish_data(host); else { diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index b037f18..a0f1734 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -292,6 +292,8 @@ struct sdhci_ops { void (*hw_reset)(struct sdhci_host *host); void (*platform_suspend)(struct sdhci_host *host); void (*platform_resume)(struct sdhci_host *host); + void (*get_platform_irq)(struct sdhci_host *host, u32 *irq); + void (*handle_platform_irq)(struct sdhci_host *host, u32 intmask); void (*adma_workaround)(struct sdhci_host *host, u32 intmask); void (*platform_init)(struct sdhci_host *host); void (*card_event)(struct sdhci_host *host); @@ -405,4 +407,7 @@ extern int sdhci_runtime_suspend_host(struct sdhci_host *host); extern int sdhci_runtime_resume_host(struct sdhci_host *host); #endif +#ifdef CONFIG_MMC_DEBUG +extern void sdhci_show_adma_error(struct sdhci_host *host); +#endif #endif /* __SDHCI_HW_H */ -- 1.8.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/2] mmc:sdhc: Add vendor specific interrupt and handle routine 2013-09-17 5:28 ` [PATCH 1/2] mmc:sdhc: Add vendor specific interrupt and handle routine Haijun Zhang @ 2013-10-21 9:20 ` Zhang Haijun 0 siblings, 0 replies; 3+ messages in thread From: Zhang Haijun @ 2013-10-21 9:20 UTC (permalink / raw) To: Haijun Zhang, linux-mmc; +Cc: cbouatmailru, cjb, scottwood, X.Xie, ulf.hansson Hi, Ulf Coud you give some advice on this patch? Thanks. 于 2013/9/17 13:28, Haijun Zhang 写道: > As spec detailed: > Error Interrupt Status Register(Offset 032h)[15-12] > Error Interrupt Status Enable Register (Offset 036h)[15-12] > Error Interrupt Signal Enable Register (Offset 03Ah)[15-12] > > Bits above are specified by vendor itself. > So add interface to handle this requirememt. > Also share sdhci_dma_show in sdhc.h for platform usr. > > Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com> > --- > drivers/mmc/host/sdhci.c | 25 +++++++++++++++++++------ > drivers/mmc/host/sdhci.h | 5 +++++ > 2 files changed, 24 insertions(+), 6 deletions(-) > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index b4d7f27..2ba9c6d 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -238,16 +238,25 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); > > static void sdhci_init(struct sdhci_host *host, int soft) > { > + u32 pltm_irq = 0, irq = 0; > + > if (soft) > sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); > else > sdhci_reset(host, SDHCI_RESET_ALL); > > - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, > - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | > + irq = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | > SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | > SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | > - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); > + SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; > + /* Vendor Specific Error Status, Status enable and Signal Enable */ > + if (host->ops->get_platform_irq) > + host->ops->get_platform_irq(host, &pltm_irq); > + > + if (pltm_irq) > + irq |= pltm_irq; > + > + sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, irq); > > if (soft) { > /* force clock reconfiguration */ > @@ -2241,6 +2250,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) > SDHCI_INT_INDEX)) > host->cmd->error = -EILSEQ; > > + if (host->ops->handle_platform_irq) > + host->ops->handle_platform_irq(host, intmask); > + > if (host->cmd->error) { > tasklet_schedule(&host->finish_tasklet); > return; > @@ -2273,7 +2285,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) > } > > #ifdef CONFIG_MMC_DEBUG > -static void sdhci_show_adma_error(struct sdhci_host *host) > +void sdhci_show_adma_error(struct sdhci_host *host) > { > const char *name = mmc_hostname(host->mmc); > u8 *desc = host->adma_desc; > @@ -2350,10 +2362,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) > pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); > sdhci_show_adma_error(host); > host->data->error = -EIO; > - if (host->ops->adma_workaround) > - host->ops->adma_workaround(host, intmask); > } > > + if (host->ops->handle_platform_irq) > + host->ops->handle_platform_irq(host, intmask); > + > if (host->data->error) > sdhci_finish_data(host); > else { > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h > index b037f18..a0f1734 100644 > --- a/drivers/mmc/host/sdhci.h > +++ b/drivers/mmc/host/sdhci.h > @@ -292,6 +292,8 @@ struct sdhci_ops { > void (*hw_reset)(struct sdhci_host *host); > void (*platform_suspend)(struct sdhci_host *host); > void (*platform_resume)(struct sdhci_host *host); > + void (*get_platform_irq)(struct sdhci_host *host, u32 *irq); > + void (*handle_platform_irq)(struct sdhci_host *host, u32 intmask); > void (*adma_workaround)(struct sdhci_host *host, u32 intmask); > void (*platform_init)(struct sdhci_host *host); > void (*card_event)(struct sdhci_host *host); > @@ -405,4 +407,7 @@ extern int sdhci_runtime_suspend_host(struct sdhci_host *host); > extern int sdhci_runtime_resume_host(struct sdhci_host *host); > #endif > > +#ifdef CONFIG_MMC_DEBUG > +extern void sdhci_show_adma_error(struct sdhci_host *host); > +#endif > #endif /* __SDHCI_HW_H */ -- Thanks & Regards Haijun. ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-10-21 9:21 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-17 5:28 [PATCH 2/2] mmc:esdhc: Enable DMA err bit for eSDHC host Haijun Zhang 2013-09-17 5:28 ` [PATCH 1/2] mmc:sdhc: Add vendor specific interrupt and handle routine Haijun Zhang 2013-10-21 9:20 ` Zhang Haijun
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).