Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e74f3a9c authored by Seungwon Jeon's avatar Seungwon Jeon Committed by Chris Ball
Browse files

mmc: dw_mmc: fix error handling in PIO mode



Data transfer will be continued until all the bytes are transmitted,
even if data crc error occurs during a multiple-block data transfer.
This means RXDR/TXDR interrupts will occurs until data transfer is
terminated. Early setting of host->sg to NULL prevents going into
xxx_data_pio functions, hence permanent unhandled RXDR/TXDR interrupts
occurs. And checking error interrupt status in the xxx_data_pio functions
is no need because dw_mci_interrupt does do the same. This patch also
removes it.

Signed-off-by: default avatarSeungwon Jeon <tgih.jun@samsung.com>
Acked-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Acked-by: default avatarWill Newton <will.newton@imgtec.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 9b2026a1
Loading
Loading
Loading
Loading
+2 −27
Original line number Original line Diff line number Diff line
@@ -1429,22 +1429,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
			nbytes += len;
			nbytes += len;
			remain -= len;
			remain -= len;
		} while (remain);
		} while (remain);
		sg_miter->consumed = offset;


		sg_miter->consumed = offset;
		status = mci_readl(host, MINTSTS);
		status = mci_readl(host, MINTSTS);
		mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
		mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
		if (status & DW_MCI_DATA_ERROR_FLAGS) {
			host->data_status = status;
			data->bytes_xfered += nbytes;
			sg_miter_stop(sg_miter);
			host->sg = NULL;
			smp_wmb();

			set_bit(EVENT_DATA_ERROR, &host->pending_events);

			tasklet_schedule(&host->tasklet);
			return;
		}
	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
	data->bytes_xfered += nbytes;
	data->bytes_xfered += nbytes;


@@ -1497,23 +1485,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
			nbytes += len;
			nbytes += len;
			remain -= len;
			remain -= len;
		} while (remain);
		} while (remain);
		sg_miter->consumed = offset;


		sg_miter->consumed = offset;
		status = mci_readl(host, MINTSTS);
		status = mci_readl(host, MINTSTS);
		mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
		mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
		if (status & DW_MCI_DATA_ERROR_FLAGS) {
			host->data_status = status;
			data->bytes_xfered += nbytes;
			sg_miter_stop(sg_miter);
			host->sg = NULL;

			smp_wmb();

			set_bit(EVENT_DATA_ERROR, &host->pending_events);

			tasklet_schedule(&host->tasklet);
			return;
		}
	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
	} while (status & SDMMC_INT_TXDR); /* if TXDR write again */
	data->bytes_xfered += nbytes;
	data->bytes_xfered += nbytes;