aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2015-02-20 13:36:43 -0500
committerBrian Norris <computersforpeace@gmail.com>2015-02-28 04:08:36 -0500
commit24542257a3b987025d4b998ec2d15e556c98ad3f (patch)
tree5fa45c4488a75455dfb75d305ec688bb8bf07d51 /drivers/mtd
parentadf716d2f3e62820cc86cdb08c277516c7012352 (diff)
mtd: pxa3xx-nand: handle PIO in threaded interrupt
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>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index bc677362bc73..3f09f2e9aeb4 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -605,11 +605,24 @@ static void start_data_dma(struct pxa3xx_nand_info *info)
605{} 605{}
606#endif 606#endif
607 607
608static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data)
609{
610 struct pxa3xx_nand_info *info = data;
611
612 handle_data_pio(info);
613
614 info->state = STATE_CMD_DONE;
615 nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ);
616
617 return IRQ_HANDLED;
618}
619
608static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) 620static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
609{ 621{
610 struct pxa3xx_nand_info *info = devid; 622 struct pxa3xx_nand_info *info = devid;
611 unsigned int status, is_completed = 0, is_ready = 0; 623 unsigned int status, is_completed = 0, is_ready = 0;
612 unsigned int ready, cmd_done; 624 unsigned int ready, cmd_done;
625 irqreturn_t ret = IRQ_HANDLED;
613 626
614 if (info->cs == 0) { 627 if (info->cs == 0) {
615 ready = NDSR_FLASH_RDY; 628 ready = NDSR_FLASH_RDY;
@@ -651,7 +664,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
651 } else { 664 } else {
652 info->state = (status & NDSR_RDDREQ) ? 665 info->state = (status & NDSR_RDDREQ) ?
653 STATE_PIO_READING : STATE_PIO_WRITING; 666 STATE_PIO_READING : STATE_PIO_WRITING;
654 handle_data_pio(info); 667 ret = IRQ_WAKE_THREAD;
668 goto NORMAL_IRQ_EXIT;
655 } 669 }
656 } 670 }
657 if (status & cmd_done) { 671 if (status & cmd_done) {
@@ -692,7 +706,7 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
692 if (is_ready) 706 if (is_ready)
693 complete(&info->dev_ready); 707 complete(&info->dev_ready);
694NORMAL_IRQ_EXIT: 708NORMAL_IRQ_EXIT:
695 return IRQ_HANDLED; 709 return ret;
696} 710}
697 711
698static inline int is_buf_blank(uint8_t *buf, size_t len) 712static inline int is_buf_blank(uint8_t *buf, size_t len)
@@ -1708,7 +1722,9 @@ static int alloc_nand_resource(struct platform_device *pdev)
1708 /* initialize all interrupts to be disabled */ 1722 /* initialize all interrupts to be disabled */
1709 disable_int(info, NDSR_MASK); 1723 disable_int(info, NDSR_MASK);
1710 1724
1711 ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info); 1725 ret = request_threaded_irq(irq, pxa3xx_nand_irq,
1726 pxa3xx_nand_irq_thread, IRQF_ONESHOT,
1727 pdev->name, info);
1712 if (ret < 0) { 1728 if (ret < 0) {
1713 dev_err(&pdev->dev, "failed to request IRQ\n"); 1729 dev_err(&pdev->dev, "failed to request IRQ\n");
1714 goto fail_free_buf; 1730 goto fail_free_buf;