From: Jerry Huang <Chang-Ming.Huang@xxxxxxxxxxxxx> For Fsl eSDHC controller, the bit DCR[DMA__AHB2MAG_IRQ_BYPASS] cannot be set automatically, when SoC reset, therefore, we need to set this bit manually. Signed-off-by: Gao Guanhua <B22826@xxxxxxxxxxxxx> Signed-off-by: Jerry Huang <Chang-Ming.Huang@xxxxxxxxxxxxx> --- drivers/mmc/host/sdhci-esdhc.h | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 7 +++++++ drivers/mmc/host/sdhci-pltfm.c | 3 +++ drivers/mmc/host/sdhci.c | 4 ++++ drivers/mmc/host/sdhci.h | 1 + include/linux/mmc/sdhci.h | 2 ++ 6 files changed, 18 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index c3b08f1..7cbaffe 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -39,6 +39,7 @@ /* OF-specific */ #define ESDHC_DMA_SYSCTL 0x40c #define ESDHC_DMA_SNOOP 0x00000040 +#define ESDHC_AHB2MAG_IRQ_BYPASS 0x20 #define ESDHC_HOST_CONTROL_RES 0x05 diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 7d5ae82..413ded5 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -68,6 +68,12 @@ static int esdhc_of_enable_dma(struct sdhci_host *host) return 0; } +static int esdhc_of_enable_irq_bypass(struct sdhci_host *host) +{ + setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_AHB2MAG_IRQ_BYPASS); + return 0; +} + static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -116,6 +122,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { .get_max_clock = esdhc_of_get_max_clock, .get_min_clock = esdhc_of_get_min_clock, .get_cd = esdhc_of_get_cd, + .enable_irq_bypass = esdhc_of_enable_irq_bypass, }; static struct sdhci_pltfm_data sdhci_esdhc_pdata = { diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 2a77435..de182c6 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -74,6 +74,9 @@ void sdhci_get_of_property(struct platform_device *pdev) if (of_get_property(np, "sdhci,dma-broken", NULL)) host->quirks |= SDHCI_QUIRK_BROKEN_DMA; + if (of_get_property(np, "sdhci,ahb2mag-irq-bypass", NULL)) + host->quirks2 |= SDHCI_QUIRK2_SET_AHB2MAG_IRQ_BYPASS; + clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) pltfm_host->clock = be32_to_cpup(clk); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index fbe2f46..ae52ab9 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -226,6 +226,10 @@ static void sdhci_init(struct sdhci_host *host, int soft) else sdhci_reset(host, SDHCI_RESET_ALL); + if (host->quirks2 & SDHCI_QUIRK2_SET_AHB2MAG_IRQ_BYPASS) + if (host->ops->enable_irq_bypass) + host->ops->enable_irq_bypass(host); + sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 82f4d27..1326557 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -263,6 +263,7 @@ struct sdhci_ops { void (*set_clock)(struct sdhci_host *host, unsigned int clock); int (*get_cd)(struct sdhci_host *host); + int (*enable_irq_bypass)(struct sdhci_host *host); int (*enable_dma)(struct sdhci_host *host); unsigned int (*get_max_clock)(struct sdhci_host *host); unsigned int (*get_min_clock)(struct sdhci_host *host); diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index e4b6935..1dbe22b 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -91,6 +91,8 @@ struct sdhci_host { unsigned int quirks2; /* More deviations from spec. */ #define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<0) +/* Controller cannot set DCR[DMA__AHB2MAG_IRQ_BYPASS] automatically */ +#define SDHCI_QUIRK2_SET_AHB2MAG_IRQ_BYPASS (1<<1) int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */ -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html