From patchwork Thu Jan 19 15:05:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Breathitt Gray X-Patchwork-Id: 717152 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3v46cP2KqKz9t1H for ; Fri, 20 Jan 2017 02:06:29 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="O2YTiAn1"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753172AbdASPG2 (ORCPT ); Thu, 19 Jan 2017 10:06:28 -0500 Received: from mail-yw0-f194.google.com ([209.85.161.194]:34289 "EHLO mail-yw0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752894AbdASPGI (ORCPT ); Thu, 19 Jan 2017 10:06:08 -0500 Received: by mail-yw0-f194.google.com with SMTP id v73so4594411ywg.1; Thu, 19 Jan 2017 07:05:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6rafzWM9ayF0g42LWPMERwz4sXvxaeTxe7JY7go/NEo=; b=O2YTiAn1BdZftY3+bZQyCa9ntFC6CH5yeTdf307IZ2xeCawkzHhaxXlpq21mLXyRG1 inyEo5pjate3fjaebuOyP/BCyvtak4FsC0hfWl5+BLGEsK6JtSDSoB3b3cP1DdfO+e+m jsdZ5aieajJHNIoCvL3Z8cVWbsR0Nmp7WPOCEhdjkX4uBnFOokwjxjXgJvjrfGC+4BzS D/g4LCyeYQYTKTS8f3Mi/9IQjhE3Gd+heWA5Q7oZYWlSnJcDkytbcmgrJB7tx4zIr21Y MgZbk2Zw8z8a9hp3YTquKPBI8rWG+vG3zHOocD682SQDD5QqnWyc/j3GSLpCiQe70/GU HTHg== 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:in-reply-to :references; bh=6rafzWM9ayF0g42LWPMERwz4sXvxaeTxe7JY7go/NEo=; b=kcjCYDjIhCtBw2MLrabD1SlBy2aJmEP6fGCBXGqnIAboKaUVroNXQSNOS7sVvfnCja YCbSARYbq7MFIf6yg5FAJKsiBTELthCpEOBkGAUdOw31XXAS9bPjnmsvZan5OyF58rRT NOr40IO0snCavDimj4CaQCVg2bSRiDyteoTeTpZ3+pj2LO6xkrV3NDBFG2Fb4oUmV0p1 A1tDe20ECRDUSH5gH+7Da7zzdKo3N+3GHbxjhomFk1Bl7vCQnKHib6clUT+5rAAGNy4H pnBABnrFKSVnPu8djbwYcVotdb7g/uve+Ein3K107c7mo1awHvNMrrl0KY3ScSZRwlCK mMyA== X-Gm-Message-State: AIkVDXIbYbW3d9UkbMfEZcdt9gI0w7W00RDsnPyNZLoY+Cx5uhESz/q1mP8CwJuh4GPmRQ== X-Received: by 10.129.78.79 with SMTP id c76mr7987838ywb.346.1484838353938; Thu, 19 Jan 2017 07:05:53 -0800 (PST) Received: from localhost (50-88-177-90.res.bhn.net. [50.88.177.90]) by smtp.gmail.com with ESMTPSA id g18sm1825317ywb.37.2017.01.19.07.05.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Jan 2017 07:05:53 -0800 (PST) From: William Breathitt Gray To: linus.walleij@linaro.org, gnurou@gmail.com Cc: linux-gpio@vger.kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, William Breathitt Gray Subject: [PATCH 3/5] gpio: gpio-mm: Add set_multiple callback function support Date: Thu, 19 Jan 2017 10:05:48 -0500 Message-Id: X-Mailer: git-send-email 2.11.0 In-Reply-To: References: Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org The Diamond Systems GPIO-MM series provides registers where 8 lines of GPIO may be set at a time. This patch add support for the set_multiple callback function, thus allowing multiple GPIO output lines to be set more efficiently in groups. Signed-off-by: William Breathitt Gray --- drivers/gpio/gpio-gpio-mm.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c index 1e7def9449ce..093489556c54 100644 --- a/drivers/gpio/gpio-gpio-mm.c +++ b/drivers/gpio/gpio-gpio-mm.c @@ -192,6 +192,44 @@ static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset, spin_unlock_irqrestore(&gpiommgpio->lock, flags); } +static void gpiomm_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip); + unsigned int i; + const unsigned int gpio_reg_size = 8; + unsigned int port; + unsigned int out_port; + unsigned int bitmask; + unsigned long flags; + + /* set bits are evaluated a gpio register size at a time */ + for (i = 0; i < chip->ngpio; i += gpio_reg_size) { + /* no more set bits in this mask word; skip to the next word */ + if (!mask[BIT_WORD(i)]) { + i = (BIT_WORD(i) + 1) * BITS_PER_LONG - gpio_reg_size; + continue; + } + + port = i / gpio_reg_size; + out_port = (port > 2) ? port + 1 : port; + bitmask = mask[BIT_WORD(i)] & bits[BIT_WORD(i)]; + + spin_lock_irqsave(&gpiommgpio->lock, flags); + + /* update output state data and set device gpio register */ + gpiommgpio->out_state[port] &= ~mask[BIT_WORD(i)]; + gpiommgpio->out_state[port] |= bitmask; + outb(gpiommgpio->out_state[port], gpiommgpio->base + out_port); + + spin_unlock_irqrestore(&gpiommgpio->lock, flags); + + /* prepare for next gpio register set */ + mask[BIT_WORD(i)] >>= gpio_reg_size; + bits[BIT_WORD(i)] >>= gpio_reg_size; + } +} + static int gpiomm_probe(struct device *dev, unsigned int id) { struct gpiomm_gpio *gpiommgpio; @@ -218,6 +256,7 @@ static int gpiomm_probe(struct device *dev, unsigned int id) gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output; gpiommgpio->chip.get = gpiomm_gpio_get; gpiommgpio->chip.set = gpiomm_gpio_set; + gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple; gpiommgpio->base = base[id]; spin_lock_init(&gpiommgpio->lock);