From patchwork Thu Dec 14 14:21:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 10112315 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 010C260352 for ; Thu, 14 Dec 2017 14:24:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E32E329130 for ; Thu, 14 Dec 2017 14:24:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D79482913F; Thu, 14 Dec 2017 14:24:09 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham 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 604E029130 for ; Thu, 14 Dec 2017 14:24:08 +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=23sbyVBMMRmtZ1luMHmY3JSg18mO0aGt+Vw6FQYislc=; b=EGwgyfoNEpR2Kw QXgqRsC6HSldz8lC91MpSim3kfsNRqfiGC2W0Nz3vQmhMNlRJ4emwqmIaF6SEF2ToNI6KLKxMCnic eOd8a5ro5GLPk9GQleoVvF4Xp1xx7FCroRd8VgxDCoLzdDaDcq3q9SyMxFD6N8S9cYjrSFejIzLUP wIxr/5rij6HkOWWZ+PmMQKxHFpD4jaVNdwfi0RomAFdtbtXw/VC2ydqEdJIU6akowP/lLye0/1wE5 L6sHhgCfb08JswCvQ1BHmljkBHCCw4Jlz7JLnARgLY/pb6pSDnGXiVLrCI7IliDi7JldW9Q8vB8gk KoSbiQHas5Qc5OBf2tyw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1ePUQh-0001Er-8b; Thu, 14 Dec 2017 14:24:07 +0000 Received: from esa5.microchip.iphmx.com ([216.71.150.166]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1ePUPt-0000W5-Fq for linux-arm-kernel@lists.infradead.org; Thu, 14 Dec 2017 14:23:24 +0000 X-IronPort-AV: E=Sophos;i="5.45,400,1508828400"; d="scan'208";a="7369256" Received: from exsmtp02.microchip.com (HELO email.microchip.com) ([198.175.253.38]) by esa5.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 14 Dec 2017 07:23:01 -0700 Received: from ibiza.corp.atmel.com (10.10.76.4) by chn-sv-exch02.mchp-main.com (10.10.76.38) with Microsoft SMTP Server id 14.3.352.0; Thu, 14 Dec 2017 07:22:59 -0700 From: Ludovic Desroches To: , Subject: [RFC PATCH 4/7] gpio: gpiolib: add bias support Date: Thu, 14 Dec 2017 15:21:35 +0100 Message-ID: <20171214142138.23008-5-ludovic.desroches@microchip.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20171214142138.23008-1-ludovic.desroches@microchip.com> References: <20171214142138.23008-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-20171214_062317_555981_68ECAC35 X-CRM114-Status: GOOD ( 15.32 ) 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: Ludovic Desroches 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 If we want to setup the bias of a pin used as a GPIO, we have, at least for some pin controllers, to declare it in the pinmuxing in order to apply the configuration wanted. If the pinmuxing strict mode is enabled, there is a conflict when the device driver requests the GPIO. It is due to an ownership mismatch. The device driver has requested the pin through the pinctrl so the owner is the device. When the GPIO is requested, there is a conflict because the owner of the GPIO is the pin controller not the requester. This patch provides a way to add the bias configuration to the flags of a GPIO. Signed-off-by: Ludovic Desroches --- drivers/gpio/gpiolib-of.c | 9 +++++++++ drivers/gpio/gpiolib.c | 34 ++++++++++++++++++++++++++++------ drivers/gpio/gpiolib.h | 3 +++ include/dt-bindings/gpio/gpio.h | 9 +++++++++ include/linux/gpio/machine.h | 3 +++ include/linux/of_gpio.h | 3 +++ 6 files changed, 55 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 67b1a7ff1e97..9c6da8c2e97c 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -158,6 +158,15 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, if (of_flags & OF_GPIO_TRANSITORY) *flags |= GPIO_TRANSITORY; + if (of_flags & OF_GPIO_BIAS_PULL_UP) + *flags |= GPIO_BIAS_PULL_UP; + + if (of_flags & OF_GPIO_BIAS_PULL_DOWN) + *flags |= GPIO_BIAS_PULL_DOWN; + + if (of_flags & OF_GPIO_BIAS_DISABLE) + *flags |= GPIO_BIAS_DISABLE; + return desc; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c887602ca0ff..2caec626dcd5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2133,7 +2133,7 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) { struct gpio_chip *chip = desc->gdev->chip; int status; - unsigned long flags; + unsigned long flags, config = 0; spin_lock_irqsave(&gpio_lock, flags); @@ -2161,6 +2161,16 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) goto done; } } + if (chip->set_config) { + /* The following flags are exclusive. */ + if (test_bit(FLAG_BIAS_PULL_UP, &desc->flags)) + config |= pinconf_to_config_packed(PIN_CONFIG_BIAS_PULL_UP, 1); + else if (test_bit(FLAG_BIAS_PULL_DOWN, &desc->flags)) + config |= pinconf_to_config_packed(PIN_CONFIG_BIAS_PULL_DOWN, 1); + else if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) + config |= pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE, 1); + chip->set_config(chip, gpio_chip_hwgpio(desc), config); + } if (chip->get_direction) { /* chip->get_direction may sleep */ spin_unlock_irqrestore(&gpio_lock, flags); @@ -3587,6 +3597,16 @@ void gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, if (lflags & GPIO_OPEN_SOURCE) set_bit(FLAG_OPEN_SOURCE, &desc->flags); + if (lflags & GPIO_BIAS_PULL_UP) + set_bit(FLAG_BIAS_PULL_UP, &desc->flags); + + if (lflags & GPIO_BIAS_PULL_DOWN) + set_bit(FLAG_BIAS_PULL_DOWN, &desc->flags); + + if (lflags & GPIO_BIAS_DISABLE) + set_bit(FLAG_BIAS_DISABLE, &desc->flags); +} + int gpiod_process_flags(struct gpio_desc *desc, const char *con_id, unsigned long lflags, enum gpiod_flags dflags) { @@ -3760,10 +3780,6 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (IS_ERR(desc)) return desc; - ret = gpiod_request(desc, label); - if (ret) - return ERR_PTR(ret); - if (active_low) lflags |= GPIO_ACTIVE_LOW; @@ -3777,7 +3793,13 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (transitory) lflags |= GPIO_TRANSITORY; - ret = gpiod_configure_and_process_flags(desc, propname, lflags, dflags); + gpiod_configure_flags(desc, propname, lflags, dflags); + + ret = gpiod_request(desc, label); + if (ret) + return ERR_PTR(ret); + + ret = gpiod_process_flags(desc, propname, lflags, dflags); if (ret < 0) { gpiod_put(desc); return ERR_PTR(ret); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index a03553d4be1c..381a7a1bf540 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -210,6 +210,9 @@ struct gpio_desc { #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ #define FLAG_IS_HOGGED 11 /* GPIO is hogged */ #define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */ +#define FLAG_BIAS_PULL_UP 13 +#define FLAG_BIAS_PULL_DOWN 14 +#define FLAG_BIAS_DISABLE 15 /* Connection label */ const char *label; diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index 2cc10ae4bbb7..28ccfce72c59 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -33,4 +33,13 @@ #define GPIO_PERSISTENT 0 #define GPIO_TRANSITORY 8 +/* Bit 4 express Bias Pull up */ +#define GPIO_BIAS_PULL_UP 16 + +/* Bit 5 express Bias Pull down */ +#define GPIO_BIAS_PULL_DOWN 32 + +/* Bit 6 express Bias Disable */ +#define GPIO_BIAS_DISABLE 64 + #endif diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index b2f2dc638463..e0b6ac64871f 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -12,6 +12,9 @@ enum gpio_lookup_flags { GPIO_OPEN_SOURCE = (1 << 2), GPIO_PERSISTENT = (0 << 3), GPIO_TRANSITORY = (1 << 3), + GPIO_BIAS_PULL_UP = (1 << 4), + GPIO_BIAS_PULL_DOWN = (1 << 5), + GPIO_BIAS_DISABLE = (1 << 6), }; /** diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index f928c2df2bcd..1b025e6680ea 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -33,6 +33,9 @@ enum of_gpio_flags { OF_GPIO_SINGLE_ENDED = BIT(1), OF_GPIO_OPEN_DRAIN = BIT(2), OF_GPIO_TRANSITORY = BIT(3), + OF_GPIO_BIAS_PULL_UP = BIT(4), + OF_GPIO_BIAS_PULL_DOWN = BIT(5), + OF_GPIO_BIAS_DISABLE = BIT(6), }; #ifdef CONFIG_OF_GPIO