Return-Path: X-Cyrus-Session-Id: sloti22d1t05-2963937-1514769902-2-1049173043182430617 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-charsets: from='UTF-8', cc='UTF-8', plain='UTF-8' X-Resolved-to: linux@kroah.com X-Delivered-to: linux@kroah.com X-Mail-from: linux-kernel-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=arctest; t=1514769901; b=FXxYwXjLoUQ4loxiL2J9jSLRTP5GFyUHu9a9UY1JwtXunSN k48ruNcQ49TnJmSbtaMWtfUdeQsWvp+Oywp+MI4szsnJ0QNi1iWaMP1QW2aX79X8 pQqhK2Wl+UNV9Mk0kWMuh2xClVCplONOdu2s6+0aLB4XcU6iB9FUePSVoTeK0Mgn +hQ45uHTIpxtmMryq+p8Lxx/zk7cyY6pzH+96nV1fchseFRuv2StiLjOINVe8RKR mtU2GMME+H8zZ2Heb5voC/Y0amoW2SaQozyvsZMGZQqZAoqAspC/yyF54TxMBRO1 kJomWA/uvrA2tn5lXBYLBCN+i1DGGWvrjlLozLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=from:to:cc:subject:date:in-reply-to :references:mime-version:content-type:content-transfer-encoding :message-id:sender:list-id; s=arctest; t=1514769901; bh=ien2Q0MA nK50ad1DfgGWC3t16V9bxqjHkWjG4pLkhr0=; b=iRmw5TADzUWwldBoZJPRxFZU YwU7SyH/4d2DeAizPF8Hb/SDLfAOorbEEG8wIXzOMPuRDJ+XuJdrhBE6QVwRTBZG sde891iPXHEaJ0P8+6PNS0kSCxNDzhtdRQOcvTVbxq0CZ1aTOeyK+LkGcyVGufEF YIQBPmben3XYXqcAMUDONZth2vQaPyHTwp56AWu+gimz1Z9TaRtH1nGSakqE+94c CoyPCQe80LLnylwC3/BPFmBxCy6+nf8fDlh0ufJ96IdgFfw0TrfRLj9LVXqLR8MZ mnrWXceo0s32VOyDahE1nhU1boegJUrW97C6B06NlRcEdXPPvIRokm7FijBEKA== ARC-Authentication-Results: i=1; mx4.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=rwth-aachen.de; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=rwth-aachen.de header.result=pass header_is_org_domain=yes Authentication-Results: mx4.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=rwth-aachen.de; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=rwth-aachen.de header.result=pass header_is_org_domain=yes Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751106AbeAABYy (ORCPT ); Sun, 31 Dec 2017 20:24:54 -0500 Received: from mail-out-1.itc.rwth-aachen.de ([134.130.5.46]:10879 "EHLO mail-out-1.itc.rwth-aachen.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750937AbeAABYw (ORCPT ); Sun, 31 Dec 2017 20:24:52 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2C+CQAvjUla/54agoZdHAEBAQQBAQoBA?= =?us-ascii?q?YM+ggEHhACZO4FamWYKhTsChDBDFAEBAQEBAQEBAWsohSQGIwQLAUYQJQImAgJ?= =?us-ascii?q?XBg4Fii4Er2OBbTqISoFlAQEBAQEFAQEBAQEjCQGBBYJ9ghKDaAyGKYUFgmUFi?= =?us-ascii?q?k+YfYEToDaHaZZWAgICAgkCGoE8NiKBT3CCeoJUHIFod4gEAYEVAQEB?= X-IPAS-Result: =?us-ascii?q?A2C+CQAvjUla/54agoZdHAEBAQQBAQoBAYM+ggEHhACZO4F?= =?us-ascii?q?amWYKhTsChDBDFAEBAQEBAQEBAWsohSQGIwQLAUYQJQImAgJXBg4Fii4Er2OBb?= =?us-ascii?q?TqISoFlAQEBAQEFAQEBAQEjCQGBBYJ9ghKDaAyGKYUFgmUFik+YfYEToDaHaZZ?= =?us-ascii?q?WAgICAgkCGoE8NiKBT3CCeoJUHIFod4gEAYEVAQEB?= X-IronPort-AV: E=Sophos;i="5.45,489,1508796000"; d="scan'208";a="31493520" From: =?UTF-8?q?Stefan=20Br=C3=BCns?= To: CC: Peter Meerwald-Stadler , =?UTF-8?q?Stefan=20Br=C3=BCns?= , Maciej Purski , , "Andrew F . Davis" , Lars-Peter Clausen , Jonathan Cameron , Hartmut Knaack Subject: [PATCH v4 5/7] iio: adc: ina2xx: Use a monotonic clock for delay calculation Date: Mon, 1 Jan 2018 02:24:42 +0100 X-Mailer: git-send-email 2.15.1 In-Reply-To: <20171229174806.5a615b63@archlinux> References: <20171229174806.5a615b63@archlinux> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [77.182.71.79] X-ClientProxiedBy: rwthex-s1-b.rwth-ad.de (2002:8682:1a99::8682:1a99) To rwthex-w2-a.rwth-ad.de (2002:8682:1a9e::8682:1a9e) Message-ID: <3dfac802-d735-421b-9676-085e6def4cad@rwthex-w2-a.rwth-ad.de> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX Content-Length: 3196 The iio timestamp clock is user selectable and may be non-monotonic. Also, only part of the acquisition time is measured, thus the delay was longer than intended. Use a monotonic timestamp to track the time for the next poll iteration. The timestamp is advanced by the sampling interval each iteration. In case the conversion overrruns the register readout (i.e. fast sampling combined with a slow bus), one or multiple samples will be dropped. Signed-off-by: Stefan BrĂ¼ns --- Changes in v4: - Typo, div_s64, not s64_div Changes in v3: - use s64_div for 64 bit integer division to fix compiles on 32 bit archs Changes in v2: - add a comment mentioning skipping samples on overrun drivers/iio/adc/ina2xx-adc.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index 2621a34ee5c6..b55b8bd1427b 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c @@ -703,10 +703,10 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) /* data buffer needs space for channel data and timestap */ unsigned short data[4 + sizeof(s64)/sizeof(short)]; int bit, ret, i = 0; - s64 time_a, time_b; + s64 time; unsigned int alert; - time_a = iio_get_time_ns(indio_dev); + time = iio_get_time_ns(indio_dev); /* * Because the timer thread and the chip conversion clock @@ -752,11 +752,9 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) data[i++] = val; } - time_b = iio_get_time_ns(indio_dev); + iio_push_to_buffers_with_timestamp(indio_dev, data, time); - iio_push_to_buffers_with_timestamp(indio_dev, data, time_a); - - return (unsigned long)(time_b - time_a) / 1000; + return 0; }; static int ina2xx_capture_thread(void *data) @@ -764,7 +762,9 @@ static int ina2xx_capture_thread(void *data) struct iio_dev *indio_dev = data; struct ina2xx_chip_info *chip = iio_priv(indio_dev); int sampling_us = SAMPLING_PERIOD(chip); - int buffer_us, delay_us; + int ret; + struct timespec64 next, now, delta; + s64 delay_us; /* * Poll a bit faster than the chip internal Fs, in case @@ -773,15 +773,28 @@ static int ina2xx_capture_thread(void *data) if (!chip->allow_async_readout) sampling_us -= 200; + ktime_get_ts64(&next); + do { - buffer_us = ina2xx_work_buffer(indio_dev); - if (buffer_us < 0) - return buffer_us; + ret = ina2xx_work_buffer(indio_dev); + if (ret < 0) + return ret; - if (sampling_us > buffer_us) { - delay_us = sampling_us - buffer_us; - usleep_range(delay_us, (delay_us * 3) >> 1); - } + ktime_get_ts64(&now); + + /* + * Advance the timestamp for the next poll by one sampling + * interval, and sleep for the remainder (next - now) + * In case "next" has already passed, the interval is added + * multiple times, i.e. samples are dropped. + */ + do { + timespec64_add_ns(&next, 1000 * sampling_us); + delta = timespec64_sub(next, now); + delay_us = div_s64(timespec64_to_ns(&delta), 1000); + } while (delay_us <= 0); + + usleep_range(delay_us, (delay_us * 3) >> 1); } while (!kthread_should_stop()); -- 2.15.1