From patchwork Thu Jan 19 15:05:59 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: 717155 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 3v46dP4bFXz9sCX for ; Fri, 20 Jan 2017 02:07:21 +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="tLnFp+s8"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752894AbdASPGa (ORCPT ); Thu, 19 Jan 2017 10:06:30 -0500 Received: from mail-yb0-f194.google.com ([209.85.213.194]:34793 "EHLO mail-yb0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752936AbdASPGI (ORCPT ); Thu, 19 Jan 2017 10:06:08 -0500 Received: by mail-yb0-f194.google.com with SMTP id w194so2796893ybe.1; Thu, 19 Jan 2017 07:06:06 -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=MTxQxITDPbYulcT6HTKaNyyRl8szH4AG5vM0mQWqQ/s=; b=tLnFp+s8J5QM6mJUXFuGNxY4Hi8WZ7P8Gmgxkl80oiY4Fki12SMQQZgc6/Xtfe0qp3 MWu6azEepYMKzuenRybs29OF8Y4ZAAaosI909msg8niijm3E1QfCsRWuEq8drya8keG5 k9WWwvPpzpSxjySeG2owc7ZGDo/IoKoYHUxk84FWswsUIBZrNR8HIrhLCbNkzBGXWn9b q4WFybMyr4/z5OhYVYELxri3V+q6GyadlaGv5vMq4BqRcE0i6Q823KvfwoFEnKXZKhkG 16P0Hc2EEiLXNZgT97cVqGBY+ZLLG4ibRBnTlFbAkaIW3DPf9GMLb6IyOyrL44MASW4/ 965Q== 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=MTxQxITDPbYulcT6HTKaNyyRl8szH4AG5vM0mQWqQ/s=; b=c5HNXI1zoukzqULwD0gFZ9LRm//nS9q9jToqIAhpnMcCcSrJaE0SYVy8w9zPqY8pEq cohd2jjzEOHDkTDaIT/IxtylY+jhi/kveB5jzkrBC321wT/KaW0HE1G7yNeQymRoI2kO MuIqsGXBJeDlsSQy61gXluwU0GCKMM9KmIJuacn98sgWrXbsuR6J07FS3WFpBL9c0S6M npH06ESRyQr29gLUhQp9z4PLNGXJAbFgbZOnAAEa849tX0FloxYRFXYZI+rOydRPv58A IHzAeB5LGxFOT7YYZ29obYOopkGjIZSXn2pFyBEz6rl1azglFAIkjn8lQBFR3lkCA3az noQA== X-Gm-Message-State: AIkVDXLo0AsRAsFpMT8mm7Ly9ma2Sp8568xmID71s2Vn3hh645REZ0qZLTVcmQWP8qR09A== X-Received: by 10.37.55.138 with SMTP id e132mr6996265yba.35.1484838364893; Thu, 19 Jan 2017 07:06:04 -0800 (PST) Received: from localhost (50-88-177-90.res.bhn.net. [50.88.177.90]) by smtp.gmail.com with ESMTPSA id h3sm1820871ywc.54.2017.01.19.07.06.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Jan 2017 07:06:04 -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 4/5] gpio: ws16c48: Add set_multiple callback function support Date: Thu, 19 Jan 2017 10:05:59 -0500 Message-Id: <2b5658acecdc3e8d922ea8e299bd488e6ee18e2d.1484838095.git.vilhelm.gray@gmail.com> 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 WinSystems WS16C48 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-ws16c48.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c index eaa71d440ccf..25e539530c08 100644 --- a/drivers/gpio/gpio-ws16c48.c +++ b/drivers/gpio/gpio-ws16c48.c @@ -155,6 +155,46 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value) spin_unlock_irqrestore(&ws16c48gpio->lock, flags); } +static void ws16c48_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct ws16c48_gpio *const ws16c48gpio = gpiochip_get_data(chip); + unsigned int i; + const unsigned int gpio_reg_size = 8; + unsigned int port; + unsigned int iomask; + 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; + + /* mask out GPIO configured for input */ + iomask = mask[BIT_WORD(i)] & ~ws16c48gpio->io_state[port]; + bitmask = iomask & bits[BIT_WORD(i)]; + + spin_lock_irqsave(&ws16c48gpio->lock, flags); + + /* update output state data and set device gpio register */ + ws16c48gpio->out_state[port] &= ~iomask; + ws16c48gpio->out_state[port] |= bitmask; + outb(ws16c48gpio->out_state[port], ws16c48gpio->base + port); + + spin_unlock_irqrestore(&ws16c48gpio->lock, flags); + + /* prepare for next gpio register set */ + mask[BIT_WORD(i)] >>= gpio_reg_size; + bits[BIT_WORD(i)] >>= gpio_reg_size; + } +} + static void ws16c48_irq_ack(struct irq_data *data) { struct gpio_chip *chip = irq_data_get_irq_chip_data(data); @@ -329,6 +369,7 @@ static int ws16c48_probe(struct device *dev, unsigned int id) ws16c48gpio->chip.direction_output = ws16c48_gpio_direction_output; ws16c48gpio->chip.get = ws16c48_gpio_get; ws16c48gpio->chip.set = ws16c48_gpio_set; + ws16c48gpio->chip.set_multiple = ws16c48_gpio_set_multiple; ws16c48gpio->base = base[id]; ws16c48gpio->irq = irq[id];