dw_mmc: fix suspend/resume operation
Subsystems (2)
Jaehoon Chung
maintainerPATCH 1/1 dw_mmc: fix suspend/resume operation
This patch is applied about re-init processing when 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.
--- drivers/mmc/host/dw_mmc.c | 22 ++++++++++++++++++++-- include/linux/mmc/dw_mmc.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-)
drivers/mmc/host/dw_mmc.c +20 -2
@@ -1633,8 +1633,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 );
@@ -1766,6 +1767,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)
include/linux/mmc/dw_mmc.h +1 -0
@@ -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 ];
Quoted 8 lines · Jaehoon Chung
This patch is applied about re-init processing when 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.Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>
Looks ok to me.
Hi,
Quoted 59 lines · Jaehoon Chung
This patch is applied about re-init processing when 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.Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/mmc/host/dw_mmc.c | 22 ++++++++++++++++++++-- include/linux/mmc/dw_mmc.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-)drivers/mmc/host/dw_mmc.c +20
-2@@ -1633,8 +1633,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 );@@ -1766,6 +1767,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)include/linux/mmc/dw_mmc.h +0
-0
include/linux/mmc/dw_mmc.h struct dw_mci { · line 146
Quoted 7 lines
include/linux/mmc/dw_mmc.h +1
-0@@ -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 ];
Thanks, will merge for .39 with Will's ACK.
Signature · 2 lines
Chris Ball <[email protected]> <http://printf.net/> One Laptop Per Child