From patchwork Tue Jan 16 09:17:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 124633 Delivered-To: patch@linaro.org Received: by 10.46.64.148 with SMTP id r20csp947438lje; Tue, 16 Jan 2018 01:19:22 -0800 (PST) X-Google-Smtp-Source: ACJfBosjlaJhMPSJWGB7TBudkjemjLgSdVg2V4wd6Hqx5mvbxSUKBFHNmmDlAhGE4gC6g4tjvbrz X-Received: by 10.101.71.202 with SMTP id f10mr2127565pgs.208.1516094362634; Tue, 16 Jan 2018 01:19:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516094362; cv=none; d=google.com; s=arc-20160816; b=XetyeAM5ySSiS/ByIgJzQRPlDv5OJzKrsXkh5B2dSLzinU7y7wf2rlwkoNc3eH/8SY F4suQ9SPnwfJ3h1CeKyLF61QFBwiqQOAa6W6xUWMeW7CHJYFwS4HlyM6px3SeRmpigCF lyoveIM2DCIIAyNzUMVjKG6L8ABXBaIjBH1OOo38ETItIKOeqXOEzNPoDTpB30Tk2FbI 6ZkqvQ3L++xumRdVY7VHBz8yEESqGaVAOPHGXwrtS8IuLE5jnCvzBPpayuiQFd4pL6Yf UqRSS0BQBbVb3g1TBn9M8l7yh874vzfuMLDqGMFH67jjcCFgx3S6kxcuIpzT7fNcGRvR a9Vw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=CbDeV6Q8RNGQvRcpq9HLx9CWmzTovYIsNIbLsSeRt6A=; b=QmuO8AoVfZBL3nBGgA7Q+nrsA5yUEFdgv+pnRJzKiOG7ZWmzxBeGpmKVTMrwZJ6HBe OKYBKYN2sFv5ZL6/zPKntEaJDjz48M2PEIsNDtSyS62qsVIBPrxFtcbDeotNyMlLBwC2 QO71/abZRdyp9VSu+q28bBdcrvEQpxu6S/WzaQBhr5cwt2xoh1I2yfieZSIWoZ9LuoD4 D/+Hnk6CsZkuOjbvgbdZvf9hy2gKN2fhyXShWRxVjg4EQDymJ2+0IezSagASSwt+RxQ4 CHRvs6EJL0COpsTfebNc0hqfRczSEFJOpLZPlDAWH4yLPnngNMXAUdgN+kllSi8tkqNF ehnQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=gMLbcKUH; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n1si1282597pgp.26.2018.01.16.01.19.22; Tue, 16 Jan 2018 01:19:22 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-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 header.s=google header.b=gMLbcKUH; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751210AbeAPJTV (ORCPT + 6 others); Tue, 16 Jan 2018 04:19:21 -0500 Received: from mail-lf0-f65.google.com ([209.85.215.65]:36284 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750926AbeAPJTU (ORCPT ); Tue, 16 Jan 2018 04:19:20 -0500 Received: by mail-lf0-f65.google.com with SMTP id t79so1116560lfe.3 for ; Tue, 16 Jan 2018 01:19:20 -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=DX+qcwtlZnWChX1oXBT4Guaqp6l4qvzNwwp/iLVIWmQ=; b=gMLbcKUH/nEHsN0eaekUI1PVJglnzzJ6rGA+p6dzLX5X0QXBLWdZ2ieT4vaMyp8blG D2kFZ0WoXcvZaZaW6s8564Hz0nkWWZ9sYpodjVdCRwMvQCD6mevjc29mS6nUMFP4eNdE OXwj6T2uIYBOuu2NPmVWOYbwUvf9m7gPxPWzw= 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=DX+qcwtlZnWChX1oXBT4Guaqp6l4qvzNwwp/iLVIWmQ=; b=CMpm27uwwRU95P8csgdJL+F72chTCJQSY1hLSasv5sT+bTZkqnLqwtzyxfLNmF0bH4 eeKnHjv7YkLY8bxY2Rzw6woVp5XLp8XK/h4HFuXmKFixIO1qt0k+UyYT3L6LQDlnLAw+ h2D1Chl2ZYigpbJl9xdy/FRehao0NhpFq06zvMotiNiva8Jkjgi98bG417ChobQyrK3g HIp35NAhTgv8mZyQ7VYyhgQrumzBokrBUjivL5KC9dNCQaegcP1dX7W56chb6u2a2sVv cDTGMtoc5KXMBnPYz/DjdPhHuAaUGgH5VPp7zgufxNyDAx3b8LOC0X48SJNXmqDjKvcc OoUg== X-Gm-Message-State: AKwxytehCNkYq2T04/5PGmvi6xMifsVPtW4QvA8FO3P1YxGuPmVhaaM8 OwoWxh/4blKaq/SocTbFJ38xmjpIk0c= X-Received: by 10.25.152.18 with SMTP id a18mr2013259lfe.49.1516094358959; Tue, 16 Jan 2018 01:19:18 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id h11sm181538lfd.53.2018.01.16.01.19.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 16 Jan 2018 01:19:18 -0800 (PST) From: Linus Walleij To: linux-gpio@vger.kernel.org, Clemens Gruber , Lukas Wunner Cc: Linus Walleij , Bartosz Golaszewski Subject: [PATCH] gpio: mmio: Also read bits that are zero Date: Tue, 16 Jan 2018 10:17:14 +0100 Message-Id: <20180116091714.20963-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The code for .get_multiple() has bugs: 1. The simple .get_multiple() just reads a register, masks it and sets the return value. This is not correct: we only want to assign values (whether 0 or 1) to the bits that are set in the mask. Fix this by using &= ~mask to clear all bits in the mask and then |= val & mask to set the corresponding bits from the read. 2. The bgpio_get_multiple_be() call has a similar problem: it uses the |= operator to set the bits, so only the bits in the mask are affected, but it misses to clear all returned bits from the mask initially, so some bits will be returned erroneously set to 1. 3. The bgpio_get_set_multiple() again fails to clear the bits from the mask. Fixes: 80057cb417b2 ("gpio-mmio: Use the new .get_multiple() callback") Cc: Bartosz Golaszewski Reported-by: Clemens Gruber Reported-by: Lukas Wunner Signed-off-by: Linus Walleij --- Clemens: it would be great if you could test this, I want to push the fix ASAP if it solves the problem. --- drivers/gpio/gpio-mmio.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) -- 2.14.3 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" 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/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index f9042bcc27a4..eae078d43611 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -154,6 +154,9 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long set_mask = 0; int bit = 0; + /* Make sure we first clear any bits that are zero when we read the register */ + *bits &= ~*mask; + while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) { if (gc->bgpio_dir & BIT(bit)) set_mask |= BIT(bit); @@ -176,13 +179,13 @@ static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) /* * This only works if the bits in the GPIO register are in native endianness. - * It is dirt simple and fast in this case. (Also the most common case.) */ static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { - - *bits = gc->read_reg(gc->reg_dat) & *mask; + /* Make sure we first clear any bits that are zero when we read the register */ + *bits &= ~*mask; + *bits |= gc->read_reg(gc->reg_dat) & *mask; return 0; } @@ -196,6 +199,9 @@ static int bgpio_get_multiple_be(struct gpio_chip *gc, unsigned long *mask, unsigned long val; int bit; + /* Make sure we first clear any bits that are zero when we read the register */ + *bits &= ~*mask; + /* Create a mirrored mask */ bit = 0; while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio)