From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6647B423A7C; Tue, 31 Mar 2026 16:31:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774974685; cv=none; b=RrFdrwyHT1W3sSIcqVfUTROb/F6TkoHj4WRtsN0NkKzYBkzYvYE7q7J0+KxNtrqQWn4rutxzG235LjiF4iivtFf1y56aUuPxkO8OPGdwwIS41lET3pRVGI2hjciC0qvtzniHvFJA3DIh4Eti1Fy4lkSStHH3fvaEnuHDhB49Xz4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774974685; c=relaxed/simple; bh=r/sZj+GHxtReJFVBwG4TI7/nyH8DYzfiQZbcye9an0g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TnKFT5mavKfM2RACR3svwtBXUeP7o6Pryxnek++UJStr7XWsPXTiGVE/WdM2w3JR9w0N1HB1fGBqBxp/z6xl+kt6eXGX5KdeF3sURUcyH1GLmz6dllNqsrfg2b+YmhjqobzzrlYlwSvcJPaD5WL3agc59fQTI1VaiqSzbfkuWSY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=IEETJJt9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="IEETJJt9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F28A2C4AF0B; Tue, 31 Mar 2026 16:31:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1774974685; bh=r/sZj+GHxtReJFVBwG4TI7/nyH8DYzfiQZbcye9an0g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IEETJJt97qJ/eqDCg8a3blFVbyDuB4QP8DgrjQ81BUxJbet/m0LVZIsHynp5teDRo 8TG9J5EOeVr4GrEsBuIk1FNwMUNjFKz2pJkGY8oBxZCBwL4CmBVOK5fhSt338AI3B5 dCCbHpLXwa9cmAvCmNLOyehyqzrwSZxIj3l9xSts= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Pratyush Yadav , Michael Walle , Luke Wang , Pratyush Yadav , Liyin Zhang Subject: [PATCH 6.6 151/175] mtd: spi-nor: core: avoid odd length/address writes in 8D-8D-8D mode Date: Tue, 31 Mar 2026 18:22:15 +0200 Message-ID: <20260331161735.338721646@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260331161729.779738837@linuxfoundation.org> References: <20260331161729.779738837@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.6-stable review patch. If anyone has any objections, please let me know. ------------------ From: Pratyush Yadav [ Upstream commit 17926cd770ec837ed27d9856cf07f2da8dda4131 ] On Octal DTR capable flashes like Micron Xcella the writes cannot start or end at an odd address in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to make sure the start address and end address are even. 0xff is used because on NOR flashes a program operation can only flip bits from 1 to 0, not the other way round. 0 to 1 flip needs to happen via erases. Signed-off-by: Pratyush Yadav Reviewed-by: Michael Walle Signed-off-by: Luke Wang Signed-off-by: Pratyush Yadav Link: https://lore.kernel.org/r/20250708091646.292-2-ziniu.wang_1@nxp.com Signed-off-by: Liyin Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/spi-nor/core.c | 69 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -2199,6 +2199,68 @@ read_err: } /* + * On Octal DTR capable flashes, writes cannot start or end at an odd address + * in Octal DTR mode. Extra 0xff bytes need to be appended or prepended to + * make sure the start address and end address are even. 0xff is used because + * on NOR flashes a program operation can only flip bits from 1 to 0, not the + * other way round. 0 to 1 flip needs to happen via erases. + */ +static int spi_nor_octal_dtr_write(struct spi_nor *nor, loff_t to, size_t len, + const u8 *buf) +{ + u8 *tmp_buf; + size_t bytes_written; + loff_t start, end; + int ret; + + if (IS_ALIGNED(to, 2) && IS_ALIGNED(len, 2)) + return spi_nor_write_data(nor, to, len, buf); + + tmp_buf = kmalloc(nor->params->page_size, GFP_KERNEL); + if (!tmp_buf) + return -ENOMEM; + + memset(tmp_buf, 0xff, nor->params->page_size); + + start = round_down(to, 2); + end = round_up(to + len, 2); + + memcpy(tmp_buf + (to - start), buf, len); + + ret = spi_nor_write_data(nor, start, end - start, tmp_buf); + if (ret == 0) { + ret = -EIO; + goto out; + } + if (ret < 0) + goto out; + + /* + * More bytes are written than actually requested, but that number can't + * be reported to the calling function or it will confuse its + * calculations. Calculate how many of the _requested_ bytes were + * written. + */ + bytes_written = ret; + + if (to != start) + ret -= to - start; + + /* + * Only account for extra bytes at the end if they were actually + * written. For example, if for some reason the controller could only + * complete a partial write then the adjustment for the extra bytes at + * the end is not needed. + */ + if (start + bytes_written == end) + ret -= end - (to + len); + +out: + kfree(tmp_buf); + return ret; +} + +/* * Write an address range to the nor chip. Data must be written in * FLASH_PAGESIZE chunks. The address range may be any size provided * it is within the physical boundaries. @@ -2248,7 +2310,12 @@ static int spi_nor_write(struct mtd_info goto write_err; } - ret = spi_nor_write_data(nor, addr, page_remain, buf + i); + if (nor->write_proto == SNOR_PROTO_8_8_8_DTR) + ret = spi_nor_octal_dtr_write(nor, addr, page_remain, + buf + i); + else + ret = spi_nor_write_data(nor, addr, page_remain, + buf + i); spi_nor_unlock_device(nor); if (ret < 0) goto write_err;