get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2196253/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2196253,
    "url": "http://patchwork.ozlabs.org/api/patches/2196253/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260213092958.864411-10-tzungbi@kernel.org/",
    "project": {
        "id": 42,
        "url": "http://patchwork.ozlabs.org/api/projects/42/?format=api",
        "name": "Linux GPIO development",
        "link_name": "linux-gpio",
        "list_id": "linux-gpio.vger.kernel.org",
        "list_email": "linux-gpio@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260213092958.864411-10-tzungbi@kernel.org>",
    "list_archive_url": null,
    "date": "2026-02-13T09:29:56",
    "name": "[v3,09/11] gpio: Remove gpio_chip_guard by using revocable",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "903255faac1a2cc5e668b00a497744135f48a5bc",
    "submitter": {
        "id": 83557,
        "url": "http://patchwork.ozlabs.org/api/people/83557/?format=api",
        "name": "Tzung-Bi Shih",
        "email": "tzungbi@kernel.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/20260213092958.864411-10-tzungbi@kernel.org/mbox/",
    "series": [
        {
            "id": 492068,
            "url": "http://patchwork.ozlabs.org/api/series/492068/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=492068",
            "date": "2026-02-13T09:29:47",
            "name": "gpio: Adopt revocable mechanism for UAF prevention",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/492068/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2196253/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2196253/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-gpio+bounces-31666-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-gpio@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256\n header.s=k20201202 header.b=aJWbFHe2;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-gpio+bounces-31666-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=\"aJWbFHe2\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=10.30.226.201"
        ],
        "Received": [
            "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fC6V94C8Rz1xpl\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 13 Feb 2026 20:35:45 +1100 (AEDT)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 7C01231925E4\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 13 Feb 2026 09:31:30 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 207CB34B43D;\n\tFri, 13 Feb 2026 09:31:30 +0000 (UTC)",
            "from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org\n [10.30.226.201])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id D40622DC774;\n\tFri, 13 Feb 2026 09:31:29 +0000 (UTC)",
            "by smtp.kernel.org (Postfix) with ESMTPSA id E72D9C16AAE;\n\tFri, 13 Feb 2026 09:31:26 +0000 (UTC)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1770975089; cv=none;\n b=l1RAaV4S0W+TznhdEBX1B29gF1z8jaeIP0o/MF/Po0utOnK3ItmDMijhJnRkiUP7bPZbkK0bNCzLD3q4OB+QaLGZLWso2l8gGzjtIi/vzZtpRzKv9lreS6G8aH8PmI+JF+YkIeomUr9X58kAVGCKovSFuJfofLLjsRIy7SKi6RE=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1770975089; c=relaxed/simple;\n\tbh=xrZENLz4dIxYm05qchHPEj52css9L6e1PnU4QEDqYIU=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=VSSXOPlv6rIBp+6nOllXcRYvihwt/9UGn0QlMRZ95V/QgP7H/g5aiH0+3HsieVNSLELdsdAbYNbNEGA6PLK0H58Jlmjn9+p9/0Y8OCV4kAgLPbggGAFy1fQpV3VgkbdjYcPkzFmc+zUuQOUo1TvZqVPJBD09muWxc1czvjL0svw=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org\n header.b=aJWbFHe2; arc=none smtp.client-ip=10.30.226.201",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org;\n\ts=k20201202; t=1770975089;\n\tbh=xrZENLz4dIxYm05qchHPEj52css9L6e1PnU4QEDqYIU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=aJWbFHe2FPlh42eq2d9VlEXZdCY7m/tPUp+h2ZXwIYI0Q+AqUtFPHvqPK8kmMFfIj\n\t lO4KSqV5jsKckjUBAmgARyDyCUYVKVxIl8TyW51Mj534xXxcCKXmeePzKEfIrxOeYU\n\t DgEjaxvh2UnNExClCG7SCdDs0j4wlfE5DDjS4UcCLFrUAukQov1p4KrUyNPgUDdrdB\n\t OU8O6qLovciHPfjPbnq9p6lueXQkkOgSGlpfPJOhL5ZfqC/cvhoEw8GQBEkf1Sxidd\n\t N2wmadxzbSB4CkF90JFwp3T1TGd7Fde3f+OaSfTEWJYE+vIGHRpH46L4AqjXI09KW4\n\t U3svKoSA3vWLw==",
        "From": "Tzung-Bi Shih <tzungbi@kernel.org>",
        "To": "Bartosz Golaszewski <brgl@kernel.org>,\n\tLinus Walleij <linusw@kernel.org>",
        "Cc": "Greg Kroah-Hartman <gregkh@linuxfoundation.org>,\n\t\"Rafael J. Wysocki\" <rafael@kernel.org>,\n\tDanilo Krummrich <dakr@kernel.org>,\n\tJonathan Corbet <corbet@lwn.net>,\n\tShuah Khan <shuah@kernel.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tWolfram Sang <wsa+renesas@sang-engineering.com>,\n\tJason Gunthorpe <jgg@nvidia.com>,\n\tJohan Hovold <johan@kernel.org>,\n\t\"Paul E . McKenney\" <paulmck@kernel.org>,\n\tDan Williams <dan.j.williams@intel.com>,\n\tchrome-platform@lists.linux.dev,\n\ttzungbi@kernel.org,\n\tlinux-gpio@vger.kernel.org,\n\tlinux-kselftest@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org",
        "Subject": "[PATCH v3 09/11] gpio: Remove gpio_chip_guard by using revocable",
        "Date": "Fri, 13 Feb 2026 09:29:56 +0000",
        "Message-ID": "<20260213092958.864411-10-tzungbi@kernel.org>",
        "X-Mailer": "git-send-email 2.53.0.310.g728cabbaf7-goog",
        "In-Reply-To": "<20260213092958.864411-1-tzungbi@kernel.org>",
        "References": "<20260213092958.864411-1-tzungbi@kernel.org>",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-gpio@vger.kernel.org",
        "List-Id": "<linux-gpio.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-gpio+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-gpio+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "Struct gpio_device now provides a revocable provider to the underlying\nstruct gpio_chip.  Leverage revocable for accessing the struct\ngpio_chip instead of using gpio_chip_guard.\n\nSigned-off-by: Tzung-Bi Shih <tzungbi@kernel.org>\n---\nv3:\n- Change revocable API usages accordingly.\n\nv2: https://lore.kernel.org/all/20260203061059.975605-10-tzungbi@kernel.org\n- Separate from v1 for including gpio_chip_guard only.\n\nv1: https://lore.kernel.org/all/20260116081036.352286-23-tzungbi@kernel.org\n\n drivers/gpio/gpiolib-cdev.c  |   9 +-\n drivers/gpio/gpiolib-sysfs.c |  30 +++----\n drivers/gpio/gpiolib.c       | 163 ++++++++++++++++-------------------\n drivers/gpio/gpiolib.h       |  21 -----\n 4 files changed, 89 insertions(+), 134 deletions(-)",
    "diff": "diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c\nindex b491e2737ef2..2a61c4aa3e18 100644\n--- a/drivers/gpio/gpiolib-cdev.c\n+++ b/drivers/gpio/gpiolib-cdev.c\n@@ -2205,10 +2205,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,\n \tu32 debounce_period_us;\n \tunsigned long dflags;\n \tconst char *label;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn;\n+\trevocable_try_access_or_return_void(desc->gdev->chip_rp, gc);\n \n \tmemset(info, 0, sizeof(*info));\n \tinfo->offset = gpiod_hwgpio(desc);\n@@ -2241,10 +2240,10 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,\n \t    test_bit(GPIOD_FLAG_IS_HOGGED, &dflags) ||\n \t    test_bit(GPIOD_FLAG_EXPORT, &dflags) ||\n \t    test_bit(GPIOD_FLAG_SYSFS, &dflags) ||\n-\t    !gpiochip_line_is_valid(guard.gc, info->offset)) {\n+\t    !gpiochip_line_is_valid(gc, info->offset)) {\n \t\tinfo->flags |= GPIO_V2_LINE_FLAG_USED;\n \t} else if (!atomic) {\n-\t\tif (!pinctrl_gpio_can_use_line(guard.gc, info->offset))\n+\t\tif (!pinctrl_gpio_can_use_line(gc, info->offset))\n \t\t\tinfo->flags |= GPIO_V2_LINE_FLAG_USED;\n \t}\n \ndiff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c\nindex 3fdcfa0c7d42..9bacd89cba93 100644\n--- a/drivers/gpio/gpiolib-sysfs.c\n+++ b/drivers/gpio/gpiolib-sysfs.c\n@@ -215,10 +215,9 @@ static int gpio_sysfs_request_irq(struct gpiod_data *data, unsigned char flags)\n \tstruct gpio_desc *desc = data->desc;\n \tunsigned long irq_flags;\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tdata->irq = gpiod_to_irq(desc);\n \tif (data->irq < 0)\n@@ -244,7 +243,7 @@ static int gpio_sysfs_request_irq(struct gpiod_data *data, unsigned char flags)\n \t * Remove this redundant call (along with the corresponding unlock)\n \t * when those drivers have been fixed.\n \t */\n-\tret = gpiochip_lock_as_irq(guard.gc, gpiod_hwgpio(desc));\n+\tret = gpiochip_lock_as_irq(gc, gpiod_hwgpio(desc));\n \tif (ret < 0)\n \t\tgoto err_clr_bits;\n \n@@ -258,7 +257,7 @@ static int gpio_sysfs_request_irq(struct gpiod_data *data, unsigned char flags)\n \treturn 0;\n \n err_unlock:\n-\tgpiochip_unlock_as_irq(guard.gc, gpiod_hwgpio(desc));\n+\tgpiochip_unlock_as_irq(gc, gpiod_hwgpio(desc));\n err_clr_bits:\n \tclear_bit(GPIOD_FLAG_EDGE_RISING, &desc->flags);\n \tclear_bit(GPIOD_FLAG_EDGE_FALLING, &desc->flags);\n@@ -273,14 +272,13 @@ static int gpio_sysfs_request_irq(struct gpiod_data *data, unsigned char flags)\n static void gpio_sysfs_free_irq(struct gpiod_data *data)\n {\n \tstruct gpio_desc *desc = data->desc;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn;\n+\trevocable_try_access_or_return_void(desc->gdev->chip_rp, gc);\n \n \tdata->irq_flags = 0;\n \tfree_irq(data->irq, data);\n-\tgpiochip_unlock_as_irq(guard.gc, gpiod_hwgpio(desc));\n+\tgpiochip_unlock_as_irq(gc, gpiod_hwgpio(desc));\n \tclear_bit(GPIOD_FLAG_EDGE_RISING, &desc->flags);\n \tclear_bit(GPIOD_FLAG_EDGE_FALLING, &desc->flags);\n }\n@@ -473,13 +471,12 @@ static DEVICE_ATTR_RO(ngpio);\n static int export_gpio_desc(struct gpio_desc *desc)\n {\n \tint offset, ret;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \toffset = gpiod_hwgpio(desc);\n-\tif (!gpiochip_line_is_valid(guard.gc, offset)) {\n+\tif (!gpiochip_line_is_valid(gc, offset)) {\n \t\tpr_debug_ratelimited(\"%s: GPIO %d masked\\n\", __func__,\n \t\t\t\t     gpiod_hwgpio(desc));\n \t\treturn -EINVAL;\n@@ -732,6 +729,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)\n \tstruct gpio_device *gdev;\n \tstruct attribute **attrs;\n \tint status;\n+\tstruct gpio_chip *gc;\n \n \t/* can't export until sysfs is available ... */\n \tif (!class_is_registered(&gpio_class)) {\n@@ -744,9 +742,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)\n \t\treturn -EINVAL;\n \t}\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tif (test_and_set_bit(GPIOD_FLAG_EXPORT, &desc->flags))\n \t\treturn -EPERM;\n@@ -769,7 +765,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)\n \n \tdesc_data->desc = desc;\n \tmutex_init(&desc_data->mutex);\n-\tif (guard.gc->direction_input && guard.gc->direction_output)\n+\tif (gc->direction_input && gc->direction_output)\n \t\tdesc_data->direction_can_change = direction_may_change;\n \telse\n \t\tdesc_data->direction_can_change = false;\ndiff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c\nindex 7ef4dc4e6e9e..34f2665a9311 100644\n--- a/drivers/gpio/gpiolib.c\n+++ b/drivers/gpio/gpiolib.c\n@@ -449,14 +449,13 @@ int gpiod_get_direction(struct gpio_desc *desc)\n \tunsigned long flags;\n \tunsigned int offset;\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n \tret = validate_desc(desc, __func__);\n \tif (ret <= 0)\n \t\treturn -EINVAL;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \toffset = gpiod_hwgpio(desc);\n \tflags = READ_ONCE(desc->flags);\n@@ -469,7 +468,7 @@ int gpiod_get_direction(struct gpio_desc *desc)\n \t    test_bit(GPIOD_FLAG_IS_OUT, &flags))\n \t\treturn 0;\n \n-\tret = gpiochip_get_direction(guard.gc, offset);\n+\tret = gpiochip_get_direction(gc, offset);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -2475,31 +2474,30 @@ int gpiod_request_commit(struct gpio_desc *desc, const char *label)\n {\n \tunsigned int offset;\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tif (test_and_set_bit(GPIOD_FLAG_REQUESTED, &desc->flags))\n \t\treturn -EBUSY;\n \n \toffset = gpiod_hwgpio(desc);\n-\tif (!gpiochip_line_is_valid(guard.gc, offset))\n+\tif (!gpiochip_line_is_valid(gc, offset))\n \t\treturn -EINVAL;\n \n \t/* NOTE:  gpio_request() can be called in early boot,\n \t * before IRQs are enabled, for non-sleeping (SOC) GPIOs.\n \t */\n \n-\tif (guard.gc->request) {\n-\t\tret = guard.gc->request(guard.gc, offset);\n+\tif (gc->request) {\n+\t\tret = gc->request(gc, offset);\n \t\tif (ret > 0)\n \t\t\tret = -EBADE;\n \t\tif (ret)\n \t\t\tgoto out_clear_bit;\n \t}\n \n-\tif (guard.gc->get_direction)\n+\tif (gc->get_direction)\n \t\tgpiod_get_direction(desc);\n \n \tret = desc_set_label(desc, label ? : \"?\");\n@@ -2536,16 +2534,17 @@ int gpiod_request(struct gpio_desc *desc, const char *label)\n void gpiod_free_commit(struct gpio_desc *desc)\n {\n \tunsigned long flags;\n+\tstruct gpio_chip *gc;\n \n \tmight_sleep();\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n+\trevocable_try_access_or_return_void(desc->gdev->chip_rp, gc);\n \n \tflags = READ_ONCE(desc->flags);\n \n-\tif (guard.gc && test_bit(GPIOD_FLAG_REQUESTED, &flags)) {\n-\t\tif (guard.gc->free)\n-\t\t\tguard.gc->free(guard.gc, gpiod_hwgpio(desc));\n+\tif (test_bit(GPIOD_FLAG_REQUESTED, &flags)) {\n+\t\tif (gc->free)\n+\t\t\tgc->free(gc, gpiod_hwgpio(desc));\n \n \t\tclear_bit(GPIOD_FLAG_ACTIVE_LOW, &flags);\n \t\tclear_bit(GPIOD_FLAG_REQUESTED, &flags);\n@@ -2697,15 +2696,14 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc);\n int gpio_do_set_config(struct gpio_desc *desc, unsigned long config)\n {\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n-\tif (!guard.gc->set_config)\n+\tif (!gc->set_config)\n \t\treturn -ENOTSUPP;\n \n-\tret = guard.gc->set_config(guard.gc, gpiod_hwgpio(desc), config);\n+\tret = gc->set_config(gc, gpiod_hwgpio(desc), config);\n \tif (ret > 0)\n \t\tret = -EBADE;\n \n@@ -2874,17 +2872,16 @@ EXPORT_SYMBOL_GPL(gpiod_direction_input);\n int gpiod_direction_input_nonotify(struct gpio_desc *desc)\n {\n \tint ret = 0, dir;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \t/*\n \t * It is legal to have no .get() and .direction_input() specified if\n \t * the chip is output-only, but you can't specify .direction_input()\n \t * and not support the .get() operation, that doesn't make sense.\n \t */\n-\tif (!guard.gc->get && guard.gc->direction_input) {\n+\tif (!gc->get && gc->direction_input) {\n \t\tgpiod_warn(desc,\n \t\t\t   \"%s: missing get() but have direction_input()\\n\",\n \t\t\t   __func__);\n@@ -2897,11 +2894,10 @@ int gpiod_direction_input_nonotify(struct gpio_desc *desc)\n \t * direction (if .get_direction() is supported) else we silently\n \t * assume we are in input mode after this.\n \t */\n-\tif (guard.gc->direction_input) {\n-\t\tret = gpiochip_direction_input(guard.gc,\n-\t\t\t\t\t       gpiod_hwgpio(desc));\n-\t} else if (guard.gc->get_direction) {\n-\t\tdir = gpiochip_get_direction(guard.gc, gpiod_hwgpio(desc));\n+\tif (gc->direction_input) {\n+\t\tret = gpiochip_direction_input(gc, gpiod_hwgpio(desc));\n+\t} else if (gc->get_direction) {\n+\t\tdir = gpiochip_get_direction(gc, gpiod_hwgpio(desc));\n \t\tif (dir < 0)\n \t\t\treturn dir;\n \n@@ -2941,31 +2937,28 @@ static int gpiochip_set(struct gpio_chip *gc, unsigned int offset, int value)\n static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)\n {\n \tint val = !!value, ret = 0, dir;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \t/*\n \t * It's OK not to specify .direction_output() if the gpiochip is\n \t * output-only, but if there is then not even a .set() operation it\n \t * is pretty tricky to drive the output line.\n \t */\n-\tif (!guard.gc->set && !guard.gc->direction_output) {\n+\tif (!gc->set && !gc->direction_output) {\n \t\tgpiod_warn(desc,\n \t\t\t   \"%s: missing set() and direction_output() operations\\n\",\n \t\t\t   __func__);\n \t\treturn -EIO;\n \t}\n \n-\tif (guard.gc->direction_output) {\n-\t\tret = gpiochip_direction_output(guard.gc,\n-\t\t\t\t\t\tgpiod_hwgpio(desc), val);\n+\tif (gc->direction_output) {\n+\t\tret = gpiochip_direction_output(gc, gpiod_hwgpio(desc), val);\n \t} else {\n \t\t/* Check that we are in output mode if we can */\n-\t\tif (guard.gc->get_direction) {\n-\t\t\tdir = gpiochip_get_direction(guard.gc,\n-\t\t\t\t\t\t     gpiod_hwgpio(desc));\n+\t\tif (gc->get_direction) {\n+\t\t\tdir = gpiochip_get_direction(gc, gpiod_hwgpio(desc));\n \t\t\tif (dir < 0)\n \t\t\t\treturn dir;\n \n@@ -2980,7 +2973,7 @@ static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int value)\n \t\t * If we can't actively set the direction, we are some\n \t\t * output-only chip, so just drive the output as desired.\n \t\t */\n-\t\tret = gpiochip_set(guard.gc, gpiod_hwgpio(desc), val);\n+\t\tret = gpiochip_set(gc, gpiod_hwgpio(desc), val);\n \t\tif (ret)\n \t\t\treturn ret;\n \t}\n@@ -3118,20 +3111,18 @@ int gpiod_direction_output_nonotify(struct gpio_desc *desc, int value)\n int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)\n {\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n \tVALIDATE_DESC(desc);\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n-\tif (!guard.gc->en_hw_timestamp) {\n+\tif (!gc->en_hw_timestamp) {\n \t\tgpiod_warn(desc, \"%s: hw ts not supported\\n\", __func__);\n \t\treturn -ENOTSUPP;\n \t}\n \n-\tret = guard.gc->en_hw_timestamp(guard.gc,\n-\t\t\t\t\tgpiod_hwgpio(desc), flags);\n+\tret = gc->en_hw_timestamp(gc, gpiod_hwgpio(desc), flags);\n \tif (ret)\n \t\tgpiod_warn(desc, \"%s: hw ts request failed\\n\", __func__);\n \n@@ -3151,20 +3142,18 @@ EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns);\n int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)\n {\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n \tVALIDATE_DESC(desc);\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n-\tif (!guard.gc->dis_hw_timestamp) {\n+\tif (!gc->dis_hw_timestamp) {\n \t\tgpiod_warn(desc, \"%s: hw ts not supported\\n\", __func__);\n \t\treturn -ENOTSUPP;\n \t}\n \n-\tret = guard.gc->dis_hw_timestamp(guard.gc, gpiod_hwgpio(desc),\n-\t\t\t\t\t flags);\n+\tret = gc->dis_hw_timestamp(gc, gpiod_hwgpio(desc), flags);\n \tif (ret)\n \t\tgpiod_warn(desc, \"%s: hw ts release failed\\n\", __func__);\n \n@@ -3424,31 +3413,29 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,\n \t\tunsigned long *mask, *bits;\n \t\tint first, j;\n \n-\t\tCLASS(gpio_chip_guard, guard)(desc_array[i]);\n-\t\tif (!guard.gc)\n-\t\t\treturn -ENODEV;\n+\t\trevocable_try_access_or_return(desc_array[i]->gdev->chip_rp, gc);\n \n-\t\tif (likely(guard.gc->ngpio <= FASTPATH_NGPIO)) {\n+\t\tif (likely(gc->ngpio <= FASTPATH_NGPIO)) {\n \t\t\tmask = fastpath_mask;\n \t\t\tbits = fastpath_bits;\n \t\t} else {\n \t\t\tgfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC;\n \n-\t\t\tmask = bitmap_alloc(guard.gc->ngpio, flags);\n+\t\t\tmask = bitmap_alloc(gc->ngpio, flags);\n \t\t\tif (!mask)\n \t\t\t\treturn -ENOMEM;\n \n-\t\t\tbits = bitmap_alloc(guard.gc->ngpio, flags);\n+\t\t\tbits = bitmap_alloc(gc->ngpio, flags);\n \t\t\tif (!bits) {\n \t\t\t\tbitmap_free(mask);\n \t\t\t\treturn -ENOMEM;\n \t\t\t}\n \t\t}\n \n-\t\tbitmap_zero(mask, guard.gc->ngpio);\n+\t\tbitmap_zero(mask, gc->ngpio);\n \n \t\tif (!can_sleep)\n-\t\t\tWARN_ON(guard.gc->can_sleep);\n+\t\t\tWARN_ON(gc->can_sleep);\n \n \t\t/* collect all inputs belonging to the same chip */\n \t\tfirst = i;\n@@ -3463,9 +3450,9 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,\n \t\t\t\ti = find_next_zero_bit(array_info->get_mask,\n \t\t\t\t\t\t       array_size, i);\n \t\t} while ((i < array_size) &&\n-\t\t\t gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc));\n+\t\t\t gpio_device_chip_cmp(desc_array[i]->gdev, gc));\n \n-\t\tret = gpio_chip_get_multiple(guard.gc, mask, bits);\n+\t\tret = gpio_chip_get_multiple(gc, mask, bits);\n \t\tif (ret) {\n \t\t\tif (mask != fastpath_mask)\n \t\t\t\tbitmap_free(mask);\n@@ -3614,15 +3601,14 @@ EXPORT_SYMBOL_GPL(gpiod_get_array_value);\n static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)\n {\n \tint ret = 0, offset = gpiod_hwgpio(desc);\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tif (value) {\n-\t\tret = gpiochip_direction_input(guard.gc, offset);\n+\t\tret = gpiochip_direction_input(gc, offset);\n \t} else {\n-\t\tret = gpiochip_direction_output(guard.gc, offset, 0);\n+\t\tret = gpiochip_direction_output(gc, offset, 0);\n \t\tif (!ret)\n \t\t\tset_bit(GPIOD_FLAG_IS_OUT, &desc->flags);\n \t}\n@@ -3643,17 +3629,16 @@ static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)\n static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value)\n {\n \tint ret = 0, offset = gpiod_hwgpio(desc);\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tif (value) {\n-\t\tret = gpiochip_direction_output(guard.gc, offset, 1);\n+\t\tret = gpiochip_direction_output(gc, offset, 1);\n \t\tif (!ret)\n \t\t\tset_bit(GPIOD_FLAG_IS_OUT, &desc->flags);\n \t} else {\n-\t\tret = gpiochip_direction_input(guard.gc, offset);\n+\t\tret = gpiochip_direction_input(gc, offset);\n \t}\n \ttrace_gpio_direction(desc_to_gpio(desc), !value, ret);\n \tif (ret < 0)\n@@ -3666,15 +3651,15 @@ static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value)\n \n static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)\n {\n+\tstruct gpio_chip *gc;\n+\n \tif (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags)))\n \t\treturn -EPERM;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \ttrace_gpio_value(desc_to_gpio(desc), 0, value);\n-\treturn gpiochip_set(guard.gc, gpiod_hwgpio(desc), value);\n+\treturn gpiochip_set(gc, gpiod_hwgpio(desc), value);\n }\n \n /*\n@@ -3769,31 +3754,29 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,\n \t\tunsigned long *mask, *bits;\n \t\tint count = 0;\n \n-\t\tCLASS(gpio_chip_guard, guard)(desc_array[i]);\n-\t\tif (!guard.gc)\n-\t\t\treturn -ENODEV;\n+\t\trevocable_try_access_or_return(desc_array[i]->gdev->chip_rp, gc);\n \n-\t\tif (likely(guard.gc->ngpio <= FASTPATH_NGPIO)) {\n+\t\tif (likely(gc->ngpio <= FASTPATH_NGPIO)) {\n \t\t\tmask = fastpath_mask;\n \t\t\tbits = fastpath_bits;\n \t\t} else {\n \t\t\tgfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC;\n \n-\t\t\tmask = bitmap_alloc(guard.gc->ngpio, flags);\n+\t\t\tmask = bitmap_alloc(gc->ngpio, flags);\n \t\t\tif (!mask)\n \t\t\t\treturn -ENOMEM;\n \n-\t\t\tbits = bitmap_alloc(guard.gc->ngpio, flags);\n+\t\t\tbits = bitmap_alloc(gc->ngpio, flags);\n \t\t\tif (!bits) {\n \t\t\t\tbitmap_free(mask);\n \t\t\t\treturn -ENOMEM;\n \t\t\t}\n \t\t}\n \n-\t\tbitmap_zero(mask, guard.gc->ngpio);\n+\t\tbitmap_zero(mask, gc->ngpio);\n \n \t\tif (!can_sleep)\n-\t\t\tWARN_ON(guard.gc->can_sleep);\n+\t\t\tWARN_ON(gc->can_sleep);\n \n \t\tdo {\n \t\t\tstruct gpio_desc *desc = desc_array[i];\n@@ -3832,10 +3815,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep,\n \t\t\t\ti = find_next_zero_bit(array_info->set_mask,\n \t\t\t\t\t\t       array_size, i);\n \t\t} while ((i < array_size) &&\n-\t\t\t gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc));\n+\t\t\t gpio_device_chip_cmp(desc_array[i]->gdev, gc));\n \t\t/* push collected bits to outputs */\n \t\tif (count != 0) {\n-\t\t\tret = gpiochip_set_multiple(guard.gc, mask, bits);\n+\t\t\tret = gpiochip_set_multiple(gc, mask, bits);\n \t\t\tif (ret)\n \t\t\t\treturn ret;\n \t\t}\n@@ -5051,18 +5034,16 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,\n \tstruct gpio_desc *local_desc;\n \tint hwnum;\n \tint ret;\n+\tstruct gpio_chip *gc;\n \n-\tCLASS(gpio_chip_guard, guard)(desc);\n-\tif (!guard.gc)\n-\t\treturn -ENODEV;\n+\trevocable_try_access_or_return(desc->gdev->chip_rp, gc);\n \n \tif (test_and_set_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags))\n \t\treturn 0;\n \n \thwnum = gpiod_hwgpio(desc);\n \n-\tlocal_desc = gpiochip_request_own_desc(guard.gc, hwnum, name,\n-\t\t\t\t\t       lflags, dflags);\n+\tlocal_desc = gpiochip_request_own_desc(gc, hwnum, name, lflags, dflags);\n \tif (IS_ERR(local_desc)) {\n \t\tclear_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags);\n \t\tret = PTR_ERR(local_desc);\ndiff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h\nindex 56643f40e87e..a254a57f37f5 100644\n--- a/drivers/gpio/gpiolib.h\n+++ b/drivers/gpio/gpiolib.h\n@@ -224,27 +224,6 @@ struct gpio_desc {\n \n #define gpiod_not_found(desc)\t\t(IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)\n \n-struct gpio_chip_guard {\n-\tstruct gpio_device *gdev;\n-\tstruct gpio_chip *gc;\n-\tint idx;\n-};\n-\n-DEFINE_CLASS(gpio_chip_guard,\n-\t     struct gpio_chip_guard,\n-\t     srcu_read_unlock(&_T.gdev->srcu, _T.idx),\n-\t     ({\n-\t\tstruct gpio_chip_guard _guard;\n-\n-\t\t_guard.gdev = desc->gdev;\n-\t\t_guard.idx = srcu_read_lock(&_guard.gdev->srcu);\n-\t\t_guard.gc = srcu_dereference(_guard.gdev->chip,\n-\t\t\t\t\t     &_guard.gdev->srcu);\n-\n-\t\t_guard;\n-\t     }),\n-\t     struct gpio_desc *desc)\n-\n int gpiod_request(struct gpio_desc *desc, const char *label);\n int gpiod_request_commit(struct gpio_desc *desc, const char *label);\n void gpiod_free(struct gpio_desc *desc);\n",
    "prefixes": [
        "v3",
        "09/11"
    ]
}