Hi Boris, Boris Brezillon <bbrezillon@xxxxxxxxxx> wrote on Mon, 21 Jan 2019 09:51:20 +0100: > 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); > > } I don't know if this is necessary but I made the changes. I also had to change "suspended" type from unsigned int bitfield to atomic_t. Thanks, Miquèl ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/