On Wed, 16 Jan 2019 17:21:44 +0100 Miquel Raynal <miquel.raynal@xxxxxxxxxxx> wrote: > @@ -457,13 +525,31 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); > > static inline int mtd_suspend(struct mtd_info *mtd) > { > - return mtd->_suspend ? mtd->_suspend(mtd) : 0; > + struct mtd_info *master = mtd_get_master(mtd); > + int ret; > + > + if (master->suspended) > + return 0; > + > + ret = master->_suspend ? master->_suspend(master) : 0; > + if (ret) > + return ret; > + > + master->suspended = 1; It's not entirely clear to me whether dev->suspend() hooks can be called simultaneously on several CPUs or not, if that's the case, we should use an atomic_t for the ->suspended field and use the atomic_add_unless() function when manipulating it. if (!atomic_add_unless(&master->suspended, 1, 1)) return 0; ret = master->_suspend ? master->_suspend(master) : 0; if (ret) { atomic_dec(&master->suspended); return ret; } > + return 0; > } > > static inline void mtd_resume(struct mtd_info *mtd) > { > - if (mtd->_resume) > - mtd->_resume(mtd); > + struct mtd_info *master = mtd_get_master(mtd); > + > + if (!master->suspended) > + return; > + > + if (master->_resume) > + master->_resume(master); > + > + master->suspended = 0; Same here: if (!atomic_add_unless(&master->suspended, -1, 0)) return; if (master->_resume) master->_resume(master); > } ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/