From patchwork Fri May 30 19:35:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Javier Martinez Canillas X-Patchwork-Id: 4273401 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 54528BEEA7 for ; Fri, 30 May 2014 19:38:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 46E0B203AD for ; Fri, 30 May 2014 19:38:04 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 311AA203AA for ; Fri, 30 May 2014 19:38:03 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WqSbH-0007f1-Ts; Fri, 30 May 2014 19:36:23 +0000 Received: from mail-wg0-f49.google.com ([74.125.82.49]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WqSao-00076H-MS for linux-arm-kernel@lists.infradead.org; Fri, 30 May 2014 19:35:57 +0000 Received: by mail-wg0-f49.google.com with SMTP id m15so2501524wgh.32 for ; Fri, 30 May 2014 12:35:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=J472FZT9Sha86+Te3dcgdKpFviRWfElyUtY/hOiHEyI=; b=lRA3DMVS05DtA2ylab9u1qB2d79jMhwx/pEiryo9MB5uIdNSeppVCjxuKLieQ0W9Uo IeCqvLAutCtWmHsNaHIpF7X4b2bImx/AfimljHo6qpWf/QTEN56mbqIWJu/iQx/CXFlr rionrjINZ4dE8+UKG1J85R+ddF2dWk/Pgt5DncfqaCiKeU5elBdqd5SWEzIPEhpAH7S2 5mcxioX2CvGZ7eIp70DQMTL1u36D7nhm267ISq7NsBn7KoGjJTAJfL8RXpzVDpV+ode/ 7/fFzeLc0rygebl5GVRylHLBI1KPsMMdYdVps4Kk0zcLxdw8xqD6TQ4OHgJViTuEbkWo 3yDA== X-Gm-Message-State: ALoCoQmQ8QZD6RnIWqaZ2+KyE+AgGaNAtMZxAJUXMkMmFUHmiKYQ/VMvjMofj3+E6hCEG1gdDj1G MIME-Version: 1.0 X-Received: by 10.194.119.34 with SMTP id kr2mr25751565wjb.34.1401478530727; Fri, 30 May 2014 12:35:30 -0700 (PDT) Received: by 10.180.84.73 with HTTP; Fri, 30 May 2014 12:35:30 -0700 (PDT) X-Originating-IP: [95.23.101.217] In-Reply-To: <20140523151140.GF2321@atomide.com> References: <3385f19f3e1427613732f6d5c9f8513d@net2air.co> <7bd3dbc0c3217f43eefc8d228995690f@net2air.co> <20140523151140.GF2321@atomide.com> Date: Fri, 30 May 2014 21:35:30 +0200 Message-ID: Subject: Re: Accessing GPIOs from userspace using recent kernels From: Javier Martinez Canillas To: Tony Lindgren X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140530_123555_075050_EAD76834 X-CRM114-Status: GOOD ( 28.41 ) X-Spam-Score: -0.7 (/) Cc: Linus Walleij , Linux-OMAP , Peter TB Brett , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hello Tony, On Fri, May 23, 2014 at 5:11 PM, Tony Lindgren wrote: > * Linus Walleij [140523 04:36]: >> On Fri, May 16, 2014 at 12:15 PM, Peter TB Brett wrote: >> > The current call chain seems to be: gpiod_export() --> gpiod_request() --> >> > omap_gpio_request(). Looking at other GPIO drivers, it seems like >> > omap_gpio_request() should eventually call pinctrl_request_gpio(). Would be >> > useful if someone who knows about OMAP4/gpio/pinctrl could take a look at >> > this. I looked briefly at adding pinctrl back-end commands to the OMAP GPIO driver. That is to make all GPIO operations fall through to the pinctrl-single driver as Linus suggested before. The changes in the GPIO driver are quite trivial, here is a RFC patch [0] that has only build tested but I think is useful to at least discuss this. Now, in order to make that patch to actually work someone has to register the chip GPIO range to pin controller mapping with gpiochip_add_pin_range() or something similar to make pinctrl_get_device_gpio_range() to succeed. The pinctrl-single driver has a "pinctrl-single,gpio-range" property that can be used to define a GPIO range to be registered. But the problem is as you said that since there are two different hw blocks for pin muxing and GPIO control, the pins that can be multiplexed as GPIO are scattered all over the padconf registers address space. So there isn't an easy way to specify the mapping and we will have to add an entry on "pinctrl-single,gpio-range" for every single GPIO pin (that's from 128 to 256 entries depending on the SoC). To make even more complicated, the padconf registers offset for GPIO pins are SoC specific so we need a mapping for each SoC. So I wonder if is worth to add all that information to the DTS files. Athough on the other hand is nice to have a better coordination between the GPIO and pinctrl drivers and as Tony said there are use cases where this is needed to workaround some silicion erratas. > > If we do this, we also need a solution to prevent automatic remuxing > of GPIO pins from happending. For wake-up events, some drivers need > to remux a rx pin to GPIO input for the duration of idle, and then > back to device rx pin. This is needed on some other platforms too > AFAIK. > > For the drivers needing GPIO wake-up events, request_gpio is done in > the driver after drivers/base/pinctrl.c has already muxed the device > pin to rx. At minimum we would get warnings about reserved pins if > we tried to automatically mux them to GPIO. > > We may be able to use some GPIO specific property to prevent > automatic remuxing as we discussed in the #armlinux few days ago. > Yes, adding a GPIO specific property to prevent automatic remuxing sounds sensible to me. > Related to automatic remuxing of GPIO pins, there are also other > needs for pinctrl and GPIO interaction. We need to remux GPIO output > pins to input + pull + safe_mode to prevent the GPIO pins losing > value briefly during off-idle. That's the gpio errata 1.158 at as > shown at least at [1]. Because the GPIO to pinctrl mapping is > sparse and SoC specific, there's currently now obvious way to do > that. And we would need few new GPIO functions to tell pinctrl > subsystem about the change. > I'm not that familiar with the pinctrl-single driver but can't that errata be handled on pinctrl-single without the GPIO OMAP driver intervention? I mean if we already add the complete GPIO <--> pin mapping using "pinctrl-single,gpio-range" then the pinctrl-single driver will know what pins can be muxed as GPIO and which ones were set as output with pinctrl_gpio_direction_output() and then can just mux these output GPIO pins to input + pull + safe_mode during off-idle. Or am I completely lost here? :-) > Regards, > > Tony > > > [1] https://www.gitorious.org/rowboat/kernel/commit/86b15f21298b749a9d8216ff1839d33ad542464e?format=patch Best regards, Javier [0] commit 96c886987219e37395a160f8bd0d228509c1d4f0 Author: Javier Martinez Canillas Date: Fri May 30 20:50:39 2014 +0200 gpio: omap: Make GPIO operations fall through pinctrl-single On OMAP platforms, there are two diferent hardware blocks for I/O multiplexing / pad configuration and GPIO control. So two different drivers are used: pinctrl-single and gpio-omap. Since two separate drivers are used there is no coordination between these and a I/O pad is not configured as a GPIO when a GPIO pin is requested. This patch adds pinctrl back-end commands to the GPIO OMAP driver so the pinmux_ops functions in the pinctrl-single driver are called for each GPIO operation. Signed-off-by: Javier Martinez Canillas * If this is the first gpio_request for the bank, @@ -704,6 +710,8 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) */ if (!BANK_USED(bank)) pm_runtime_put(bank->dev); + + pinctrl_free_gpio(chip->base + offset); } /* @@ -947,6 +955,11 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) { struct gpio_bank *bank; unsigned long flags; + int ret; + + ret = pinctrl_gpio_direction_input(chip->base + offset); + if (ret) + return ret; bank = container_of(chip, struct gpio_bank, chip); spin_lock_irqsave(&bank->lock, flags); @@ -973,6 +986,11 @@ static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) { struct gpio_bank *bank; unsigned long flags; + int ret; + + ret = pinctrl_gpio_direction_output(chip->base + offset); + if (ret) + return ret; bank = container_of(chip, struct gpio_bank, chip); spin_lock_irqsave(&bank->lock, flags); diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 00f29aa..cee63c6 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define OFF_MODE 1 @@ -664,6 +665,11 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) { struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); unsigned long flags; + int ret; + + ret = pinctrl_request_gpio(chip->base + offset); + if (ret) + return ret; /*