From patchwork Mon Jan 15 16:24:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 10164747 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id F0E1F602C2 for ; Mon, 15 Jan 2018 16:26:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E25F9205F6 for ; Mon, 15 Jan 2018 16:26:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D5EAD2870B; Mon, 15 Jan 2018 16:26:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.7 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_MED, SUSPICIOUS_RECIPS autolearn=no version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3D02D205F6 for ; Mon, 15 Jan 2018 16:26:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=rpOmOpZi5564b3a0Nhx8Zs1RZ2QnYD+b+MxeHGHw2iI=; b=SNWhSV5MLXKlqS a7liEL/ZdhekkfxJU22aUK6W1nw5mY2F0jetXI6G308egySTP1LgaGSN620I2oqeCFYpv3fw07CW/ sFcjQMY/+A5nVOBhR8WI/F4pOaHTAmJWkvMlI6WJFSYduJojKYCcZo16tUVPj0vr17u17OXacrFYe t6cP2fInnX+QrfEdRkovnhhcrrYU0pUWFJuN/iKqcgPYwZ1INvee4sEiDuWgGKO6dwWzXRD4k0eRX YOCuLLHPSR9fNy4jVkUUItJVGkHeTMMghNMxkFRDpO3SQdTKyLSscHA4VcoaiLHWsO+5AoVWv3L1E rNvnEh6q0+U3YUD9chbQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eb7al-0007g8-R3; Mon, 15 Jan 2018 16:26:35 +0000 Received: from esa4.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eb7a7-0006Er-4j for linux-arm-kernel@lists.infradead.org; Mon, 15 Jan 2018 16:25:58 +0000 X-IronPort-AV: E=Sophos;i="5.46,364,1511852400"; d="scan'208";a="10249767" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 15 Jan 2018 09:25:43 -0700 Received: from ibiza.rfo.atmel.com (10.10.76.4) by chn-sv-exch05.mchp-main.com (10.10.76.106) with Microsoft SMTP Server id 14.3.352.0; Mon, 15 Jan 2018 09:25:43 -0700 From: Ludovic Desroches To: , Subject: [RFC PATCH 1/2] pinctrl: add consumer variant for gpio request Date: Mon, 15 Jan 2018 17:24:06 +0100 Message-ID: <20180115162407.6314-2-ludovic.desroches@microchip.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20180115162407.6314-1-ludovic.desroches@microchip.com> References: <20180115162407.6314-1-ludovic.desroches@microchip.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180115_082555_267106_2DFFC6DF X-CRM114-Status: GOOD ( 16.02 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linus.walleij@linaro.org, Ludovic Desroches , linux-kernel@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add a consumer variant to GPIO request relative functions. The goal is to fix the bad ownership, which is arbitrary set to "range->name:gpio", of a GPIO. There is a lack of configuration features for GPIO. For instance, we can't set the bias. Some pin controllers manage both device's pins and GPIOs. GPIOs can benefit from pin configuration. Usually, a pinctrl node is used to mux the pin as a GPIO and to set up its configuration. The pinmuxing strict mode involves that a pin which is muxed can't be requested as a GPIO if the owner is not the same. Unfortunately, the ownership of a GPIO is set arbitrarily to "range->name:gpio". So there is a mismatch about the ownership which prevents a device from being the owner of the pinmuxing and requesting the same pin as a GPIO. Adding some consumer variants for GPIO request stuff will allow to pass the name of the device which requests the GPIO to not return an error if it's also the owner of the pinmuxing. Signed-off-by: Ludovic Desroches --- drivers/pinctrl/core.c | 13 ++++++++++--- drivers/pinctrl/pinmux.c | 16 ++++++++++++++-- drivers/pinctrl/pinmux.h | 10 ++++++++++ include/linux/pinctrl/consumer.h | 6 ++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2c0dbfcff3e6..51c75a6057b2 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -733,14 +733,15 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, } /** - * pinctrl_gpio_request() - request a single pin to be used as GPIO + * pinctrl_gpio_request_consumer() - request a single pin to be used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space + * @consumer: the name of the device requesting the GPIO * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_request() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed in. */ -int pinctrl_gpio_request(unsigned gpio) +int pinctrl_gpio_request_consumer(unsigned gpio, const char *consumer) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; @@ -759,12 +760,18 @@ int pinctrl_gpio_request(unsigned gpio) /* Convert to the pin controllers number space */ pin = gpio_to_pin(range, gpio); - ret = pinmux_request_gpio(pctldev, range, pin, gpio); + ret = pinmux_request_gpio_consumer(pctldev, range, pin, gpio, consumer); mutex_unlock(&pctldev->mutex); return ret; } +EXPORT_SYMBOL_GPL(pinctrl_gpio_request_consumer); + +int pinctrl_gpio_request(unsigned gpio) +{ + return pinctrl_gpio_request_consumer(gpio, NULL); +} EXPORT_SYMBOL_GPL(pinctrl_gpio_request); /** diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 55502fc4479c..8d422eb0ed38 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -232,14 +232,19 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, * @pctldev: pin controller device affected * @pin: the pin to mux in for GPIO * @range: the applicable GPIO range + * @consumer: the name of the device requesting the GPIO */ -int pinmux_request_gpio(struct pinctrl_dev *pctldev, +int pinmux_request_gpio_consumer(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, - unsigned pin, unsigned gpio) + unsigned pin, unsigned gpio, + const char *consumer) { const char *owner; int ret; + if (consumer) + return pin_request(pctldev, pin, consumer, range); + /* Conjure some name stating what chip and pin this is taken by */ owner = kasprintf(GFP_KERNEL, "%s:%d", range->name, gpio); if (!owner) @@ -252,6 +257,13 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev, return ret; } +int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio) +{ + return pinmux_request_gpio_consumer(pctldev, range, pin, gpio, NULL); +} + /** * pinmux_free_gpio() - release a pin from GPIO muxing * @pctldev: the pin controller device for the pin diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index a331fcdbedd9..837599922a42 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -19,6 +19,9 @@ int pinmux_validate_map(const struct pinctrl_map *map, int i); int pinmux_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin, unsigned gpio); +int pinmux_request_gpio_consumer(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio, const char *consumer); void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, struct pinctrl_gpio_range *range); int pinmux_gpio_direction(struct pinctrl_dev *pctldev, @@ -50,6 +53,13 @@ static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev, return 0; } +static inline int pinmux_request_gpio_consumer(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio, const char *consumer) +{ + return 0; +} + static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, struct pinctrl_gpio_range *range) diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 0412cc9833e9..8c521a14db43 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -26,6 +26,7 @@ struct device; /* External interface to pin control */ extern int pinctrl_gpio_request(unsigned gpio); +extern int pinctrl_gpio_request_consumer(unsigned gpio, const char *consumer); extern void pinctrl_gpio_free(unsigned gpio); extern int pinctrl_gpio_direction_input(unsigned gpio); extern int pinctrl_gpio_direction_output(unsigned gpio); @@ -67,6 +68,11 @@ static inline int pinctrl_gpio_request(unsigned gpio) return 0; } +static inline int pinctrl_gpio_request_consumer(unsigned gpio, const char *consumer); +{ + return 0; +} + static inline void pinctrl_gpio_free(unsigned gpio) { }