Skip to content

Commit

Permalink
mmc: dw_mmc: fix suspend/resume operation
Browse files Browse the repository at this point in the history
This patch is related to re-init processing on suspend/resume.

When card is resuming, some register is reset.  If card is removable,
maybe controller should be rescan for card.  But if assume card is
non-removable, need to restore the old value at registers.

We store the value of FIFOTH at probe time and then restore it in
dw_mci_resume().

Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Will Newton <will.newton@imgtec.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
  • Loading branch information
Jaehoon Chung authored and Chris Ball committed Mar 17, 2011
1 parent fc3d772 commit e61cf11
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
22 changes: 20 additions & 2 deletions drivers/mmc/host/dw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1639,8 +1639,9 @@ static int dw_mci_probe(struct platform_device *pdev)
*/
fifo_size = mci_readl(host, FIFOTH);
fifo_size = (fifo_size >> 16) & 0x7ff;
mci_writel(host, FIFOTH, ((0x2 << 28) | ((fifo_size/2 - 1) << 16) |
((fifo_size/2) << 0)));
host->fifoth_val = ((0x2 << 28) | ((fifo_size/2 - 1) << 16) |
((fifo_size/2) << 0));
mci_writel(host, FIFOTH, host->fifoth_val);

/* disable clock to CIU */
mci_writel(host, CLKENA, 0);
Expand Down Expand Up @@ -1772,6 +1773,23 @@ static int dw_mci_resume(struct platform_device *pdev)
int i, ret;
struct dw_mci *host = platform_get_drvdata(pdev);

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

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

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

mci_writel(host, RINTSTS, 0xFFFFFFFF);
mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER |
SDMMC_INT_TXDR | SDMMC_INT_RXDR |
DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE);

for (i = 0; i < host->num_slots; i++) {
struct dw_mci_slot *slot = host->slot[i];
if (!slot)
Expand Down
1 change: 1 addition & 0 deletions include/linux/mmc/dw_mmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ struct dw_mci {
u32 bus_hz;
u32 current_speed;
u32 num_slots;
u32 fifoth_val;
struct platform_device *pdev;
struct dw_mci_board *pdata;
struct dw_mci_slot *slot[MAX_MCI_SLOTS];
Expand Down

0 comments on commit e61cf11

Please sign in to comment.