mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-17 18:36:00 +00:00
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: 8fae856c5350 ("mtd: rawnand: meson: add support for Amlogic NAND flash controller") Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru> Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/d4ef0bd6-816e-f6fa-9385-f05f775f0ae2@sberdevices.ru
This commit is contained in:
parent
9b043c6490
commit
e732e39ed9
@ -176,6 +176,7 @@ struct meson_nfc {
|
||||
|
||||
dma_addr_t daddr;
|
||||
dma_addr_t iaddr;
|
||||
u32 info_bytes;
|
||||
|
||||
unsigned long assigned_cs;
|
||||
};
|
||||
@ -503,6 +504,7 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
|
||||
nfc->daddr, datalen, dir);
|
||||
return ret;
|
||||
}
|
||||
nfc->info_bytes = infolen;
|
||||
cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
|
||||
writel(cmd, nfc->reg_base + NFC_REG_CMD);
|
||||
|
||||
@ -520,8 +522,10 @@ static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
|
||||
struct meson_nfc *nfc = nand_get_controller_data(nand);
|
||||
|
||||
dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir);
|
||||
if (infolen)
|
||||
if (infolen) {
|
||||
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)
|
||||
@ -710,6 +714,8 @@ static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
|
||||
usleep_range(10, 15);
|
||||
/* info is updated by nfc dma engine*/
|
||||
smp_rmb();
|
||||
dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes,
|
||||
DMA_FROM_DEVICE);
|
||||
ret = *info & ECC_COMPLETE;
|
||||
} while (!ret);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user