Commit e732e39e authored by Arseniy Krasnov's avatar Arseniy Krasnov Committed by Miquel Raynal

mtd: rawnand: meson: invalidate cache on polling ECC bit

'info_buf' memory is cached and driver polls ECC bit in it. This bit
is set by the NAND controller. If 'usleep_range()' returns before device
sets this bit, 'info_buf' will be cached and driver won't see update of
this bit and will loop forever.

Fixes: 8fae856c ("mtd: rawnand: meson: add support for Amlogic NAND flash controller")
Signed-off-by: default avatarArseniy Krasnov <AVKrasnov@sberdevices.ru>
Reviewed-by: default avatarNeil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/d4ef0bd6-816e-f6fa-9385-f05f775f0ae2@sberdevices.ru
parent 9b043c64
...@@ -176,6 +176,7 @@ struct meson_nfc { ...@@ -176,6 +176,7 @@ struct meson_nfc {
dma_addr_t daddr; dma_addr_t daddr;
dma_addr_t iaddr; dma_addr_t iaddr;
u32 info_bytes;
unsigned long assigned_cs; unsigned long assigned_cs;
}; };
...@@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, ...@@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
nfc->daddr, datalen, dir); nfc->daddr, datalen, dir);
return ret; return ret;
} }
nfc->info_bytes = infolen;
cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
writel(cmd, nfc->reg_base + NFC_REG_CMD); writel(cmd, nfc->reg_base + NFC_REG_CMD);
...@@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand, ...@@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
struct meson_nfc *nfc = nand_get_controller_data(nand); struct meson_nfc *nfc = nand_get_controller_data(nand);
dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
if (infolen) if (infolen) {
dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir);
nfc->info_bytes = 0;
}
} }
static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
...@@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc, ...@@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
usleep_range(10, 15); usleep_range(10, 15);
/* info is updated by nfc dma engine*/ /* info is updated by nfc dma engine*/
smp_rmb(); smp_rmb();
dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
DMA_FROM_DEVICE);
ret = *info & ECC_COMPLETE; ret = *info & ECC_COMPLETE;
} while (!ret); } while (!ret);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment