From patchwork Sun Oct 29 16:11:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Sierra X-Patchwork-Id: 831760 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="eJUVqIUA"; 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 3yQ2hJ3Yc6z9sBW for ; Mon, 30 Oct 2017 03:12:45 +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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Subject:Message-ID:To:From :Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=bX6SY+s1w+cYNa7Er1a9myTnDHqG+V5PjeZLMKIrdPQ=; b=eJUVqIUAOk3O9V +w9WhECjjoDt6WPmlVz9lk8X+ei8Ndki1i3dkFt4FnjEuhj1KJV02S+eha68SM3HfZ+Au+2xLh/sq 3yA8cVJKC/vhXehF3ITrZgbWD5GhRkCldC/YJUDbgBB3VRg/xjGHqta+ykUxRwfXsu2zgSHb5IaqJ XUnL/f5bUf6CzHdRdWHvbBql4sYdEZWwpEMS9AZRmOZs/d0QHBs5EaAehsiZu3ABm3mbo71exB2/2 pN4BwhlyV2xU4ROnNDmFsF4KN37nHSUOkJoIvKVvV0F+/G0iLUe/0Ft0u7EmYhkdMOQQhuDWzcNyQ NL6yaK6Hj21M1mHUf2qQ==; 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 1e8qCR-0005Nx-V5; Sun, 29 Oct 2017 16:12:35 +0000 Received: from xes-mad.com ([216.165.139.220] helo=mail.xes-mad.com) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1e8qC2-0005KP-Tr for linux-mtd@lists.infradead.org; Sun, 29 Oct 2017 16:12:13 +0000 Received: from zimbra.xes-mad.com (zimbra.xes-mad.com [10.52.0.127]) by mail.xes-mad.com (Postfix) with ESMTP id 18C8F2063A; Sun, 29 Oct 2017 11:11:42 -0500 (CDT) Date: Sun, 29 Oct 2017 11:11:42 -0500 (CDT) From: Aaron Sierra To: David Woodhouse , Brian Norris , Boris Brezillon , Richard Weinberger , Cyrille Pitchen , Marek Vasut Message-ID: <763349437.151011.1509293502020.JavaMail.zimbra@xes-inc.com> Subject: [PATCH] mtd: spi-nor: Check that BP bits are set properly MIME-Version: 1.0 X-Originating-IP: [10.52.0.127] X-Mailer: Zimbra 8.7.5_GA_1764 (ZimbraWebClient - FF54 (Linux)/8.7.5_GA_1764) Thread-Index: 54/MwiLZTtiif54sBSJIgMMV7P2Ekg== Thread-Topic: spi-nor: Check that BP bits are set properly X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171029_091211_083676_1C0F813E X-CRM114-Status: UNSURE ( 7.04 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 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: linux-mtd@lists.infradead.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Previously, the lock and unlock functions returned success even if the BP bits were not actually updated in the status register due to hardware write protection. Introduce write_sr_and_check() to write and read back the status register to ensure the desired BP bits are actually set as requested. Signed-off-by: Joe Schultz Signed-off-by: Aaron Sierra --- drivers/mtd/spi-nor/spi-nor.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 19c00072..8a87bd1 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -550,6 +550,31 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) return ret; } +/* Write status register and ensure bits in mask match written values */ +static int write_sr_and_check(struct spi_nor *nor, u8 new, u8 mask) +{ + int ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + write_enable(nor); + ret = write_sr(nor, new); + if (ret) + return ret; + + ret = spi_nor_wait_till_ready(nor); + if (ret) + return ret; + + ret = read_sr(nor); + if (ret < 0) + return ret; + + return ((ret & mask) != (new & mask)) ? -EIO : 0; +} + static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, uint64_t *len) { @@ -648,7 +673,6 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) loff_t lock_len; bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; bool use_top; - int ret; status_old = read_sr(nor); if (status_old < 0) @@ -712,11 +736,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) if ((status_new & mask) < (status_old & mask)) return -EINVAL; - write_enable(nor); - ret = write_sr(nor, status_new); - if (ret) - return ret; - return spi_nor_wait_till_ready(nor); + return write_sr_and_check(nor, status_new, mask); } /* @@ -733,7 +753,6 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) loff_t lock_len; bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB; bool use_top; - int ret; status_old = read_sr(nor); if (status_old < 0) @@ -800,11 +819,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) if ((status_new & mask) > (status_old & mask)) return -EINVAL; - write_enable(nor); - ret = write_sr(nor, status_new); - if (ret) - return ret; - return spi_nor_wait_till_ready(nor); + return write_sr_and_check(nor, status_new, mask); } /*