Received: by 2002:a25:b794:0:0:0:0:0 with SMTP id n20csp2579200ybh; Mon, 5 Aug 2019 03:22:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqwIoe+DYfRuUAbzDnmcH97GBhhbRIWaH3vachoms01TtbhzmNClpN4qz5xXF7rV5TZoIHP6 X-Received: by 2002:a63:4c46:: with SMTP id m6mr139780243pgl.59.1565000563517; Mon, 05 Aug 2019 03:22:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565000563; cv=none; d=google.com; s=arc-20160816; b=oZCkyZ/c4KDY4uG19TDAgqi4mQ8HQfAKuRICoe7Kfm8n2ATDlVV8LkhV7mQ2MoltXa k9L83d83ba1ksZNinDqUqINTzv1z1bYtSm7Ro129JE4F7Ca2VwBnti/3PDKAxKelUic3 0g9t+rMGkbw44bZYxRH4RIAjNuIkmEBeT9/ijyuodORIowqW9igDXHK4J18AZMwdgrzU dsAFXWppQ4JSRQRk1//dEZPjqjF3svvXj1RkQTfB1svOn8tdQtOy9/FwMdDaogPlOhD9 rn/zan5EE1ZGgLK2w4oSkpOoES2c5TezhTzKwOS4HyuW0djAe/X7OcXSgvU42DBb/vNv OxJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:to:from:dkim-signature; bh=abvBm3ejtMnYT3sN09H6tZJ7+2C7h+kf6cOB3CVgCSI=; b=qeXmk6Uces+ympzvh2sk+QtTMPXt8wgkJa1ToGK2+cp4PsqL23/BnNM6lUPzrJUgdO QY5ocJFtG2IzMaZkqkb/DUi3eFwIdaj9JOjY3HGaI0sEXj2egdoaoLjFQDv18tfD8AkS thZIQCP0Gm2jDmbx4nIyDqrQdl/kwzl+w3+PT3n/sMJe9J3wx0mqi5mBZUdRigNNS9lK R7eBHkWvSQ1uPn7/5VZzFWVnMRs4ndsAsZH9dGLiNXBgvnRtfIdQiy21XUv4n2JPgwg6 S10UBejEo+7VOfWkr5J9r/y9T2DvX6az2lKj/c/5HTue1CNG2+ZvMCwhs8pIop8MUJEj L1lQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@devtank-co-uk.20150623.gappssmtp.com header.s=20150623 header.b=mcQ6vKh4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o4si40607007plb.274.2019.08.05.03.22.27; Mon, 05 Aug 2019 03:22:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@devtank-co-uk.20150623.gappssmtp.com header.s=20150623 header.b=mcQ6vKh4; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728148AbfHEKVe (ORCPT + 99 others); Mon, 5 Aug 2019 06:21:34 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:46094 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727158AbfHEKVe (ORCPT ); Mon, 5 Aug 2019 06:21:34 -0400 Received: by mail-wr1-f65.google.com with SMTP id z1so83822944wru.13 for ; Mon, 05 Aug 2019 03:21:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=devtank-co-uk.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=abvBm3ejtMnYT3sN09H6tZJ7+2C7h+kf6cOB3CVgCSI=; b=mcQ6vKh4V1pIdCuy/h49S6XFfD5777/lYEkQ2Pm9Awje0DmNIZHDf8RfViFEl4Moap 8DlTzeByUVPTa8W/qlakH3cJxYF/XVxmIyJ49d0oAGgXSmSKz8A6XobSiZn76ACGM2M4 O0z3B1nXGWCbnRv8FxndRuA3NZlRd3azE64HGUEdWtHQQcJVSqdYyO45YF6a4PJs3BL8 /qO5hvvmVEk1eBx7syaWjTUfb/wWtxmmZxgmnrMpjZZmdisjxk6VuWMYo1V7oCH77h1R wRDGEZVi48E1uYGiMNGOantNYcld3u5+DMomgk/m1NwhpGYrqv9+lWBB2yD6Ef0dsyAf WWzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=abvBm3ejtMnYT3sN09H6tZJ7+2C7h+kf6cOB3CVgCSI=; b=RfHjlgvnzssNRyBcbHegmU5GlEmnYaS9JQarfGLMIlr4/dW6hUoCERvNTGO/sFj7pa xNNFlT1bnpDomxIQzrZB5UMdiEQrPY1j3gXMsyBvSt+x8ArDFJpSUNj6iKGBJE5yWksj Dq05jSaasuh0roVzWiM4PKmt9YOrbaO/VJRWCXzIMeSrYzId3e+bTad3Wk9Anzys+R5T 7YF+LiuQlbI9aL7a/atAiAj+8zMrriAlYYU2NJjMMgAP5rdLWFw8wDCJRVSodBDasXiZ 232IDWcR1p0nlgyoEZoi//2ypQdyzxccYSmW/0c0cDiV/fgaFhbbWXI4TftixsdRo3+4 8rbg== X-Gm-Message-State: APjAAAUAfENeBCdvm/J9PPvq8GcOvcR1VWRvarfYSOMAbEMQobIVta7k bkSSS1/1wPVngENOj4kKTjaHFZYz X-Received: by 2002:a5d:4fc9:: with SMTP id h9mr35915348wrw.349.1565000492062; Mon, 05 Aug 2019 03:21:32 -0700 (PDT) Received: from jabjoe-thinkpad.lan ([141.105.200.141]) by smtp.googlemail.com with ESMTPSA id w7sm98116105wrn.11.2019.08.05.03.21.31 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 05 Aug 2019 03:21:31 -0700 (PDT) From: Joe Burmeister To: joe.burmeister@devtank.co.uk, Arnd Bergmann , Greg Kroah-Hartman , YueHaibing , Bartosz Golaszewski , Geert Uytterhoeven , linux-kernel@vger.kernel.org Subject: [PATCH] Add erase interface for AT25 driver. Date: Mon, 5 Aug 2019 11:21:26 +0100 Message-Id: <20190805102127.19624-1-joe.burmeister@devtank.co.uk> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Joe Burmeister --- drivers/misc/eeprom/at25.c | 75 +++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 99de6939cd5a..b1fb3bfd935d 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -43,6 +43,7 @@ struct at25_data { #define AT25_WRSR 0x01 /* write status register */ #define AT25_READ 0x03 /* read byte(s) */ #define AT25_WRITE 0x02 /* write byte(s)/sector */ +#define AT25_CHIP_ERASE 0x62 /* Erase whole chip */ #define AT25_SR_nRDY 0x01 /* nRDY = write-in-progress */ #define AT25_SR_WEN 0x02 /* write enable (latched) */ @@ -52,6 +53,7 @@ struct at25_data { #define AT25_INSTR_BIT3 0x08 /* Additional address bit in instr */ + #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ /* Specs often allow 5 msec for a page write, sometimes 20 msec; @@ -59,6 +61,8 @@ struct at25_data { */ #define EE_TIMEOUT 25 +#define ERASE_TIMEOUT 2020 + /*-------------------------------------------------------------------------*/ #define io_limit PAGE_SIZE /* bytes */ @@ -304,6 +308,71 @@ static int at25_fw_to_chip(struct device *dev, struct spi_eeprom *chip) return 0; } +static void _eeprom_at25_store_erase_locked(struct at25_data *at25) +{ + unsigned long timeout, retries; + int sr, status; + u8 cp; + + cp = AT25_WREN; + status = spi_write(at25->spi, &cp, 1); + if (status < 0) { + dev_dbg(&at25->spi->dev, "ERASE WREN --> %d\n", status); + return; + } + cp = AT25_CHIP_ERASE; + status = spi_write(at25->spi, &cp, 1); + if (status < 0) { + dev_dbg(&at25->spi->dev, "CHIP_ERASE --> %d\n", status); + return; + } + /* Wait for non-busy status */ + timeout = jiffies + msecs_to_jiffies(ERASE_TIMEOUT); + retries = 0; + do { + sr = spi_w8r8(at25->spi, AT25_RDSR); + if (sr < 0 || (sr & AT25_SR_nRDY)) { + dev_dbg(&at25->spi->dev, + "rdsr --> %d (%02x)\n", sr, sr); + /* at HZ=100, this is sloooow */ + msleep(1); + continue; + } + if (!(sr & AT25_SR_nRDY)) + return; + } while (retries++ < 200 || time_before_eq(jiffies, timeout)); + + if ((sr < 0) || (sr & AT25_SR_nRDY)) { + dev_err(&at25->spi->dev, + "chip erase, timeout after %u msecs\n", + jiffies_to_msecs(jiffies - + (timeout - ERASE_TIMEOUT))); + status = -ETIMEDOUT; + return; + } +} + + +static ssize_t eeprom_at25_store_erase(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct at25_data *at25 = dev_get_drvdata(dev); + int erase = 0; + + sscanf(buf, "%d", &erase); + if (erase) { + mutex_lock(&at25->lock); + _eeprom_at25_store_erase_locked(at25); + mutex_unlock(&at25->lock); + } + + return count; +} + +static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_at25_store_erase); + + static int at25_probe(struct spi_device *spi) { struct at25_data *at25 = NULL; @@ -376,11 +445,15 @@ static int at25_probe(struct spi_device *spi) at25->chip.name, (chip.flags & EE_READONLY) ? " (readonly)" : "", at25->chip.page_size); + + if (!(chip.flags & EE_READONLY)) + if (device_create_file(&spi->dev, &dev_attr_erase)) + dev_err(&spi->dev, "can't create erase interface\n"); + return 0; } /*-------------------------------------------------------------------------*/ - static const struct of_device_id at25_of_match[] = { { .compatible = "atmel,at25", }, { } -- 2.20.1