From patchwork Mon Dec 17 11:51:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfgang Grandegger X-Patchwork-Id: 1886861 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 0DD883FCA5 for ; Mon, 17 Dec 2012 11:54:36 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TkZEd-0000eK-IE; Mon, 17 Dec 2012 11:51:52 +0000 Received: from ngcobalt02.manitu.net ([217.11.48.102]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TkZEZ-0000da-1L for linux-arm-kernel@lists.infradead.org; Mon, 17 Dec 2012 11:51:48 +0000 Received: from [192.168.140.154] (ppp-93-104-18-146.dynamic.mnet-online.de [93.104.18.146]) (authenticated as wg with PLAIN) by ngcobalt02.manitu.net (8.10.2/8.10.2) with ESMTP id qBHBpX428791; Mon, 17 Dec 2012 12:51:34 +0100 X-manitu-Original-Sender-IP: 93.104.18.146 X-manitu-Original-Receiver-Name: ngcobalt02.manitu.net Message-ID: <50CF0744.7040404@grandegger.com> Date: Mon, 17 Dec 2012 12:51:32 +0100 From: Wolfgang Grandegger User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Roland Stigge Subject: Re: [PATCH RESEND 0/6 v10] gpio: Add block GPIO References: <1355495185-24220-1-git-send-email-stigge@antcom.de> <50CB68AB.5070806@grandegger.com> <50CBBB25.20002@antcom.de> <50CF03FB.2030100@grandegger.com> In-Reply-To: <50CF03FB.2030100@grandegger.com> X-Enigmail-Version: 1.4.6 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121217_065147_443854_86017E24 X-CRM114-Status: GOOD ( 21.41 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [217.11.48.102 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: rmallon@gmail.com, gregkh@linuxfoundation.org, linus.walleij@linaro.org, broonie@opensource.wolfsonmicro.com, w.sang@pengutronix.de, linux-kernel@vger.kernel.org, grant.likely@secretlab.ca, daniel-gl@gmx.net, sr@denx.de, plagnioj@jcrosoft.com, linux-arm-kernel@lists.infradead.org, highguy@gmail.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org On 12/17/2012 12:37 PM, Wolfgang Grandegger wrote: > Hi Roland, > > On 12/15/2012 12:49 AM, Roland Stigge wrote: >> Hi Wolfgang, >> >> thank you for the patch! >> >> On 14/12/12 18:58, Wolfgang Grandegger wrote: >>> +static void at91_gpiolib_set_block(struct gpio_chip *chip, unsigned long mask, unsigned long val) >>> +{ >>> + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); >>> + void __iomem *pio = at91_gpio->regbase; >>> + >>> + __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); >>> +} >>> + >> >> Without having an AT91 available right now, I guess the hardware >> interface of this GPIO chip is different from the GPIO block API. While >> the hardware has clear and set registers, the val parameter of >> at91_gpiolib_set_block() should be interpreted as the actual output >> values. See lpc32xx_gpo_set_block() for an example for handling set and >> clear registers like this: First, set_bits and clear_bits words are >> calculated from mask and val parameters, and finally written to the >> respective hardware registers. >> >> Note that one .set_block() can result in writing both the set and clear >> registers of the hardware when val contains both 0s and 1s in >> respectively masked positions. > > Oops, I obviously did not test GPIO block write. The patch below does > work now. Feel free to add it to the next version of your series. The patch lacks an important fix, sorry. Please consider the updated patch below. Wolfgang. From a1f93ddea9c6c9c6a80d7a02d3c8d9902823fe47 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Mon, 3 Dec 2012 08:31:55 +0100 Subject: [PATCH 1/2] gpio: add GPIO block callback functions for AT91 Signed-off-by: Wolfgang Grandegger --- arch/arm/mach-at91/gpio.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index be42cf0..77c6f91 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -48,7 +48,9 @@ struct at91_gpio_chip { static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); +static void at91_gpiolib_set_block(struct gpio_chip *chip, unsigned long mask, unsigned long val); static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset); +static unsigned long at91_gpiolib_get_block(struct gpio_chip *chip, unsigned long mask); static int at91_gpiolib_direction_output(struct gpio_chip *chip, unsigned offset, int val); static int at91_gpiolib_direction_input(struct gpio_chip *chip, @@ -62,7 +64,9 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); .direction_input = at91_gpiolib_direction_input, \ .direction_output = at91_gpiolib_direction_output, \ .get = at91_gpiolib_get, \ + .get_block = at91_gpiolib_get_block, \ .set = at91_gpiolib_set, \ + .set_block = at91_gpiolib_set_block, \ .dbg_show = at91_gpiolib_dbg_show, \ .to_irq = at91_gpiolib_to_irq, \ .ngpio = nr_gpio, \ @@ -896,6 +900,16 @@ static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset) return (pdsr & mask) != 0; } +static unsigned long at91_gpiolib_get_block(struct gpio_chip *chip, unsigned long mask) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + u32 pdsr; + + pdsr = __raw_readl(pio + PIO_PDSR); + return pdsr & mask; +} + static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) { struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); @@ -905,6 +919,20 @@ static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR)); } +static void at91_gpiolib_set_block(struct gpio_chip *chip, unsigned long mask, unsigned long val) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + u32 set_bits = val & mask; + u32 clr_bits = ~val & mask; + + /* GPIO outputs can only be set at once or cleared at once */ + if (set_bits) + __raw_writel(set_bits, pio + PIO_SODR); + if (clr_bits) + __raw_writel(clr_bits, pio + PIO_CODR); +} + static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) { int i;