From patchwork Mon Dec 14 15:20:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sperl X-Patchwork-Id: 7845391 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 2905C9F32E for ; Mon, 14 Dec 2015 15:21:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 139DB202EC for ; Mon, 14 Dec 2015 15:21:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C0008203F4 for ; Mon, 14 Dec 2015 15:21:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751654AbbLNPUn (ORCPT ); Mon, 14 Dec 2015 10:20:43 -0500 Received: from 212-186-180-163.dynamic.surfer.at ([212.186.180.163]:39371 "EHLO cgate.sperl.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752489AbbLNPUm (ORCPT ); Mon, 14 Dec 2015 10:20:42 -0500 Received: from raspcm.intern.sperl.org (account martin@sperl.org [10.10.10.41] verified) by sperl.org (CommuniGate Pro SMTP 6.1.2) with ESMTPSA id 6361180; Mon, 14 Dec 2015 15:20:32 +0000 From: kernel@martin.sperl.org To: Mark Brown , Stephen Warren , Lee Jones , Eric Anholt , linux-spi@vger.kernel.org, linux-rpi-kernel@lists.infradead.org Cc: Martin Sperl Subject: [PATCH v3 7/8] spi: core: add spi_master.min_dma_len and supporting methods Date: Mon, 14 Dec 2015 15:20:24 +0000 Message-Id: <1450106426-2277-8-git-send-email-kernel@martin.sperl.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1450106426-2277-1-git-send-email-kernel@martin.sperl.org> References: <1450106426-2277-1-git-send-email-kernel@martin.sperl.org> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 From: Martin Sperl Added spi_master.min_dma_len plus methods requireing this information: * spi_translate_message_size_align_merge * spi_can_dma_min_dma_len Signed-off-by: Martin Sperl --- drivers/spi/spi.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/spi/spi.h | 14 +++++++++- 2 files changed, 79 insertions(+), 1 deletion(-) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 020e34d..883bfa8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -277,6 +277,27 @@ void spi_statistics_add_transfer_stats(struct spi_statistics *stats, } EXPORT_SYMBOL_GPL(spi_statistics_add_transfer_stats); +/** + * spi_can_dma_min_dma_len - default implementation for spi_can_dma + * that only checks spi_transfer.len is bigger + * spi_master.min_dma_len + * @master: the spi_master device + * @spi: the spi_device + * @tfr: the spi_transfer + */ +bool spi_can_dma_min_dma_len(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *tfr) +{ + /* we start DMA efforts only on bigger transfers */ + if (tfr->len < master->min_dma_len) + return false; + + /* return OK */ + return true; +} +EXPORT_SYMBOL_GPL(spi_can_dma_min_dma_len); + /* modalias support makes "modprobe $MODALIAS" new-style hotplug work, * and the sysfs version makes coldplug work too. */ @@ -2793,6 +2814,51 @@ int spi_merge_transfers(struct spi_master *master, return 0; } EXPORT_SYMBOL_GPL(spi_merge_transfers); +/*-------------------------------------------------------------------------*/ + +/** + * spi_translate_message_size_align_merge - default spi_message translation + * code that takes its parameters + * from @spi_master + * + * @master: the spi_master for which we run this translation + * @message: the spi_message which we need to translate + * + * Returns: status of tranformation + */ +int spi_translate_message_size_align_merge( + struct spi_master *master, struct spi_message *message) +{ + int ret; + + /* translate the message */ + + /* fix alignment of transfers by splitting rx_buf/tx_buf + * (and worsted case copying tx_buf) + */ + ret = spi_split_transfers_unaligned(master, message, + master->min_dma_len, + master->dma_alignment, + GFP_KERNEL); + if (ret) + return ret; + + /* limit transfer length */ + if (master->max_dma_len) { + ret = spi_split_transfers_maxsize(master, message, + master->max_dma_len, + GFP_KERNEL); + if (ret) + return ret; + } + + /* merge spi_transfers up to a full page */ + ret = spi_merge_transfers(master, message, 2, PAGE_SIZE, + GFP_KERNEL); + + return ret; +} +EXPORT_SYMBOL_GPL(spi_translate_message_size_align_merge); /*-------------------------------------------------------------------------*/ diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4b4c1e9..f055a47 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -351,6 +351,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * while the hardware is prepared, using the parent * device for the spidev * @max_dma_len: Maximum length of a DMA transfer for the device. + * @min_dma_len: Minimum length of a DMA transfer for the device. + * (mostly to avoid dma_mapping a buffer when dma is not used, + * should be multiple of dma_alignment) * @prepare_transfer_hardware: a message will soon arrive from the queue * so the subsystem requests the driver to prepare the transfer hardware * by issuing this call @@ -423,7 +426,6 @@ struct spi_master { * buffers; let protocol drivers know about these requirements. */ u16 dma_alignment; - /* spi_device.mode flags understood by this controller driver */ u16 mode_bits; @@ -517,6 +519,7 @@ struct spi_master { bool cur_msg_prepared; bool cur_msg_mapped; struct completion xfer_completion; + size_t min_dma_len; size_t max_dma_len; int (*prepare_transfer_hardware)(struct spi_master *master); @@ -940,6 +943,15 @@ extern struct spi_replaced_transfers *spi_replace_transfers( size_t extradatasize, gfp_t gfp); +/* some default implementations that drivers may use */ +extern int spi_translate_message_size_align_merge( + struct spi_master *master, struct spi_message *message); + +/* a default implementation of can_dma */ +extern bool spi_can_dma_min_dma_len(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *tfr); + /*---------------------------------------------------------------------------*/ /* SPI transfer transformation methods */