Instead of setting up a kernel pointer to track the current PIO address,
track the offset in the current page, and do a kmap for the page while
doing the actual PIO operations.

Signed-off-by: Christoph Hellwig <h...@lst.de>
---
 drivers/mmc/host/moxart-mmc.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index a0670e9cd012..116964e6506d 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -311,7 +311,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
        if (host->data_len == data->bytes_xfered)
                return;
 
-       sgp = sg_virt(host->cur_sg);
+       sgp = kmap(sg_page(host->cur_sg)) + host->cur_sg->offset;
        remain = host->data_remain;
 
        if (data->flags & MMC_DATA_WRITE) {
@@ -319,8 +319,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
                        if (moxart_wait_for_status(host, FIFO_URUN, &status)
                             == -ETIMEDOUT) {
                                data->error = -ETIMEDOUT;
-                               complete(&host->pio_complete);
-                               return;
+                               goto done;
                        }
                        for (len = 0; len < remain && len < host->fifo_width;) {
                                iowrite32(*sgp, host->base + REG_DATA_WINDOW);
@@ -335,8 +334,7 @@ static void moxart_transfer_pio(struct moxart_host *host)
                        if (moxart_wait_for_status(host, FIFO_ORUN, &status)
                            == -ETIMEDOUT) {
                                data->error = -ETIMEDOUT;
-                               complete(&host->pio_complete);
-                               return;
+                               goto done;
                        }
                        for (len = 0; len < remain && len < host->fifo_width;) {
                                /* SCR data must be read in big endian. */
@@ -356,10 +354,15 @@ static void moxart_transfer_pio(struct moxart_host *host)
        data->bytes_xfered += host->data_remain - remain;
        host->data_remain = remain;
 
-       if (host->data_len != data->bytes_xfered)
+       if (host->data_len != data->bytes_xfered) {
+               kunmap(sg_page(host->cur_sg));
                moxart_next_sg(host);
-       else
-               complete(&host->pio_complete);
+               return;
+       }
+
+done:
+       kunmap(sg_page(host->cur_sg));
+       complete(&host->pio_complete);
 }
 
 static void moxart_prepare_data(struct moxart_host *host)
@@ -614,6 +617,7 @@ static int moxart_probe(struct platform_device *pdev)
        spin_lock_init(&host->lock);
 
        mmc->ops = &moxart_ops;
+       mmc->need_kmap = 1;
        mmc->f_max = DIV_ROUND_CLOSEST(host->sysclk, 2);
        mmc->f_min = DIV_ROUND_CLOSEST(host->sysclk, CLK_DIV_MASK * 2);
        mmc->ocr_avail = 0xffff00;      /* Support 2.0v - 3.6v power. */
-- 
2.20.1

Reply via email to