aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOded Gabbay <ogabbay@advaoptical.com>2013-07-05 12:48:35 -0400
committerChris Ball <cjb@laptop.org>2013-07-05 12:48:35 -0400
commitdcaff04d36fd7f22973bf4fc108912ce19bcef4f (patch)
tree846a58971945a4ecc8683d0e2c8d78510b98523d
parent66b50a00992dca97b442e016a9b2dba892e2df61 (diff)
mmc: esdhc: Fix bug when writing to SDHCI_HOST_CONTROL register
The P2020 has a non-standard implementation of the SDHCI_HOST_CONTROL register. This patch adds a QUIRK in the SDHCI header to signal that a host controller has a non-standard SDHCI_HOST_CONTROL register. The patch adds a check to the function esdhc_writeb in file sdhci-of-esdhc.c, where it checks if the write is done to the SDHCI_HOST_CONTROL register and th host has the above mentioned QUIRK, then the function simply returns instead of writing to the register. The patch also detects if the processor is P2020 (by looking in dev tree) and if so, adds the QUIRK to the host->quirk2 Signed-off-by: Oded Gabbay <ogabbay@advaoptical.com> Reviewed-by: Anton Vorontsov <anton@enomsg.org> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c17
-rw-r--r--include/linux/mmc/sdhci.h2
2 files changed, 19 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index b2a635e73aee..15039e2d1c12 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -121,6 +121,13 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
121 if (reg == SDHCI_HOST_CONTROL) { 121 if (reg == SDHCI_HOST_CONTROL) {
122 u32 dma_bits; 122 u32 dma_bits;
123 123
124 /*
125 * If host control register is not standard, exit
126 * this function
127 */
128 if (host->quirks2 & SDHCI_QUIRK2_BROKEN_HOST_CONTROL)
129 return;
130
124 /* DMA select is 22,23 bits in Protocol Control Register */ 131 /* DMA select is 22,23 bits in Protocol Control Register */
125 dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5; 132 dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5;
126 clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5, 133 clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5,
@@ -289,6 +296,7 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = {
289static int sdhci_esdhc_probe(struct platform_device *pdev) 296static int sdhci_esdhc_probe(struct platform_device *pdev)
290{ 297{
291 struct sdhci_host *host; 298 struct sdhci_host *host;
299 struct device_node *np;
292 int ret; 300 int ret;
293 301
294 host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0); 302 host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0);
@@ -297,6 +305,15 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
297 305
298 sdhci_get_of_property(pdev); 306 sdhci_get_of_property(pdev);
299 307
308 np = pdev->dev.of_node;
309 if (of_device_is_compatible(np, "fsl,p2020-esdhc")) {
310 /*
311 * Freescale messed up with P2020 as it has a non-standard
312 * host control register
313 */
314 host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL;
315 }
316
300 /* call to generic mmc_of_parse to support additional capabilities */ 317 /* call to generic mmc_of_parse to support additional capabilities */
301 mmc_of_parse(host->mmc); 318 mmc_of_parse(host->mmc);
302 319
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index a74518009099..e3c6a74d980a 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -96,6 +96,8 @@ struct sdhci_host {
96#define SDHCI_QUIRK2_NO_1_8_V (1<<2) 96#define SDHCI_QUIRK2_NO_1_8_V (1<<2)
97#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3) 97#define SDHCI_QUIRK2_PRESET_VALUE_BROKEN (1<<3)
98#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4) 98#define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4)
99/* Controller has a non-standard host control register */
100#define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5)
99 101
100 int irq; /* Device IRQ */ 102 int irq; /* Device IRQ */
101 void __iomem *ioaddr; /* Mapped address */ 103 void __iomem *ioaddr; /* Mapped address */