This patch implemnet the workaround that the bit
DCR[DMA__AHB2MAG_IRQ_BYPASS] cannot be set automatically
when SoC reset.
---
 arch/powerpc/boot/dts/p2020ds.dts |    1 +
 drivers/mmc/host/sdhci-of.c       |    5 ++++-
 drivers/mmc/host/sdhci.c          |    8 ++++++++
 drivers/mmc/host/sdhci.h          |    3 +++
 4 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/boot/dts/p2020ds.dts 
b/arch/powerpc/boot/dts/p2020ds.dts
index 574ad4f..8b1056d 100644
--- a/arch/powerpc/boot/dts/p2020ds.dts
+++ b/arch/powerpc/boot/dts/p2020ds.dts
@@ -460,6 +460,7 @@
                        interrupts = <72 0x2>;
                        interrupt-parent = <&mpic>;
                        fsl,sdhci-dma-broken;
+                       fsl,sdhci-ahb2mag-irq-bypass;
                        clock-frequency = <0>;
                };
 
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 5879483..0bc75b3 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -272,6 +272,9 @@ static int __devinit sdhci_of_probe(struct of_device *ofdev,
 
        if (of_get_property(np, "fsl,sdhci-dma-broken", NULL))
                host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+
+       if (of_get_property(np, "fsl,sdhci-ahb2mag-irq-bypass", NULL))
+               host->quirks |= SDHCI_QUIRK_SET_AHB2MAG_IRQ_BYPASS;
 
        clk = of_get_property(np, "clock-frequency", &size);
        if (clk && size == sizeof(*clk) && *clk)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index cc6d45c..711cbcd 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -176,11 +176,19 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
 
 static void sdhci_init(struct sdhci_host *host)
 {
+       u32 ctrl;
+
        sdhci_reset(host, SDHCI_RESET_ALL);
 
        /* Enable cache snooping */
        sdhci_writel(host, SDHCI_CACHE_SNOOP, SDHCI_HOST_DMA_CONTROL);
 
+       if (host->quirks & SDHCI_QUIRK_SET_AHB2MAG_IRQ_BYPASS) {
+               ctrl = sdhci_readl(host, SDHCI_HOST_DMA_CONTROL);
+               ctrl |= SDHCI_AHB2MAG_IRQ_BYPASS;
+               sdhci_writel(host, ctrl, SDHCI_HOST_DMA_CONTROL);
+       }
+
        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 9ee9622..cb8beea 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -178,6 +178,7 @@
 
 /* 40C DMA control register*/
 #define SDHCI_HOST_DMA_CONTROL 0x40C
+#define SDHCI_AHB2MAG_IRQ_BYPASS       0x20
 #define SDHCI_CACHE_SNOOP      0x40
 
 struct sdhci_ops;
@@ -238,6 +239,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_DELAY_AFTER_POWER                  (1<<23)
 /* Controller uses SDCLK instead of TMCLK for data timeouts */
 #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK            (1<<24)
+/* Controller cannot set DCR[DMA__AHB2MAG_IRQ_BYPASS] automatically*/
+#define SDHCI_QUIRK_SET_AHB2MAG_IRQ_BYPASS             (1<<25)
 
        int                     irq;            /* Device IRQ */
        void __iomem *          ioaddr;         /* Mapped address */
-- 
1.6.4

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to