From patchwork Fri Nov 4 06:10:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BDC33C433FE for ; Fri, 4 Nov 2022 06:10:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230172AbiKDGK2 (ORCPT ); Fri, 4 Nov 2022 02:10:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230021AbiKDGKY (ORCPT ); Fri, 4 Nov 2022 02:10:24 -0400 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E116A28E36; Thu, 3 Nov 2022 23:10:22 -0700 (PDT) Received: by mail-pl1-x635.google.com with SMTP id u6so3977862plq.12; Thu, 03 Nov 2022 23:10:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0bbqffuj8GDPgiTExwtSV/0E3fSitJ002WmiZw+SKCw=; b=USWpivDglRC74Px6hvCW6cz8r58wFAGm88yHE+C+6P0tyq4Bcfl705uegGlbut0fIV bPr4byregreBm6NnlhcmPP1XuuGcO5Y9qUyjBuSX1V4Mc+D152+Es00EDLtwqFVvKTXM ONAGCRFuAT4IwPVwEqsbjYgPoyDvLWXW/AnRYVRxeUkTJFu+/GbBzc8u/NQ0zYRb8Y68 +cdmpfTCl25exYPp0YmmYGwHFA9Sv/IFzD97s7H3lPkCEpjujmaXr4pABYTnnI7gxpli cuwkVeBY4AbMsYvRVzHeV+ivyt4fhwX/wmWNOeXLXKB9IrNcBVzegZtyYqcSG2od9F6h tluQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0bbqffuj8GDPgiTExwtSV/0E3fSitJ002WmiZw+SKCw=; b=bL9wPqXWzp1cwX/NYvjVJib5NicdhKy/5D47K133ZZMaPit5JmV3GHb/fndLO+sxbM kIB/fL8AlO+HT/T3k5DrLllfYBHe2st0FbLLBKtpa2+uY0+2yKtkMOp2z/YhWDcf+jnw kbHzfDvij5Qoi0yoVzc0/KBwEteBTiYBe3IBc/+YYZPvlOa/Jejw26a1pOaF9cwgjKKg vGzTiX0BIa4hklHucrpcXWD+Qt/8fyF1FoY2OmYa3kPEIMxPBsmUVcSZaJGPBkfTW3+3 QaxlVqGL0I0Ft8o0jQIC9rJUt4FeViAAD0q3+XXo5tfdBCdWK4hTaXNPwUGh6EB3/7He 40yg== X-Gm-Message-State: ACrzQf0RTgV9ZtQJLR3GJwZ1tNKFyHn4T0B8LwzW6Kj9QbGFaWL78MvK +ZHQuR8gbG/pZiU8wG1K1QHbuX18Tyo= X-Google-Smtp-Source: AMsMyM78QLEAJK5f93YKlQITbBw7m6d1c432NDZDxCNnKU7GiLgehaSt1CKczX/69Th/BVuncP7fjw== X-Received: by 2002:a17:90b:4a92:b0:213:2421:5f38 with SMTP id lp18-20020a17090b4a9200b0021324215f38mr35950804pjb.10.1667542222248; Thu, 03 Nov 2022 23:10:22 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:21 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/6] gpiolib: of: change of_find_gpio() to accept device node Date: Thu, 3 Nov 2022 23:10:11 -0700 Message-Id: <20221031-gpiolib-swnode-v1-1-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org In preparation of switching all OF-based GPIO lookups to go through of_find_gpio() let's change it to accept device node as its argument as we do not always have access to device structure. Signed-off-by: Dmitry Torokhov --- drivers/gpio/gpiolib-of.c | 7 +++---- drivers/gpio/gpiolib-of.h | 4 ++-- drivers/gpio/gpiolib.c | 5 +++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 012e66344b56..607bf4358ff7 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -605,7 +605,7 @@ static const of_find_gpio_quirk of_find_gpio_quirks[] = { NULL }; -struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, +struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, unsigned int idx, unsigned long *flags) { char prop_name[32]; /* 32 is max size of property name */ @@ -623,8 +623,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, snprintf(prop_name, sizeof(prop_name), "%s", gpio_suffixes[i]); - desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx, - &of_flags); + desc = of_get_named_gpiod_flags(np, prop_name, idx, &of_flags); if (!gpiod_not_found(desc)) break; @@ -632,7 +631,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, /* Properly named GPIO was not found, try workarounds */ for (q = of_find_gpio_quirks; gpiod_not_found(desc) && *q; q++) - desc = (*q)(dev->of_node, con_id, idx, &of_flags); + desc = (*q)(np, con_id, idx, &of_flags); if (IS_ERR(desc)) return desc; diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h index 22d314229bbd..c44be0f285f3 100644 --- a/drivers/gpio/gpiolib-of.h +++ b/drivers/gpio/gpiolib-of.h @@ -17,7 +17,7 @@ struct gpio_desc; struct gpio_device; #ifdef CONFIG_OF_GPIO -struct gpio_desc *of_find_gpio(struct device *dev, +struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, unsigned int idx, unsigned long *lookupflags); @@ -31,7 +31,7 @@ struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, enum gpiod_flags dflags, const char *label); #else -static inline struct gpio_desc *of_find_gpio(struct device *dev, +static inline struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, unsigned int idx, unsigned long *lookupflags) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8faedca6b14..c5a80def8be4 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4070,14 +4070,15 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, int ret; /* Maybe we have a device name, maybe not */ const char *devname = dev ? dev_name(dev) : "?"; - const struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; + struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); /* Using device tree? */ if (is_of_node(fwnode)) { dev_dbg(dev, "using device tree for GPIO lookup\n"); - desc = of_find_gpio(dev, con_id, idx, &lookupflags); + desc = of_find_gpio(to_of_node(fwnode), + con_id, idx, &lookupflags); } else if (is_acpi_node(fwnode)) { dev_dbg(dev, "using ACPI for GPIO lookup\n"); desc = acpi_find_gpio(dev, con_id, idx, &flags, &lookupflags); From patchwork Fri Nov 4 06:10:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621544 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B3F2C43217 for ; Fri, 4 Nov 2022 06:10:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230315AbiKDGKa (ORCPT ); Fri, 4 Nov 2022 02:10:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230075AbiKDGK0 (ORCPT ); Fri, 4 Nov 2022 02:10:26 -0400 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3EB5BFA; Thu, 3 Nov 2022 23:10:24 -0700 (PDT) Received: by mail-pf1-x42e.google.com with SMTP id v28so3639572pfi.12; Thu, 03 Nov 2022 23:10:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SYYciqss2h8x47THt+MGpIvKBIq3VnELKV/9J5zDz4Y=; b=EGq1zbBxoKvqhbPCQ6Dig8/2CDIPgcTwz2LVK8P/QSjWyyJlsd3MLn0upj7VjzSVuw 0D7ZN47IlnQsUuy5v1F4QN1NuWT2IcrSFJh5ZnPuNj7LR5+dpIvz+Pk59MUnCCGt98VT r1zqbo8lAz13T3UI4earjGRWHdHpZCyggba4Q33nUy4m5yBf1tTbgtxY71Aq/QX1A05Y NiFmZz8q8o8kMx1sK3rDJF5fBumvd5JRqR5HU1EB3b4FbvrGtoA2XmHTMjkXLAEHNk6P D99clZZyiEzLTB5+ZYG8+8aLmyCJHq1BXXuZcPcLwOhdAlEzM65tWmamxcRfLjIB5hKB VP6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SYYciqss2h8x47THt+MGpIvKBIq3VnELKV/9J5zDz4Y=; b=AISES1IqvQjXgjabD5zYarGhe40NFXo7HccrYbVoWuQ1frYurhSjKXCcjVHn0AtAVi B+nepoBunbHlEnLaQ6RIKrJ8fncZNzwZklQUB14e9+sa8vFLXG8+ACd1OjxMmNB1PWOZ siwZuf5kRTRwTDhy970XRBZNEXWNZIjFp7oSNHEzBxgBASVUQNMw0ZRcO17IXwfMBIDa NN7MaqXXoqoidJhhOtbw/bCgvKZl0f5CU29Z8M5qCwcgAZB9ihlBqPi7i7RqNM4Nm8Kt +yb6qjMe4v0hmyKlExB4RM+qwTRz9QEZlvLZ6kl0BA5NwXNgAoSFl3R0tjlexlA/KU7R TogQ== X-Gm-Message-State: ACrzQf3nGc6aR7ywIdfr7Izqtoya4nwYIVfyohgMDIiNXjoGb7CJCMVf J+3ziNgu0z4oiRBWdWKEx1pJoXF970U= X-Google-Smtp-Source: AMsMyM5dIMO1BxCCYisjc9VpDbbeMK6sYOxmq6P0rmTku1dbFrz5VWosrPBiuRYq6LU56GyeSmwnug== X-Received: by 2002:a65:44c1:0:b0:428:ab8f:62dd with SMTP id g1-20020a6544c1000000b00428ab8f62ddmr29328951pgs.211.1667542224082; Thu, 03 Nov 2022 23:10:24 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:23 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/6] gpiolib: acpi: change acpi_find_gpio() to accept firmware node Date: Thu, 3 Nov 2022 23:10:12 -0700 Message-Id: <20221031-gpiolib-swnode-v1-2-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org In preparation of switching all ACPI-based GPIO lookups to go through acpi_find_gpio() let's change it to accept device node as its argument as we do not always have access to device structure. Signed-off-by: Dmitry Torokhov --- drivers/gpio/gpiolib-acpi.c | 8 ++++++-- drivers/gpio/gpiolib-acpi.h | 4 ++-- drivers/gpio/gpiolib.c | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 064ba5150fd4..ccb74e208989 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -906,18 +906,22 @@ static bool acpi_can_fallback_to_crs(struct acpi_device *adev, return con_id == NULL; } -struct gpio_desc *acpi_find_gpio(struct device *dev, +struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, unsigned long *lookupflags) { - struct acpi_device *adev = ACPI_COMPANION(dev); + struct acpi_device *adev; struct acpi_gpio_info info; struct gpio_desc *desc; char propname[32]; int i; + adev = to_acpi_device_node(fwnode); + if (!adev) + return ERR_PTR(-ENODEV); + /* Try first from _DSD */ for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) { diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h index 01e0cb480a00..bd1f9b92ea9e 100644 --- a/drivers/gpio/gpiolib-acpi.h +++ b/drivers/gpio/gpiolib-acpi.h @@ -60,7 +60,7 @@ int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, struct acpi_gpio_info *info); -struct gpio_desc *acpi_find_gpio(struct device *dev, +struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, @@ -95,7 +95,7 @@ acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, } static inline struct gpio_desc * -acpi_find_gpio(struct device *dev, const char *con_id, +acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, unsigned long *lookupflags) { diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c5a80def8be4..eebcdaca5e06 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4081,7 +4081,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, con_id, idx, &lookupflags); } else if (is_acpi_node(fwnode)) { dev_dbg(dev, "using ACPI for GPIO lookup\n"); - desc = acpi_find_gpio(dev, con_id, idx, &flags, &lookupflags); + desc = acpi_find_gpio(fwnode, + con_id, idx, &flags, &lookupflags); } /* From patchwork Fri Nov 4 06:10:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3562C4332F for ; Fri, 4 Nov 2022 06:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231140AbiKDGKw (ORCPT ); Fri, 4 Nov 2022 02:10:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43478 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230147AbiKDGK1 (ORCPT ); Fri, 4 Nov 2022 02:10:27 -0400 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D48128E30; Thu, 3 Nov 2022 23:10:26 -0700 (PDT) Received: by mail-pl1-x62e.google.com with SMTP id io19so3993646plb.8; Thu, 03 Nov 2022 23:10:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=J8by26zBfJpt7L2atZn5FOME6ope8yoyFn+mCDRyv34=; b=IVQ81+VemRohBHMazkHsK1zuoXcjUZg9BU1wvONtzW2NM+XC/VQ+nCASVAOOLOEEyi Rx9R0wZuZb1/HQn74VuvinoHx2x1WCAK1pvYU7hiNNQnCgE11Z8BUHDtHYKtu/UPsAwS IK9pg1t/+eDrYtm+PxdJQ8i2dFJJajnVz9IkL/Ka4A+b42n1AvaUDhHOO8DRWB6/QfyZ gq7QOQ+yeQ4Fj8uoTTFaWD8hRj+Qo/mWWLQWxTeN+YBU2TEKl2wF82Nx7Xk6Zk4LgqyA ye+Ky1G3pg+X+RcTH3RwQx+lmaIARO6F5uC6147XoPn1zkJZ+thySI9DRFvY5CBz3FZ0 /0Pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=J8by26zBfJpt7L2atZn5FOME6ope8yoyFn+mCDRyv34=; b=qdCaktIo+aow54biQhre3wEUrZDk4UgzNz8p7NOHCS/VFbTBFLIL2JBy+xqcJoCXFT eKEKCxg3QFDq1/7GsNm/58I/uRoefOxtr5/yl/Ww8DQHxA45jdVjkmpX1moTYdNZyheP EaK2CYlBAyiChewFZcEnKghfKV99UFY6GDcQE1MdXhNNfyyrViaB5l+H/zLwQfa/phAq AjKXZiZiO2uWJxr4aXPiWcBINOwEgSMDa3OPx6dQkOjoWhvbwtXP63JpZ+VGFLZ6dy52 mkRl8GmwOIjF1PxbqtYQJG03bGJqSPsnoC4EsB4LVQUayKdRGPeZDj8ic1rardH8UzgW 7nSg== X-Gm-Message-State: ACrzQf0wwfoZGz3zUtLFgr2jKRIVUldTh2ZjsmRH3F3E4JdXpOObv8dk 9M6YxzKq3+anvxOQua90Jds= X-Google-Smtp-Source: AMsMyM6vzXSDhl7+O55gjdP8y0qvfQ5J4wxmwlw3fbsZLEIbjhT5vfygJnKu5Ds7uhEGzvgvogbzrg== X-Received: by 2002:a17:903:2452:b0:186:99e0:672d with SMTP id l18-20020a170903245200b0018699e0672dmr34142314pls.95.1667542225831; Thu, 03 Nov 2022 23:10:25 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:25 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/6] gpiolib: acpi: teach acpi_find_gpio() to handle data-only nodes Date: Thu, 3 Nov 2022 23:10:13 -0700 Message-Id: <20221031-gpiolib-swnode-v1-3-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org In preparation of switching all ACPI-based GPIO lookups to go through acpi_find_gpio() we need to make sure it can handle data-only ACPI nodes, same as existing acpi_node_get_gpiod(). Signed-off-by: Dmitry Torokhov --- drivers/gpio/gpiolib-acpi.c | 76 +++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index ccb74e208989..d51bf2a3203d 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -864,8 +864,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, * function only returns the first. */ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, - const char *propname, int index, - struct acpi_gpio_info *info) + const char *propname, + int index, + struct acpi_gpio_info *info) { struct acpi_gpio_lookup lookup; int ret; @@ -896,6 +897,44 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, return ret ? ERR_PTR(ret) : lookup.desc; } +/** + * acpi_get_gpiod_from_data() - get a GPIO descriptor from ACPI data node + * @fwnode: pointer to an ACPI firmware node to get the GPIO information from + * @propname: Property name of the GPIO + * @index: index of GpioIo/GpioInt resource (starting from %0) + * @info: info pointer to fill in (optional) + * + * This function uses the property-based GPIO lookup to get to the GPIO + * resource with the relevant information from a data-only ACPI firmware node + * and uses that to obtain the GPIO descriptor to return. + * + * If the GPIO cannot be translated or there is an error an ERR_PTR is + * returned. + */ +static struct gpio_desc *acpi_get_gpiod_from_data(struct fwnode_handle *fwnode, + const char *propname, + int index, + struct acpi_gpio_info *info) +{ + struct acpi_gpio_lookup lookup; + int ret; + + if (!is_acpi_data_node(fwnode)) + return ERR_PTR(-ENODEV); + + if (!propname) + return ERR_PTR(-EINVAL); + + lookup.index = index; + + ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); + if (ret) + return ERR_PTR(ret); + + ret = acpi_gpio_resource_lookup(&lookup, info); + return ret ? ERR_PTR(ret) : lookup.desc; +} + static bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) { @@ -912,16 +951,12 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, enum gpiod_flags *dflags, unsigned long *lookupflags) { - struct acpi_device *adev; + struct acpi_device *adev = to_acpi_device_node(fwnode); struct acpi_gpio_info info; struct gpio_desc *desc; char propname[32]; int i; - adev = to_acpi_device_node(fwnode); - if (!adev) - return ERR_PTR(-ENODEV); - /* Try first from _DSD */ for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) { @@ -932,7 +967,12 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, gpio_suffixes[i]); } - desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); + if (adev) + desc = acpi_get_gpiod_by_index(adev, + propname, idx, &info); + else + desc = acpi_get_gpiod_from_data(fwnode, + propname, idx, &info); if (!IS_ERR(desc)) break; if (PTR_ERR(desc) == -EPROBE_DEFER) @@ -941,7 +981,7 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, /* Then from plain _CRS GPIOs */ if (IS_ERR(desc)) { - if (!acpi_can_fallback_to_crs(adev, con_id)) + if (!adev || !acpi_can_fallback_to_crs(adev, con_id)) return ERR_PTR(-ENOENT); desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); @@ -979,29 +1019,13 @@ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, struct acpi_gpio_info *info) { - struct acpi_gpio_lookup lookup; struct acpi_device *adev; - int ret; adev = to_acpi_device_node(fwnode); if (adev) return acpi_get_gpiod_by_index(adev, propname, index, info); - if (!is_acpi_data_node(fwnode)) - return ERR_PTR(-ENODEV); - - if (!propname) - return ERR_PTR(-EINVAL); - - memset(&lookup, 0, sizeof(lookup)); - lookup.index = index; - - ret = acpi_gpio_property_lookup(fwnode, propname, index, &lookup); - if (ret) - return ERR_PTR(ret); - - ret = acpi_gpio_resource_lookup(&lookup, info); - return ret ? ERR_PTR(ret) : lookup.desc; + return acpi_get_gpiod_from_data(fwnode, propname, index, info); } /** From patchwork Fri Nov 4 06:10:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FB93C4167E for ; Fri, 4 Nov 2022 06:10:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230233AbiKDGKz (ORCPT ); Fri, 4 Nov 2022 02:10:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230267AbiKDGKa (ORCPT ); Fri, 4 Nov 2022 02:10:30 -0400 Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43D4929342; Thu, 3 Nov 2022 23:10:28 -0700 (PDT) Received: by mail-pg1-x530.google.com with SMTP id e129so3567810pgc.9; Thu, 03 Nov 2022 23:10:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=a2/aVQ0pMiGyvsxYh3JvcOH3C/8mHWBmqc26g+70UqY=; b=EuGPyG06evvdLIq7DCUkREdSdsmfXSS2DqkyqHCmHJBk4jtg3BgUwPIB287GilRWuq S7ZMfZRi2Rk+oYayJxiCrvSgyPviSjyvjI9XMKi49eVUxLbjq5tVG/oKuKxFfZ+jmYll c3VsOhKT1dYgPMui09dDcTnqu1aMW1ti8NqbyTV6QnlU5EJ6lgfcY0RNPNPXnqPILM+E wEIHbsqIvYJfbTEmk3srvwSvzCvsHfjAqKjHdClQWK4hAS7CeH37AX+9Ew0rbB64wcVi wDwN8oBxKgvsd33J6dNAttl23wXFhYtnt6UcJ6etFikv06DA/Wkr2ktWad5yE307AFa1 PR9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a2/aVQ0pMiGyvsxYh3JvcOH3C/8mHWBmqc26g+70UqY=; b=nidHMFXM4FwrPq9EJBRxu5Gwyl+P5QRZcoM+3swUHivMeeLdiJYvOxlQ+/DAJW621G bPQurNEoWpgc+B1Sf6SoQcEJvPzuIyvxONg80aYJkBonJmXtaMeptyrQeRaJAmZJ3E3b XwoJeAHTiWEXW87Ze7Ohv2aRYisK4UXXFe46mlqhWbG73M2ezfSIPDlDUWhIC+NZcFsm 8e+LbUN3YIGQCZV9y69zJl4Gea+u41zFS6dysyPS74sA/9r8OTRGU3Oyi48i1erCyJin 3Y1+BVJ537XSakIHHbeqwJoM0JusBeP49H8t1e6i5rbOZeFgVEiyG9zACiNN2uqKlO31 7R0w== X-Gm-Message-State: ACrzQf2xP3Mfr2st60E0d8SaRMRiZiGFEddJxRHimrAJlS65bemK1jZj /Ic1Cxll9kGrcXvSrZYjctgnZUQrhj4= X-Google-Smtp-Source: AMsMyM4Xk/WfThtJCg+gf2/ER+SintXyzxSQPqF4lS+NEW33Ua6QoayP2unbg42aiJWOTOfyw7UU2A== X-Received: by 2002:a05:6a02:186:b0:431:25fb:f1fe with SMTP id bj6-20020a056a02018600b0043125fbf1femr29925755pgb.130.1667542227622; Thu, 03 Nov 2022 23:10:27 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:26 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/6] gpiolib: acpi: avoid leaking ACPI details into upper gpiolib layers Date: Thu, 3 Nov 2022 23:10:14 -0700 Message-Id: <20221031-gpiolib-swnode-v1-4-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org There is no need for the generic parts of GPIOLIB to be aware of implementation details of ACPI-bases lookups. Signed-off-by: Dmitry Torokhov --- drivers/gpio/gpiolib-acpi.c | 51 ++++++++++++++++++++++++++++++++++++++------- drivers/gpio/gpiolib-acpi.h | 46 +++------------------------------------- drivers/gpio/gpiolib.c | 8 ++----- 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d51bf2a3203d..1bc386032ca8 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -89,6 +89,30 @@ struct acpi_gpio_chip { struct list_head deferred_req_irqs_list_entry; }; +/** + * struct acpi_gpio_info - ACPI GPIO specific information + * @adev: reference to ACPI device which consumes GPIO resource + * @flags: GPIO initialization flags + * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo + * @pin_config: pin bias as provided by ACPI + * @polarity: interrupt polarity as provided by ACPI + * @triggering: triggering type as provided by ACPI + * @wake_capable: wake capability as provided by ACPI + * @debounce: debounce timeout as provided by ACPI + * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping + */ +struct acpi_gpio_info { + struct acpi_device *adev; + enum gpiod_flags flags; + bool gpioint; + int pin_config; + int polarity; + int triggering; + bool wake_capable; + unsigned int debounce; + unsigned int quirks; +}; + /* * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a @@ -670,8 +694,8 @@ __acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, enum gpiod_flags update) return ret; } -int -acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) +static int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, + struct acpi_gpio_info *info) { struct device *dev = &info->adev->dev; enum gpiod_flags old = *flags; @@ -690,8 +714,8 @@ acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *inf return ret; } -int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, - struct acpi_gpio_info *info) +static int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, + struct acpi_gpio_info *info) { switch (info->pin_config) { case ACPI_PIN_CONFIG_PULLUP: @@ -1005,7 +1029,8 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, * @fwnode: pointer to an ACPI firmware node to get the GPIO information from * @propname: Property name of the GPIO * @index: index of GpioIo/GpioInt resource (starting from %0) - * @info: info pointer to fill in (optional) + * @lflags: bitmask of gpio_lookup_flags GPIO_* values + * @dflags: gpiod initialization flags * * If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it. * Otherwise (i.e. it is a data-only non-device object), use the property-based @@ -1017,15 +1042,25 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, */ struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, - struct acpi_gpio_info *info) + unsigned long *lflags, + enum gpiod_flags *dflags) { + struct acpi_gpio_info info; struct acpi_device *adev; + struct gpio_desc *desc; adev = to_acpi_device_node(fwnode); if (adev) - return acpi_get_gpiod_by_index(adev, propname, index, info); + desc = acpi_get_gpiod_by_index(adev, propname, index, &info); + else + desc = acpi_get_gpiod_from_data(fwnode, propname, index, &info); - return acpi_get_gpiod_from_data(fwnode, propname, index, info); + if (!IS_ERR(desc)) { + acpi_gpio_update_gpiod_flags(dflags, &info); + acpi_gpio_update_gpiod_lookup_flags(lflags, &info); + } + + return desc; } /** diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h index bd1f9b92ea9e..8880615327ac 100644 --- a/drivers/gpio/gpiolib-acpi.h +++ b/drivers/gpio/gpiolib-acpi.h @@ -22,30 +22,6 @@ struct gpio_chip; struct gpio_desc; struct gpio_device; -/** - * struct acpi_gpio_info - ACPI GPIO specific information - * @adev: reference to ACPI device which consumes GPIO resource - * @flags: GPIO initialization flags - * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo - * @pin_config: pin bias as provided by ACPI - * @polarity: interrupt polarity as provided by ACPI - * @triggering: triggering type as provided by ACPI - * @wake_capable: wake capability as provided by ACPI - * @debounce: debounce timeout as provided by ACPI - * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping - */ -struct acpi_gpio_info { - struct acpi_device *adev; - enum gpiod_flags flags; - bool gpioint; - int pin_config; - int polarity; - int triggering; - bool wake_capable; - unsigned int debounce; - unsigned int quirks; -}; - #ifdef CONFIG_ACPI void acpi_gpiochip_add(struct gpio_chip *chip); void acpi_gpiochip_remove(struct gpio_chip *chip); @@ -55,11 +31,6 @@ void acpi_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev); void acpi_gpiochip_request_interrupts(struct gpio_chip *chip); void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); -int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, - struct acpi_gpio_info *info); -int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, - struct acpi_gpio_info *info); - struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int idx, @@ -67,7 +38,8 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, unsigned long *lookupflags); struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, int index, - struct acpi_gpio_info *info); + unsigned long *lflags, + enum gpiod_flags *dflags); int acpi_gpio_count(struct device *dev, const char *con_id); #else @@ -82,18 +54,6 @@ acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { } static inline void acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { } -static inline int -acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info) -{ - return 0; -} -static inline int -acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags, - struct acpi_gpio_info *info) -{ - return 0; -} - static inline struct gpio_desc * acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, unsigned int idx, enum gpiod_flags *dflags, @@ -103,7 +63,7 @@ acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, } static inline struct gpio_desc * acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, - int index, struct acpi_gpio_info *info) + int index, unsigned long *lflags, enum gpiod_flags *dflags) { return ERR_PTR(-ENXIO); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index eebcdaca5e06..f0a7a59ac630 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3838,14 +3838,10 @@ static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, label); return desc; } else if (is_acpi_node(fwnode)) { - struct acpi_gpio_info info; - - desc = acpi_node_get_gpiod(fwnode, propname, index, &info); + desc = acpi_node_get_gpiod(fwnode, propname, index, + &lflags, &dflags); if (IS_ERR(desc)) return desc; - - acpi_gpio_update_gpiod_flags(&dflags, &info); - acpi_gpio_update_gpiod_lookup_flags(&lflags, &info); } else { return ERR_PTR(-EINVAL); } From patchwork Fri Nov 4 06:10:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621543 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00D1DC43219 for ; Fri, 4 Nov 2022 06:10:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230443AbiKDGKx (ORCPT ); Fri, 4 Nov 2022 02:10:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230377AbiKDGKd (ORCPT ); Fri, 4 Nov 2022 02:10:33 -0400 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0432A2935C; Thu, 3 Nov 2022 23:10:30 -0700 (PDT) Received: by mail-pf1-x42e.google.com with SMTP id z26so3675819pff.1; Thu, 03 Nov 2022 23:10:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/WeCjGQ1uvTl0Wb0p7VnpqtsqrS1wW0ymF0shYhz+Ak=; b=dV3HKd7qRVRaHkFmVmCcjRaixBIonYsxsjW771JRnq6BeiwxWizfIGU/6Ki6Wwl+l5 DaU1k2zxG2ILzpboRw59D+ppMgr4A4xCaMppToL1dV3qj/TcXmDojabjvIpc/jtSSot8 /c08dduTY8vqgh0RKIfI+8i14QCAuqY50wBX83zwVl3VBq81KRxWVmwkJwH2epu2qgIl GdIlcpJK9DXawNEzRGKL3oWAZLlzdzxUheLxPRtQSGGS1lylKNNZ1zopC8K8bpUtGGgq l12r1/m/RCnxS2VkDT5kpGRrVVaNYcLKMj2nZIZTfb2+uM4/CNrddHerfFnks+BsVFaI KYnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/WeCjGQ1uvTl0Wb0p7VnpqtsqrS1wW0ymF0shYhz+Ak=; b=L0V+mkIMkFqmKyqkkh3nfUXJnl9+2TRocvtjehb3p05qIkrI9M1MMmJwpdO3/4JMid XtlgVcyQ+gsJoJcehskWry73hWVmJSxBMrlk0RKC3JPkxZ8l1PFJ35/iZwgWoAdbLqgS EEY6NF4ycYieMcy+Vuem9Qo2UL4rMRLEq35uJaSwtzEx5G+2gbth98hdg966zT1NY9E7 N9SDJrERYzY+AnlKNmLQ+jD22JwHdRKW3OWQMM+tlv9ZHHsiIJlcWUlqITLF2vqdHfu1 8TLY2gZiBUFMLOVkAyLRFQkQhPXcajPCZKE3hvMqZ8L2LAWRkgRIA9dIBezt5BC352kL 7i3A== X-Gm-Message-State: ACrzQf14sw0Rl/4H5Mx/JSvDGU3Gm1FunOmVAgUTYCaKfI/hf+j8Z/8F wYXoja6n02Xo8yTPDHs++/4= X-Google-Smtp-Source: AMsMyM7xpCgztqvwVIbFwItv64vo9D6nEcUenU5MYwwDUsnAiOyy/JxcQuUI729aLmYgzIQnS0/Svg== X-Received: by 2002:a63:c146:0:b0:46f:c9e8:777d with SMTP id p6-20020a63c146000000b0046fc9e8777dmr20503447pgi.459.1667542229288; Thu, 03 Nov 2022 23:10:29 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:28 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 5/6] gpiolib: consolidate GPIO lookups Date: Thu, 3 Nov 2022 23:10:15 -0700 Message-Id: <20221031-gpiolib-swnode-v1-5-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Ensure that all paths to obtain/look up GPIOD from generic consumer-visible APIs go through the new gpiod_find_and_request() helper, so that we can easily extend it with support for new firmware mechanisms. Signed-off-by: Dmitry Torokhov --- drivers/gpio/gpiolib-acpi.c | 39 --------- drivers/gpio/gpiolib-acpi.h | 10 --- drivers/gpio/gpiolib-of.c | 45 ---------- drivers/gpio/gpiolib-of.h | 12 --- drivers/gpio/gpiolib.c | 206 +++++++++++++++++--------------------------- 5 files changed, 80 insertions(+), 232 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 1bc386032ca8..bed0380c5136 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -1024,45 +1024,6 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, return desc; } -/** - * acpi_node_get_gpiod() - get a GPIO descriptor from ACPI resources - * @fwnode: pointer to an ACPI firmware node to get the GPIO information from - * @propname: Property name of the GPIO - * @index: index of GpioIo/GpioInt resource (starting from %0) - * @lflags: bitmask of gpio_lookup_flags GPIO_* values - * @dflags: gpiod initialization flags - * - * If @fwnode is an ACPI device object, call acpi_get_gpiod_by_index() for it. - * Otherwise (i.e. it is a data-only non-device object), use the property-based - * GPIO lookup to get to the GPIO resource with the relevant information and use - * that to obtain the GPIO descriptor to return. - * - * If the GPIO cannot be translated or there is an error an ERR_PTR is - * returned. - */ -struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, - const char *propname, int index, - unsigned long *lflags, - enum gpiod_flags *dflags) -{ - struct acpi_gpio_info info; - struct acpi_device *adev; - struct gpio_desc *desc; - - adev = to_acpi_device_node(fwnode); - if (adev) - desc = acpi_get_gpiod_by_index(adev, propname, index, &info); - else - desc = acpi_get_gpiod_from_data(fwnode, propname, index, &info); - - if (!IS_ERR(desc)) { - acpi_gpio_update_gpiod_flags(dflags, &info); - acpi_gpio_update_gpiod_lookup_flags(lflags, &info); - } - - return desc; -} - /** * acpi_dev_gpio_irq_wake_get_by() - Find GpioInt and translate it to Linux IRQ number * @adev: pointer to a ACPI device to get IRQ from diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h index 8880615327ac..9475f99a9694 100644 --- a/drivers/gpio/gpiolib-acpi.h +++ b/drivers/gpio/gpiolib-acpi.h @@ -36,10 +36,6 @@ struct gpio_desc *acpi_find_gpio(struct fwnode_handle *fwnode, unsigned int idx, enum gpiod_flags *dflags, unsigned long *lookupflags); -struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode, - const char *propname, int index, - unsigned long *lflags, - enum gpiod_flags *dflags); int acpi_gpio_count(struct device *dev, const char *con_id); #else @@ -61,12 +57,6 @@ acpi_find_gpio(struct fwnode_handle *fwnode, const char *con_id, { return ERR_PTR(-ENOENT); } -static inline struct gpio_desc * -acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname, - int index, unsigned long *lflags, enum gpiod_flags *dflags) -{ - return ERR_PTR(-ENXIO); -} static inline int acpi_gpio_count(struct device *dev, const char *con_id) { return -ENODEV; diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 607bf4358ff7..7508628b9f6e 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -390,51 +390,6 @@ static unsigned long of_convert_gpio_flags(enum of_gpio_flags flags) return lflags; } -/** - * 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. - * - * In case of error an ERR_PTR() is returned. - */ -struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) -{ - unsigned long lflags; - struct gpio_desc *desc; - enum of_gpio_flags of_flags; - int ret; - - desc = of_get_named_gpiod_flags(node, propname, index, &of_flags); - if (!desc || IS_ERR(desc)) - return desc; - - ret = gpiod_request(desc, label); - if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) - return desc; - if (ret) - return ERR_PTR(ret); - - lflags = of_convert_gpio_flags(of_flags); - - ret = gpiod_configure_flags(desc, propname, lflags, dflags); - if (ret < 0) { - gpiod_put(desc); - return ERR_PTR(ret); - } - - return desc; -} - static struct gpio_desc *of_find_gpio_rename(struct device_node *np, const char *con_id, unsigned int idx, diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h index c44be0f285f3..16c0848c9a25 100644 --- a/drivers/gpio/gpiolib-of.h +++ b/drivers/gpio/gpiolib-of.h @@ -26,10 +26,6 @@ void of_gpiochip_remove(struct gpio_chip *gc); int of_gpio_get_count(struct device *dev, const char *con_id); bool of_gpio_need_valid_mask(const struct gpio_chip *gc); void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev); -struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label); #else static inline struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id, @@ -52,14 +48,6 @@ static inline void of_gpio_dev_init(struct gpio_chip *gc, struct gpio_device *gdev) { } -static inline -struct gpio_desc *gpiod_get_from_of_node(const struct device_node *node, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) -{ - return ERR_PTR(-ENOSYS); -} #endif /* CONFIG_OF_GPIO */ extern struct notifier_block gpio_of_notifier; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0a7a59ac630..79aaba693c4f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3801,58 +3801,87 @@ static int platform_gpio_count(struct device *dev, const char *con_id) return count; } -/** - * 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 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 opaque firmware. - * - * 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. - * - * Returns: - * On successful request the GPIO pin is configured in accordance with - * provided @dflags. - * - * In case of error an ERR_PTR() is returned. - */ -static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname, int index, - enum gpiod_flags dflags, - const char *label) +static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, + struct device *consumer, + const char *con_id, + unsigned int idx, + enum gpiod_flags *flags, + unsigned long *lookupflags) { - unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT; - struct gpio_desc *desc = ERR_PTR(-ENODEV); - int ret; + struct gpio_desc *desc = ERR_PTR(-ENOENT); + dev_dbg(consumer, "GPIO lookup for consumer %s in node '%s'\n", + con_id, fwnode_get_name(fwnode)); + + /* Using device tree? */ if (is_of_node(fwnode)) { - desc = gpiod_get_from_of_node(to_of_node(fwnode), - propname, index, - dflags, - label); - return desc; + dev_dbg(consumer, "using device tree for GPIO lookup\n"); + desc = of_find_gpio(to_of_node(fwnode), + con_id, idx, lookupflags); } else if (is_acpi_node(fwnode)) { - desc = acpi_node_get_gpiod(fwnode, propname, index, - &lflags, &dflags); - if (IS_ERR(desc)) - return desc; - } else { - return ERR_PTR(-EINVAL); + dev_dbg(consumer, "using ACPI for GPIO lookup\n"); + desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags); } - /* Currently only ACPI takes this path */ + return desc; +} + +static struct gpio_desc *gpiod_find_and_request(struct device *consumer, + struct fwnode_handle *fwnode, + const char *con_id, + unsigned int idx, + enum gpiod_flags flags, + const char *label, + bool platform_lookup_allowed) +{ + struct gpio_desc *desc = ERR_PTR(-ENOENT); + unsigned long lookupflags; + int ret; + + if (fwnode) + desc = gpiod_find_by_fwnode(fwnode, consumer, con_id, idx, + &flags, &lookupflags); + + if (gpiod_not_found(desc) && platform_lookup_allowed) { + /* + * Either we are not using DT or ACPI, or their lookup did not + * return a result. In that case, use platform lookup as a + * fallback. + */ + dev_dbg(consumer, "using lookup tables for GPIO lookup\n"); + desc = gpiod_find(consumer, con_id, idx, &lookupflags); + } + + if (IS_ERR(desc)) { + dev_dbg(consumer, "No GPIO consumer %s found\n", con_id); + return desc; + } + + /* + * If a connection label was passed use that, else attempt to use + * the device name as label + */ ret = gpiod_request(desc, label); - if (ret) - return ERR_PTR(ret); + if (ret) { + if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) + return ERR_PTR(ret); + + /* + * This happens when there are several consumers for + * the same GPIO line: we just return here without + * further initialization. It is a bit of a hack. + * This is necessary to support fixed regulators. + * + * FIXME: Make this more sane and safe. + */ + dev_info(consumer, + "nonexclusive access to GPIO for %s\n", con_id); + return desc; + } - ret = gpiod_configure_flags(desc, propname, lflags, dflags); + ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); if (ret < 0) { + dev_dbg(consumer, "setup of GPIO %s failed\n", con_id); gpiod_put(desc); return ERR_PTR(ret); } @@ -3885,29 +3914,14 @@ static struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, * In case of error an ERR_PTR() is returned. */ struct gpio_desc *fwnode_gpiod_get_index(struct fwnode_handle *fwnode, - const char *con_id, int index, + const char *con_id, + int index, enum gpiod_flags flags, const char *label) { - struct gpio_desc *desc; - char prop_name[32]; /* 32 is max size of property name */ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { - if (con_id) - snprintf(prop_name, sizeof(prop_name), "%s-%s", - con_id, gpio_suffixes[i]); - else - snprintf(prop_name, sizeof(prop_name), "%s", - gpio_suffixes[i]); - desc = fwnode_get_named_gpiod(fwnode, prop_name, index, flags, - label); - if (!gpiod_not_found(desc)) - break; - } - - return desc; + return gpiod_find_and_request(NULL, fwnode, con_id, index, flags, label, + false); } EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index); @@ -4061,72 +4075,12 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, unsigned int idx, enum gpiod_flags flags) { - unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT; - struct gpio_desc *desc = NULL; - int ret; - /* Maybe we have a device name, maybe not */ - const char *devname = dev ? dev_name(dev) : "?"; struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; + const char *devname = dev ? dev_name(dev) : "?"; + const char *label = con_id ?: devname; - dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); - - /* Using device tree? */ - if (is_of_node(fwnode)) { - dev_dbg(dev, "using device tree for GPIO lookup\n"); - desc = of_find_gpio(to_of_node(fwnode), - con_id, idx, &lookupflags); - } else if (is_acpi_node(fwnode)) { - dev_dbg(dev, "using ACPI for GPIO lookup\n"); - desc = acpi_find_gpio(fwnode, - con_id, idx, &flags, &lookupflags); - } - - /* - * Either we are not using DT or ACPI, or their lookup did not return - * a result. In that case, use platform lookup as a fallback. - */ - if (!desc || gpiod_not_found(desc)) { - dev_dbg(dev, "using lookup tables for GPIO lookup\n"); - desc = gpiod_find(dev, con_id, idx, &lookupflags); - } - - if (IS_ERR(desc)) { - dev_dbg(dev, "No GPIO consumer %s found\n", con_id); - return desc; - } - - /* - * If a connection label was passed use that, else attempt to use - * the device name as label - */ - ret = gpiod_request(desc, con_id ?: devname); - if (ret) { - if (!(ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) - return ERR_PTR(ret); - - /* - * This happens when there are several consumers for - * the same GPIO line: we just return here without - * further initialization. It is a bit of a hack. - * This is necessary to support fixed regulators. - * - * FIXME: Make this more sane and safe. - */ - dev_info(dev, "nonexclusive access to GPIO for %s\n", con_id ?: devname); - return desc; - } - - ret = gpiod_configure_flags(desc, con_id, lookupflags, flags); - if (ret < 0) { - dev_dbg(dev, "setup of GPIO %s failed\n", con_id); - gpiod_put(desc); - return ERR_PTR(ret); - } - - blocking_notifier_call_chain(&desc->gdev->notifier, - GPIOLINE_CHANGED_REQUESTED, desc); - - return desc; + return gpiod_find_and_request(dev, fwnode, con_id, idx, flags, label, + true); } EXPORT_SYMBOL_GPL(gpiod_get_index); From patchwork Fri Nov 4 06:10:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 621542 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DC53C4332F for ; Fri, 4 Nov 2022 06:11:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230511AbiKDGLb (ORCPT ); Fri, 4 Nov 2022 02:11:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230507AbiKDGKw (ORCPT ); Fri, 4 Nov 2022 02:10:52 -0400 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7ADE429367; Thu, 3 Nov 2022 23:10:31 -0700 (PDT) Received: by mail-pj1-x102d.google.com with SMTP id e7-20020a17090a77c700b00216928a3917so2458205pjs.4; Thu, 03 Nov 2022 23:10:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Mz3SxtBsg329L+3fRZS9MYteoJhzga8XhsBAQr3LWvc=; b=Ruzp+sbx3l3D0LY8ZrkEtOhqSqzNEGZZhjEn7RrR+eiTLQRB/s9ZOULcIF1So2tulI jamvz+Y8M7yGw1cLUGBbOClP8sHExevgHsx8bT9GnAi5eEtFx4/kzKnQreP0wpPqP8OH Lsc6p/xs+eLlrFKUpldHaDudajoua/QsW2XFlBQdUEUYYryZzppCl016K4bNY8xW8D46 bZJx1a6kY1lJHf3GmvoCO2n5rFnaOqN8JvB/BHjAATPsYIXxg2lZIM8qiM9EcMJ6qeO2 MgpDY8UUHCbtCyxym3awOV56LDo40Te7SzWq9ac+GEkSm/EjNLLPUcJbwxA4U+9g81GV UW3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Mz3SxtBsg329L+3fRZS9MYteoJhzga8XhsBAQr3LWvc=; b=OZHg1vEO2yp8zdWG1dGDFODPxO5OHoH7B/WGzdvGvzpHK5OaIbsQdf2d2u1IKs11r7 E+qAUvxTKQ0ECpCRWDQ3p/K/RRZ2Uhieb/nmN+ugPfHEjsYQX+nTi3HhdoFfuMtAD/Tn IfxJ4cgrD6PHURheosTurX9DYYKy1Sy34NE8GgqDffGHKpwfXbkVZjcScz5h2KeA8Nj/ CgURcPh28XMWxizwgXtX3OSL27ap2zGq7k4yJ4/Io29hQ0lSuQeQEMXq9rZ7/Vzgl/uc u/HRr1YN5eKZbRI/KUxTGlMUZ61eyCVvleKGFrgZ/Ivcwi4S0tGhJK+uAhpMZXxzZ6Tj kP4w== X-Gm-Message-State: ACrzQf2vEn58Je3pFZ7KEnEXgcdMYnDaWd5NhhAphJx5VVsXylLuY9yq x83nqUFMOX9S+3qNGSjYqBw= X-Google-Smtp-Source: AMsMyM5Z1Bg6zvy47FTBq2SK6m6jaOV7nAaWMlEyzwu33RoZwJg7cuJTj91r2nYhR3N0PZJx09bHmw== X-Received: by 2002:a17:90a:24b:b0:213:9da2:5c98 with SMTP id t11-20020a17090a024b00b002139da25c98mr35329803pje.123.1667542230785; Thu, 03 Nov 2022 23:10:30 -0700 (PDT) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:a6ae:11ff:fe11:fcc3]) by smtp.gmail.com with ESMTPSA id x5-20020aa79ac5000000b0056bfd4a2702sm1791411pfp.45.2022.11.03.23.10.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 23:10:30 -0700 (PDT) From: Dmitry Torokhov To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko Cc: linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 6/6] gpiolib: add support for software nodes Date: Thu, 3 Nov 2022 23:10:16 -0700 Message-Id: <20221031-gpiolib-swnode-v1-6-a0ab48d229c7@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> References: <20221031-gpiolib-swnode-v1-0-a0ab48d229c7@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Now that static device properties understand notion of child nodes and references, let's teach gpiolib to handle them: - GPIOs are represented as a references to software nodes representing gpiochip - references must have 2 arguments - GPIO number within the chip and GPIO flags (GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH, etc). - name of the software node representing gpiochip must match label of the gpiochip, as we use it to locate gpiochip structure at runtime. const struct software_node gpio_bank_b_node = { .name = "B", }; const struct property_entry simone_key_enter_props[] __initconst = { PROPERTY_ENTRY_U32("linux,code", KEY_ENTER), PROPERTY_ENTRY_STRING("label", "enter"), PROPERTY_ENTRY_REF("gpios", &gpio_bank_b_node, 123, GPIO_ACTIVE_LOW), { } }; Signed-off-by: Dmitry Torokhov --- drivers/gpio/Makefile | 1 + drivers/gpio/gpiolib-swnode.c | 106 ++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib-swnode.h | 13 ++++++ drivers/gpio/gpiolib.c | 35 +++++++++++++- 4 files changed, 153 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 8629e9eaf79e..010587025fc8 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_OF_GPIO) += gpiolib-of.o obj-$(CONFIG_GPIO_CDEV) += gpiolib-cdev.o obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o +obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o # Device drivers. Generally keep list sorted alphabetically obj-$(CONFIG_GPIO_REGMAP) += gpio-regmap.o diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c new file mode 100644 index 000000000000..d005ce0b986d --- /dev/null +++ b/drivers/gpio/gpiolib-swnode.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Software Node helpers for the GPIO API + * + * Copyright 2022 Google LLC + */ +#include +#include +#include + +#include "gpiolib.h" +#include "gpiolib-swnode.h" + +static int swnode_gpiochip_match_name(struct gpio_chip *chip, void *data) +{ + return !strcmp(chip->label, data); +} + +struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, + const char *con_id, unsigned int idx, + unsigned long *flags) +{ + const struct software_node *chip_node; + const struct software_node *swnode; + struct fwnode_reference_args args; + struct gpio_chip *chip; + struct gpio_desc *desc; + char prop_name[32]; /* 32 is max size of property name */ + int error; + + swnode = to_software_node(fwnode); + if (!swnode) + return ERR_PTR(-EINVAL); + + /* + * Note we do not need to try both -gpios and -gpio suffixes, + * as, unlike OF and ACPI, we can fix software nodes to conform + * to the proper binding. + */ + if (con_id) + snprintf(prop_name, sizeof(prop_name), "%s-gpios", con_id); + else + strscpy(prop_name, "gpios", sizeof(prop_name)); + + /* + * We expect all swnode-described GPIOs have GPIO number and + * polarity arguments, hence nargs is set to 2. + */ + error = fwnode_property_get_reference_args(fwnode, prop_name, NULL, + 2, idx, &args); + if (error) { + pr_debug("%s: can't parse '%s' property of node '%pfwP[%d]'\n", + __func__, prop_name, fwnode, idx); + return ERR_PTR(error); + } + + chip_node = to_software_node(args.fwnode); + if (!chip_node || !chip_node->name) + return ERR_PTR(-EINVAL); + + chip = gpiochip_find((void *)chip_node->name, + swnode_gpiochip_match_name); + if (!chip) + return ERR_PTR(-EPROBE_DEFER); + + desc = gpiochip_get_desc(chip, args.args[0]); + *flags = args.args[1]; /* We expect native GPIO flags */ + + pr_debug("%s: parsed '%s' property of node '%pfwP[%d]' - status (%d)\n", + __func__, prop_name, fwnode, idx, PTR_ERR_OR_ZERO(desc)); + + return desc; +} + +/** + * swnode_gpio_count - count the GPIOs associated with a device / function + * @fwnode: firmware node of the GPIO consumer, can be %NULL for + * system-global GPIOs + * @con_id: function within the GPIO consumer + * + * Return: + * The number of GPIOs associated with a device / function or %-ENOENT, + * if no GPIO has been assigned to the requested function. + */ +int swnode_gpio_count(struct fwnode_handle *fwnode, const char *con_id) +{ + struct fwnode_reference_args args; + char prop_name[32]; + int count; + + if (con_id) + snprintf(prop_name, sizeof(prop_name), "%s-gpios", con_id); + else + strscpy(prop_name, "gpios", sizeof(prop_name)); + + /* + * This is not very efficient, but GPIO lists usually have only + * 1 or 2 entries. + */ + count = 0; + while (fwnode_property_get_reference_args(fwnode, prop_name, NULL, + 0, count, &args) == 0) + count++; + + return count ? count : -ENOENT; +} diff --git a/drivers/gpio/gpiolib-swnode.h b/drivers/gpio/gpiolib-swnode.h new file mode 100644 index 000000000000..afd51c9b6e34 --- /dev/null +++ b/drivers/gpio/gpiolib-swnode.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef GPIOLIB_SWNODE_H +#define GPIOLIB_SWNODE_H + +struct fwnode_handle; + +struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, + const char *con_id, unsigned int idx, + unsigned long *flags); +int swnode_gpio_count(struct fwnode_handle *fwnode, const char *con_id); + +#endif /* GPIOLIB_SWNODE_H */ diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 79aaba693c4f..b9976485587d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -26,6 +26,7 @@ #include "gpiolib.h" #include "gpiolib-of.h" #include "gpiolib-acpi.h" +#include "gpiolib-swnode.h" #include "gpiolib-cdev.h" #include "gpiolib-sysfs.h" @@ -3813,6 +3814,19 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, dev_dbg(consumer, "GPIO lookup for consumer %s in node '%s'\n", con_id, fwnode_get_name(fwnode)); + /* + * First look up GPIO in the secondary software node in case + * it was used to store updated properties. + */ + if (is_software_node(fwnode->secondary)) { + dev_dbg(consumer, + "using secondary software node for GPIO lookup\n"); + desc = swnode_find_gpio(fwnode->secondary, + con_id, idx, lookupflags); + if (!gpiod_not_found(desc)) + return desc; + } + /* Using device tree? */ if (is_of_node(fwnode)) { dev_dbg(consumer, "using device tree for GPIO lookup\n"); @@ -3821,6 +3835,9 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, } else if (is_acpi_node(fwnode)) { dev_dbg(consumer, "using ACPI for GPIO lookup\n"); desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags); + } else if (is_software_node(fwnode)) { + dev_dbg(consumer, "using software node for GPIO lookup\n"); + desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags); } return desc; @@ -3933,13 +3950,27 @@ EXPORT_SYMBOL_GPL(fwnode_gpiod_get_index); */ int gpiod_count(struct device *dev, const char *con_id) { - const struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; - int count = -ENOENT; + struct fwnode_handle *fwnode = dev ? dev_fwnode(dev) : NULL; + int count; + + /* + * First look up GPIO in the secondary software node in case + * it was used to store updated properties. + */ + if (!IS_ERR_OR_NULL(fwnode) && is_software_node(fwnode->secondary)) { + count = swnode_gpio_count(fwnode->secondary, con_id); + if (count > 0) + return count; + } if (is_of_node(fwnode)) count = of_gpio_get_count(dev, con_id); else if (is_acpi_node(fwnode)) count = acpi_gpio_count(dev, con_id); + else if (is_software_node(fwnode)) + count = swnode_gpio_count(fwnode, con_id); + else + count = -ENOENT; if (count < 0) count = platform_gpio_count(dev, con_id);