From patchwork Thu Oct 19 21:58:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 828366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="OM/woUAh"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yJ2tZ1pk0z9t6M for ; Fri, 20 Oct 2017 09:00:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752152AbdJSWAx (ORCPT ); Thu, 19 Oct 2017 18:00:53 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:49520 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752142AbdJSWAw (ORCPT ); Thu, 19 Oct 2017 18:00:52 -0400 Received: by mail-lf0-f66.google.com with SMTP id w21so11198403lfc.6 for ; Thu, 19 Oct 2017 15:00:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=G4xJnIWUG8I7lx5r/QFtfR8+8pN8eO3LXCHzP8tOYEw=; b=OM/woUAh7WNVIBivoaCtmDg3OcV3fI9TUEKu9l06EoNfJbPEBMobSGiKWTz+VnESOX rfKZp5y0GSnZbo3CzsEviurHaYTKK+3tt5VjLLZdv0C+Dpc1e5Kn35PfRYaDaJPf2HDn B6RcLjnHRdQDuemXe4lK9UMEfkEiTYsML3jvY= 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=G4xJnIWUG8I7lx5r/QFtfR8+8pN8eO3LXCHzP8tOYEw=; b=XslROxBX4F+gmYC/bsVhKe1xJYOlV0z/M0C4COm1Ki9xr80nPJiDHgGCs27qUHnYls a2kx1ejZfpfBxZ5blfYb7JrJM0p/QgSDCKk5TgmgO/UO1nfBgDw5fNFblxroS3FhwSvA 4QyNdHkqd+1fhhKZEz6DopFUBhKmExN+0IVH62WwW/cK4EC14Eq4vlBLJPVnhvvhuFkH z5DnWys4j1LoB4Yl6kFW/xVmrbwkMmg9DgbMdozw0itzzu5cXvfdBXh7td0RkrHg8Svd 8MrRSVWNWvkSsoyyN6TeoBLuAARZCaJD7Z/0ebpM7dvhq6Umt+P1eEEyRxbyZfmsy5Tg trfQ== X-Gm-Message-State: AMCzsaVyLsLWPDHGfTp9Gx3MbvzvkxeBNs/gxwfabu9p63sm7p9igI2Y Tvu5ySlLCk6diyrupOoJeiwxCGBZ+nU= X-Google-Smtp-Source: ABhQp+Rd4txY0V695Ll8Dcc4jlP3byvosM6VMQaV/PBDEyQoc7gH6nIhCIMey2GmiOyMcU43NjEmTA== X-Received: by 10.46.65.14 with SMTP id o14mr1288315lja.172.1508450450868; Thu, 19 Oct 2017 15:00:50 -0700 (PDT) Received: from localhost.localdomain (c-5f7c71d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.124.95]) by smtp.gmail.com with ESMTPSA id r29sm3843734lje.4.2017.10.19.15.00.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 19 Oct 2017 15:00:50 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org Cc: Linus Walleij , Anton Vorontsov , Lukas Wunner Subject: [PATCH] gpio-mmio: Use the new .get_multiple() callback Date: Thu, 19 Oct 2017 23:58:45 +0200 Message-Id: <20171019215845.4012-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.6 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org It is possible to read all lines of a generic MMIO GPIO chip with a single register read so support this. Add an especially quirky callback to read multiple lines for the variants that require you to read values from the output registers if and only if the line is set as output. We managed to do that with a maximum of two register reads, and just one read if the requested lines are all input or all output. Cc: Anton Vorontsov Cc: Lukas Wunner Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index f7da40e46c55..826e22725b29 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -147,11 +147,52 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) return !!(gc->read_reg(gc->reg_dat) & pinmask); } +static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + unsigned long get_mask = 0; + unsigned long set_mask = 0; + unsigned long retbits = 0; + unsigned long pinmask; + int bit = 0; + + while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) { + pinmask = gc->pin2mask(gc, bit); + + if (gc->bgpio_dir & pinmask) + set_mask |= pinmask; + else + get_mask |= pinmask; + } + + if (set_mask) + retbits |= gc->read_reg(gc->reg_set) & set_mask; + if (get_mask) + retbits |= gc->read_reg(gc->reg_dat) & get_mask; + + *bits = retbits; + + return 0; +} + static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) { return !!(gc->read_reg(gc->reg_dat) & gc->pin2mask(gc, gpio)); } +static int bgpio_get_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + unsigned long mapped_mask = 0; + int bit = 0; + + while ((bit = find_next_bit(mask, gc->ngpio, bit)) != gc->ngpio) + mapped_mask |= gc->pin2mask(gc, bit); + *bits = gc->read_reg(gc->reg_dat) & mapped_mask; + + return 0; +} + static void bgpio_set_none(struct gpio_chip *gc, unsigned int gpio, int val) { } @@ -462,10 +503,13 @@ static int bgpio_setup_io(struct gpio_chip *gc, } if (!(flags & BGPIOF_UNREADABLE_REG_SET) && - (flags & BGPIOF_READ_OUTPUT_REG_SET)) + (flags & BGPIOF_READ_OUTPUT_REG_SET)) { gc->get = bgpio_get_set; - else + gc->get_multiple = bgpio_get_set_multiple; + } else { gc->get = bgpio_get; + gc->get_multiple = bgpio_get_multiple; + } return 0; }