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

Commit 87a74d39 authored by Kyoungil Kim's avatar Kyoungil Kim Committed by Chris Ball
Browse files

mmc: dw_mmc: empty FIFO after data transfer over interrupt in pio mode



In dwc manual, the below contents are described:

"During end of packet, interrupt is not generated if threshold
programming is larger than any remaining data. It is responsibility
of host to read remaining bytes on seeing Data Transfer Done
interrupt"

We also have seen the data cannot be read fully when
"sg_miter->length" is less than FIFO size.

Signed-off-by: default avatarKyoungil Kim <ki0351.kim@samsung.com>
Signed-off-by: default avatarSeungwon Jeon <tgih.jun@samsung.com>
Acked-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 0cea529d
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -1438,7 +1438,7 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt)
	host->pull_data(host, buf, cnt);
}

static void dw_mci_read_data_pio(struct dw_mci *host)
static void dw_mci_read_data_pio(struct dw_mci *host, bool dto)
{
	struct sg_mapping_iter *sg_miter = &host->sg_miter;
	void *buf;
@@ -1473,7 +1473,9 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
		sg_miter->consumed = offset;
		status = mci_readl(host, MINTSTS);
		mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
	} while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
	/* if the RXDR is ready read again */
	} while ((status & SDMMC_INT_RXDR) ||
		 (dto && SDMMC_GET_FCNT(mci_readl(host, STATUS))));
	data->bytes_xfered += nbytes;

	if (!remain) {
@@ -1605,7 +1607,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
			smp_wmb();
			if (host->dir_status == DW_MCI_RECV_STATUS) {
				if (host->sg != NULL)
					dw_mci_read_data_pio(host);
					dw_mci_read_data_pio(host, true);
			}
			set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
			tasklet_schedule(&host->tasklet);
@@ -1614,7 +1616,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
		if (pending & SDMMC_INT_RXDR) {
			mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
			if (host->dir_status == DW_MCI_RECV_STATUS && host->sg)
				dw_mci_read_data_pio(host);
				dw_mci_read_data_pio(host, false);
		}

		if (pending & SDMMC_INT_TXDR) {