mvebu: fix NAND flash issues (FS#67)

Remove the previous PIO delay patch and add a revert patch for a faulty
upstream commit, which seems to have introduced this issue in the first
place

Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Felix Fietkau 2016-07-31 20:30:08 +02:00
parent 5d9a4c210d
commit ba1aa4e33b
2 changed files with 69 additions and 36 deletions

View File

@ -1,36 +0,0 @@
Handle delays/excessive latency during flash command processing with PIO.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -227,6 +227,7 @@ struct pxa3xx_nand_info {
int use_dma; /* use DMA ? */
int use_spare; /* use spare ? */
int need_wait;
+ int pio_progress;
/* Amount of real data per full chunk */
unsigned int chunk_size;
@@ -769,6 +770,7 @@ static irqreturn_t pxa3xx_nand_irq_threa
{
struct pxa3xx_nand_info *info = data;
+ info->pio_progress = 1;
handle_data_pio(info);
info->state = STATE_CMD_DONE;
@@ -1175,8 +1177,13 @@ static void nand_cmdfunc(struct mtd_info
info->need_wait = 1;
pxa3xx_nand_start(info);
+retry:
+ info->pio_progress = 0;
if (!wait_for_completion_timeout(&info->cmd_complete,
CHIP_DELAY_TIMEOUT)) {
+ if (info->pio_progress)
+ goto retry;
+
dev_err(&info->pdev->dev, "Wait time out!!!\n");
/* Stop State Machine for next command cycle */
pxa3xx_nand_stop(info);

View File

@ -0,0 +1,69 @@
Revert "mtd: pxa3xx-nand: handle PIO in threaded interrupt"
This reverts commit 24542257a3b987025d4b998ec2d15e556c98ad3f
This upstream change has been causing spurious timeouts on accesses
to the NAND flash if something else on the system is causing
significant latency.
Nothing guarantees that the thread will run in time, so the
usual timeout is unreliable.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -765,24 +765,11 @@ static void start_data_dma(struct pxa3xx
__func__, direction, info->dma_cookie, info->sg.length);
}
-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;
@@ -824,8 +811,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
} else {
info->state = (status & NDSR_RDDREQ) ?
STATE_PIO_READING : STATE_PIO_WRITING;
- ret = IRQ_WAKE_THREAD;
- goto NORMAL_IRQ_EXIT;
+ handle_data_pio(info);
}
}
if (status & cmd_done) {
@@ -870,7 +856,7 @@ static irqreturn_t pxa3xx_nand_irq(int i
if (is_ready)
complete(&info->dev_ready);
NORMAL_IRQ_EXIT:
- return ret;
+ return IRQ_HANDLED;
}
static inline int is_buf_blank(uint8_t *buf, size_t len)
@@ -1849,9 +1835,7 @@ static int alloc_nand_resource(struct pl
/* initialize all interrupts to be disabled */
disable_int(info, NDSR_MASK);
- ret = request_threaded_irq(irq, pxa3xx_nand_irq,
- pxa3xx_nand_irq_thread, IRQF_ONESHOT,
- pdev->name, info);
+ ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
if (ret < 0) {
dev_err(&pdev->dev, "failed to request IRQ\n");
goto fail_free_buf;