From patchwork Tue Nov 10 05:29:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vignesh Raghavendra X-Patchwork-Id: 7588201 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E57469F9BC for ; Tue, 10 Nov 2015 05:32:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E28DF20639 for ; Tue, 10 Nov 2015 05:32:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DD46C2077E for ; Tue, 10 Nov 2015 05:32:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751870AbbKJFbu (ORCPT ); Tue, 10 Nov 2015 00:31:50 -0500 Received: from comal.ext.ti.com ([198.47.26.152]:54973 "EHLO comal.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751451AbbKJFaw (ORCPT ); Tue, 10 Nov 2015 00:30:52 -0500 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id tAA5UDre007630; Mon, 9 Nov 2015 23:30:13 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id tAA5UDto032694; Mon, 9 Nov 2015 23:30:13 -0600 Received: from dlep33.itg.ti.com (157.170.170.75) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.224.2; Mon, 9 Nov 2015 23:30:13 -0600 Received: from uda0132425.apr.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id tAA5U5vB023652; Mon, 9 Nov 2015 23:30:09 -0600 From: Vignesh R To: Mark Brown , Tony Lindgren CC: Rob Herring , Michal Suchanek , Russell King , Vignesh R , , , , , , Subject: [PATCH v3 1/5] spi: introduce mmap read support for spi flash devices Date: Tue, 10 Nov 2015 10:59:55 +0530 Message-ID: <1447133399-25658-2-git-send-email-vigneshr@ti.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1447133399-25658-1-git-send-email-vigneshr@ti.com> References: <1447133399-25658-1-git-send-email-vigneshr@ti.com> MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In addition to providing direct access to SPI bus, some spi controller hardwares (like ti-qspi) provide special memory mapped port to accesses SPI flash devices in order to increase read performance. This means the controller can automatically send the SPI signals required to read data from the SPI flash device. For this, spi controller needs to know flash specific information like read command to use, dummy bytes and address width. Once these settings are populated in hardware registers, any read accesses to flash's memory map region(SoC specific) through memcpy (or mem-to mem DMA copy) will be handled by controller hardware. The hardware will automatically generate SPI signals required to read data from flash and present it to CPU/DMA. Introduce spi_mtd_mmap_read() interface to support memory mapped read over SPI flash devices. SPI master drivers can implement this callback to support memory mapped read interfaces. m25p80 flash driver and other flash drivers can call this to request memory mapped read. The interface should only be used MTD flashes and cannot be used with other SPI devices. Signed-off-by: Vignesh R --- v3: * Remove use of mmap_lock_mutex, use bus_lock_mutex instead. drivers/spi/spi.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/spi/spi.h | 20 ++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e2415be209d5..0448d29fefc8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1134,6 +1134,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) } } + mutex_lock(&master->bus_lock_mutex); trace_spi_message_start(master->cur_msg); if (master->prepare_message) { @@ -1143,6 +1144,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) "failed to prepare message: %d\n", ret); master->cur_msg->status = ret; spi_finalize_current_message(master); + mutex_unlock(&master->bus_lock_mutex); return; } master->cur_msg_prepared = true; @@ -1152,6 +1154,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) if (ret) { master->cur_msg->status = ret; spi_finalize_current_message(master); + mutex_unlock(&master->bus_lock_mutex); return; } @@ -1159,8 +1162,10 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread) if (ret) { dev_err(&master->dev, "failed to transfer one message from queue\n"); + mutex_unlock(&master->bus_lock_mutex); return; } + mutex_unlock(&master->bus_lock_mutex); } /** @@ -2327,6 +2332,35 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message) EXPORT_SYMBOL_GPL(spi_async_locked); +int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len, + size_t *retlen, u_char *buf, u8 read_opcode, + u8 addr_width, u8 dummy_bytes) + +{ + struct spi_master *master = spi->master; + int ret; + + if (master->auto_runtime_pm) { + ret = pm_runtime_get_sync(master->dev.parent); + if (ret < 0) { + dev_err(&master->dev, "Failed to power device: %d\n", + ret); + goto err; + } + } + mutex_lock(&master->bus_lock_mutex); + ret = master->spi_mtd_mmap_read(spi, from, len, retlen, buf, + read_opcode, addr_width, + dummy_bytes); + mutex_unlock(&master->bus_lock_mutex); + if (master->auto_runtime_pm) + pm_runtime_put(master->dev.parent); + +err: + return ret; +} +EXPORT_SYMBOL_GPL(spi_mtd_mmap_read); + /*-------------------------------------------------------------------------*/ /* Utility methods for SPI master protocol drivers, layered on diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d1..2f2c431b8917 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -361,6 +361,11 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * @handle_err: the subsystem calls the driver to handle an error that occurs * in the generic implementation of transfer_one_message(). * @unprepare_message: undo any work done by prepare_message(). + * @spi_mtd_mmap_read: some spi-controller hardwares provide memory. + * Flash drivers (like m25p80) can request memory + * mapped read via this method. This interface + * should only be used by mtd flashes and cannot be + * used by other spi devices. * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS * number. Any individual value may be -ENOENT for CS lines that * are not GPIOs (driven by the SPI controller itself). @@ -507,6 +512,11 @@ struct spi_master { struct spi_message *message); int (*unprepare_message)(struct spi_master *master, struct spi_message *message); + int (*spi_mtd_mmap_read)(struct spi_device *spi, + loff_t from, size_t len, + size_t *retlen, u_char *buf, + u8 read_opcode, u8 addr_width, + u8 dummy_bytes); /* * These hooks are for drivers that use a generic implementation @@ -999,6 +1009,16 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd) return be16_to_cpu(result); } +/* SPI core interface for memory mapped read support */ +static inline bool spi_mmap_read_supported(struct spi_device *spi) +{ + return spi->master->spi_mtd_mmap_read ? true : false; +} + +int spi_mtd_mmap_read(struct spi_device *spi, loff_t from, size_t len, + size_t *retlen, u_char *buf, u8 read_opcode, + u8 addr_width, u8 dummy_bytes); + /*---------------------------------------------------------------------------*/ /*