From patchwork Tue Aug 1 22:41:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Dasu X-Patchwork-Id: 796414 X-Patchwork-Delegate: cyrille.pitchen@atmel.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=65.50.211.133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="c8/+tPrb"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="rUdAPnGX"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 3xMWY612Y8z9t0F for ; Wed, 2 Aug 2017 08:42:34 +1000 (AEST) 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=QSDkYaj5t8l1No8iUqZYwQZMLQPyunLGceN4O+ihJkw=; b=c8/+tPrbdMaUXOxTTZ+NEp0VZ5 6g5v+R2xyLsV8Me7dOe8/YLDzvEX+qKBxAFJRgG0Rje6cU002cm9xTxtOyL6oevlD9sGAQkQyph7D UrGihL/R63B7GtEoL9NT0ie3muGvsZATdN0F20SlRlEaj0Jwv80BncWGyvo4ReW594GJnx1xblUql WdmiLAQmbHqVRPOX8Xh/OvhYszAaDMqNWRfMRiIQbiZKdm8lnmtp6vDUHbu1mclyLrapUE1wC8Xnd PSFyeBPz/9ql7uftvpEdzs8ghu7OnCp5GilEHzMfHcBOE2SHSPcn+BLkBMP1/yv3FyAzrXSHIxFB4 VbakSKyA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dcfrv-0005s7-Rm; Tue, 01 Aug 2017 22:42:27 +0000 Received: from mail-qt0-x242.google.com ([2607:f8b0:400d:c0d::242]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dcfrp-0005ml-Ig for linux-mtd@lists.infradead.org; Tue, 01 Aug 2017 22:42:23 +0000 Received: by mail-qt0-x242.google.com with SMTP id t37so3047677qtg.2 for ; Tue, 01 Aug 2017 15:42:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LwNctGRbI4lpHda0WBeWQkXgEoQGz+xrGy8yeNQY7I0=; b=rUdAPnGX3/nzBRuSQg9lJZBRR4J0quYn7dBcEsAfMj4ysCzhyDldwEVj09BlDat5Q5 Dzi1ifS/XIPiXsMQlvzpuoVbkR3iml4db60XMHTMGLsHZIwZhMDmQHfOwUVJl9XgDlAv 7HzzPDDau6UikmZp5VtZUzoZ8DZ/HqdwUg+mvJtozcsO479XnUFxwTZlet/WXfGFq8HK 2h4hrUc/EhLkmbtJ5SQmSkfYQ08L5MpFD/IE4RauE5emZvTQjNQCAxP4vTF5GWsVW0oz 3LMMBXGtA+VTCXjHG1PWZZUr1i4qLleFrx4X/k1ge6YQvbGQb0NHtjBuItlmXhVjE1eS 792Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=LwNctGRbI4lpHda0WBeWQkXgEoQGz+xrGy8yeNQY7I0=; b=QKvL4iFQRtuPMiw8ZejtRbfxw/nucLNP1A2BwvbOZxVZb+AAqHF1TcX+BnPVCpCiyf INzagK8ygoEG+O4unO5aFhlWkMiECCwA3jm6Xew/4GYAeEdAHY4wBIU8JhuXAraUecPK kgUQhdQX46353u3Cq9rwcR+RKNLQUtI/KsdIrZ91Rgpp6/YWALpfBgCaB+TQfJkZg0f3 I2KoCvd+F7Mmhc3J9voHdJ0Jr1BJX+Nmiy0Q9mWJDgfIKdxhljOv/Nt4xZMZZI4rbwmG LFHRfhWkyjdweYVzK7Q8mktCBFlIbMkVsakX+F769GnURsOC8eXWGC6Q/6J/wsjv3V2m 8x4w== X-Gm-Message-State: AIVw112gK8M0yfya9FKaic48Q1b2EF0HL8tb35LMmHriRI1gtZoBoWq5 eMTKJ3U4ubW7sw== X-Received: by 10.237.33.204 with SMTP id m12mr29827440qtc.249.1501627324985; Tue, 01 Aug 2017 15:42:04 -0700 (PDT) Received: from mail.broadcom.com ([192.19.231.250]) by smtp.gmail.com with ESMTPSA id k36sm4233176qtc.41.2017.08.01.15.42.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 01 Aug 2017 15:42:04 -0700 (PDT) From: Kamal Dasu To: cyrille.pitchen@wedev4u.fr, marek.vasut@gmail.com Subject: [PATCH v7 1/2] mtd: spi-nor: add spi_nor_init() function Date: Tue, 1 Aug 2017 18:41:15 -0400 Message-Id: <1501627276-4567-2-git-send-email-kdasu.kdev@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1501627276-4567-1-git-send-email-kdasu.kdev@gmail.com> References: <1501627276-4567-1-git-send-email-kdasu.kdev@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170801_154221_776813_99FB19EB X-CRM114-Status: GOOD ( 20.19 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400d:c0d:0:0:0:242 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (kdasu.kdev[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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: boris.brezillon@free-electrons.com, f.fainelli@gmail.com, Kamal Dasu , richard@nod.at, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, bcm-kernel-feedback-list@broadcom.com, computersforpeace@gmail.com MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This patch extracts some chunks from spi_nor_init_params and spi_nor_scan() and moves them into a new spi_nor_init() function. Indeed, spi_nor_init() regroups all the required SPI flash commands to be sent to the SPI flash memory before performing any runtime operations (Fast Read, Page Program, Sector Erase, ...). Hence spi_nor_init(): 1) removes the flash protection if applicable for certain vendors. 2) sets the Quad Enable bit, if needed, before using Quad SPI protocols. 3) makes the memory enter its (stateful) 4-byte address mode, if needed, for SPI flash memory > 128Mbits not supporting the 4-byte address instruction set. spi_nor_scan() now ends by calling spi_nor_init() once the probe phase has completed. Further patches could also use spi_nor_init() to implement the mtd->_resume() handler for the spi-nor framework. Signed-off-by: Kamal Dasu --- drivers/mtd/spi-nor/spi-nor.c | 62 ++++++++++++++++++++++++++++++------------- include/linux/mtd/spi-nor.h | 9 +++++++ 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1413828..10033ed 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1784,7 +1784,6 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, const struct spi_nor_hwcaps *hwcaps) { u32 ignored_mask, shared_mask; - bool enable_quad_io; int err; /* @@ -1829,20 +1828,42 @@ static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info, return err; } - /* Enable Quad I/O if needed. */ - enable_quad_io = (spi_nor_get_protocol_width(nor->read_proto) == 4 || - spi_nor_get_protocol_width(nor->write_proto) == 4); - if (enable_quad_io && params->quad_enable) { - err = params->quad_enable(nor); + return 0; +} + +static int spi_nor_init(struct spi_nor *nor) +{ + int err; + + /* + * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up + * with the software protection bits set + */ + if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL || + JEDEC_MFR(nor->info) == SNOR_MFR_INTEL || + JEDEC_MFR(nor->info) == SNOR_MFR_SST || + nor->info->flags & SPI_NOR_HAS_LOCK) { + write_enable(nor); + write_sr(nor, 0); + spi_nor_wait_till_ready(nor); + } + + if (nor->quad_enable) { + err = nor->quad_enable(nor); if (err) { dev_err(nor->dev, "quad mode not supported\n"); return err; } } + if ((JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) && + !(nor->info->flags & SPI_NOR_4B_OPCODES)) + set_4byte(nor, nor->info, 1); + return 0; } + int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { @@ -1853,6 +1874,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, struct device_node *np = spi_nor_get_flash_node(nor); int ret; int i; + bool enable_quad_io; ret = spi_nor_check(nor); if (ret) @@ -1915,15 +1937,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, * with the software protection bits set */ - if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || - JEDEC_MFR(info) == SNOR_MFR_INTEL || - JEDEC_MFR(info) == SNOR_MFR_SST || - info->flags & SPI_NOR_HAS_LOCK) { - write_enable(nor); - write_sr(nor, 0); - spi_nor_wait_till_ready(nor); - } - if (!mtd->name) mtd->name = dev_name(dev); mtd->priv = nor; @@ -2002,8 +2015,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (JEDEC_MFR(info) == SNOR_MFR_SPANSION || info->flags & SPI_NOR_4B_OPCODES) spi_nor_set_4byte_opcodes(nor, info); - else - set_4byte(nor, info, 1); } else { nor->addr_width = 3; } @@ -2020,8 +2031,21 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, return ret; } - dev_info(dev, "%s (%lld Kbytes)\n", info->name, - (long long)mtd->size >> 10); + /* Send all the required SPI flash commands to initialize device */ + nor->info = info; + /* Enable Quad I/O if needed. */ + enable_quad_io = (spi_nor_get_protocol_width(nor->read_proto) == 4 || + spi_nor_get_protocol_width(nor->write_proto) == 4); + if (enable_quad_io && params.quad_enable) + nor->quad_enable = params.quad_enable; + + ret = spi_nor_init(nor); + if (ret) + return ret; + + dev_info(dev, "%s (%lld Kbytes), %dByte addr, %s\n", info->name, + (long long)mtd->size >> 10, nor->addr_width, + (nor->quad_enable ? "quad io enabled" : "quad io disabled")); dev_dbg(dev, "mtd .name = %s, .size = 0x%llx (%lldMiB), " diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 55faa2f..db127b8 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -220,11 +220,17 @@ enum spi_nor_option_flags { SNOR_F_READY_XSR_RDY = BIT(4), }; +/* struct flash_info - Forward declaration of a structure used internally by + * spi_nor_scan() + */ +struct flash_info; + /** * struct spi_nor - Structure for defining a the SPI NOR layer * @mtd: point to a mtd_info structure * @lock: the lock for the read/write/erase/lock/unlock operations * @dev: point to a spi device, or a spi nor controller device. + * @info: spi-nor part JDEC MFR id and other info * @page_size: the page size of the SPI NOR * @addr_width: number of address bytes * @erase_opcode: the opcode for erasing a sector @@ -251,6 +257,7 @@ enum spi_nor_option_flags { * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is + * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * completely locked * @priv: the private data */ @@ -258,6 +265,7 @@ struct spi_nor { struct mtd_info mtd; struct mutex lock; struct device *dev; + const struct flash_info *info; u32 page_size; u8 addr_width; u8 erase_opcode; @@ -285,6 +293,7 @@ struct spi_nor { int (*flash_lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); + int (*quad_enable)(struct spi_nor *nor); void *priv; };