From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932366AbdJ3J0q convert rfc822-to-8bit (ORCPT ); Mon, 30 Oct 2017 05:26:46 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:53811 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752370AbdJ3J0p (ORCPT ); Mon, 30 Oct 2017 05:26:45 -0400 Date: Mon, 30 Oct 2017 10:26:33 +0100 From: Boris Brezillon To: Chen Bin Cc: David Woodhouse , Richard Weinberger , linux-kernel@vger.kernel.org, Marek Vasut , linux-mtd@lists.infradead.org, Cyrille Pitchen , Joe Perches , Brian Norris Subject: Re: [PATCH] mtd: cfi_cmdset_0002: fix Cypress S29GL flash erase suspend Message-ID: <20171030102633.26c00bfe@bbrezillon> In-Reply-To: <1505397491-4493-1-git-send-email-chenbin5635@163.com> References: <1505397491-4493-1-git-send-email-chenbin5635@163.com> X-Mailer: Claws Mail 3.14.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Chen, On Thu, 14 Sep 2017 21:58:11 +0800 Chen Bin wrote: > On UBIFS, Cypress S29GL01GT flash is failed to access occasionally > , and throw below error information and call trace: > MTD get_chip(): chip not ready after erase suspend > UBI error: ubi_io_write: error -5 while writing 512 bytes to > PEB 932:36992, written 0 bytes > Call Trace: [jiffies: 0x10000ad9b] > [] dump_stack+0x8/0x34 > [] ubi_io_write+0x52c/0x670 > [] ubi_eba_write_leb+0xd8/0x758 > [] ubifs_leb_write+0xd0/0x178 > [] ubifs_wbuf_write_nolock+0x430/0x798 > [] ubifs_jnl_write_data+0x1e4/0x348 > [] do_writepage+0xc8/0x258 > [] __writepage+0x18/0x78 > [] write_cache_pages+0x1e0/0x4c8 > [] generic_writepages+0x40/0x78 > [] __writeback_single_inode+0x58/0x370 > [] writeback_sb_inodes+0x2e4/0x498 > [] __writeback_inodes_wb+0xc0/0x118 > [] wb_writeback+0x234/0x3c0 > [] wb_do_writeback+0x230/0x2b0 > [] bdi_writeback_workfn+0x84/0x268 > [] process_one_work+0x180/0x4d0 > [] worker_thread+0x158/0x420 > [] kthread+0xa8/0xb0 > [] ret_from_kernel_thread+0x10/0x18 > > After issue erase suspend command, flash don't go to ready state, > and fail to access consequently. > In Cypress S29GL01GT/S29GL512T flash datasheet, the type value of > Erase Resume to next Erase suspend(tERS) is 100 µs. > If Erase Suspend followed Erase Resume without enough delay time, > Erase Suspend would fail to work. > 500 μs is chosen because it works well and the latency is acceptable. > > Signed-off-by: Chen Bin > --- > drivers/mtd/chips/cfi_cmdset_0002.c | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c > index 56aa6b7..c7d18ec 100644 > --- a/drivers/mtd/chips/cfi_cmdset_0002.c > +++ b/drivers/mtd/chips/cfi_cmdset_0002.c > @@ -513,6 +513,22 @@ static void cfi_fixup_m29ew_delay_after_resume(struct cfi_private *cfi) > cfi_udelay(500); > } > > +static void cfi_fixup_delay_after_resume(struct cfi_private *cfi) > +{ > + cfi_fixup_m29ew_delay_after_resume(cfi); Can we move the content of cfi_fixup_m29ew_delay_after_resume() directly in this function? > + > + /* > + * For Cypress S29GL01GT/S29GL512T flash, the type value of > + * Erase Resume to next Erase suspend(tERS) is 100 µs. > + * If Erase Suspend followed Erase Resume without enough delay time, > + * Erase Suspend would fail to work. > + * 500 μs is chosen because it works well and the latency > + * is acceptable. > + */ > + if (cfi->mfr == CFI_MFR_AMD && (cfi->id == 0x2801 || cfi->id == 0x2301)) > + cfi_udelay(500); > +} > + > struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) > { > struct cfi_private *cfi = map->fldrv_priv; > @@ -890,7 +906,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad > cfi_fixup_m29ew_erase_suspend(map, > chip->in_progress_block_addr); > map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr); > - cfi_fixup_m29ew_delay_after_resume(cfi); > + cfi_fixup_delay_after_resume(cfi); > chip->oldstate = FL_READY; > chip->state = FL_ERASING; > break;