linux/drivers/mtd/nand
Xiaolei Li 39b3926aad mtd: nand: mtk: fix infinite ECC decode IRQ issue
commit 1d2fcdcf33 upstream.

For MT2701 NAND Controller, there may generate infinite ECC decode IRQ
during long time burn test on some platforms. Once this issue occurred,
the ECC decode IRQ status cannot be cleared in the IRQ handler function,
and threads cannot be scheduled.

ECC HW generates decode IRQ each sector, so there will have more than one
decode IRQ if read one page of large page NAND.

Currently, ECC IRQ handle flow is that we will check whether it is decode
IRQ at first by reading the register ECC_DECIRQ_STA. This is a read-clear
type register. If this IRQ is decode IRQ, then the ECC IRQ signal will be
cleared at the same time.
Secondly, we will check whether all sectors are decoded by reading the
register ECC_DECDONE. This is because the current IRQ may be not dealed
in time, and the next sectors have been decoded before reading the
register ECC_DECIRQ_STA. Then, the next sectors's decode IRQs will not
be generated.
Thirdly, if all sectors are decoded by comparing with ecc->sectors, then we
will complete ecc->done, set ecc->sectors as 0, and disable ECC IRQ by
programming the register ECC_IRQ_REG(op) as 0. Otherwise, wait for the
next ECC IRQ.

But, there is a timing issue between step one and two. When we read the
reigster ECC_DECIRQ_STA, all sectors are decoded except the last sector,
and the ECC IRQ signal is cleared. But the last sector is decoded before
reading ECC_DECDONE, so the ECC IRQ signal is enabled again by ECC HW, and
it means we will receive one extra ECC IRQ later. In step three, we will
find that all sectors were decoded, then disable ECC IRQ and return.
When deal with the extra ECC IRQ, the ECC IRQ status cannot be cleared
anymore. That is because the register ECC_DECIRQ_STA can only be cleared
when the register ECC_IRQ_REG(op) is enabled. But actually we have
disabled ECC IRQ in the previous ECC IRQ handle. So, there will
keep receiving ECC decode IRQ.

Now, we read the register ECC_DECIRQ_STA once again before completing the
ecc done event. This ensures that there will be no extra ECC decode IRQ.

Also, remove writel(0, ecc->regs + ECC_IRQ_REG(op)) from irq handler,
because ECC IRQ is disabled in mtk_ecc_disable(). And clear ECC_DECIRQ_STA
in mtk_ecc_disable() in case there is a timeout to wait decode IRQ.

Fixes: 1d6b1e4649 ("mtd: mediatek: driver for MTK Smart Device")
Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
History 2017-11-30 08:40:52 +00:00
..
atmel mtd: nand: atmel: Actually use the PM ops 2017-11-30 08:40:52 +00:00
bcm47xxnflash License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
brcmnand License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
gpmi-nand mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
ams-delta.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
au1550nd.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
bf5xx_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
cafe_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
cmx270_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
cs553x_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
davinci_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
denali.c linux/kernel.h: move DIV_ROUND_DOWN_ULL() macro 2017-09-08 18:26:47 -07:00
denali.h mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
denali_dt.c mtd: nand: denali: Handle return value of clk_prepare_enable. 2017-08-23 16:49:18 +02:00
denali_pci.c mtd: nand: denali: avoid magic numbers and rename for clarification 2017-06-20 09:14:57 +02:00
diskonchip.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
docg4.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
fsl_elbc_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
fsl_ifc_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
fsl_upm.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
fsmc_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
gpio.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
hisi504_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
jz4740_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
jz4780_bch.c mtd: nand: jz4780: Update MODULE_AUTHOR email address 2016-07-11 08:40:19 +02:00
jz4780_bch.h mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs 2016-01-07 09:35:11 -08:00
jz4780_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
Kconfig mtd: nand: pxa3xx_nand: enable building on mvebu 64-bit platforms 2017-08-23 16:49:18 +02:00
lpc32xx_mlc.c mtd: nand: lpc32xx_mlc: Fix an error handling path in lpc32xx_nand_probe() 2017-09-18 12:07:30 +02:00
lpc32xx_slc.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
mpc5121_nfc.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
mtk_ecc.c mtd: nand: mtk: fix infinite ECC decode IRQ issue 2017-11-30 08:40:52 +00:00
mtk_ecc.h mtd: nand: mediatek: add support for different MTK NAND FLASH Controller IP 2017-06-01 10:09:37 +02:00
mtk_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
mxc_nand.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
nand_amd.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_base.c mtd: nand: Fix writing mtdoops to nand flash. 2017-11-30 08:40:52 +00:00
nand_bbt.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_bch.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_ecc.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_hynix.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
nand_ids.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_macronix.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_micron.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_samsung.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nand_timings.c This pull request contains the following core changes: 2017-09-01 15:34:30 +02:00
nand_toshiba.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nandsim.c mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid 2017-11-30 08:40:51 +00:00
ndfc.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
nuc900_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
omap2.c mtd: nand: omap2: Fix subpage write 2017-11-30 08:40:52 +00:00
omap_elm.c mtd: omap_elm: print interrupt resource using %pr 2015-12-18 10:16:17 -08:00
orion_nand.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
oxnas_nand.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
pasemi_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
plat_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
pxa3xx_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
qcom_nandc.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
r852.c mtd: nand: make use of nand_set/get_controller_data() helpers 2016-01-07 10:23:41 -08:00
r852.h mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
s3c2410.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
sh_flctl.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
sharpsl.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
sm_common.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
sm_common.h mtd: use __packed shorthand 2014-08-19 11:53:08 -07:00
socrates_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
sunxi_nand.c This pull request contains the following core changes: 2017-09-01 15:34:30 +02:00
tango_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
tmio_nand.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
txx9ndfmc.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00
vf610_nfc.c Merge branch 'nand/rename-header-file' of git://git.infradead.org/l2-mtd into nand/next 2017-08-23 17:00:12 +02:00
xway_nand.c mtd: nand: Rename nand.h into rawnand.h 2017-08-13 10:11:49 +02:00