From patchwork Wed Nov 9 19:30:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 623356 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 2C775C43217 for ; Wed, 9 Nov 2022 19:30:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229615AbiKITaw (ORCPT ); Wed, 9 Nov 2022 14:30:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231194AbiKITaw (ORCPT ); Wed, 9 Nov 2022 14:30:52 -0500 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DB0DA474; Wed, 9 Nov 2022 11:30:51 -0800 (PST) Received: by mail-pf1-x429.google.com with SMTP id 130so17629343pfu.8; Wed, 09 Nov 2022 11:30:51 -0800 (PST) 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=8HJkA3m4z41ixW5vvs68RcjpRXugbjaOG03xYMJ1aMU=; b=mja+7UfyhLK1qpyQkMQPTCjX1zkySzQH+J1RXZS7FcKQcb/xE1aIaFeD6hulqiLFGH 68hnzP4Jr5HlYABEFYyEv4WcxIAH2kSnj0jLom5V/ICjF5Dw9OkNxmJCe1KKwfKhkbnn rmRDxK3w6mOljgKn2fPiYgq7i6M2uf+Uu5ngPze6h0OPdXeFAUlLBJGS5sLO8yUyJfZL tQy/8nSmERh8n5r6pLmg2WG8z4YA6A78t4BgifztUEaODBN5tZ3bRm6OImP9GhH9h5W4 KRCf98aQeL78hBNhObK1wN/IewZNWeux4dV9Z5Ou4TrIhGNlAZjIAM1jndI40PlhcdGq hSsA== 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=8HJkA3m4z41ixW5vvs68RcjpRXugbjaOG03xYMJ1aMU=; b=JTsr3RSNGaG6Rr/afml2uoZ4ACG73DoF3p0Mei5jUuXYPGh+nr38WnGzwURY1JrS1C uE/9wCPWIHwH1jqRsBLzWt8logGj5Fnu+BQ3Jw3yNJVmkcY6QOTWV0iVidVLVWhWSkO1 Bdi6bV4yJ279/SSxjAsrzLjyK9ybBCLiXKAW+ibHhFDyX7m1TcAiNw5FchuSLQOrsRqp dpw/MZmiulKdpb/PbwwmsD3yGKfCuuBIHrxNS2QdcJ2emVWYo5/gz9e6IXnrB6I5vGS2 u1rkOzeBlU+LRYuqNO8Mw2XWPO5TF/68jefipHEgCQQE/SKO41WOnBVp+IHvPHKdgNE9 9mkw== X-Gm-Message-State: ACrzQf3utfgVqCr6CyXQZMwroK3/ALUUpJbURZQBki+yAcKQSD4nLe7K 86nBoYClyV9Z6cSdGtBT0o0= X-Google-Smtp-Source: AMsMyM4DnM+K7Tru1k0hYwnwuEVyj2s3FohttORFLSaxFqm9L9I0Hg8ZbIcYFCrosjWePP5O8ui13Q== X-Received: by 2002:a63:d015:0:b0:46f:b2a4:a34e with SMTP id z21-20020a63d015000000b0046fb2a4a34emr47364062pgf.594.1668022250626; Wed, 09 Nov 2022 11:30:50 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:49 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 1/6] gpiolib: of: change of_find_gpio() to accept device node Date: Wed, 9 Nov 2022 11:30:39 -0800 Message-Id: <20221031-gpiolib-swnode-v3-1-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@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. Reviewed-by: Andy Shevchenko Acked-by: Linus Walleij 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 be9c34cca322..52e4ac0fcaa1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -623,7 +623,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 */ @@ -641,8 +641,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; @@ -650,7 +649,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 1b5df39a952e..cb8b70a2723e 100644 --- a/drivers/gpio/gpiolib-of.h +++ b/drivers/gpio/gpiolib-of.h @@ -16,7 +16,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); @@ -26,7 +26,7 @@ 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); #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 Wed Nov 9 19:30:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 622958 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 5221FC43217 for ; Wed, 9 Nov 2022 19:30:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231379AbiKITaz (ORCPT ); Wed, 9 Nov 2022 14:30:55 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34018 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229551AbiKITax (ORCPT ); Wed, 9 Nov 2022 14:30:53 -0500 Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0396727B33; Wed, 9 Nov 2022 11:30:53 -0800 (PST) Received: by mail-pj1-x1035.google.com with SMTP id d13-20020a17090a3b0d00b00213519dfe4aso2880070pjc.2; Wed, 09 Nov 2022 11:30:52 -0800 (PST) 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=GdJFy/Jw06zpP+63ffqxVPckP7PtfLIb1CoKR1TTueA=; b=JtWyteaZcQLBtx/CeSsFju4zAPJcegVwUkAAr94WHCoBHTARrO84PApYQuQPdF1Obp 4Nw+CjLoCTLSMtzBm8x+35auFt5GKoDKTscQtxtERq7Kf6/oLE8p4qWOeLIIwBJXvSqL FPBu/ABw9G3bCmraid/SSuw0cpfJtvazp4SdQuYYOtMgnkDUH7yxwzBBv3un8s/26JPH bAPli+cDWQEbnvD4gJzuppW2uc4ZA9XJMdiN6XUqwYUxQ0I8GUhDRd8yxndj2ak/Pr9l 4v2dMutZZ98Sl8pcaeLCnjJe2FL4QmmSCtCEanVYk5HAEzOr8ycQ/G0ATyeSUqbykibM bWcQ== 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=GdJFy/Jw06zpP+63ffqxVPckP7PtfLIb1CoKR1TTueA=; b=M4y/yNBKnA2R1ruJofrLC7v5kP/qP+cA+chceQ88dTTe4sywfAuRMh8lS+74CNWHPb ukprmIRuoTBTwXDtk3jdde64MAbhCKXCYSkf5PsCiZGUOup5OyqbEWW5WwlkT80rErp+ FyZ407ZLh99x0cRgAwFRmm8w+itbOtQKgw7dpWV09sidwzq7eeurvyqKVRoinhjlebMe BUK//WQSBWqZNI7xYhUkicOGB/752Uh7JPt8nuQpWkoWSR0ffLJqxDJMgdOD+1+HZOuj Fb1tbzRvyqj0zcuZlG35DnlZSSyNYA1TJnkm9S7rBAdK15M6vE04rbPFLwBGkGa3yWzo lx2A== X-Gm-Message-State: ACrzQf1mr1gXDb9mdsjWBBy/LFRufG0zhQtIre70lf8k/g0Yi59mbmjW v3w+jOUv6qVAorLcAOj95NGXVjDvWOk= X-Google-Smtp-Source: AMsMyM5fJYa9eCBbDIwGGQ8yFf1xHcJEJhvKfgKK90w/7uA+HXiXpV1zfnvlGzZHeaiuQgQhXl5Nqw== X-Received: by 2002:a17:90a:7e10:b0:213:9e81:87e2 with SMTP id i16-20020a17090a7e1000b002139e8187e2mr66359796pjl.1.1668022252360; Wed, 09 Nov 2022 11:30:52 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:51 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 2/6] gpiolib: acpi: change acpi_find_gpio() to accept firmware node Date: Wed, 9 Nov 2022 11:30:40 -0800 Message-Id: <20221031-gpiolib-swnode-v3-2-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@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. Reviewed-by: Andy Shevchenko Acked-by: Linus Walleij 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 Wed Nov 9 19:30:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 623355 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 21B02C433FE for ; Wed, 9 Nov 2022 19:31:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231355AbiKITbA (ORCPT ); Wed, 9 Nov 2022 14:31:00 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231362AbiKITaz (ORCPT ); Wed, 9 Nov 2022 14:30:55 -0500 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D53F2A94A; Wed, 9 Nov 2022 11:30:54 -0800 (PST) Received: by mail-pl1-x632.google.com with SMTP id j12so18025014plj.5; Wed, 09 Nov 2022 11:30:54 -0800 (PST) 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=p+ottrNj/QWc9Vetbcog1ENbzksG0RcS9PunOwnV9HY=; b=dXsJbxpJUyrFJZM3EEuRQCwS21WLv2LyLpUhg2q7f2rwVCvZGjUlnYpmtmxUJ/yn2v Q88XgQhMtEcmj1f4UklSYHCIfryKFOd6pnMgNLkw58HA4A6GqwDY+tU1xZeGb/1rZQ96 j+NOerCW/vLRWsftGVRmoB+H5CO6wMX+qamceBp7N6KnMeGle60u0OfWvLMKo9L5vnEa PUlhXKnANVMVdoVF0qGG20JiemK1h4ncQr+eDndGI8uaJfskPng1MotSldOKvSqTfqK0 IAE7k1Y7zyjlLMQMDimJFEi70tQAFGPR6PWQLRqPISkKpuSuX5GlDi5lSI7cVo+V1evw 9jhA== 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=p+ottrNj/QWc9Vetbcog1ENbzksG0RcS9PunOwnV9HY=; b=UhBx0cp8BjuPWXcaeFDYaXe7Mu2RHmp196UDIR+HNw0rOqsy5EKK2Ew+iKLsatOlNG FefB0xqkGRb3JGZQwSjkBHLuw00B0qAwEC+ZpWc4BdGzxsm8Q85sQKRC6uvtnpJdhYK2 HyAVnTlBhpzqIeQ4y9oa4e9rVawWdYcqJk35Asbzmg6uYITw2K6IjX2mxhabbFr+kHRL ZmChfsjIe2Uo6IHP2jVwrUqx2da+Fhm9pHpVsh5DjtK9BjEXqJHg+pDVUbd4pfDsFTaq 4l2CUBi8DWVQPRZ4aC54LxS8I86D8N4Ugx2vbpwHT7G7w5bzw4YRM2fP26ExGkrcYMSz zHcA== X-Gm-Message-State: ACrzQf3Rv8pn5vzZgJ5yMEjMjTnnImOjyMPc80SY1tw5J98a8ziDueVw iFk41Q8+rCTgrjbJDX64xyb2jnuJeKU= X-Google-Smtp-Source: AMsMyM5vlvQIABT6pNHd8LM51v1gHymO7mkjFg8DGjSyG+RBjHf8El5ChUa95WD0UJtKSdFAJ9vwBw== X-Received: by 2002:a17:902:e9c2:b0:186:79dc:7d87 with SMTP id 2-20020a170902e9c200b0018679dc7d87mr61784585plk.59.1668022254003; Wed, 09 Nov 2022 11:30:54 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:53 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 3/6] gpiolib: acpi: teach acpi_find_gpio() to handle data-only nodes Date: Wed, 9 Nov 2022 11:30:41 -0800 Message-Id: <20221031-gpiolib-swnode-v3-3-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@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(). Reviewed-by: Andy Shevchenko Acked-by: Linus Walleij 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 Wed Nov 9 19:30:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 622957 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 CAFC0C4321E for ; Wed, 9 Nov 2022 19:31:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229551AbiKITbB (ORCPT ); Wed, 9 Nov 2022 14:31:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231401AbiKITa6 (ORCPT ); Wed, 9 Nov 2022 14:30:58 -0500 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 772EB27917; Wed, 9 Nov 2022 11:30:56 -0800 (PST) Received: by mail-pf1-x42f.google.com with SMTP id i3so17611097pfc.11; Wed, 09 Nov 2022 11:30:56 -0800 (PST) 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=2AGc3emho2rw8bHzX4XM873wewr02G0nK1D2GVmf5H0=; b=accBbSpLQtPccYSWR2w1V1yxh2trznItH90eP3VzdlI1w5OWua8DNFpYHXYPksM1jC aW/b9AdWIVzFpM7Vb32hWwDia+jGVbE6QL26dqdLHfbywgPhByH39KRrByeqBBUdZr0c M6bw/E16xkJswLtSYebYCYKhDquc+RJMwV7u7uVlxbifg6FqxRM4iilraZS5opRc9E+U uHsVnelaIS1KceMpiqN9YsFqP1e9a+Xrpzod8sM2Fn0PuKRY4NYGxDzTfYOfZr9ADgPo OOuw9+0jY7grLbmqpjBLJZDiKO2lPPicshlI5piKdTmL2e/N3hsd1e7vgUR9H+wPWQZU eCuw== 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=2AGc3emho2rw8bHzX4XM873wewr02G0nK1D2GVmf5H0=; b=YVQ1FjIE6QOWhhmQFV9K1c00w/lrLO0LdEASeQH0OZwdviQser0YILMX2YjBveC2F+ gp/cbdRGUephryJrovpg8ZmXl9qj8z6PtQ2r25hGiLYmx/Dzu6yipPMMmo4MCeNlsp2I +K1bzuaDY8U8AvT7wFVnDOG3SAsevFCcBBhC/LiFDOOJfBgirvaxUZ80y8JCt89mwvKm rNTdysWTQ0iyeFCCMwjDru7dSSwe5z88SeLjyOYcmIc8Tra7imBZNLRZSqq2xhTthQDn DtLU/J4lSFSlHGnhtplmT9v+QqMaRqrDOyuzZ+Ejwb7ito0GOo/ZqoHKYJQktLNd27Zq GXqA== X-Gm-Message-State: ACrzQf1xzX3jvKkbprDFZ0mhDLv3dOiLBDFNC2Ft5koynpew7FOl2jJy P77K6m8fLHFWdoO8W+i27vQ= X-Google-Smtp-Source: AMsMyM4jFe2pq2XxKCz+HJEZnxNPJWwtl7Gt8Kt0ILaiymk77OOVQllTz4UPsYL4GAXiMdxCW3RLtA== X-Received: by 2002:a63:fc0b:0:b0:46f:87a8:97aa with SMTP id j11-20020a63fc0b000000b0046f87a897aamr52329196pgi.234.1668022255736; Wed, 09 Nov 2022 11:30:55 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:55 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 4/6] gpiolib: acpi: avoid leaking ACPI details into upper gpiolib layers Date: Wed, 9 Nov 2022 11:30:42 -0800 Message-Id: <20221031-gpiolib-swnode-v3-4-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org There is no need for the generic parts of GPIOLIB to be aware of implementation details of ACPI-bases lookups. Reviewed-by: Andy Shevchenko Acked-by: Linus Walleij 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 Wed Nov 9 19:30:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 623354 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 AFE26C43217 for ; Wed, 9 Nov 2022 19:31:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231607AbiKITbL (ORCPT ); Wed, 9 Nov 2022 14:31:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231484AbiKITa7 (ORCPT ); Wed, 9 Nov 2022 14:30:59 -0500 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 77E0026108; Wed, 9 Nov 2022 11:30:58 -0800 (PST) Received: by mail-pl1-x62e.google.com with SMTP id k7so18026431pll.6; Wed, 09 Nov 2022 11:30:58 -0800 (PST) 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=objDjwxP2jUBK/MvOUZMQoLAH5BbEb2VehLY7RsMP7g=; b=FCuVYgsqaLR6oMSO76IddaDZTQenj7zth9qImzjTuv5GNsJN49aBaAJvcFUTAKWcCz 0UYUk0fKhztwj6SD2NLLG/LrpHNpJUEwqk/WY4n2KucQxToON1u5+CkfmcVlUdipvBHF zbYqeTAcGYmx9IpfSH0XE4eM4LZi3v9lq/+y3sTNmEvLp/4406ZUK8zxfW0UTMiaOM9T w27ckAQaYJgZCkvBoDliekY6LgRtJCxHu6oqkAXwBVS9H8Q0cQjIaMsoj82gWBSYbZ7b 34rIl9fwxPZ1ofVT20savXujL9TAX+vTJN7ePp9cwWUIjmNgWY+teM0lrWj4HxORkaFG B8DA== 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=objDjwxP2jUBK/MvOUZMQoLAH5BbEb2VehLY7RsMP7g=; b=f507CJDCTwedx6au7vDr6SesMDkVSVu/hMZp2EHWNiD47gwDR6VEhJwOJh9YuQ3hhp nTv/xbBIcUGC3ACsoKFcxPTCTfSU/SwE+SAWsb3U5/sHWVJyNeVNVs+iQG9OZGoRPmTq HkWH2LgKFmS4jV9LMVdGy0xv6q8cus9aE9Pb4lUtgzhxrAOGOZZcS7WRhmCvwWHM/ShJ Yh7k+2CgU/bJidmGpFfxmT1qCrVZEbgVIomN1zriwrOtyLDNfBoUeIX+0H+ifZ0LEA5S bxxi5ri+rSyhkiz5CCcCMNWI3RjHbI/W9bnJCPiN2erPBhapXyzjxKDHY9m5iUFmodNB ytVA== X-Gm-Message-State: ACrzQf1ftIXovi7f3BuD1Y7177gnv8R6Mv4Kx4v7BnDmE6UA6jBZlL7m aSpNNO+peDoZwW9l8oosVoQ= X-Google-Smtp-Source: AMsMyM6juyrjOPAt8igCDSEfBo05z7/TzxeJQvcXRe3GZbx6Kr8HK1kFZS+bh49TqFxU06r8PE6rOA== X-Received: by 2002:a17:903:124e:b0:179:da2f:244e with SMTP id u14-20020a170903124e00b00179da2f244emr63158975plh.169.1668022257730; Wed, 09 Nov 2022 11:30:57 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:57 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 5/6] gpiolib: consolidate GPIO lookups Date: Wed, 9 Nov 2022 11:30:43 -0800 Message-Id: <20221031-gpiolib-swnode-v3-5-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@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. The only exception is OF-specific [devm_]gpiod_get_from_of_node() API that is still being used by a couple of drivers and will be removed as soon as patches converting them to use generic fwnode/device APIs are accepted. Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov Reviewed-by: Andy Shevchenko --- drivers/gpio/gpiolib-acpi.c | 39 --------- drivers/gpio/gpiolib-acpi.h | 10 --- drivers/gpio/gpiolib.c | 204 +++++++++++++++++--------------------------- 3 files changed, 76 insertions(+), 177 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.c b/drivers/gpio/gpiolib.c index f0a7a59ac630..b1a57fdd96b6 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -366,7 +366,7 @@ static int gpiochip_set_desc_names(struct gpio_chip *gc) static int devprop_gpiochip_set_names(struct gpio_chip *chip) { struct gpio_device *gdev = chip->gpiodev; - struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev); + const struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev); const char **names; int ret, i; int count; @@ -3801,58 +3801,84 @@ 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); 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 DT '%pfw' for '%s' GPIO lookup\n", + fwnode, con_id); + 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 '%pfw' for '%s' GPIO lookup\n", + fwnode, con_id); + 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 (!IS_ERR_OR_NULL(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 +3911,12 @@ 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 +4070,11 @@ 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 Wed Nov 9 19:30:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Torokhov X-Patchwork-Id: 622956 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 0462FC4332F for ; Wed, 9 Nov 2022 19:31:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231731AbiKITbj (ORCPT ); Wed, 9 Nov 2022 14:31:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34254 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231539AbiKITbD (ORCPT ); Wed, 9 Nov 2022 14:31:03 -0500 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82E4B2A956; Wed, 9 Nov 2022 11:31:00 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id 4so18075816pli.0; Wed, 09 Nov 2022 11:31:00 -0800 (PST) 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=zzRmVyZjNLOkQVNMRdyPxVXGBGg/HG7r2x/54f2F8u4=; b=prVeqri7KEgFKB9KvY6lzuQWL6mbuTlild1ZL4LVUN8dcHGbqjDoBeJ99W5Pw2E5xa I+ZoEK7T51p7pApRAge8S2/uAGhu5qeY5+FAwy2A827TOV/ShpIzV9rqGhjxWyAMARrW 0iJMi6ufXpyNG7GYbV60YEmAbwe46lv4c6ybEUY6FFZfTaYi4bR5gvdsNS8c9g16Zh9K preLcD51ltqgTtbpdmV6vhw3DHV8+coQCjmo2M6QLRxHbqsDjimF5DjyBe8zaLahw5sQ mtFOKCiiqaX1A+Z5gq0E8NdU8IPgohSXXQjTz/0fVBrBgZiDMklEDbBfYtZSHNUIcJJU pflA== 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=zzRmVyZjNLOkQVNMRdyPxVXGBGg/HG7r2x/54f2F8u4=; b=BfE/l3/Siy2f4V+sKrBzUINfVx9WsGKel3BhPncK+jyGdGyR+0wUxtz4uZMPA3hcBR 2KdIfxiikVNT3IQ8g9HUrhMidvb7I3KEfDoJOabm8VRIbu5YYJoGlKD/no8xktZP+wI+ gp+wZPrycGV1sjkB/z93rBB9KfjFov4l8TLDejQjTtPZKVbLlbAQ3AWSIXhx2tA06Ym5 OknmEQsVxpOeVlLzPV5iMEzIhw/nGI2ClIwi7BpZphCevumhlcp8M4BEHZzPQng/Ton/ L3XDg2yNSOvCdOoTBUK/66x6zJSQgwGOF48JqnxdYoQbm3OyrwuvgUazcA7ypYbzIIrT nKtg== X-Gm-Message-State: ANoB5pkGbxkUpv6bpw5nM6TaD2BxVxbyouNjV/zTyD1Wq+aHlwVXevZw FKeTGWhga5L3ytLe9X5Uv+A= X-Google-Smtp-Source: AA0mqf6+kTefudacE11UKxxQWLdEcqaG2Mtxb2mIa0LXz2wkvqZhe+w/zwi/q96Nvh6m0wzBIuWl8g== X-Received: by 2002:a17:902:e5c7:b0:188:71b1:8f0e with SMTP id u7-20020a170902e5c700b0018871b18f0emr24939783plf.27.1668022259728; Wed, 09 Nov 2022 11:30:59 -0800 (PST) Received: from dtor-ws.mtv.corp.google.com ([2620:15c:9d:2:9f46:7242:26:f220]) by smtp.gmail.com with ESMTPSA id l2-20020a170902f68200b00186ac4b21cfsm9567462plg.230.2022.11.09.11.30.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Nov 2022 11:30:59 -0800 (PST) From: Dmitry Torokhov To: Linus Walleij , Andy Shevchenko , Bartosz Golaszewski Cc: linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-gpio@vger.kernel.org Subject: [PATCH v3 6/6] gpiolib: add support for software nodes Date: Wed, 9 Nov 2022 11:30:44 -0800 Message-Id: <20221031-gpiolib-swnode-v3-6-0282162b0fa4@gmail.com> X-Mailer: git-send-email 2.38.1.431.g37b22c650d-goog In-Reply-To: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> References: <20221031-gpiolib-swnode-v3-0-0282162b0fa4@gmail.com> MIME-Version: 1.0 X-Mailer: b4 0.11.0-dev-28747 Precedence: bulk List-ID: X-Mailing-List: linux-acpi@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) - a new PROPERTY_ENTRY_GPIO() macro is supplied to ensure the above - name of the software node representing gpiochip must match label of the gpiochip, as we use it to locate gpiochip structure at runtime The following illustrates use of software nodes to describe a "System" button that is currently specified via use of gpio_keys_platform_data in arch/mips/alchemy/board-mtx1.c. It follows bindings specified in Documentation/devicetree/bindings/input/gpio-keys.yaml. static const struct software_node mxt1_gpiochip2_node = { .name = "alchemy-gpio2", }; static const struct property_entry mtx1_gpio_button_props[] = { PROPERTY_ENTRY_U32("linux,code", BTN_0), PROPERTY_ENTRY_STRING("label", "System button"), PROPERTY_ENTRY_GPIO("gpios", &mxt1_gpiochip2_node, 7, GPIO_ACTIVE_LOW), { } }; Similarly, arch/arm/mach-tegra/board-paz00.c can be converted to: static const struct software_node tegra_gpiochip_node = { .name = "tegra-gpio", }; static struct property_entry wifi_rfkill_prop[] __initdata = { PROPERTY_ENTRY_STRING("name", "wifi_rfkill"), PROPERTY_ENTRY_STRING("type", "wlan"), PROPERTY_ENTRY_GPIO("reset-gpios", &tegra_gpiochip_node, 25, GPIO_ACTIVE_HIGH); PROPERTY_ENTRY_GPIO("shutdown-gpios", &tegra_gpiochip_node, 85, GPIO_ACTIVE_HIGH); { }, }; static struct platform_device wifi_rfkill_device = { .name = "rfkill_gpio", .id = -1, }; ... software_node_register(&tegra_gpiochip_node); device_create_managed_software_node(&wifi_rfkill_device.dev, wifi_rfkill_prop, NULL); Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov Reviewed-by: Andy Shevchenko --- drivers/gpio/Makefile | 1 + drivers/gpio/gpiolib-swnode.c | 123 ++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib-swnode.h | 14 +++++ drivers/gpio/gpiolib.c | 7 +++ include/linux/gpio/property.h | 11 ++++ 5 files changed, 156 insertions(+) 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..dd9ccac214d1 --- /dev/null +++ b/drivers/gpio/gpiolib-swnode.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Software Node helpers for the GPIO API + * + * Copyright 2022 Google LLC + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpiolib.h" +#include "gpiolib-swnode.h" + +static void swnode_format_propname(const char *con_id, char *propname, + size_t max_size) +{ + /* + * 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(propname, max_size, "%s-gpios", con_id); + else + strscpy(propname, "gpios", max_size); +} + +static int swnode_gpiochip_match_name(struct gpio_chip *chip, void *data) +{ + return !strcmp(chip->label, data); +} + +static struct gpio_chip *swnode_get_chip(struct fwnode_handle *fwnode) +{ + const struct software_node *chip_node; + struct gpio_chip *chip; + + chip_node = to_software_node(fwnode); + if (!chip_node || !chip_node->name) + return ERR_PTR(-EINVAL); + + chip = gpiochip_find((void *)chip_node->name, swnode_gpiochip_match_name); + return chip ?: ERR_PTR(-EPROBE_DEFER); +} + +struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, + const char *con_id, unsigned int idx, + unsigned long *flags) +{ + const struct software_node *swnode; + struct fwnode_reference_args args; + struct gpio_chip *chip; + struct gpio_desc *desc; + char propname[32]; /* 32 is max size of property name */ + int error; + + swnode = to_software_node(fwnode); + if (!swnode) + return ERR_PTR(-EINVAL); + + swnode_format_propname(con_id, propname, sizeof(propname)); + + /* + * 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, propname, NULL, 2, idx, &args); + if (error) { + pr_debug("%s: can't parse '%s' property of node '%pfwP[%d]'\n", + __func__, propname, fwnode, idx); + return ERR_PTR(error); + } + + chip = swnode_get_chip(args.fwnode); + fwnode_handle_put(args.fwnode); + if (IS_ERR(chip)) + return ERR_CAST(chip); + + 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__, propname, 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(const struct fwnode_handle *fwnode, const char *con_id) +{ + struct fwnode_reference_args args; + char propname[32]; + int count; + + swnode_format_propname(con_id, propname, sizeof(propname)); + + /* + * This is not very efficient, but GPIO lists usually have only + * 1 or 2 entries. + */ + count = 0; + while (fwnode_property_get_reference_args(fwnode, propname, NULL, 0, + count, &args) == 0) { + fwnode_handle_put(args.fwnode); + count++; + } + + return count ?: -ENOENT; +} diff --git a/drivers/gpio/gpiolib-swnode.h b/drivers/gpio/gpiolib-swnode.h new file mode 100644 index 000000000000..af849e56f6bc --- /dev/null +++ b/drivers/gpio/gpiolib-swnode.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef GPIOLIB_SWNODE_H +#define GPIOLIB_SWNODE_H + +struct fwnode_handle; +struct gpio_desc; + +struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, + const char *con_id, unsigned int idx, + unsigned long *flags); +int swnode_gpio_count(const 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 b1a57fdd96b6..2f4150bf411a 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" @@ -3818,6 +3819,10 @@ static struct gpio_desc *gpiod_find_by_fwnode(struct fwnode_handle *fwnode, dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", fwnode, con_id); desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags); + } else if (is_software_node(fwnode)) { + dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", + fwnode, con_id); + desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags); } return desc; @@ -3935,6 +3940,8 @@ int gpiod_count(struct device *dev, const char *con_id) 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); if (count < 0) count = platform_gpio_count(dev, con_id); diff --git a/include/linux/gpio/property.h b/include/linux/gpio/property.h new file mode 100644 index 000000000000..6c75c8bd44a0 --- /dev/null +++ b/include/linux/gpio/property.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +#ifndef __LINUX_GPIO_PROPERTY_H +#define __LINUX_GPIO_PROPERTY_H + +#include /* for GPIO_* flags */ +#include + +#define PROPERTY_ENTRY_GPIO(_name_, _chip_node_, _idx_, _flags_) \ + PROPERTY_ENTRY_REF(_name_, _chip_node_, _idx_, _flags_) + +#endif /* __LINUX_GPIO_PROPERTY_H */