Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754665AbbBTSg5 (ORCPT ); Fri, 20 Feb 2015 13:36:57 -0500 Received: from smtp11.smtpout.orange.fr ([80.12.242.133]:57272 "EHLO smtp.smtpout.orange.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752165AbbBTSg4 (ORCPT ); Fri, 20 Feb 2015 13:36:56 -0500 X-ME-Helo: beldin.home X-ME-Date: Fri, 20 Feb 2015 19:36:54 +0100 X-ME-IP: 90.16.210.142 From: Robert Jarzmik To: Ezequiel Garcia , David Woodhouse , Brian Norris , Maxime Ripard Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, Robert Jarzmik Subject: [PATCH v2] mtd: pxa3xx-nand: handle PIO in threaded interrupt Date: Fri, 20 Feb 2015 19:36:43 +0100 Message-Id: <1424457403-6669-1-git-send-email-robert.jarzmik@free.fr> X-Mailer: git-send-email 2.1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2780 Lines: 85 Change the handling of the data stage in the driver : don't pump data in the top-half interrupt, but rather schedule a thread for non dma cases. This will enable latencies in the data pumping, especially if delays are required. Moreover platform shall be more reactive as other interrupts can be served while pumping data. No throughput degradation was observed, at least on the zylonite platform, while a slight degradation was being expected. Signed-off-by: Robert Jarzmik Tested-by: Maxime Ripard --- Since v1: use IRQF_ONESHOT per Maxime's comment --- drivers/mtd/nand/pxa3xx_nand.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 96b0b1d..7ff5202 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -569,11 +569,24 @@ static void start_data_dma(struct pxa3xx_nand_info *info) {} #endif +static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data) +{ + struct pxa3xx_nand_info *info = data; + + handle_data_pio(info); + + info->state = STATE_CMD_DONE; + nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); + + return IRQ_HANDLED; +} + static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) { struct pxa3xx_nand_info *info = devid; unsigned int status, is_completed = 0, is_ready = 0; unsigned int ready, cmd_done; + irqreturn_t ret = IRQ_HANDLED; if (info->cs == 0) { ready = NDSR_FLASH_RDY; @@ -615,7 +628,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) } else { info->state = (status & NDSR_RDDREQ) ? STATE_PIO_READING : STATE_PIO_WRITING; - handle_data_pio(info); + ret = IRQ_WAKE_THREAD; + goto NORMAL_IRQ_EXIT; } } if (status & cmd_done) { @@ -656,7 +670,7 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) if (is_ready) complete(&info->dev_ready); NORMAL_IRQ_EXIT: - return IRQ_HANDLED; + return ret; } static inline int is_buf_blank(uint8_t *buf, size_t len) @@ -1672,7 +1686,9 @@ static int alloc_nand_resource(struct platform_device *pdev) /* initialize all interrupts to be disabled */ disable_int(info, NDSR_MASK); - ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info); + ret = request_threaded_irq(irq, pxa3xx_nand_irq, + pxa3xx_nand_irq_thread, IRQF_ONESHOT, + pdev->name, info); if (ret < 0) { dev_err(&pdev->dev, "failed to request IRQ\n"); goto fail_free_buf; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/