mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
mmc: dw_mmc: fix suspend/resume operation
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>
This commit is contained in:
parent
fc3d772054
commit
e61cf1184d
2 changed files with 21 additions and 2 deletions
|
@ -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);
|
||||
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue