[PATCH 09/13] mtd: rawnand: gpmi: poll the BCH interrupt bit in start_dma_with_bch_irq()

Sam Lefebvre sam.lefebvre at essensium.com
Thu Apr 26 08:41:30 PDT 2018


To improve nand performance, the BCH interrupt bit must be polled
before waiting for occurence. This avoids an unnecessary context switch.

Signed-off-by: Sam Lefebvre <sam.lefebvre at essensium.com>
---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 60bc1bac7741..28a2cf106ddc 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -503,18 +503,31 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this,
  * Actually, we must wait for two interrupts :
  *	[1] firstly the DMA interrupt and
  *	[2] secondly the BCH interrupt.
+ *	To improve performance, we first poll for the BCH
+ *	interrupt.
  */
 int start_dma_with_bch_irq(struct gpmi_nand_data *this,
 			struct dma_async_tx_descriptor *desc)
 {
 	struct completion *bch_c = &this->bch_done;
+	struct resources *r = &this->resources;
 	unsigned long timeout;
 
-	/* Prepare to receive an interrupt from the BCH block. */
-	init_completion(bch_c);
+	/* Disable interrupt */
+	writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, r->bch_regs + HW_BCH_CTRL_CLR);
 
 	/* start the DMA */
 	start_dma_without_bch_irq(this, desc);
+	if (readl(r->bch_regs + HW_BCH_CTRL) & BM_BCH_CTRL_COMPLETE_IRQ) {
+		writel(BM_BCH_CTRL_COMPLETE_IRQ, r->bch_regs + HW_BCH_CTRL_CLR);
+		return 0;
+	}
+
+	/* Prepare to receive an interrupt from the BCH block. */
+	init_completion(bch_c);
+
+	/* Re-enable interrupt */
+	writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, r->bch_regs + HW_BCH_CTRL_SET);
 
 	/* Wait for the interrupt from the BCH block. */
 	timeout = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000));
-- 
2.14.1




More information about the linux-mtd mailing list