mmc: tmio: use PIO for short transfers

This patch allows transferring of some requests in PIO and some in DMA
mode and defaults to using DMA only for transfers longer than 8 bytes.
This is especially useful with SDIO, which can have lots of 2- and 4-byte
transfers, creating unnecessary high overhead, when executed in DMA.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Chris Ball <cjb@laptop.org>

authored by Guennadi Liakhovetski and committed by Chris Ball 5f52c355 51fc7b2c

+23 -10
+23 -10
drivers/mmc/host/tmio_mmc.c
··· 100 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) 101 #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) 102 103 #define enable_mmc_irqs(host, i) \ 104 do { \ 105 u32 mask;\ ··· 149 struct platform_device *pdev; 150 151 /* DMA support */ 152 struct dma_chan *chan_rx; 153 struct dma_chan *chan_tx; 154 struct tasklet_struct dma_complete; ··· 388 host->cmd = NULL; 389 host->data = NULL; 390 host->mrq = NULL; 391 392 spin_unlock_irqrestore(&host->lock, flags); 393 ··· 408 host->mrq = NULL; 409 host->cmd = NULL; 410 host->data = NULL; 411 412 cancel_delayed_work(&host->delayed_reset_work); 413 ··· 490 unsigned int count; 491 unsigned long flags; 492 493 - if (host->chan_tx || host->chan_rx) { 494 pr_err("PIO IRQ in DMA mode!\n"); 495 return; 496 } else if (!data) { ··· 556 */ 557 558 if (data->flags & MMC_DATA_READ) { 559 - if (!host->chan_rx) 560 - disable_mmc_irqs(host, TMIO_MASK_READOP); 561 - else 562 tmio_check_bounce_buffer(host); 563 dev_dbg(&host->pdev->dev, "Complete Rx request %p\n", 564 host->mrq); 565 } else { 566 - if (!host->chan_tx) 567 - disable_mmc_irqs(host, TMIO_MASK_WRITEOP); 568 dev_dbg(&host->pdev->dev, "Complete Tx request %p\n", 569 host->mrq); 570 } ··· 584 if (!data) 585 goto out; 586 587 - if (host->chan_tx && (data->flags & MMC_DATA_WRITE)) { 588 /* 589 * Has all data been written out yet? Testing on SuperH showed, 590 * that in most cases the first interrupt comes already with the ··· 597 disable_mmc_irqs(host, TMIO_STAT_DATAEND); 598 tasklet_schedule(&host->dma_complete); 599 } 600 - } else if (host->chan_rx && (data->flags & MMC_DATA_READ)) { 601 disable_mmc_irqs(host, TMIO_STAT_DATAEND); 602 tasklet_schedule(&host->dma_complete); 603 } else { 604 tmio_mmc_do_data_irq(host); 605 } 606 out: 607 spin_unlock(&host->lock); ··· 651 */ 652 if (host->data && !cmd->error) { 653 if (host->data->flags & MMC_DATA_READ) { 654 - if (!host->chan_rx) 655 enable_mmc_irqs(host, TMIO_MASK_READOP); 656 else 657 tasklet_schedule(&host->dma_issue); 658 } else { 659 - if (!host->chan_tx) 660 enable_mmc_irqs(host, TMIO_MASK_WRITEOP); 661 else 662 tasklet_schedule(&host->dma_issue); ··· 812 goto pio; 813 } 814 815 disable_mmc_irqs(host, TMIO_STAT_RXRDY); 816 817 /* The only sg element can be unaligned, use our bounce buffer then */ ··· 883 align >= MAX_ALIGN)) || !multiple) { 884 ret = -EINVAL; 885 goto pio; 886 } 887 888 disable_mmc_irqs(host, TMIO_STAT_TXRQ); ··· 1131 1132 fail: 1133 host->mrq = NULL; 1134 mrq->cmd->error = ret; 1135 mmc_request_done(mmc, mrq); 1136 }
··· 100 TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) 101 #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) 102 103 + #define TMIO_MIN_DMA_LEN 8 104 + 105 #define enable_mmc_irqs(host, i) \ 106 do { \ 107 u32 mask;\ ··· 147 struct platform_device *pdev; 148 149 /* DMA support */ 150 + bool force_pio; 151 struct dma_chan *chan_rx; 152 struct dma_chan *chan_tx; 153 struct tasklet_struct dma_complete; ··· 385 host->cmd = NULL; 386 host->data = NULL; 387 host->mrq = NULL; 388 + host->force_pio = false; 389 390 spin_unlock_irqrestore(&host->lock, flags); 391 ··· 404 host->mrq = NULL; 405 host->cmd = NULL; 406 host->data = NULL; 407 + host->force_pio = false; 408 409 cancel_delayed_work(&host->delayed_reset_work); 410 ··· 485 unsigned int count; 486 unsigned long flags; 487 488 + if ((host->chan_tx || host->chan_rx) && !host->force_pio) { 489 pr_err("PIO IRQ in DMA mode!\n"); 490 return; 491 } else if (!data) { ··· 551 */ 552 553 if (data->flags & MMC_DATA_READ) { 554 + if (host->chan_rx && !host->force_pio) 555 tmio_check_bounce_buffer(host); 556 dev_dbg(&host->pdev->dev, "Complete Rx request %p\n", 557 host->mrq); 558 } else { 559 dev_dbg(&host->pdev->dev, "Complete Tx request %p\n", 560 host->mrq); 561 } ··· 583 if (!data) 584 goto out; 585 586 + if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) { 587 /* 588 * Has all data been written out yet? Testing on SuperH showed, 589 * that in most cases the first interrupt comes already with the ··· 596 disable_mmc_irqs(host, TMIO_STAT_DATAEND); 597 tasklet_schedule(&host->dma_complete); 598 } 599 + } else if (host->chan_rx && (data->flags & MMC_DATA_READ) && !host->force_pio) { 600 disable_mmc_irqs(host, TMIO_STAT_DATAEND); 601 tasklet_schedule(&host->dma_complete); 602 } else { 603 tmio_mmc_do_data_irq(host); 604 + disable_mmc_irqs(host, TMIO_MASK_READOP | TMIO_MASK_WRITEOP); 605 } 606 out: 607 spin_unlock(&host->lock); ··· 649 */ 650 if (host->data && !cmd->error) { 651 if (host->data->flags & MMC_DATA_READ) { 652 + if (host->force_pio || !host->chan_rx) 653 enable_mmc_irqs(host, TMIO_MASK_READOP); 654 else 655 tasklet_schedule(&host->dma_issue); 656 } else { 657 + if (host->force_pio || !host->chan_tx) 658 enable_mmc_irqs(host, TMIO_MASK_WRITEOP); 659 else 660 tasklet_schedule(&host->dma_issue); ··· 810 goto pio; 811 } 812 813 + if (sg->length < TMIO_MIN_DMA_LEN) { 814 + host->force_pio = true; 815 + return; 816 + } 817 + 818 disable_mmc_irqs(host, TMIO_STAT_RXRDY); 819 820 /* The only sg element can be unaligned, use our bounce buffer then */ ··· 876 align >= MAX_ALIGN)) || !multiple) { 877 ret = -EINVAL; 878 goto pio; 879 + } 880 + 881 + if (sg->length < TMIO_MIN_DMA_LEN) { 882 + host->force_pio = true; 883 + return; 884 } 885 886 disable_mmc_irqs(host, TMIO_STAT_TXRQ); ··· 1119 1120 fail: 1121 host->mrq = NULL; 1122 + host->force_pio = false; 1123 mrq->cmd->error = ret; 1124 mmc_request_done(mmc, mrq); 1125 }