hack not works
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index ca01b7d..23d9232 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -29,7 +29,7 @@
 #define DRIVER_NAME	"mvsdio"
 
 static int maxfreq;
-static int nodma;
+static int nodma=1;
 
 struct mvsd_host {
 	void __iomem *base;
@@ -38,8 +38,9 @@ struct mvsd_host {
 	unsigned int xfer_mode;
 	unsigned int intr_en;
 	unsigned int ctrl;
+	bool use_pio;
+	struct sg_mapping_iter sg_miter;
 	unsigned int pio_size;
-	void *pio_ptr;
 	unsigned int sg_frags;
 	unsigned int ns_per_clk;
 	unsigned int clock;
@@ -114,11 +115,18 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
 		 * data when the buffer is not aligned on a 64 byte
 		 * boundary.
 		 */
+		unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */
+
+		if (data->flags & MMC_DATA_READ)
+			miter_flags |= SG_MITER_TO_SG;
+		else
+			miter_flags |= SG_MITER_FROM_SG;
+
 		host->pio_size = data->blocks * data->blksz;
-		host->pio_ptr = sg_virt(data->sg);
+		sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags);
 		if (!nodma)
-			dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n",
-				host->pio_ptr, host->pio_size);
+			dev_dbg(host->dev, "fallback to PIO for data\n");
+		host->use_pio = true;
 		return 1;
 	} else {
 		dma_addr_t phys_addr;
@@ -129,6 +137,7 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
 		phys_addr = sg_dma_address(data->sg);
 		mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
 		mvsd_write(MVSD_SYS_ADDR_HI,  (u32)phys_addr >> 16);
+		host->use_pio = false;
 		return 0;
 	}
 }
@@ -288,8 +297,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
 {
 	void __iomem *iobase = host->base;
 
-	if (host->pio_ptr) {
-		host->pio_ptr = NULL;
+	if (host->use_pio) {
+		sg_miter_stop(&host->sg_miter);
 		host->pio_size = 0;
 	} else {
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
@@ -341,6 +350,128 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
 	return err_status;
 }
 
+static int mvsd_pio(struct mvsd_host *host, u32 *intr_status)
+{
+	struct sg_mapping_iter *sgm = &host->sg_miter;
+	void __iomem *iobase = host->base;
+	unsigned int consumed = 0;
+	int irq_handled = 0;
+	u32 irs = *intr_status;
+	u16 *p;
+	int s; /* Remaining in current segment */
+
+	/*
+	 * As we set sgm->consumed this always gives a valid buffer
+	 * position.
+	 */
+	if (!sg_miter_next(sgm)) {
+		/* This should not happen */
+		if (host->pio_size)
+			dev_err(host->dev, "ran out of scatter segments\n");
+		spin_unlock(&host->lock);
+		host->intr_en &=
+			~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W |
+			  MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+		mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+		return 1;
+	}
+
+	p = sgm->addr;
+	s = sgm->length;
+	if (s > host->pio_size)
+		s = host->pio_size;
+
+	/* PIO handling, if needed. Messy business... */
+	if ((irs & host->intr_en &
+	     (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+		while (s >= 32 && (irs & MVSD_NOR_RX_FIFO_8W)) {
+			readsw(iobase + MVSD_FIFO, p, 16);
+			p += 16;
+			s -= 32;
+			consumed += 32;
+			irs = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		/*
+		 * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+		 * doesn't appear to assert when there is exactly 32 bytes
+		 * (8 words) left to fetch in a transfer.
+		 */
+		if (s <= 32) {
+			while (s >= 4 && (irs & MVSD_NOR_RX_READY)) {
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				s -= 4;
+				consumed += 4;
+				irs = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s && s < 4 && (irs & MVSD_NOR_RX_READY)) {
+				u16 val[2] = {0, 0};
+				val[0] = mvsd_read(MVSD_FIFO);
+				val[1] = mvsd_read(MVSD_FIFO);
+				memcpy(p, ((void *)&val) + 4 - s, s);
+				consumed += s;
+				s = 0;
+				irs = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			/* PIO transfer done */
+			host->pio_size -= consumed;
+			sgm->consumed = consumed;
+			if (host->pio_size == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			} else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+				host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+				host->intr_en |= MVSD_NOR_RX_READY;
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, irs, mvsd_read(MVSD_HW_STATE));
+		irq_handled = 1;
+	} else if ((irs & host->intr_en &
+		    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+		/*
+		 * The TX_FIFO_8W bit is unreliable. When set, bursting
+		 * 16 halfwords all at once in the FIFO drops data. Actually
+		 * TX_AVAIL does go off after only one word is pushed even if
+		 * TX_FIFO_8W remains set.
+		 */
+		while (s >= 4 && (irs & MVSD_NOR_TX_AVAIL)) {
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			s -= 4;
+			consumed += 4;
+			irs = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		if (s < 4) {
+			if (s && (irs & MVSD_NOR_TX_AVAIL)) {
+				u16 val[2] = {0, 0};
+				memcpy(((void *)&val) + 4 - s, p, s);
+				mvsd_write(MVSD_FIFO, val[0]);
+				mvsd_write(MVSD_FIFO, val[1]);
+				consumed += s;
+				s = 0;
+				irs = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			/* PIO transfer done */
+			host->pio_size -= consumed;
+			sgm->consumed = consumed;
+			if (host->pio_size == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, irs, mvsd_read(MVSD_HW_STATE));
+		irq_handled = 1;
+	}
+
+	*intr_status = irs;
+	return irq_handled;
+}
+
 static irqreturn_t mvsd_irq(int irq, void *dev)
 {
 	struct mvsd_host *host = dev;
@@ -369,90 +500,8 @@ static irqreturn_t mvsd_irq(int irq, void *dev)
 
 	spin_lock(&host->lock);
 
-	/* PIO handling, if needed. Messy business... */
-	if (host->pio_size &&
-	    (intr_status & host->intr_en &
-	     (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
-		u16 *p = host->pio_ptr;
-		int s = host->pio_size;
-		while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
-			readsw(iobase + MVSD_FIFO, p, 16);
-			p += 16;
-			s -= 32;
-			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
-		}
-		/*
-		 * Normally we'd use < 32 here, but the RX_FIFO_8W bit
-		 * doesn't appear to assert when there is exactly 32 bytes
-		 * (8 words) left to fetch in a transfer.
-		 */
-		if (s <= 32) {
-			while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
-				put_unaligned(mvsd_read(MVSD_FIFO), p++);
-				put_unaligned(mvsd_read(MVSD_FIFO), p++);
-				s -= 4;
-				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
-			}
-			if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
-				u16 val[2] = {0, 0};
-				val[0] = mvsd_read(MVSD_FIFO);
-				val[1] = mvsd_read(MVSD_FIFO);
-				memcpy(p, ((void *)&val) + 4 - s, s);
-				s = 0;
-				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
-			}
-			if (s == 0) {
-				host->intr_en &=
-				     ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
-				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
-			} else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
-				host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
-				host->intr_en |= MVSD_NOR_RX_READY;
-				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
-			}
-		}
-		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
-			s, intr_status, mvsd_read(MVSD_HW_STATE));
-		host->pio_ptr = p;
-		host->pio_size = s;
-		irq_handled = 1;
-	} else if (host->pio_size &&
-		   (intr_status & host->intr_en &
-		    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
-		u16 *p = host->pio_ptr;
-		int s = host->pio_size;
-		/*
-		 * The TX_FIFO_8W bit is unreliable. When set, bursting
-		 * 16 halfwords all at once in the FIFO drops data. Actually
-		 * TX_AVAIL does go off after only one word is pushed even if
-		 * TX_FIFO_8W remains set.
-		 */
-		while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
-			mvsd_write(MVSD_FIFO, get_unaligned(p++));
-			mvsd_write(MVSD_FIFO, get_unaligned(p++));
-			s -= 4;
-			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
-		}
-		if (s < 4) {
-			if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
-				u16 val[2] = {0, 0};
-				memcpy(((void *)&val) + 4 - s, p, s);
-				mvsd_write(MVSD_FIFO, val[0]);
-				mvsd_write(MVSD_FIFO, val[1]);
-				s = 0;
-				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
-			}
-			if (s == 0) {
-				host->intr_en &=
-				     ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
-				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
-			}
-		}
-		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
-			s, intr_status, mvsd_read(MVSD_HW_STATE));
-		host->pio_ptr = p;
-		host->pio_size = s;
-		irq_handled = 1;
+	if (host->use_pio) {
+		irq_handled = mvsd_pio(host, &intr_status);
 	}
 
 	mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);