From patchwork Tue Jan 9 00:24:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 857179 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="PkohWup9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zFtJR2p3wz9ryT for ; Tue, 9 Jan 2018 11:27:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754473AbeAIA1X (ORCPT ); Mon, 8 Jan 2018 19:27:23 -0500 Received: from mail-lf0-f68.google.com ([209.85.215.68]:44915 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754153AbeAIA1V (ORCPT ); Mon, 8 Jan 2018 19:27:21 -0500 Received: by mail-lf0-f68.google.com with SMTP id w23so3859065lfd.11 for ; Mon, 08 Jan 2018 16:27:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=XsD+hFF+Z4MF6WlkjkvzuCuxJFloNRgGpMgiDrfPYk0=; b=PkohWup9Mp2IH5RXXjf0cSKJ7XEniv2PvxToDk8hfaFZvt7ri8mSoSxuvIR3UO8wMX m8UWyiV9dxgmVgEt/WG046TAiiqvTZsR+YyJED59zoa40oIvHQ2VOWfrE/FKu/6k0e1F L/KyArLJPYkQHL6S+cEZC4xmXLLI0SuHUnW74= 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; bh=XsD+hFF+Z4MF6WlkjkvzuCuxJFloNRgGpMgiDrfPYk0=; b=C5hUsX2HGaLWOYqHq4WCpAmYBMRB4+ENbRbrgy7JGLWhtJ9zrJ5Tq3lRREr9Qbag02 SF1yebQayBQCvQvPHft04tM3wLZmOTrdjyobmFdKvOoygHWcH9EAXhLGctUwIhE7rO5M wZvveo/ShJmx+WrVGhZImdsqpmz1gmTZOTxhkZ+j4AkAP4eIuQWOLwUDUwvSm/0gjrcp tNA5MvsBSVP6AO8gSxDiBe1bP0KI7QAbZVQxAaKvNNXw3qNvZWDM1PvNfm6kuITi96/e nkgVabKwnSvU3nNdpYiz686nneRHnQEEIdQ4wnt7N/gCVKCHaRGtLXQS2SWClQCpVsVF 4HJg== X-Gm-Message-State: AKGB3mIeo8P2iixfmeiG5BLwJ+JhgPaRMpZAXNIXEAxXurKhHfSG3RmF rF9HT/BaOtkZdK2zuFvrvPNGRw== X-Google-Smtp-Source: ACJfBos3NBbrMW2EmTAz0D7uQv5NGffr2kLkJNlgbyfaAjmCdCAXNKnZA8/8lHeUCnJ0f1hmz/k4nw== X-Received: by 10.46.112.24 with SMTP id l24mr7666907ljc.66.1515457640489; Mon, 08 Jan 2018 16:27:20 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id i1sm2580145lji.22.2018.01.08.16.27.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Jan 2018 16:27:19 -0800 (PST) From: Linus Walleij To: Liam Girdwood , Mark Brown , linux-gpio@vger.kernel.org, Rob Herring Cc: linux-kernel@vger.kernel.org, Linus Walleij Subject: [PATCH 1/4] gpio: of: Support regulator nonstandard GPIO properties Date: Tue, 9 Jan 2018 01:24:51 +0100 Message-Id: <20180109002451.22618-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Before it was clearly established that all GPIO properties in the device tree shall be named "foo-gpios" (with the deprecated variant "foo-gpio" for single lines) we unfortunately merged a few bindings for regulators with random phandle names. As we want to switch the GPIO regulator driver to using descriptors, we need devm_gpiod_get() to return something reasonable when looking up these in the device tree. Put in a special #ifdef:ed kludge to do this special lookup only for the regulator case and gets compiled out if we're not enabling regulators. Supply a whitelist with properties we accept. Cc: Rob Herring Signed-off-by: Linus Walleij --- This patch is preperatory work for converting fixed and GPIO regulators to deal only with GPIO descriptors. --- drivers/gpio/gpiolib-of.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index e0d59e61b52f..9686922310a4 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -117,6 +117,41 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name, } EXPORT_SYMBOL(of_get_named_gpio_flags); +/* + * Some regulator bindings happened before we managed to establish that GPIO + * properties should be named "foo-gpios" so we have this special kludge for + * them. + */ +static struct gpio_desc *of_find_regulator_gpio(struct device *dev, const char *con_id, + enum of_gpio_flags *of_flags) +{ + /* These are the connection IDs we accept as legacy GPIO phandles */ + const char *whitelist[] = { + "wlf,ldoena", /* Arizona */ + "wlf,ldo1ena", /* WM8994 */ + "wlf,ldo2ena", /* WM8994 */ + }; + struct device_node *np = dev->of_node; + struct gpio_desc *desc; + int i; + + if (!IS_ENABLED(CONFIG_REGULATOR)) + return ERR_PTR(-ENOENT); + + if (!con_id) + return ERR_PTR(-ENOENT); + + for (i = 0; i < ARRAY_SIZE(whitelist); i++) + if (!strcmp(con_id, whitelist[i])) + break; + + if (i == ARRAY_SIZE(whitelist)) + return ERR_PTR(-ENOENT); + + desc = of_get_named_gpiod_flags(np, con_id, 0, of_flags); + return desc; +} + struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) @@ -126,6 +161,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, struct gpio_desc *desc; unsigned int i; + /* Try GPIO property "foo-gpios" and "foo-gpio" */ for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, @@ -140,6 +176,10 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, break; } + /* Special handling for regulator GPIOs if used */ + if (IS_ERR(desc)) + desc = of_find_regulator_gpio(dev, con_id, &of_flags); + if (IS_ERR(desc)) return desc; From patchwork Tue Jan 9 00:27:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 857180 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="TRfDC3Lb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zFtM71Mr1z9ryT for ; Tue, 9 Jan 2018 11:29:55 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753989AbeAIA3x (ORCPT ); Mon, 8 Jan 2018 19:29:53 -0500 Received: from mail-lf0-f68.google.com ([209.85.215.68]:41320 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753381AbeAIA3w (ORCPT ); Mon, 8 Jan 2018 19:29:52 -0500 Received: by mail-lf0-f68.google.com with SMTP id h137so14021571lfe.8 for ; Mon, 08 Jan 2018 16:29:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=avkwYsRDLnEN8RMuyk5MqCgDUscrPjP5mDXuM3OajSs=; b=TRfDC3LbDNUX3eNPES/k2bJgH7mZvZT49yehDvwg49gnuaqPsaFPvRVYZgz482oxsu ar5mOpK7bhIhQEZfVkkScCu991K0oryHpti6qVfs0DnxH1xUmUOF3LjAVusA7xyNSJBn jUtLNzn6oHXRDG7VNeEbe5iF/34RIj+BwxFTU= 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; bh=avkwYsRDLnEN8RMuyk5MqCgDUscrPjP5mDXuM3OajSs=; b=gJ5ZNOucJu43j5mwWQqvVaMfXGrqgYGqeU+5QnFGI2Sya0WX+dHSHJRCxE1N7x5AfG P3C8yDuFW0ypgZiZtB+6Y2IiYREM+xSn7Hh6rkyMPrp003MzQAjBh8bbAc7GN2l5IRic jyF954ZDVYRTen6/cxfx/hK4+67LAaGV4HjcAnD/gmD2BxwG8JKFsEFW//+mnPv6wv+I h3zKZpIjT+PTxWOvQRDsBWO4Nj+AzagpqiKxg6Dje6GPXfCui7B7KwyX69XIrT4Umy4/ XYu0FNjq4S36C5LRrrQzfpJGrZVsCqT/DerztT8y/B9hO7XMBEyx+oDX47QLwyLCBOri 7Bzg== X-Gm-Message-State: AKwxyteUztwuRrDiJ4U9VytpLTKrLIx2PgttyUiJyoHVS7UOJhrOmYV2 vjxzXoKIN2OnczgVOlTvVYBowQ== X-Google-Smtp-Source: ACJfBotzZNeubc1Rt8BX+EtEkpZwTQDRXoUN2i7UCMrXDcjlZA686aJBWji6VYxjeEi61Xhay0snFw== X-Received: by 10.25.24.147 with SMTP id 19mr1818035lfy.132.1515457790851; Mon, 08 Jan 2018 16:29:50 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id 2sm2583013lju.17.2018.01.08.16.29.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Jan 2018 16:29:50 -0800 (PST) From: Linus Walleij To: Liam Girdwood , Mark Brown , linux-gpio@vger.kernel.org, Rob Herring Cc: linux-kernel@vger.kernel.org, Linus Walleij Subject: [PATCH 2/4] gpio: Break out code to get a descriptor from a DT node Date: Tue, 9 Jan 2018 01:27:27 +0100 Message-Id: <20180109002727.22676-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Sometimes a GPIO needs to be taken from a node without a device associated with it. The fwnode accessor does this, let's however break out the DT code for now. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 117 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 34 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index aad84a6306c4..294c255e6227 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3629,18 +3629,83 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, } EXPORT_SYMBOL_GPL(gpiod_get_index); +/** + * gpiod_get_from_of_node() - obtain a GPIO from an OF node + * @node: handle of the OF node + * @propname: name of the DT property representing the GPIO + * @index: index of the GPIO to obtain for the consumer + * @dflags: GPIO initialization flags + * @label: label to attach to the requested GPIO + * + * Returns: + * On successful request the GPIO pin is configured in accordance with + * provided @dflags. If the node does not have the requested GPIO + * property, NULL is returned. + * + * In case of error an ERR_PTR() is returned. + */ +static struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) +{ + struct gpio_desc *desc = ERR_PTR(-ENODEV); + unsigned long lflags = 0; + enum of_gpio_flags flags; + bool active_low = false; + bool single_ended = false; + bool open_drain = false; + int ret; + + desc = of_get_named_gpiod_flags(node, propname, + index, &flags); + + if (!desc || IS_ERR(desc)) { + /* If it is not there, just return NULL */ + if (PTR_ERR(desc) == -ENOENT) + return NULL; + return desc; + } + + active_low = flags & OF_GPIO_ACTIVE_LOW; + single_ended = flags & OF_GPIO_SINGLE_ENDED; + open_drain = flags & OF_GPIO_OPEN_DRAIN; + + ret = gpiod_request(desc, label); + if (ret) + return ERR_PTR(ret); + + if (active_low) + lflags |= GPIO_ACTIVE_LOW; + + if (single_ended) { + if (open_drain) + lflags |= GPIO_OPEN_DRAIN; + else + lflags |= GPIO_OPEN_SOURCE; + } + + ret = gpiod_configure_flags(desc, propname, lflags, dflags); + if (ret < 0) { + gpiod_put(desc); + return ERR_PTR(ret); + } + + return desc; +} + /** * fwnode_get_named_gpiod - obtain a GPIO from firmware node * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO - * @index: index of the GPIO to obtain in the consumer + * @index: index of the GPIO to obtain for the consumer * @dflags: GPIO initialization flags * @label: label to attach to the requested GPIO * * This function can be used for drivers that get their configuration - * from firmware. + * from opaque firmware. * - * Function properly finds the corresponding GPIO using whatever is the + * The function properly finds the corresponding GPIO using whatever is the * underlying firmware interface and then makes sure that the GPIO * descriptor is requested before it is returned to the caller. * @@ -3657,53 +3722,37 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, { struct gpio_desc *desc = ERR_PTR(-ENODEV); unsigned long lflags = 0; - bool active_low = false; - bool single_ended = false; - bool open_drain = false; int ret; if (!fwnode) return ERR_PTR(-EINVAL); if (is_of_node(fwnode)) { - enum of_gpio_flags flags; - - desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, - index, &flags); - if (!IS_ERR(desc)) { - active_low = flags & OF_GPIO_ACTIVE_LOW; - single_ended = flags & OF_GPIO_SINGLE_ENDED; - open_drain = flags & OF_GPIO_OPEN_DRAIN; - } + desc = gpiod_get_from_of_node(to_of_node(fwnode), + propname, index, + dflags, + label); + return desc; } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; desc = acpi_node_get_gpiod(fwnode, propname, index, &info); - if (!IS_ERR(desc)) { - active_low = info.polarity == GPIO_ACTIVE_LOW; - ret = acpi_gpio_update_gpiod_flags(&dflags, info.flags); - if (ret) - pr_debug("Override GPIO initialization flags\n"); - } - } + if (IS_ERR(desc)) + return desc; - if (IS_ERR(desc)) - return desc; + ret = acpi_gpio_update_gpiod_flags(&dflags, info.flags); + if (ret) + pr_debug("Override GPIO initialization flags\n"); + if (info.polarity == GPIO_ACTIVE_LOW) + lflags |= GPIO_ACTIVE_LOW; + } + + /* Currently only ACPI takes this path */ ret = gpiod_request(desc, label); if (ret) return ERR_PTR(ret); - if (active_low) - lflags |= GPIO_ACTIVE_LOW; - - if (single_ended) { - if (open_drain) - lflags |= GPIO_OPEN_DRAIN; - else - lflags |= GPIO_OPEN_SOURCE; - } - ret = gpiod_configure_flags(desc, propname, lflags, dflags); if (ret < 0) { gpiod_put(desc); From patchwork Tue Jan 9 00:29:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 857181 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="LI8uvDxm"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zFtPh5xjMz9ryT for ; Tue, 9 Jan 2018 11:32:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752769AbeAIAcH (ORCPT ); Mon, 8 Jan 2018 19:32:07 -0500 Received: from mail-lf0-f67.google.com ([209.85.215.67]:39281 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752446AbeAIAcG (ORCPT ); Mon, 8 Jan 2018 19:32:06 -0500 Received: by mail-lf0-f67.google.com with SMTP id m8so7958304lfc.6 for ; Mon, 08 Jan 2018 16:32:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=hYzVO1NfD7aLCNyYOxGjiQZDW/K2oo2pqJ2cUszNCb8=; b=LI8uvDxm6pFnIfJ5TYCZekkxsQIwMhs0Hf3NnkBFfdB3/X016I+LitE1VDiKFddqSe vCKNbpeZpADDhUkgJUPLnTrJQr/rbCmLku7HO7RTuh+a0XcEd97bsYxRSFMKxB+v/mYd 4nr+dffqM8HB29cbbo/VYVI4kfL5XxHC/NSas= 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; bh=hYzVO1NfD7aLCNyYOxGjiQZDW/K2oo2pqJ2cUszNCb8=; b=djNDpP6xezBYm00O7w3iZR4qkQRuW46TMBML0P4p/innwQ2p/rh2awN4vqwzzOABI6 YaT30UbwJxs94K4NkVl+fxHjBy8SfN1XHTN/D9ziPPtX3UZWOBUnDNnnwdT4G6yc2621 1PCJkAn1QADlAf+fwvpwLhkglKdWIddl2pPdtvhVpWeAKTPWTMLhTcr9DZ0VpG+WciTt PZHNGrSUSoW7cenLph0cg3ChLl6vYkdg1f6737TDMw3g717cfuRooiZbIMP87/KjQTSP lBKZ2Y3L8piPau0dkvWwwpwysFUZTkKx2wmx30ixE6xJR88vrIELFGEJTXFVXogB+2bY 9aDQ== X-Gm-Message-State: AKwxytdftZdjgDiTiRKswQ5uO9UYQzR9AIxspha2b1ktrTsvW4AKoWo8 18HsJbvOLcSQXqTEyELv89kVzWfWc0g= X-Google-Smtp-Source: ACJfBovaqyaBqbCn/5ES1I4vmZOuk3F48SF89b/5UebfZxpuK17LfbJIcWNi5Pcu3Hjvf1Jg3mVDvA== X-Received: by 10.25.79.84 with SMTP id a20mr6000979lfk.123.1515457925244; Mon, 08 Jan 2018 16:32:05 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id h97sm2622629lji.77.2018.01.08.16.32.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Jan 2018 16:32:04 -0800 (PST) From: Linus Walleij To: Liam Girdwood , Mark Brown , linux-gpio@vger.kernel.org, Rob Herring Cc: linux-kernel@vger.kernel.org, Linus Walleij Subject: [PATCH 3/4] gpio: Export devm_gpiod_get_from_of_node() for consumers Date: Tue, 9 Jan 2018 01:29:59 +0100 Message-Id: <20180109002959.22738-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org We have been holding back on adding an API for fetching GPIO handles directly from device nodes, strongly preferring to get it from the spawn devices instead. The fwnode interface however already contains an API for doing this, as it is used for opaque device tree nodes or ACPI nodes for getting handles to LEDs and keys that use GPIO: those are specified as one child per LED/key in the device tree and are not individual devices. However regulators present a special problem as they already have helper functions to traverse the device tree from a regulator node and two levels down to fill in data, and as it already traverses GPIO nodes in its own way, and already holds a pointer to each regulators device tree node, it makes most sense to export an API to fetch the GPIO descriptor directly from the node. We only support the devm_* version for now, hopefully no non-devres version will be needed. Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 9 +++++---- drivers/gpio/gpiolib.h | 6 ++++++ include/linux/gpio/consumer.h | 17 +++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index afbff155a0ba..e82cc763633c 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -124,6 +124,48 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, } EXPORT_SYMBOL(devm_gpiod_get_index); +/** + * devm_gpiod_get_from_of_node() - obtain a GPIO from an OF node + * @dev: device for lifecycle management + * @node: handle of the OF node + * @propname: name of the DT property representing the GPIO + * @index: index of the GPIO to obtain for the consumer + * @dflags: GPIO initialization flags + * @label: label to attach to the requested GPIO + * + * Returns: + * On successful request the GPIO pin is configured in accordance with + * provided @dflags. + * + * In case of error an ERR_PTR() is returned. + */ +struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, + struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) +{ + struct gpio_desc **dr; + struct gpio_desc *desc; + + dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *), + GFP_KERNEL); + if (!dr) + return ERR_PTR(-ENOMEM); + + desc = gpiod_get_from_of_node(node, propname, index, dflags, label); + if (IS_ERR(desc)) { + devres_free(dr); + return desc; + } + + *dr = desc; + devres_add(dev, dr); + + return desc; +} +EXPORT_SYMBOL(devm_gpiod_get_from_of_node); + /** * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a * device's child node diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 294c255e6227..762a470030ce 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3644,10 +3644,10 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * * In case of error an ERR_PTR() is returned. */ -static struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) +struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) { struct gpio_desc *desc = ERR_PTR(-ENODEV); unsigned long lflags = 0; @@ -3693,6 +3693,7 @@ static struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, return desc; } +EXPORT_SYMBOL(gpiod_get_from_of_node); /** * fwnode_get_named_gpiod - obtain a GPIO from firmware node diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index af48322839c3..187056b8c6a6 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -189,6 +189,12 @@ void gpiod_set_array_value_complex(bool raw, bool can_sleep, struct gpio_desc **desc_array, int *value_array); +/* This is just passed between gpiolib and devres */ +struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label); + extern struct spinlock gpio_lock; extern struct list_head gpio_devices; diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 7447d85dbe2f..9f3cb651cb3c 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -150,8 +150,14 @@ struct gpio_desc *gpio_to_desc(unsigned gpio); int desc_to_gpio(const struct gpio_desc *desc); /* Child properties interface */ +struct device_node; struct fwnode_handle; +struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, + struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label); struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, enum gpiod_flags dflags, @@ -464,8 +470,19 @@ static inline int desc_to_gpio(const struct gpio_desc *desc) } /* Child properties interface */ +struct device_node; struct fwnode_handle; +static inline +struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, + struct device_node *node, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) +{ + return ERR_PTR(-ENOSYS); +} + static inline struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, From patchwork Tue Jan 9 00:32:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 857182 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="LPpTmnwK"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zFtSl0NSDz9ryT for ; Tue, 9 Jan 2018 11:34:47 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755022AbeAIAeq (ORCPT ); Mon, 8 Jan 2018 19:34:46 -0500 Received: from mail-lf0-f66.google.com ([209.85.215.66]:34284 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752907AbeAIAep (ORCPT ); Mon, 8 Jan 2018 19:34:45 -0500 Received: by mail-lf0-f66.google.com with SMTP id h140so14038814lfg.1 for ; Mon, 08 Jan 2018 16:34:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=8po5DbOU+D2gLBjycWLFcgyH4oDl6KaDXH+9d2m8vS8=; b=LPpTmnwKO3D+Q4t+b1/M+yxC7ZNLvjCyrhAGW+iPKZfRnzK7JOv1n3TCAVpERHNPUA ya001lavZkcoqN4fhbq1meWvLjzi2L51GC1ofkSUOLzLUrcKH0EfoxSNTeR/iKTWg+LX tpS7lryELa3O0wPcqmiCsRiojOVc/PQ+rDCEI= 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; bh=8po5DbOU+D2gLBjycWLFcgyH4oDl6KaDXH+9d2m8vS8=; b=PaI3s6qGkdeT2F/gIqjDi2lOsmiJoC5ymw/vPHK5pZTU6UJF90U2mVA93lkFJYtz+d B67dKnH5dAP3wgcs5/auYYUygeKdwpWu11s2EgDJU8RTHj3+nwmuwpswhqee3wHEWsnv S8wpEFk5753Mb8nZ7jjM0bRptY0PO5yT45Vu5SI7v7R3gcFIdruWEAPAix90//wUCfh9 ie7dbtogY/m1JHBuDS2CsJLnMq9K7mou+oImPbicE6erBXkzHVPZez7Qf3hLPNPIdP1g 03wWcLKHdYiiiZA0HNbR4a8gjba2wbpjBpyfGN3xu3ufKgT0G3knJjSA1KJSCTJvwtRT xtTw== X-Gm-Message-State: AKwxytfHDIhbJ/6jmdf+DEsRPhAgT7MlSTdLbnUdq4VIy8pxV3/Ss198 lqAxTc1k6CKPTBBmBeXjZ8FwsA== X-Google-Smtp-Source: ACJfBosx87GYIjrHWYvshyd0JU9dw75F/xkvuxieHkviBO0swnmJT/f5/J/PIDfkydfk+qZ1glihkQ== X-Received: by 10.25.215.223 with SMTP id q92mr5914496lfi.107.1515458083645; Mon, 08 Jan 2018 16:34:43 -0800 (PST) Received: from localhost.localdomain (c-cb7471d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.116.203]) by smtp.gmail.com with ESMTPSA id g192sm2342786lfg.69.2018.01.08.16.34.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 08 Jan 2018 16:34:42 -0800 (PST) From: Linus Walleij To: Liam Girdwood , Mark Brown , linux-gpio@vger.kernel.org, Rob Herring Cc: linux-kernel@vger.kernel.org, Linus Walleij Subject: [PATCH 4/4] gpio: of: Add special quirk to parse regulator flags Date: Tue, 9 Jan 2018 01:32:40 +0100 Message-Id: <20180109003240.22924-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.14.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org While most GPIOs are indicated to be active low or open drain using their twocell flags, we have legacy regulator bindings to take into account. Add a quirk respecting the special boolean active-high and open drain flags when parsing regulator nodes for GPIOs. This makes it possible to get rid of duplicated inversion semantics handling in the regulator core and any regulator drivers parsing and handling this separately. Unfortunately the old regulator inversion semantics are specified such that the presence or absence of "enable-active-high" solely controls the semantics, so we cannot deprecate this in favor of the phandle-provided inversion flag, instead any such phandle inversion flag provided in the second cell of a GPIO handle must be actively ignored, so we print a warning to contain the situation and make things easy for the users. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 9686922310a4..37bd3e8f2b0b 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -56,6 +56,42 @@ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip, return gpiochip_get_desc(chip, ret); } +static void of_gpio_flags_quirks(struct device_node *np, + enum of_gpio_flags *flags) +{ + /* + * Some GPIO fixed regulator quirks. + * Note that active low is the default. + */ + if (IS_ENABLED(CONFIG_REGULATOR) && + (of_device_is_compatible(np, "reg-fixed-voltage") || + of_device_is_compatible(np, "regulator-gpio"))) { + /* + * The regulator GPIO handles are specified such that the + * presence or absence of "enable-active-high" solely controls + * the polarity of the GPIO line. Any phandle flags must + * be actively ignored. + */ + if (*flags & OF_GPIO_ACTIVE_LOW) { + pr_warn("%s GPIO handle specifies active low - ignored\n", + of_node_full_name(np)); + *flags &= ~OF_GPIO_ACTIVE_LOW; + } + if (!of_property_read_bool(np, "enable-active-high")) + *flags |= OF_GPIO_ACTIVE_LOW; + } + /* + * Legacy open drain handling for fixed voltage regulators. + */ + if (IS_ENABLED(CONFIG_REGULATOR) && + of_device_is_compatible(np, "reg-fixed-voltage") && + of_property_read_bool(np, "gpio-open-drain")) { + *flags |= (OF_GPIO_SINGLE_ENDED | OF_GPIO_OPEN_DRAIN); + pr_info("%s uses legacy open drain flag - update the DTS if you can\n", + of_node_full_name(np)); + } +} + /** * of_get_named_gpiod_flags() - Get a GPIO descriptor and flags for GPIO API * @np: device node to get GPIO from @@ -93,6 +129,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, if (IS_ERR(desc)) goto out; + of_gpio_flags_quirks(np, flags); + pr_debug("%s: parsed '%s' property of node '%pOF[%d]' - status (%d)\n", __func__, propname, np, index, PTR_ERR_OR_ZERO(desc));