[PATCH 4/6] sdhci: Fixup AHB2MAG IRQ bypass hardware workaround

Gao Guanhua B22826 at freescale.com
Wed Sep 23 19:08:10 EST 2009


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



More information about the Linuxppc-dev mailing list