From patchwork Fri Dec 30 17:36:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 89398 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp6538368qgi; Fri, 30 Dec 2016 09:36:34 -0800 (PST) X-Received: by 10.98.113.201 with SMTP id m192mr37788936pfc.42.1483119394311; Fri, 30 Dec 2016 09:36:34 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 64si57473910pgj.306.2016.12.30.09.36.34; Fri, 30 Dec 2016 09:36:34 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751723AbcL3Rgc (ORCPT + 3 others); Fri, 30 Dec 2016 12:36:32 -0500 Received: from mail-lf0-f44.google.com ([209.85.215.44]:34844 "EHLO mail-lf0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750984AbcL3Rgb (ORCPT ); Fri, 30 Dec 2016 12:36:31 -0500 Received: by mail-lf0-f44.google.com with SMTP id b14so240086098lfg.2 for ; Fri, 30 Dec 2016 09:36:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=V0Mj9MmRXzAFg6RdTCFg6x0OXYOOyggstQgFHWCVsM4=; b=kp+MEAvLoiwmXGpXzESODJXpexR/UqpEp6wK6bPYdDdfsAD0a4yxyXL9Qn2wKPoBkt T1/4L7KqBZOBInbaW4WcLTFlnPdGsRXdAEzCmzCbADPdpA9zc0BhZrvuarXW7NmWauCF EPJQI33HMkgrRP2gEpjTUusynf4ubEHPotHpw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=V0Mj9MmRXzAFg6RdTCFg6x0OXYOOyggstQgFHWCVsM4=; b=IL1ThNAkhhDMIrYhyCe/uwImvXdpgGo4dP1UpHHPaafb3WxIDXn6xIKmSJ34QH3nH0 LYtWVxZGNtjAfKNwBQme2wRx/p8KvnZhZSsAVPgLdKeTyRKaexSesieewZLyQy0pwwcU m+ci8NIzt82UntOPShxuCMqUlIgUPm5SYYg3PffA7o54mSG6MBm4C09NqVbGeT7L4S2r 2naEN3x4QX4gkjOesWmxR1/ziQyzh3r4QKCabScCVUroKzDE83K/SJaEKP707NR5rtXc ywfwTZwMZm24PV3eSpkoyYz2wpRizNKd9CMctHuU8A5NJlIarbIODseU819plC38umAe 5Wag== X-Gm-Message-State: AIkVDXJRKhtMfttFUu1o2ShX9IT8uHiZszF/kUoYF5uTLMe29iGHOFbHef96MJ8XoI8saOtj X-Received: by 10.46.21.93 with SMTP id 29mr16234144ljv.54.1483119389665; Fri, 30 Dec 2016 09:36:29 -0800 (PST) Received: from localhost.localdomain (c-357171d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.113.53]) by smtp.gmail.com with ESMTPSA id y10sm13664047lja.45.2016.12.30.09.36.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Dec 2016 09:36:28 -0800 (PST) From: Linus Walleij To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: Linus Walleij , stable@vger.kernel.org, Gregor Boirie , Giuseppe Barba , Denis Ciocca Subject: [PATCH] Revert "iio:st_sensors: align on storagebits boundaries" Date: Fri, 30 Dec 2016 18:36:20 +0100 Message-Id: <20161230173620.30851-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.9.3 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org This reverts commit e7385de5291e347f5bc85985acdce3a3f5096667. This change is bad, because it breaks all 12bit sensors and breaks userspace such as iio_generic_buffer. The commit computes the number of bytes to read out from the hardware like this: unsigned int bytes_to_read = channel->scan_type.realbits >> 3; This works fine with 8 or 16 bit channels resulting in 1 or 2 bytes to read respectively. But when using this with 12bit sensors such as the LIS3LV02 this fails since 12 >> 3 = 1 but we need to read 2 bytes! Unless we do this, the DRDY signal does not go low and the status loop just spins. Further, it packs all bytes in the buffer to make it "dense". Even if I try to fix the above by using DIV_ROUND_UP(), it will result in erroneous data in the buffer for 12bit sensors, since the macro ST_SENSORS_LSM_CHANNELS() used by all sensors defines scan type shift, storagebits and realbits such that the userspace like iio_generic_buffer will read 2 bytes, then shift it by 4. This will not work anymore after this patch. I do not understand the point of the original commit, I suggest this be reverted for now. Fixes: e7385de5291e ("iio:st_sensors: align on storagebits boundaries") Cc: stable@vger.kernel.org Cc: Gregor Boirie Cc: Giuseppe Barba Cc: Denis Ciocca Signed-off-by: Linus Walleij --- drivers/iio/common/st_sensors/st_sensors_buffer.c | 37 ++++++++++++----------- drivers/iio/common/st_sensors/st_sensors_core.c | 2 +- 2 files changed, 20 insertions(+), 19 deletions(-) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe stable" 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/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c index fe7775bb3740..3c964a106afa 100644 --- a/drivers/iio/common/st_sensors/st_sensors_buffer.c +++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c @@ -24,29 +24,30 @@ static int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf) { - int i; + int i, len; + int total = 0; struct st_sensor_data *sdata = iio_priv(indio_dev); unsigned int num_data_channels = sdata->num_data_channels; - for_each_set_bit(i, indio_dev->active_scan_mask, num_data_channels) { - const struct iio_chan_spec *channel = &indio_dev->channels[i]; - unsigned int bytes_to_read = channel->scan_type.realbits >> 3; - unsigned int storage_bytes = - channel->scan_type.storagebits >> 3; - - buf = PTR_ALIGN(buf, storage_bytes); - if (sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev, - channel->address, - bytes_to_read, buf, - sdata->multiread_bit) < - bytes_to_read) - return -EIO; - - /* Advance the buffer pointer */ - buf += storage_bytes; + for (i = 0; i < num_data_channels; i++) { + unsigned int bytes_to_read; + + if (test_bit(i, indio_dev->active_scan_mask)) { + bytes_to_read = indio_dev->channels[i].scan_type.storagebits >> 3; + len = sdata->tf->read_multiple_byte(&sdata->tb, + sdata->dev, indio_dev->channels[i].address, + bytes_to_read, + buf + total, sdata->multiread_bit); + + if (len < bytes_to_read) + return -EIO; + + /* Advance the buffer pointer */ + total += len; + } } - return 0; + return total; } irqreturn_t st_sensors_trigger_handler(int irq, void *p) diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 975a1f19f747..4abe8aca1b29 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -483,7 +483,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev, int err; u8 *outdata; struct st_sensor_data *sdata = iio_priv(indio_dev); - unsigned int byte_for_channel = ch->scan_type.realbits >> 3; + unsigned int byte_for_channel = ch->scan_type.storagebits >> 3; outdata = kmalloc(byte_for_channel, GFP_KERNEL); if (!outdata)