Skip to content

Commit

Permalink
mmc: dw_mmc: fix the IDMAC sw reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Seungwon Jeon authored and Chris Ball committed Jun 6, 2012
1 parent eed6c63 commit 141a712
Showing 1 changed file with 12 additions and 12 deletions.
24 changes: 12 additions & 12 deletions drivers/mmc/host/dw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host)
p->des3 = host->sg_dma;
p->des0 = IDMAC_DES0_ER;

mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET);

/* Mask out interrupts - get Tx & Rx complete only */
mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI |
SDMMC_IDMAC_INT_TI);
Expand Down Expand Up @@ -1724,7 +1726,8 @@ static void dw_mci_work_routine_card(struct work_struct *work)

#ifdef CONFIG_MMC_DW_IDMAC
ctrl = mci_readl(host, BMOD);
ctrl |= 0x01; /* Software reset of DMA */
/* Software reset of DMA */
ctrl |= SDMMC_IDMAC_SWRESET;
mci_writel(host, BMOD, ctrl);
#endif

Expand Down Expand Up @@ -1949,10 +1952,6 @@ int dw_mci_probe(struct dw_mci *host)
spin_lock_init(&host->lock);
INIT_LIST_HEAD(&host->queue);


host->dma_ops = host->pdata->dma_ops;
dw_mci_init_dma(host);

/*
* Get the host data width - this assumes that HCON has been set with
* the correct values.
Expand Down Expand Up @@ -1980,10 +1979,11 @@ int dw_mci_probe(struct dw_mci *host)
}

/* Reset all blocks */
if (!mci_wait_reset(&host->dev, host)) {
ret = -ENODEV;
goto err_dmaunmap;
}
if (!mci_wait_reset(&host->dev, host))
return -ENODEV;

host->dma_ops = host->pdata->dma_ops;
dw_mci_init_dma(host);

/* Clear the interrupts for the host controller */
mci_writel(host, RINTSTS, 0xFFFFFFFF);
Expand Down Expand Up @@ -2169,14 +2169,14 @@ int dw_mci_resume(struct dw_mci *host)
if (host->vmmc)
regulator_enable(host->vmmc);

if (host->dma_ops->init)
host->dma_ops->init(host);

if (!mci_wait_reset(&host->dev, host)) {
ret = -ENODEV;
return ret;
}

if (host->dma_ops->init)
host->dma_ops->init(host);

/* Restore the old value at FIFOTH register */
mci_writel(host, FIFOTH, host->fifoth_val);

Expand Down

0 comments on commit 141a712

Please sign in to comment.