linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Trent Piepho <tpiepho-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	yuhang wang
	<wangyuhang2014-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Sourav Poddar <sourav.poddar-l0cyMroinI0@public.gmane.org>
Subject: [PATCH 4/4] spi: Simplify bit width checking code
Date: Wed, 25 Sep 2013 16:52:30 -0700	[thread overview]
Message-ID: <20130925235230.22061.63402.stgit@Graphine> (raw)
In-Reply-To: <CA+7tXigzKW8sydfnktr4F5uY-SKk0JAMjaxFn74XLbw_NTYVXg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

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 <tpiepho-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi.c       |   49 +++++++++++++++++++----------------------------
 include/linux/spi/spi.h |    2 ++
 2 files changed, 22 insertions(+), 29 deletions(-)

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 */


------------------------------------------------------------------------------
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

  parent reply	other threads:[~2013-09-25 23:52 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-11 10:15 [PATCH v3 1/2]spi: DUAL and QUAD support wangyuhang
2013-08-22 12:30 ` Mark Brown
2013-08-22 12:35 ` Sourav Poddar
2013-08-22 13:21   ` Mark Brown
     [not found]     ` <20130822132122.GK26118-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2013-08-22 14:23       ` Sourav Poddar
2013-08-22 12:37 ` Mark Brown
     [not found] ` <1376216117-5864-1-git-send-email-wangyuhang2014-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-09-04  3:24   ` Trent Piepho
     [not found]     ` <CA+7tXih4XkhZ8xGcaUdGU6O4ZN1ZLfqyjb2UEKsRxsZBA+=DZw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-09-04  7:07       ` yuhang wang
     [not found]         ` <CAHSAbzOCRhpxMzQRtD2po3LrmNExscoYESPPi_-jnZQaEBuFTg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-09-25 23:33           ` Trent Piepho
     [not found]             ` <CA+7tXigzKW8sydfnktr4F5uY-SKk0JAMjaxFn74XLbw_NTYVXg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-09-25 23:52               ` [PATCH 1/4] spi: Use of_property_read_u32 Trent Piepho
2013-09-26  6:12                 ` Sourav Poddar
2013-09-25 23:52               ` [PATCH 2/4] spi: Order fields in spi_device for better packing Trent Piepho
2013-09-26  6:14                 ` Sourav Poddar
2013-09-25 23:52               ` [PATCH 3/4] spi: Encode data width more efficiently Trent Piepho
2013-09-26  6:14                 ` Sourav Poddar
2013-09-25 23:52               ` Trent Piepho [this message]
2013-09-26  6:14                 ` [PATCH 4/4] spi: Simplify bit width checking code Sourav Poddar
2013-09-04  9:45     ` [PATCH v3 1/2]spi: DUAL and QUAD support Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130925235230.22061.63402.stgit@Graphine \
    --to=tpiepho-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=sourav.poddar-l0cyMroinI0@public.gmane.org \
    --cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=wangyuhang2014-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).