From patchwork Wed Sep 25 23:52:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trent Piepho X-Patchwork-Id: 2946121 Return-Path: X-Original-To: patchwork-spi-devel-general@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7F0679F3C4 for ; Wed, 25 Sep 2013 23:52:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 93C9C202FF for ; Wed, 25 Sep 2013 23:52:40 +0000 (UTC) Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 936C5202AB for ; Wed, 25 Sep 2013 23:52:39 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1VOyso-0002a2-Tf; Wed, 25 Sep 2013 23:52:38 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1VOysm-0002Zj-Qt for spi-devel-general@lists.sourceforge.net; Wed, 25 Sep 2013 23:52:36 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of gmail.com designates 209.85.160.49 as permitted sender) client-ip=209.85.160.49; envelope-from=tpiepho@gmail.com; helo=mail-pb0-f49.google.com; Received: from mail-pb0-f49.google.com ([209.85.160.49]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1VOysm-0007qj-3S for spi-devel-general@lists.sourceforge.net; Wed, 25 Sep 2013 23:52:36 +0000 Received: by mail-pb0-f49.google.com with SMTP id xb4so334461pbc.22 for ; Wed, 25 Sep 2013 16:52:30 -0700 (PDT) X-Received: by 10.66.145.4 with SMTP id sq4mr166696pab.178.1380153150273; Wed, 25 Sep 2013 16:52:30 -0700 (PDT) Received: from [127.0.1.1] (174-31-223-101.tukw.qwest.net. [174.31.223.101]) by mx.google.com with ESMTPSA id fy4sm50295075pbb.1.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 25 Sep 2013 16:52:29 -0700 (PDT) Subject: [PATCH 4/4] spi: Simplify bit width checking code To: spi-devel-general@lists.sourceforge.net, Mark Brown , yuhang wang From: Trent Piepho Date: Wed, 25 Sep 2013 16:52:30 -0700 Message-ID: <20130925235230.22061.63402.stgit@Graphine> In-Reply-To: References: User-Agent: StGit/0.15 MIME-Version: 1.0 X-Spam-Score: -1.6 (-) X-Headers-End: 1VOysm-0007qj-3S Cc: Sourav Poddar X-BeenThere: spi-devel-general@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux SPI core/device drivers discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: spi-devel-general-bounces@lists.sourceforge.net X-Spam-Status: No, score=-8.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,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 The code that checks [tr]x_nbits for every transfer is more complex than it needs to be. Checking for SPI_3WIRE isn't needed. spi_config() already prevents 3WIRE mode from being combined with DUAL or QUAD mode support. So there is no need to differentiate between a single bit device with SPI_3WIRE set and one with without. It doesn't change the allowed bit widths. By using the sensible rule that the width codes should be sequential, it's possible to avoid checking for every single valid code individually and instead use a single comparison to check for codes greater than the largest valid code. Signed-off-by: Trent Piepho Reviewed-by: Sourav Poddar Tested-by: Sourav Poddar --- drivers/spi/spi.c | 49 +++++++++++++++++++---------------------------- include/linux/spi/spi.h | 2 ++ 2 files changed, 22 insertions(+), 29 deletions(-) ------------------------------------------------------------------------------ October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0e8e5e8..fd79767 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1447,6 +1447,8 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) * it is not set for this transfer. */ list_for_each_entry(xfer, &message->transfers, transfer_list) { + int max_width; + message->frame_length += xfer->len; if (!xfer->bits_per_word) xfer->bits_per_word = spi->bits_per_word; @@ -1473,40 +1475,29 @@ static int __spi_async(struct spi_device *spi, struct spi_message *message) xfer->speed_hz > master->max_speed_hz) return -EINVAL; - /* check transfer tx/rx_nbits: - * 1. keep the value is not out of single, dual and quad - * 2. keep tx/rx_nbits is contained by mode in spi_device - * 3. if SPI_3WIRE, tx/rx_nbits should be in single + /* Check transfer's tx/rx_nbits. Do not allow a width greater + * than the max the device supports. As the width codes are + * assigned sequentially, a non-existent width code will also be + * greater than the largest allowed value. */ if (xfer->tx_buf) { - if (xfer->tx_nbits != SPI_NBITS_SINGLE && - xfer->tx_nbits != SPI_NBITS_DUAL && - xfer->tx_nbits != SPI_NBITS_QUAD) - return -EINVAL; - if ((xfer->tx_nbits == SPI_NBITS_DUAL) && - !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD))) - return -EINVAL; - if ((xfer->tx_nbits == SPI_NBITS_QUAD) && - !(spi->mode & SPI_TX_QUAD)) - return -EINVAL; - if ((spi->mode & SPI_3WIRE) && - (xfer->tx_nbits != SPI_NBITS_SINGLE)) + if (spi->mode & SPI_TX_QUAD) + max_width = SPI_NBITS_QUAD; + else if (spi->mode & SPI_TX_DUAL) + max_width = SPI_NBITS_DUAL; + else + max_width = SPI_NBITS_SINGLE; + if (xfer->tx_nbits > max_width) return -EINVAL; } - /* check transfer rx_nbits */ if (xfer->rx_buf) { - if (xfer->rx_nbits != SPI_NBITS_SINGLE && - xfer->rx_nbits != SPI_NBITS_DUAL && - xfer->rx_nbits != SPI_NBITS_QUAD) - return -EINVAL; - if ((xfer->rx_nbits == SPI_NBITS_DUAL) && - !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD))) - return -EINVAL; - if ((xfer->rx_nbits == SPI_NBITS_QUAD) && - !(spi->mode & SPI_RX_QUAD)) - return -EINVAL; - if ((spi->mode & SPI_3WIRE) && - (xfer->rx_nbits != SPI_NBITS_SINGLE)) + if (spi->mode & SPI_RX_QUAD) + max_width = SPI_NBITS_QUAD; + else if (spi->mode & SPI_RX_DUAL) + max_width = SPI_NBITS_DUAL; + else + max_width = SPI_NBITS_SINGLE; + if (xfer->rx_nbits > max_width) return -EINVAL; } } diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4dbf40e..ffccfdd 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -549,6 +549,8 @@ struct spi_transfer { unsigned cs_change:1; unsigned tx_nbits:2; unsigned rx_nbits:2; +/* These should be assigned sequentially, so that numeric comparisons produce + * the correct result, e.g. SPI_NBITS_DUAL < SPI_NBITS_QUAD. */ #define SPI_NBITS_SINGLE 0x00 /* 1x wide transfer */ #define SPI_NBITS_DUAL 0x01 /* 2x wide transfer */ #define SPI_NBITS_QUAD 0x02 /* 4x wide transfer */