From patchwork Fri Dec 7 09:26:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 1009294 X-Patchwork-Delegate: tudor.ambarus@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Mp1GQrCj"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43B6tb1lvRz9s55 for ; Fri, 7 Dec 2018 20:41:43 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=ugZacPigTAs/JJOmDCmrWyyEWIwfj89GcVIZWm4J7j8=; b=Mp1GQrCjAh3eEDlz8aeCwTBZh3 j7KhQBTaWeMMCHHPi0LO28jA4qPByx8CHY9UJHqf/iB4iZ9xKBOBJ4ZIUaZoCsApqnWURnYd50Fr7 4/hj7AXNmimCruxrXbgeUBqP8mjTp/E1P42SJ7KLCQwssnZ9NE5BtMAiE3iN4Z+BLqHlg9hv+zGHG dQ2grBwzKw5bI4MjRtErUQM4lVXPHWXEJcxG4+jwCe6F9CNhxjsvL0r5CRRNLxQv3CmXWbLbdFz/W 5ASdhobt8+/tmSBlWlAdLU7zQ7GfV5VpWRoh60zBknTTD1/QNFPW3QYAjxNzXrqIG4kxSqshjr/WU dS8jv8wg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCdU-00061N-4b; Fri, 07 Dec 2018 09:41:28 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVCPf-000101-Bx for linux-mtd@lists.infradead.org; Fri, 07 Dec 2018 09:27:21 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id D98D320DC0; Fri, 7 Dec 2018 10:26:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.2 Received: from localhost.localdomain (aaubervilliers-681-1-79-44.w90-88.abo.wanadoo.fr [90.88.21.44]) by mail.bootlin.com (Postfix) with ESMTPSA id 5B19920DBC; Fri, 7 Dec 2018 10:26:39 +0100 (CET) From: Boris Brezillon To: Tudor Ambarus , Marek Vasut Subject: [RFC PATCH 08/34] mtd: spi-nor: Add a ->convert_addr() method Date: Fri, 7 Dec 2018 10:26:11 +0100 Message-Id: <20181207092637.18687-9-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181207092637.18687-1-boris.brezillon@bootlin.com> References: <20181207092637.18687-1-boris.brezillon@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181207_012712_424484_5CEAF10B X-CRM114-Status: GOOD ( 17.42 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yogesh Narayan Gaur , Vignesh R , Richard Weinberger , Boris Brezillon , linux-mtd@lists.infradead.org, Miquel Raynal , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In order to separate manufacturer quirks from the core we need to get rid of all the manufacturer specific flags, like the SNOR_F_S3AN_ADDR_DEFAULT one. This can easily be replaced by a ->convert_addr() hook, which when implemented will provide the core with an easy way to convert an absolute address into something the flash understands. Right now the only user are the S3AN chips, but other manufacturers can implement it if needed. Signed-off-by: Boris Brezillon --- drivers/mtd/spi-nor/spi-nor.c | 24 ++++++++++++++---------- include/linux/mtd/spi-nor.h | 17 ++++++++++------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index ffea0085b4fe..f6b1c9b8079a 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -622,10 +622,9 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) * Addr can safely be unsigned int, the biggest S3AN device is smaller than * 4 MiB. */ -static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) +static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr) { - unsigned int offset; - unsigned int page; + u32 offset, page; offset = addr % nor->page_size; page = addr / nor->page_size; @@ -634,6 +633,14 @@ static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) return page | offset; } +static u32 spi_nor_convert_addr(struct spi_nor *nor, u32 addr) +{ + if (!nor->convert_addr) + return addr; + + return nor->convert_addr(nor, addr); +} + /* * Initiate the erasure of a single sector */ @@ -642,8 +649,7 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) u8 buf[SPI_NOR_MAX_ADDR_WIDTH]; int i; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); if (nor->erase) return nor->erase(nor, addr); @@ -2054,8 +2060,7 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, while (len) { loff_t addr = from; - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); ret = nor->read(nor, addr, len, buf); if (ret == 0) { @@ -2199,8 +2204,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, page_remain = min_t(size_t, nor->page_size - page_offset, len - i); - if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) - addr = spi_nor_s3an_addr_convert(nor, addr); + addr = spi_nor_convert_addr(nor, addr); write_enable(nor); ret = nor->write(nor, addr, page_remain, buf + i); @@ -2266,7 +2270,7 @@ static int s3an_nor_scan(struct spi_nor *nor) nor->mtd.erasesize = 8 * nor->page_size; } else { /* Flash in Default addressing mode */ - nor->flags |= SNOR_F_S3AN_ADDR_DEFAULT; + nor->convert_addr = s3an_convert_addr; } return 0; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 73dad2a77455..2c8fbd5d614d 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -229,13 +229,12 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB = BIT(1), SNOR_F_NO_OP_CHIP_ERASE = BIT(2), - SNOR_F_S3AN_ADDR_DEFAULT = BIT(3), - SNOR_F_READY_XSR_RDY = BIT(4), - SNOR_F_USE_CLSR = BIT(5), - SNOR_F_BROKEN_RESET = BIT(6), - SNOR_F_4B_OPCODES = BIT(7), - SNOR_F_HAS_LOCK = BIT(8), - SNOR_F_CLR_SW_PROT_BITS = BIT(9), + SNOR_F_READY_XSR_RDY = BIT(3), + SNOR_F_USE_CLSR = BIT(4), + SNOR_F_BROKEN_RESET = BIT(5), + SNOR_F_4B_OPCODES = BIT(6), + SNOR_F_HAS_LOCK = BIT(7), + SNOR_F_CLR_SW_PROT_BITS = BIT(8), }; /** @@ -365,6 +364,9 @@ struct flash_info; * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @set_4byte: [FLASH-SPECIFIC] put the SPI NOR in 4 byte addressing * mode + * @convert_addr: [FLASH-SPECIFIC] convert an absolute address into + * something the flash will understand. Particularly + * useful when pagesize is not a power-of-2 * @locking_ops: [FLASH-SPECIFIC] SPI NOR locking methods * @priv: the private data */ @@ -400,6 +402,7 @@ struct spi_nor { int (*quad_enable)(struct spi_nor *nor); int (*set_4byte)(struct spi_nor *nor, bool enable); + u32 (*convert_addr)(struct spi_nor *nor, u32 addr); const struct spi_nor_locking_ops *locking_ops;