From patchwork Tue Dec 5 18:13:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Sierra X-Patchwork-Id: 844875 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="YUfU/pg9"; 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 3yrqdW5jm1z9sxR for ; Wed, 6 Dec 2017 05:14:23 +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=KLAT8kQOvIiZioU9hrGh8C4qDsqDiSk6xGoOPmHlurM=; b=YUfU/pg9S85uxO Ic3eES2SWmJiZGrTUmX4dt+K91WElGKPGCOjONXEltdCMGZk36gm7ChGnKuXKqiv0aTVPYPuoDFKI nL8piML4+VUwfbxB7QfYexNGnGkYp569Z1I524DRbN11mGCpuiosa/j15WBmq6+JQZ3drNWNUB0Dn 3LvsGcALum6UxwR/uo5uWEgQo+nE3Xx66HBSXuq6PMa6wxVje5nENI5VvCwOctceEkk5iU4DXoIeF I5WsN65Ho2r+2n72X8RStjkFgBc0wvtoIdtFBclVZJo2TLD0MYvfkip1KHtTQGwxkqUHkBysW80lU th0k3cweUjw6zN06UgQQ==; 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 1eMHjP-0003ag-JI; Tue, 05 Dec 2017 18:14:11 +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 1eMHjM-0003a9-Es for linux-mtd@lists.infradead.org; Tue, 05 Dec 2017 18:14:10 +0000 Received: from zimbra.xes-mad.com (zimbra.xes-mad.com [10.52.0.127]) by mail.xes-mad.com (Postfix) with ESMTP id EEEAC20243; Tue, 5 Dec 2017 12:13:44 -0600 (CST) Date: Tue, 5 Dec 2017 12:13:44 -0600 (CST) From: Aaron Sierra To: Cyrille Pitchen , David Woodhouse , Brian Norris , Boris Brezillon , Richard Weinberger , Marek Vasut Message-ID: <84804381.386644.1512497624913.JavaMail.zimbra@xes-inc.com> Subject: [PATCH v2] 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 - FF57 (Linux)/8.7.5_GA_1764) Thread-Index: 9PPFk8XuAgq9THIRCp41FI8CeFlM1A== 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-20171205_101408_610450_C828661E X-CRM114-Status: UNSURE ( 6.28 ) 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 , Joe Schultz 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 | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) v2: * Removed unnecessary spi_nor_wait_till_ready() call * Renamed "new" variable to "status_new" diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index bc266f7..c3ee168 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -552,6 +552,27 @@ 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 status_new, u8 mask) +{ + int ret; + + write_enable(nor); + ret = write_sr(nor, status_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) != (status_new & mask)) ? -EIO : 0; +} + static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, uint64_t *len) { @@ -650,7 +671,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) @@ -714,11 +734,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); } /* @@ -735,7 +751,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) @@ -802,11 +817,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); } /*