diff mbox series

mmc: dw_mmc: Fixes data read when receiving DTO interrupt in FIFO mode

Message ID 20210426033505.1906-1-ley.foon.tan@intel.com
State Accepted
Commit 8cb9d3ed3a6402f984356988c581546866acf0da
Delegated to: Peng Fan
Headers show
Series mmc: dw_mmc: Fixes data read when receiving DTO interrupt in FIFO mode | expand

Commit Message

Ley Foon Tan April 26, 2021, 3:35 a.m. UTC
The data read is not working when using FIFO mode.

From DesignWare databook, when a Data_Transfer_Over (DTO) interrupt is
received, the software should read the remaining data from FIFO.

Add DTO interrupt checking on data read path and clear interrupts before
start reading from FIFO. So, it doesn't clear the next pending
interrupts unintentionally after read from FIFO.

Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
---
 drivers/mmc/dw_mmc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Jaehoon Chung April 26, 2021, 10:15 p.m. UTC | #1
On 4/26/21 12:35 PM, Ley Foon Tan wrote:
> The data read is not working when using FIFO mode.
> 
>>From DesignWare databook, when a Data_Transfer_Over (DTO) interrupt is
> received, the software should read the remaining data from FIFO.
> 
> Add DTO interrupt checking on data read path and clear interrupts before
> start reading from FIFO. So, it doesn't clear the next pending
> interrupts unintentionally after read from FIFO.
> 
> Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/dw_mmc.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
> index 7c8a312fa71a..a949dad57402 100644
> --- a/drivers/mmc/dw_mmc.c
> +++ b/drivers/mmc/dw_mmc.c
> @@ -166,7 +166,9 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
>  		if (host->fifo_mode && size) {
>  			len = 0;
>  			if (data->flags == MMC_DATA_READ &&
> -			    (mask & DWMCI_INTMSK_RXDR)) {
> +			    (mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) {
> +				dwmci_writel(host, DWMCI_RINTSTS,
> +					     DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO);
>  				while (size) {
>  					ret = dwmci_fifo_ready(host,
>  							DWMCI_FIFO_EMPTY,
> @@ -182,8 +184,6 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
>  						dwmci_readl(host, DWMCI_DATA);
>  					size = size > len ? (size - len) : 0;
>  				}
> -				dwmci_writel(host, DWMCI_RINTSTS,
> -					     DWMCI_INTMSK_RXDR);
>  			} else if (data->flags == MMC_DATA_WRITE &&
>  				   (mask & DWMCI_INTMSK_TXDR)) {
>  				while (size) {
>
diff mbox series

Patch

diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 7c8a312fa71a..a949dad57402 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -166,7 +166,9 @@  static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
 		if (host->fifo_mode && size) {
 			len = 0;
 			if (data->flags == MMC_DATA_READ &&
-			    (mask & DWMCI_INTMSK_RXDR)) {
+			    (mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) {
+				dwmci_writel(host, DWMCI_RINTSTS,
+					     DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO);
 				while (size) {
 					ret = dwmci_fifo_ready(host,
 							DWMCI_FIFO_EMPTY,
@@ -182,8 +184,6 @@  static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
 						dwmci_readl(host, DWMCI_DATA);
 					size = size > len ? (size - len) : 0;
 				}
-				dwmci_writel(host, DWMCI_RINTSTS,
-					     DWMCI_INTMSK_RXDR);
 			} else if (data->flags == MMC_DATA_WRITE &&
 				   (mask & DWMCI_INTMSK_TXDR)) {
 				while (size) {