From patchwork Tue Feb 18 14:55:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 24864 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f71.google.com (mail-pb0-f71.google.com [209.85.160.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 345E9202B2 for ; Tue, 18 Feb 2014 14:58:26 +0000 (UTC) Received: by mail-pb0-f71.google.com with SMTP id jt11sf38937716pbb.6 for ; Tue, 18 Feb 2014 06:58:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=9/VodbMT3YgBXl3NLWs/pOaOXqkieq162rKBTmRFPhg=; b=lcKqPdygT4LUQt5czT0Uf1IC5hW9kfbrfPtiUFV7D2pwLs8aHvsXsl+XB7ht21hdJA rMxPUDQVNwlCmjdPGwT7YBhzQL3NIZGGefAQKrfpd5o8wRoV0CeTIvOUV9nej89rgMI3 Aqms0ijtHrpDoekmDlCWzP7K3m/bDw/kaTWiezSmjexsRlkE9CPCUFVLxqjs2QtaLfzW K+E+sPfBP7gRin13+SNXBN31Jvepf4BX5I3G0wb3MtDTRGGh6CV8vei+2zGzZzM+3f38 Id6c4pTJ9nckSzJYM4B4o+WOqrJG+P+A/n9BEN99v4UcaOIGdZLBCgdGHhliJ5b4+t9N umOg== X-Gm-Message-State: ALoCoQnQ5+XMf2Sz8KxiziueV/Gp6JCCwv6UdxLCucuB8ng3SD4uWirAeOMID/Qwaijpvz53IFXc X-Received: by 10.66.66.109 with SMTP id e13mr12819376pat.1.1392735506235; Tue, 18 Feb 2014 06:58:26 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.84.103 with SMTP id k94ls1298814qgd.39.gmail; Tue, 18 Feb 2014 06:58:26 -0800 (PST) X-Received: by 10.220.252.71 with SMTP id mv7mr147908vcb.68.1392735506063; Tue, 18 Feb 2014 06:58:26 -0800 (PST) Received: from mail-ve0-f172.google.com (mail-ve0-f172.google.com [209.85.128.172]) by mx.google.com with ESMTPS id 16si247108vce.12.2014.02.18.06.58.26 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 18 Feb 2014 06:58:26 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.172 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.172; Received: by mail-ve0-f172.google.com with SMTP id c14so13693691vea.31 for ; Tue, 18 Feb 2014 06:58:26 -0800 (PST) X-Received: by 10.220.225.71 with SMTP id ir7mr794866vcb.50.1392735505988; Tue, 18 Feb 2014 06:58:25 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp222623vcz; Tue, 18 Feb 2014 06:58:25 -0800 (PST) X-Received: by 10.68.93.132 with SMTP id cu4mr33367773pbb.129.1392735504513; Tue, 18 Feb 2014 06:58:24 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id zk9si18584091pac.231.2014.02.18.06.58.23; Tue, 18 Feb 2014 06:58:23 -0800 (PST) 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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932343AbaBRO5j (ORCPT + 27 others); Tue, 18 Feb 2014 09:57:39 -0500 Received: from mail-we0-f178.google.com ([74.125.82.178]:42773 "EHLO mail-we0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932328AbaBRO5d (ORCPT ); Tue, 18 Feb 2014 09:57:33 -0500 Received: by mail-we0-f178.google.com with SMTP id q59so11857518wes.9 for ; Tue, 18 Feb 2014 06:57:32 -0800 (PST) X-Received: by 10.180.164.174 with SMTP id yr14mr18465742wib.18.1392735452559; Tue, 18 Feb 2014 06:57:32 -0800 (PST) Received: from localhost.localdomain ([80.76.198.141]) by mx.google.com with ESMTPSA id h13sm46039687wjr.22.2014.02.18.06.57.30 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 18 Feb 2014 06:57:31 -0800 (PST) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: lee.jones@linaro.org, DCG_UPD_stlinux_kernel@list.st.com, dwmw2@infradead.org, linux-mtd@lists.infradead.org, computersforpeace@gmail.com, Angus.Clark@st.com Subject: [PATCH 25/35] mtd: st_spi_fsm: Add the ability to read from a Serial Flash device Date: Tue, 18 Feb 2014 14:55:52 +0000 Message-Id: <1392735362-1245-26-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1392735362-1245-1-git-send-email-lee.jones@linaro.org> References: <1392735362-1245-1-git-send-email-lee.jones@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lee.jones@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.172 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , When a read is issued by userspace the MTD framework calls back into the driver to conduct the actual command issue and data extraction. Here we provide the routines which do exactly that. Acked-by Angus Clark Signed-off-by: Lee Jones --- drivers/mtd/devices/st_spi_fsm.c | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index fe538bb..e4815fe 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c @@ -238,6 +238,9 @@ #define FLASH_CMD_READ4_1_1_4 0x6c #define FLASH_CMD_READ4_1_4_4 0xec +#define FLASH_PAGESIZE 256 /* In Bytes */ +#define FLASH_PAGESIZE_32 (FLASH_PAGESIZE / 4) /* In uint32_t */ + /* * Flags to tweak operation of default read/write/erase routines */ @@ -942,6 +945,100 @@ static int stfsm_n25q_config(struct stfsm *fsm) return 0; } +static int stfsm_read(struct stfsm *fsm, uint8_t *buf, uint32_t size, + uint32_t offset) +{ + struct stfsm_seq *seq = &stfsm_seq_read; + uint32_t data_pads; + uint32_t read_mask; + uint32_t size_ub; + uint32_t size_lb; + uint32_t size_mop; + uint32_t tmp[4]; + uint32_t page_buf[FLASH_PAGESIZE_32]; + uint8_t *p; + + dev_dbg(fsm->dev, "reading %d bytes from 0x%08x\n", size, offset); + + /* Enter 32-bit address mode, if required */ + if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR) + stfsm_enter_32bit_addr(fsm, 1); + + /* Must read in multiples of 32 cycles (or 32*pads/8 Bytes) */ + data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1; + read_mask = (data_pads << 2) - 1; + + /* Handle non-aligned buf */ + p = ((uint32_t)buf & 0x3) ? (uint8_t *)page_buf : buf; + + /* Handle non-aligned size */ + size_ub = (size + read_mask) & ~read_mask; + size_lb = size & ~read_mask; + size_mop = size & read_mask; + + seq->data_size = TRANSFER_SIZE(size_ub); + seq->addr1 = (offset >> 16) & 0xffff; + seq->addr2 = offset & 0xffff; + + stfsm_load_seq(fsm, seq); + + if (size_lb) + stfsm_read_fifo(fsm, (uint32_t *)p, size_lb); + + if (size_mop) { + stfsm_read_fifo(fsm, tmp, read_mask + 1); + memcpy(p + size_lb, &tmp, size_mop); + } + + /* Handle non-aligned buf */ + if ((uint32_t)buf & 0x3) + memcpy(buf, page_buf, size); + + /* Wait for sequence to finish */ + stfsm_wait_seq(fsm); + + stfsm_clear_fifo(fsm); + + /* Exit 32-bit address mode, if required */ + if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR) + stfsm_enter_32bit_addr(fsm, 0); + + return 0; +} + +/* + * Read an address range from the flash chip. The address range + * may be any size provided it is within the physical boundaries. + */ +static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent); + uint32_t bytes; + + dev_dbg(fsm->dev, "%s from 0x%08x, len %zd\n", + __func__, (u32)from, len); + + mutex_lock(&fsm->lock); + + while (len > 0) { + bytes = min_t(size_t, len, FLASH_PAGESIZE); + + stfsm_read(fsm, buf, bytes, from); + + buf += bytes; + from += bytes; + len -= bytes; + + if (retlen) + *retlen += bytes; + } + + mutex_unlock(&fsm->lock); + + return 0; +} + static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec) { const struct stfsm_seq *seq = &stfsm_seq_read_jedec; @@ -1198,6 +1295,8 @@ static int stfsm_probe(struct platform_device *pdev) fsm->mtd.size = info->sector_size * info->n_sectors; fsm->mtd.erasesize = info->sector_size; + fsm->mtd._read = stfsm_mtd_read; + dev_err(&pdev->dev, "Found serial flash device: %s\n" " size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",