On 09/01/2019 20:44, Boris Brezillon wrote: > Might be caused by a missing barrier: when de-asserting the CE line, we > must make sure all accesses to the ->data_va range have been done. > Can you try with the following diff applied? > > --->8--- > diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c > index 325b4414dccc..264d809c2d37 100644 > --- a/drivers/mtd/nand/raw/fsmc_nand.c > +++ b/drivers/mtd/nand/raw/fsmc_nand.c > @@ -598,16 +598,21 @@ static void fsmc_ce_ctrl(struct fsmc_nand_data *host, bool assert) > { > u32 pc = readl(host->regs_va + FSMC_PC); > > - if (!assert) > + if (!assert) { > + /* > + * Make sure all previous read/write have been done before > + * de-asserting the CE line. > + */ > + mb(); > writel_relaxed(pc & ~FSMC_ENABLE, host->regs_va + FSMC_PC); > - else > + } else { > writel_relaxed(pc | FSMC_ENABLE, host->regs_va + FSMC_PC); > - > - /* > - * nCE line changes must be applied before returning from this > - * function. > - */ > - mb(); > + /* > + * nCE assertion must be applied before returning from this > + * function. > + */ > + mb(); > + } + Will Deacon, an expert on arm mmio shenanigans. e.g. https://elinux.org/images/a/a8/Uh-oh-Its-IO-Ordering-Will-Deacon-Arm.pdf As far as I understand (which isn't very far), a memory barrier (however strong) cannot guarantee that all (posted) writes have reached a device (unless the underlying bus explicitly provides such guarantees?) At best, a memory barrier guarantees that the mmio writes have "left" the CPU and its "coherency fabric" (shared LLC). Thus subsequent accesses are guaranteed to appear "later" on the bus. (Much hand-waving sorry) I've been told that the one true way to ensure that a posted write has reached a device is simply to read the value back, i.e. writel+readl. If I'm wrong, I'd like to be schooled :-) Regards. ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/