Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3039218imm; Mon, 16 Jul 2018 20:22:13 -0700 (PDT) X-Google-Smtp-Source: AAOMgpf2aqRH/e4CSKTIkbmJZbA7CckEMod9+kBZGxhFnXsPSg4xZv2PE4L6XhoAGFnu033f2CQL X-Received: by 2002:a17:902:292b:: with SMTP id g40-v6mr19319367plb.273.1531797733726; Mon, 16 Jul 2018 20:22:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531797733; cv=none; d=google.com; s=arc-20160816; b=HjSu6e+OoF6RR9EnOjjUx9B/Q3kp/q2zKT6Fuff/BoQHTlX+sDSGSJK95VkASLpFPe MeTNJzFCondAZJ1tchq9QUx80wOe21D9711cEbZbo+efBtEhHss4vKQkesKEDVyJbU2U 9EFLaBRXase5wBr7nNKqAQV6q8ViALXj9g4Zss1ZnV6UCEtT6athhlQgFblkzx7lkFWG 0qGHfdA/jlqRK4+Nsh9CkSfD5SdzqFl1MWBckohu63Z/ByEttiXBO6mz9x8gX77yxcl3 eg7stm+2Wx27xnS1V5gidSAB4eIFvLWVbFJ6tcB1XsR7OUO2QbyCiX/Ue5GlasJ67tTZ vfyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=W/yNDmAMhx65X3CEqQ5jF7hA7f8iPmWUcVLODVN0Q6M=; b=dapdYHoRpgzn3Lo9tDdEhcW89sYNhm4nJzLi2aL+5Ngo+rWJhrDp+Q/19PbWFYAomn V813p8NwmwGykgK9T1NK8LpDVrC7fLvl/J0x2Z0YNYdacx4m/LGlCsmwF5lG8DrOMxux enitvecf6/r2smMwOLMXCZtiyoHUdJvSyV5nue0wmm5DzTaL1toQgndelsKQLHv8wENm sO3+xHl4YD+lPJNsaj8jgD4HY8mvv/LkaAu5RizqU4PFioLJ+sExWAroet9oxaHU/h+6 qBGhLH75nMThG+4vQBzdYxp4pOefWfp9kKPiNAdsrLNPKC47FjinOIkL+23R/xstrXpM +fvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@lechnology.com header.s=default header.b=kEZ4Pgni; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h18-v6si30479114pgd.238.2018.07.16.20.21.58; Mon, 16 Jul 2018 20:22:13 -0700 (PDT) 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; Authentication-Results: mx.google.com; dkim=fail header.i=@lechnology.com header.s=default header.b=kEZ4Pgni; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731117AbeGQDvo (ORCPT + 99 others); Mon, 16 Jul 2018 23:51:44 -0400 Received: from vern.gendns.com ([206.190.152.46]:35649 "EHLO vern.gendns.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729967AbeGQDvl (ORCPT ); Mon, 16 Jul 2018 23:51:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lechnology.com; s=default; h=References:In-Reply-To:Message-Id:Date:Subject :Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=W/yNDmAMhx65X3CEqQ5jF7hA7f8iPmWUcVLODVN0Q6M=; b=kEZ4PgnipvmJ6mcw7Cnlx+cKV kMlEx/T7+cFv/T+fjAkKNAR0ExL+bfCFP3q2jks+Zse7m7rd8dincoEsgYyRVnsgta+omlnn3dFRQ mqGqAQImpgzTNw0siobWjeaGwkwwfJ8AOK/kypdIPx/+WzdchP9RjvzdxUBe2aN9pi3DyRJYaZJSR ncO9waCZelIe4IoKQL14D3XSIpRCUpvDsAVScASxo+4AEecrNvg9aefnRkVfmRDfa7MrUoydloeb+ W4RHf+bw1BM/yqtsNISmHV48mBzA353XDUUQVq/b+LqEmo3OXoQGqdC86z9JCJXE5HdY2i4QLZvwm qluFNVtvA==; Received: from 108-198-5-147.lightspeed.okcbok.sbcglobal.net ([108.198.5.147]:53228 helo=freyr.lechnology.com) by vern.gendns.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.91) (envelope-from ) id 1ffGY9-00CnnZ-Mo; Mon, 16 Jul 2018 23:21:17 -0400 From: David Lechner To: linux-spi@vger.kernel.org, linux-iio@vger.kernel.org Cc: David Lechner , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Mark Brown , linux-kernel@vger.kernel.org Subject: [PATCH 4/4] iio: adc: ti-ads7950: use SPI_CS_WORD to reduce CPU usage Date: Mon, 16 Jul 2018 22:20:52 -0500 Message-Id: <20180717032052.12273-5-david@lechnology.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180717032052.12273-1-david@lechnology.com> References: <20180717032052.12273-1-david@lechnology.com> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vern.gendns.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lechnology.com X-Get-Message-Sender-Via: vern.gendns.com: authenticated_id: davidmain+lechnology.com/only user confirmed/virtual account not confirmed X-Authenticated-Sender: vern.gendns.com: davidmain@lechnology.com X-Source: X-Source-Args: X-Source-Dir: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This changes how the SPI message for the triggered buffer is setup in the TI ADS7950 A/DC driver. By using the SPI_CS_WORD flag, we can read multiple samples in a single SPI transfer. If the SPI controller supports DMA transfers, we can see a significant reduction in CPU usage. For example, on an ARM9 system running at 456MHz reading just 4 channels at 100Hz: before this change, top shows the CPU usage of the IRQ thread of this driver to be ~7.7%. After this change, the CPU usage drops to ~3.8%. Signed-off-by: David Lechner --- Dependency: this patch applies on top of "iio: adc: ti-ads7950: allow simultaneous use of buffer and direct mode"[1] [1]: https://lore.kernel.org/lkml/20180716233550.6449-1-david@lechnology.com/ drivers/iio/adc/ti-ads7950.c | 53 +++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index ba7e5a027490..60de4cbbd5fc 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -60,7 +60,7 @@ struct ti_ads7950_state { struct iio_dev *indio_dev; struct spi_device *spi; - struct spi_transfer ring_xfer[TI_ADS7950_MAX_CHAN + 2]; + struct spi_transfer ring_xfer; struct spi_transfer scan_single_xfer[3]; struct spi_message ring_msg; struct spi_message scan_single_msg; @@ -69,16 +69,16 @@ struct ti_ads7950_state { unsigned int vref_mv; unsigned int settings; - __be16 single_tx; - __be16 single_rx; + u16 single_tx; + u16 single_rx; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - __be16 rx_buf[TI_ADS7950_MAX_CHAN + TI_ADS7950_TIMESTAMP_SIZE] + u16 rx_buf[TI_ADS7950_MAX_CHAN + 2 + TI_ADS7950_TIMESTAMP_SIZE] ____cacheline_aligned; - __be16 tx_buf[TI_ADS7950_MAX_CHAN]; + u16 tx_buf[TI_ADS7950_MAX_CHAN + 2]; }; struct ti_ads7950_chip_info { @@ -116,7 +116,7 @@ enum ti_ads7950_id { .realbits = bits, \ .storagebits = 16, \ .shift = 12 - (bits), \ - .endianness = IIO_BE, \ + .endianness = IIO_CPU, \ }, \ } @@ -257,23 +257,14 @@ static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev, len = 0; for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) { cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(i) | st->settings; - st->tx_buf[len++] = cpu_to_be16(cmd); + st->tx_buf[len++] = cmd; } /* Data for the 1st channel is not returned until the 3rd transfer */ - len += 2; - for (i = 0; i < len; i++) { - if ((i + 2) < len) - st->ring_xfer[i].tx_buf = &st->tx_buf[i]; - if (i >= 2) - st->ring_xfer[i].rx_buf = &st->rx_buf[i - 2]; - st->ring_xfer[i].len = 2; - st->ring_xfer[i].cs_change = 1; - } - /* make sure last transfer's cs_change is not set */ - st->ring_xfer[len - 1].cs_change = 0; + st->tx_buf[len++] = 0; + st->tx_buf[len++] = 0; - spi_message_init_with_transfers(&st->ring_msg, st->ring_xfer, len); + st->ring_xfer.len = len * 2; return 0; } @@ -289,7 +280,7 @@ static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p) if (ret < 0) goto out; - iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf, + iio_push_to_buffers_with_timestamp(indio_dev, &st->rx_buf[2], iio_get_time_ns(indio_dev)); out: @@ -305,13 +296,13 @@ static int ti_ads7950_scan_direct(struct ti_ads7950_state *st, unsigned int ch) mutex_lock(&st->indio_dev->mlock); cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings; - st->single_tx = cpu_to_be16(cmd); + st->single_tx = cmd; ret = spi_sync(st->spi, &st->scan_single_msg); if (ret) goto out; - ret = be16_to_cpu(st->single_rx); + ret = st->single_rx; out: mutex_unlock(&st->indio_dev->mlock); @@ -385,6 +376,14 @@ static int ti_ads7950_probe(struct spi_device *spi) const struct ti_ads7950_chip_info *info; int ret; + spi->bits_per_word = 16; + spi->mode |= SPI_CS_WORD; + ret = spi_setup(spi); + if (ret < 0) { + dev_err(&spi->dev, "Error in spi setup\n"); + return ret; + } + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -406,6 +405,16 @@ static int ti_ads7950_probe(struct spi_device *spi) indio_dev->num_channels = info->num_channels; indio_dev->info = &ti_ads7950_info; + /* build spi ring message */ + spi_message_init(&st->ring_msg); + + st->ring_xfer.tx_buf = &st->tx_buf[0]; + st->ring_xfer.rx_buf = &st->rx_buf[0]; + /* len will be set later */ + st->ring_xfer.cs_change = true; + + spi_message_add_tail(&st->ring_xfer, &st->ring_msg); + /* * Setup default message. The sample is read at the end of the first * transfer, then it takes one full cycle to convert the sample and one -- 2.17.1