aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorSeungwon Jeon <tgih.jun@samsung.com>2012-05-22 00:01:03 -0400
committerChris Ball <cjb@laptop.org>2012-06-06 09:36:21 -0400
commit141a712a4eb09639dd4973a7c5e6999e3b8ae04a (patch)
tree30a6eb7319b718c585f34e9827bf86fb3b2c3637 /drivers/mmc
parenteed6c63cefaf935e6fb28c4dd9977a280ae544a8 (diff)
mmc: dw_mmc: fix the IDMAC sw reset
IDMAC may not be cleaned in driver probe if it has been already used in boot time. So IDMAC needs sw reset newly. And DMA interface reset precedes the internal DMAC reset. Additionally SDMMC_IDMAC_SWRESET is replaced with magic code. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Acked-by: Will Newton <will.newton@gmail.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/dw_mmc.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b46faf0cfb2..98fe02347d5 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host)
418 p->des3 = host->sg_dma; 418 p->des3 = host->sg_dma;
419 p->des0 = IDMAC_DES0_ER; 419 p->des0 = IDMAC_DES0_ER;
420 420
421 mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET);
422
421 /* Mask out interrupts - get Tx & Rx complete only */ 423 /* Mask out interrupts - get Tx & Rx complete only */
422 mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | 424 mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI |
423 SDMMC_IDMAC_INT_TI); 425 SDMMC_IDMAC_INT_TI);
@@ -1724,7 +1726,8 @@ static void dw_mci_work_routine_card(struct work_struct *work)
1724 1726
1725#ifdef CONFIG_MMC_DW_IDMAC 1727#ifdef CONFIG_MMC_DW_IDMAC
1726 ctrl = mci_readl(host, BMOD); 1728 ctrl = mci_readl(host, BMOD);
1727 ctrl |= 0x01; /* Software reset of DMA */ 1729 /* Software reset of DMA */
1730 ctrl |= SDMMC_IDMAC_SWRESET;
1728 mci_writel(host, BMOD, ctrl); 1731 mci_writel(host, BMOD, ctrl);
1729#endif 1732#endif
1730 1733
@@ -1949,10 +1952,6 @@ int dw_mci_probe(struct dw_mci *host)
1949 spin_lock_init(&host->lock); 1952 spin_lock_init(&host->lock);
1950 INIT_LIST_HEAD(&host->queue); 1953 INIT_LIST_HEAD(&host->queue);
1951 1954
1952
1953 host->dma_ops = host->pdata->dma_ops;
1954 dw_mci_init_dma(host);
1955
1956 /* 1955 /*
1957 * Get the host data width - this assumes that HCON has been set with 1956 * Get the host data width - this assumes that HCON has been set with
1958 * the correct values. 1957 * the correct values.
@@ -1980,10 +1979,11 @@ int dw_mci_probe(struct dw_mci *host)
1980 } 1979 }
1981 1980
1982 /* Reset all blocks */ 1981 /* Reset all blocks */
1983 if (!mci_wait_reset(&host->dev, host)) { 1982 if (!mci_wait_reset(&host->dev, host))
1984 ret = -ENODEV; 1983 return -ENODEV;
1985 goto err_dmaunmap; 1984
1986 } 1985 host->dma_ops = host->pdata->dma_ops;
1986 dw_mci_init_dma(host);
1987 1987
1988 /* Clear the interrupts for the host controller */ 1988 /* Clear the interrupts for the host controller */
1989 mci_writel(host, RINTSTS, 0xFFFFFFFF); 1989 mci_writel(host, RINTSTS, 0xFFFFFFFF);
@@ -2169,14 +2169,14 @@ int dw_mci_resume(struct dw_mci *host)
2169 if (host->vmmc) 2169 if (host->vmmc)
2170 regulator_enable(host->vmmc); 2170 regulator_enable(host->vmmc);
2171 2171
2172 if (host->dma_ops->init)
2173 host->dma_ops->init(host);
2174
2175 if (!mci_wait_reset(&host->dev, host)) { 2172 if (!mci_wait_reset(&host->dev, host)) {
2176 ret = -ENODEV; 2173 ret = -ENODEV;
2177 return ret; 2174 return ret;
2178 } 2175 }
2179 2176
2177 if (host->dma_ops->init)
2178 host->dma_ops->init(host);
2179
2180 /* Restore the old value at FIFOTH register */ 2180 /* Restore the old value at FIFOTH register */
2181 mci_writel(host, FIFOTH, host->fifoth_val); 2181 mci_writel(host, FIFOTH, host->fifoth_val);
2182 2182