Skip to content

Commit

Permalink
mtd: pxa3xx-nand: handle PIO in threaded interrupt
Browse files Browse the repository at this point in the history
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 <robert.jarzmik@free.fr>
Tested-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
  • Loading branch information
Robert Jarzmik authored and Brian Norris committed Feb 28, 2015
1 parent adf716d commit 2454225
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions drivers/mtd/nand/pxa3xx_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,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;
Expand Down Expand Up @@ -651,7 +664,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) {
Expand Down Expand Up @@ -692,7 +706,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)
Expand Down Expand Up @@ -1708,7 +1722,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;
Expand Down

0 comments on commit 2454225

Please sign in to comment.