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);