From patchwork Thu Sep 6 07:59:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 146071 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp194928ljw; Thu, 6 Sep 2018 00:59:33 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYt5cQXhdQ15aHq+llxq1O6rZMwEcfgkd00CYz5Oup0WWA38mtMzYhTpS232wGqZ/hsLWDX X-Received: by 2002:a17:902:f096:: with SMTP id go22mr1504862plb.183.1536220773461; Thu, 06 Sep 2018 00:59:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536220773; cv=none; d=google.com; s=arc-20160816; b=dEa0fofgBdPBbSavIJsMIsuIqXzDWTvmdPABphAtyk+OHAMLLQgPiTkfkZ02IwdOwc X052HF0maoIMYyLct7k4V1XVM/w205teEppbFbwu+4118OuJLxqVn6Y79MsEAmM0C+mw jgOph7HWQYsF0PeLGFwLQWX6jEHvTs/vaTdOppEvRa04oRNAWtS7Cg5Snyb1kbZswOXK VzzT5hBQaG66J9tnglmQz7FqM4M6qBlXaPgN7Woh4qCAbib2PclDHfxun9fbXh8oJ6Yf t8pwatKVviUyUbd/jh6uWG+ek6mQPeCd4DcDNgvN2Zhs6Aws7GDsLCNGNv262DjlVCcW yt6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=4P//Bhy39oDN7JIcuMYrXLtTeFqfAaKbP7iuSwlqE0k=; b=KY93pnoj+NCisCR/0ntYepxMOUxWpey6y7cpq9DScnt+UDknggV9pHPa3N4mdUyGE2 kIC1MSaucQlc6gRXDHj3M9QPl4K+O7YuxOhxqUAIxd1w8B+WnnCpZ1tjdD5m4WWUZW3b CmqFi+dMVR0VGGhJDhuY2W9BhBQVTyUq4VrQD2niLlg3xucyjkpR9N/EaJKNN1dvUykx ho6AmAs0GiWPlI3cwmIMvGXdJimT1hNiNlKDgoSqE43a7avAW4MMcQmv0R9N3DR6ETwn mRhLp69nlk+s4sfj+Gjr+D6b+k4Mu0f9JTrS3lEXknuFTpHNORH/0T+MtD8oCh7mdBz8 vOwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JRAFOiMA; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d20-v6si4596262pgj.535.2018.09.06.00.59.33; Thu, 06 Sep 2018 00:59:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JRAFOiMA; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728018AbeIFMd1 (ORCPT + 5 others); Thu, 6 Sep 2018 08:33:27 -0400 Received: from mail-lj1-f196.google.com ([209.85.208.196]:37946 "EHLO mail-lj1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728056AbeIFMd1 (ORCPT ); Thu, 6 Sep 2018 08:33:27 -0400 Received: by mail-lj1-f196.google.com with SMTP id p6-v6so8531871ljc.5 for ; Thu, 06 Sep 2018 00:59:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4P//Bhy39oDN7JIcuMYrXLtTeFqfAaKbP7iuSwlqE0k=; b=JRAFOiMAMouw4bAhDl80ErHqgQvb4IxCj06DM3WyjRo5DPWYZ0SoX0fZT1QMdJ1GM+ MQ4PxmervVu1fiJzFbbvAPxIK+abXlARM4AU8rGXrkkVsTC3DnoOoUKCYm83l86bI7Hl wmswj3s+PZRq0o0toxJtxowWUAFwaVdA8cKXY= 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:in-reply-to :references; bh=4P//Bhy39oDN7JIcuMYrXLtTeFqfAaKbP7iuSwlqE0k=; b=pPozCuqQZnO92EGxqWmq8Bfk1oJIOPy+L1YDLRWp3+1AN0kv59LDsg46qbIjTBAOXd HRGelsE0pusLBsahJ7mzOcN/+fODZqBUxZTNpij9xiPK0+aIWrY9YjzpJkfvKgZX9K8f iTZFCs8mbcS7v8GlzWmZg0Mt9smiqUCCEWe2rz8llJu5xSSl2hLH9rfXUfHOh52piH3g YT/9WKIe/cyxLOPiT83aUtFyFQrQCZIRhDM39sCJ0lA42mEc0Y3GUeia5+TChQt3GWsx C2ESSc+N4E/gk0zIBUPcyh8QT84wOqN6x3iyKhTb8qPBo3eNuen7DIq1Rlbf04szmuSE ddBg== X-Gm-Message-State: APzg51A/dQwunJzdtB2A4uQhfjIjWpY31bL1WRv4xKYT0t3q0uxlEGBE s6Kae0W5vTtDIt8Eeel1OmrOmw== X-Received: by 2002:a2e:21d5:: with SMTP id h82-v6mr1023422lji.46.1536220753580; Thu, 06 Sep 2018 00:59:13 -0700 (PDT) Received: from localhost.bredbandsbolaget (c-ae7b71d5.014-348-6c756e10.bbcust.telenor.se. [213.113.123.174]) by smtp.gmail.com with ESMTPSA id f129-v6sm690869lff.37.2018.09.06.00.59.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 06 Sep 2018 00:59:12 -0700 (PDT) From: Linus Walleij To: Dmitry Torokhov , linux-input@vger.kernel.org, linux-gpio@vger.kernel.org Cc: Andy Shevchenko , "Rafael J . Wysocki" , Sakari Ailus , Linus Walleij Subject: [PATCH 1/3] gpio: fwnode: Obtains descs from machine tables Date: Thu, 6 Sep 2018 09:59:00 +0200 Message-Id: <20180906075902.31240-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180906075902.31240-1-linus.walleij@linaro.org> References: <20180906075902.31240-1-linus.walleij@linaro.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org In some cases, such as the input gpio_keys code, we want to just call devm_fwnode_get_gpiod_from_child() and not worry about whether the GPIO descriptor is coming from DT or ACPI. To get rid of legacy hard-coded global GPIO numbers we also need to be able to look up GPIOs from machine GPIO descriptor tables. This patch fixes this by using machine tables as a fallback. Since the machine tables are flat and have no concept such as "children" as DT or ACPI has, we simply convert the child to an index in request order. In these few legacy use cases, only the children have GPIO descriptors assigned, the parent does not, so it should be safe to assume that we can represent the children as index 0..N of the parent "gpios" property in machine tables. As these pass the rest of the per-key configuration as an array in the struct gpio_keys_platform_data buttons array, it is natural for users to define the descriptor with an index when converting to machine GPIO descriptor tables. Since the board files have no concept of any "firmware node" we need to pass the device down from the devm_fwnode_*() calls so we can use the device name to locate the descriptor look-up tables, so we wrap fwnode_get_named_gpiod into fwnode_get_named_gpiod_dev() where current users that are DT-only or ACPI-only can pass NULL if they like. Cc: Dmitry Torokhov Cc: Andy Shevchenko Cc: Rafael J. Wysocki Cc: Sakari Ailus Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 4 +-- drivers/gpio/gpiolib.c | 47 +++++++++++++++++++++++++---------- include/linux/gpio/consumer.h | 19 +++++++++++--- 3 files changed, 51 insertions(+), 19 deletions(-) -- 2.17.1 diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index e82cc763633c..48464eafc670 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -206,8 +206,8 @@ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, snprintf(prop_name, sizeof(prop_name), "%s", gpio_suffixes[i]); - desc = fwnode_get_named_gpiod(child, prop_name, index, flags, - label); + desc = fwnode_get_named_gpiod_dev(dev, child, prop_name, index, + flags, label); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8f8a1999393..501ddcd9c86f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3994,7 +3994,8 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, EXPORT_SYMBOL(gpiod_get_from_of_node); /** - * fwnode_get_named_gpiod - obtain a GPIO from firmware node + * fwnode_get_named_gpiod_dev - obtain a GPIO from firmware node + * @dev: corresponding device, may be NULL for DT and ACPI * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO * @index: index of the GPIO to obtain for the consumer @@ -4002,7 +4003,7 @@ EXPORT_SYMBOL(gpiod_get_from_of_node); * @label: label to attach to the requested GPIO * * This function can be used for drivers that get their configuration - * from opaque firmware. + * from opaque firmware or machine descriptors in board files. * * The function properly finds the corresponding GPIO using whatever is the * underlying firmware interface and then makes sure that the GPIO @@ -4012,20 +4013,19 @@ EXPORT_SYMBOL(gpiod_get_from_of_node); * On successful request the GPIO pin is configured in accordance with * provided @dflags. * - * In case of error an ERR_PTR() is returned. + * In case of error an ERR_PTR() is returned. -ENOENT is returned if + * no GPIO descriptor can be located in DT, ACPI or board file tables. */ -struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) +struct gpio_desc *fwnode_get_named_gpiod_dev(struct device *dev, + struct fwnode_handle *fwnode, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) { struct gpio_desc *desc = ERR_PTR(-ENODEV); - unsigned long lflags = 0; + enum gpio_lookup_flags lflags = 0; int ret; - if (!fwnode) - return ERR_PTR(-EINVAL); - if (is_of_node(fwnode)) { desc = gpiod_get_from_of_node(to_of_node(fwnode), propname, index, @@ -4043,9 +4043,30 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (info.polarity == GPIO_ACTIVE_LOW) lflags |= GPIO_ACTIVE_LOW; + } else { + desc = gpiod_find(dev, propname, index, &lflags); + if (IS_ERR(desc)) + return desc; + /* + * This is a special case. This happens when you try + * to look up more than one child node from + * fwnode_get_*_from_child(): the boardfile tables + * do not have hierarchy or children, they are flat. + * To get out of this without having to reinvent a + * complex datastructure for board files, we convert + * the child to an index by simply trying the next + * descriptor index until we get something not busy + * (already requested) or -ENOENT. + */ + while (test_bit(FLAG_REQUESTED, &desc->flags)) { + index++; + desc = gpiod_find(dev, propname, index, + &lflags); + if (IS_ERR(desc)) + return desc; + } } - /* Currently only ACPI takes this path */ ret = gpiod_request(desc, label); if (ret) return ERR_PTR(ret); @@ -4058,7 +4079,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, return desc; } -EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod); +EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod_dev); /** * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 21ddbe440030..6ddb62a70f4a 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -157,10 +157,21 @@ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev, 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, - const char *label); +struct gpio_desc *fwnode_get_named_gpiod_dev(struct device *dev, + struct fwnode_handle *fwnode, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label); +static inline struct gpio_desc *fwnode_get_named_gpiod( + struct fwnode_handle *fwnode, + const char *propname, int index, + enum gpiod_flags dflags, + const char *label) +{ + /* Just a wrapper calling the former for device NULL */ + return fwnode_get_named_gpiod_dev(NULL, fwnode, propname, index, + dflags, label); +} struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, const char *con_id, int index, struct fwnode_handle *child,