From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C24D7369964; Tue, 3 Feb 2026 06:11:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099113; cv=none; b=RV/vX82LG64aC1hXYyFveTYJAR4qPswRAgJg5YHeZrKEqFM00L+d3W1hMWxS4LZI0wNTQcNnRA9mn/P2+qtQSJs2tXE+p1FJVOdRjihm3LKldqiskyQTHRe9DLnjGtCoEV3pKPqEptcWy48hYNKjca7oYfsOtbiLvmGcR7tYmPA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099113; c=relaxed/simple; bh=9YxyRXQE5kVPwTtGkSgy0U2f3ePQUxO3G44Txlw2CP4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JCosR/2QEXpep2CnKwkYCwSElKuIlIRvK1p+VjCsgWQawzSdL0Pa6PPWsPFWa4i3pYFSvOSIER6VPv9fxT2sqgwUooEmfvJYtxCIMvJDcFWa0DFwvAtuccLbN00cRzLuYrFakV55We/JiC52UMh+kEYWVyuva3VTWbu73DkMpyc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Oa1RfMNw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Oa1RfMNw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08F45C2BC86; Tue, 3 Feb 2026 06:11:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099113; bh=9YxyRXQE5kVPwTtGkSgy0U2f3ePQUxO3G44Txlw2CP4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Oa1RfMNwz78iW7e/YjWiAp+BQrjFLnw4oJUi5eeGIFaIR/6nuXdTboMq4FhSCeCj9 rizGM7Yk+AGmnSWqNWV62R0s1aIYY1jq70rowLWkrgjYHDSmQUjcfilgTRzyVzpcrm BzqATe1xT19KJl9RmnJBCCo095Iu6C3nEqqVECgx5zPIwSjFQ73KczvN+k9QYp5eZo ATrVYq8vtCEaaJo+PiRoa6mlJNKgl8GQoCjAY5TGDZ/rzXFpzC19UO7M/43ExFHe96 J9ZY0q94KX8eTtfw/3C9/MNWLGfB9nPmqFk4XDn2jBV6kEg6GroFURhWiflEyqWcSJ 82pynaxkGxUJg== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 01/11] gpio: Access `gpio_bus_type` in gpiochip_setup_dev() Date: Tue, 3 Feb 2026 06:10:48 +0000 Message-ID: <20260203061059.975605-2-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To make the intent clear, access `gpio_bus_type` only when it's ready in gpiochip_setup_dev(). Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-7-tzungbi@kernel.org drivers/gpio/gpiolib.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 039cd3e56baf..f51f53511ae3 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -902,6 +902,8 @@ static int gpiochip_setup_dev(struct gpio_device *gdev) struct fwnode_handle *fwnode =3D dev_fwnode(&gdev->dev); int ret; =20 + gdev->dev.bus =3D &gpio_bus_type; + /* * If fwnode doesn't belong to another device, it's safe to clear its * initialized flag. @@ -1078,7 +1080,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, =20 device_initialize(&gdev->dev); gdev->dev.type =3D &gpio_dev_type; - gdev->dev.bus =3D &gpio_bus_type; gdev->dev.parent =3D gc->parent; device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc)); =20 @@ -1216,8 +1217,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, * we get a device node entry in sysfs under * /sys/bus/gpio/devices/gpiochipN/dev that can be used for * coldplug of device nodes and other udev business. - * We can do this only if gpiolib has been initialized. - * Otherwise, defer until later. + * We can do this only if gpiolib has been initialized + * (i.e., `gpio_bus_type` is ready). Otherwise, defer until later. */ if (gpiolib_initialized) { ret =3D gpiochip_setup_dev(gdev); --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D613369964; Tue, 3 Feb 2026 06:11:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099116; cv=none; b=RNIFWSePWEVYWSvF1bivASjvdJZoNl7eBNW5iiNW69jygaXYq9/b+ANgspJxATmKzYuzLf0TIhiNXedBTpL9q3TNjMfSKKCl6yLg6OWyPHgpYq9rwQr4m3xlph5QAzU4NaMwxRewG9ikDYQOGXJgaLIO5Q1fn5UeRIlzOsCAQ3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099116; c=relaxed/simple; bh=0vNR5cNKN4N6Ad0oCcxkV3hwFhTeIBItllECCwiylBA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XjhxywuOV647VL+1t8NXgTTPv193zFFn6FdOriHqGt1IOkA+swcf8+p029xxopVXXRQZFnGjUt69ad0iYdWD8w4Smhn2VPAmx2TKWycos6tGF9er/xo9XSgYEspp+cWm/6T4hVBWZzzdLlT9ZkVGv05XISGqox73vuJWVG61x2Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HPrjFc0j; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HPrjFc0j" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B86A5C16AAE; Tue, 3 Feb 2026 06:11:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099116; bh=0vNR5cNKN4N6Ad0oCcxkV3hwFhTeIBItllECCwiylBA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HPrjFc0jgdYeWIrmyvJq/ajTRd6lfW6UnK7IiKinOPu5OieOXbEzp2Z/KVFTUSetd WduZLwwAonMIq/FxWZ+64RFvqGWrwv4UEUxpCaCweSJLoF2MEpqEBZFizHYnrRlxR/ f5fuZqyo0BIkPeTqb7v0hltinZBpredcmVH6gw8PzO3tCm3EDybcrKgmR58F7pRNeU 2CwPh6Ho25Sq7hWG1gbm9PohAcbZejkA5q75T8rpEQ8md03zkj5kykPcARi8rvdtrC 7yayDeR53WgT22bggPLonApZz9soBVYbuyuz35O5HcCdDH63/X309I1RaCiTuJ2ov0 vieitVZGkP18g== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 02/11] gpio: Remove redundant check for struct gpio_chip Date: Tue, 3 Feb 2026 06:10:49 +0000 Message-ID: <20260203061059.975605-3-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" gpiolib_dbg_show() is only called by gpiolib_seq_show() which has ensured the struct gpio_chip. Remove the redundant check in gpiolib_dbg_show(). Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-8-tzungbi@kernel.org drivers/gpio/gpiolib.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f51f53511ae3..a6dd07be126c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -5308,23 +5308,14 @@ core_initcall(gpiolib_dev_init); =20 #ifdef CONFIG_DEBUG_FS =20 -static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev) +static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *gc) { bool active_low, is_irq, is_out; struct gpio_desc *desc; unsigned int gpio =3D 0; - struct gpio_chip *gc; unsigned long flags; int value; =20 - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); - if (!gc) { - seq_puts(s, "Underlying GPIO chip is gone\n"); - return; - } - for_each_gpio_desc(gc, desc) { guard(srcu)(&desc->gdev->desc_srcu); flags =3D READ_ONCE(desc->flags); @@ -5437,7 +5428,7 @@ static int gpiolib_seq_show(struct seq_file *s, void = *v) if (gc->dbg_show) gc->dbg_show(s, gc); else - gpiolib_dbg_show(s, gdev); + gpiolib_dbg_show(s, gc); =20 return 0; } --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F0CDE36BCD4; Tue, 3 Feb 2026 06:11:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099119; cv=none; b=uyzFholYAUQTaEa2xRgjzQPh7A1B6HZeohCdBfND70ot7jMrTT/ToxM5CzQTaXZNs/GnkUvX24Fa9rhrP0ZFnHoT4l9wW/UO8+5XIvTzIG1coM6ceiiTHomloHFHyk4B9a2a/JrrChWsl5l0XfN02N9TiYaiyY9nkP15FtSbD4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099119; c=relaxed/simple; bh=EJ+TDb9a/0MDYPCDTU4S8VEwVGR8TQu0WaVai1yH6Jw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B6Trc5da2dA4/uO0fyBOyqkD5MPfJ9AksG0jPt2bbR3s9GMfUs1UBiFzztdHUZIomuMWr4iaq9i0GqvXHO2Zy5yOg5sdbowNUQfqye9lmYNz5Z9a3WYHQBIbhwVbXVfVfE5tKGQVpy/DIl6hkEv8Ivi1LQ1hcQP03t2GukioqPM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RXVydcL6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RXVydcL6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73176C116D0; Tue, 3 Feb 2026 06:11:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099118; bh=EJ+TDb9a/0MDYPCDTU4S8VEwVGR8TQu0WaVai1yH6Jw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RXVydcL6Q96CW6A0FJPpzoI09yjEL9SRxE+UflwoDbGIfAsPFGQj0cOcKukEmd2L4 k/sbHXMc22D2Ym03lE5h//Q76BgZEFToypgKdWrk2QKSAyyajJvqWN+Qb+eZGpQJCF rl93X5DttqxTc9gdc4mfXBMCE9EaEAcIiiuECX34Dx5DidMJRLIPjrdsu6WFFNCpIb TLHK1bv/w8pJ8/SEaVdSSlabnniAsMuR4LBAHmXsVAHeGxwq2DjlCTkcArCjbBjvJU mtuMApDBLAyHDywZPaiJQzrTi2BddLj2Cs7gaQYXv79mxrIBkbL/j8x4lugIZU4Fhi G3/CYgeS4+0Og== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 03/11] gpio: sysfs: Remove redundant check for struct gpio_chip Date: Tue, 3 Feb 2026 06:10:50 +0000 Message-ID: <20260203061059.975605-4-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" gpiochip_sysfs_unregister() is only called by gpiochip_remove() where the struct gpio_chip is ensured. Remove the redundant check. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-9-tzungbi@kernel.org drivers/gpio/gpiolib-sysfs.c | 9 +-------- drivers/gpio/gpiolib-sysfs.h | 6 ++++-- drivers/gpio/gpiolib.c | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index cd553acf3055..8e6b09d8b559 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -1048,11 +1048,10 @@ int gpiochip_sysfs_register(struct gpio_device *gde= v) return 0; } =20 -void gpiochip_sysfs_unregister(struct gpio_device *gdev) +void gpiochip_sysfs_unregister(struct gpio_device *gdev, struct gpio_chip = *chip) { struct gpiodev_data *data; struct gpio_desc *desc; - struct gpio_chip *chip; =20 scoped_guard(mutex, &sysfs_lock) { data =3D gdev_get_data(gdev); @@ -1066,12 +1065,6 @@ void gpiochip_sysfs_unregister(struct gpio_device *g= dev) kfree(data); } =20 - guard(srcu)(&gdev->srcu); - - chip =3D srcu_dereference(gdev->chip, &gdev->srcu); - if (!chip) - return; - /* unregister gpiod class devices owned by sysfs */ for_each_gpio_desc_with_flag(chip, desc, GPIOD_FLAG_SYSFS) { gpiod_unexport(desc); diff --git a/drivers/gpio/gpiolib-sysfs.h b/drivers/gpio/gpiolib-sysfs.h index b794b396d6a5..93debe8e118c 100644 --- a/drivers/gpio/gpiolib-sysfs.h +++ b/drivers/gpio/gpiolib-sysfs.h @@ -8,7 +8,8 @@ struct gpio_device; #ifdef CONFIG_GPIO_SYSFS =20 int gpiochip_sysfs_register(struct gpio_device *gdev); -void gpiochip_sysfs_unregister(struct gpio_device *gdev); +void gpiochip_sysfs_unregister(struct gpio_device *gdev, + struct gpio_chip *chip); =20 #else =20 @@ -17,7 +18,8 @@ static inline int gpiochip_sysfs_register(struct gpio_dev= ice *gdev) return 0; } =20 -static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev) +static inline void gpiochip_sysfs_unregister(struct gpio_device *gdev, + struct gpio_chip *chip) { } =20 diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a6dd07be126c..3137e6f1108a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1281,7 +1281,7 @@ void gpiochip_remove(struct gpio_chip *gc) struct gpio_device *gdev =3D gc->gpiodev; =20 /* FIXME: should the legacy sysfs handling be moved to gpio_device? */ - gpiochip_sysfs_unregister(gdev); + gpiochip_sysfs_unregister(gdev, gc); gpiochip_free_hogs(gc); gpiochip_free_remaining_irqs(gc); =20 --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDB362F12C9; Tue, 3 Feb 2026 06:12:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099122; cv=none; b=B3wDNu1ul9JPN3dtdvhKNDHzP2I//YgzeQUKDPLoTpGpfrBfHUO3e++xfe5LSVU+qSSpxLdJUBe+mHLoB4GH5x0wViwHXfQ4vp7ZuPgQjPdUSx9KB2k9RpD/anzeQKiTkR6iUSgu1Mt0H6oP4k3zD/atBbvJfdPJrewe4QlHs8M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099122; c=relaxed/simple; bh=BpRnb8HlJCckOF1TQGnoEDWIxdW1FFDdRoCSkW9rW4s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PoJQfCbuwWQN+h+Ab0JyRMkXInkcXEVvuYNa/BlMlgp5t7l/B5aUejiemn5Ze2zRCgbyxGMeUWAcbulpDot9mG/U5ITrJeJXm2FB4kVIk49+7tMi+ZuNil4tsprqChHwKkAFvtSSyD/OG8QaCDmaDvTWnmgi47iISPoVIWxLXs4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ElBKPToe; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ElBKPToe" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 31D38C2BCB3; Tue, 3 Feb 2026 06:11:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099121; bh=BpRnb8HlJCckOF1TQGnoEDWIxdW1FFDdRoCSkW9rW4s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ElBKPToeTRlsfX2w4mOkWQD80NqMYxPCgSvOvlQoDgAb/f98YSYR4WOJUXAscW6Wq IVshiR2JX+wxfW49kpFiCJrFYTQhpI0O1vVJPya/yWdggWfxdyDExXT52RWV7B8ZrU l4+QGJTIL01vOZB4bJns6Qz6SGrSE5gUFsokawqhIaBqg6LPt1JgrjZVQrI1jkksoh jg1FpcJl/O8PAZ2j6uOOrFg27XAaz3Q61y5j6dpVjO8F+eREIpUo8kXmp3tPGhI/TW 4NkhEF75EtbChBYvNxP5vgArND3TuPetK/HWyJuH7JEZIedj3674t3Ba4t0OmNBejL xpzKEyKHLYXow== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 04/11] gpio: Ensure struct gpio_chip for gpiochip_setup_dev() Date: Tue, 3 Feb 2026 06:10:51 +0000 Message-ID: <20260203061059.975605-5-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Ensure struct gpio_chip for gpiochip_setup_dev(). This eliminates a few checks for struct gpio_chip. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-10-tzungbi@kernel.org drivers/gpio/gpiolib-cdev.c | 12 ++---------- drivers/gpio/gpiolib-cdev.h | 3 ++- drivers/gpio/gpiolib-sysfs.c | 11 ++--------- drivers/gpio/gpiolib-sysfs.h | 5 +++-- drivers/gpio/gpiolib.c | 24 +++++++++++++++++------- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 2adc3c070908..b89201578516 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2782,9 +2782,9 @@ static const struct file_operations gpio_fileops =3D { #endif }; =20 -int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt) +int gpiolib_cdev_register(struct gpio_device *gdev, struct gpio_chip *gc, + dev_t devt) { - struct gpio_chip *gc; int ret; =20 cdev_init(&gdev->chrdev, &gpio_fileops); @@ -2802,14 +2802,6 @@ int gpiolib_cdev_register(struct gpio_device *gdev, = dev_t devt) return ret; } =20 - guard(srcu)(&gdev->srcu); - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); - if (!gc) { - cdev_device_del(&gdev->chrdev, &gdev->dev); - destroy_workqueue(gdev->line_state_wq); - return -ENODEV; - } - gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); =20 return 0; diff --git a/drivers/gpio/gpiolib-cdev.h b/drivers/gpio/gpiolib-cdev.h index b42644cbffb8..16ef1e2e96a0 100644 --- a/drivers/gpio/gpiolib-cdev.h +++ b/drivers/gpio/gpiolib-cdev.h @@ -7,7 +7,8 @@ =20 struct gpio_device; =20 -int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt); +int gpiolib_cdev_register(struct gpio_device *gdev, struct gpio_chip *gc, + dev_t devt); void gpiolib_cdev_unregister(struct gpio_device *gdev); =20 #endif /* GPIOLIB_CDEV_H */ diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 8e6b09d8b559..a4427a5cfa85 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -978,10 +978,9 @@ void gpiod_unexport(struct gpio_desc *desc) } EXPORT_SYMBOL_GPL(gpiod_unexport); =20 -int gpiochip_sysfs_register(struct gpio_device *gdev) +int gpiochip_sysfs_register(struct gpio_device *gdev, struct gpio_chip *ch= ip) { struct gpiodev_data *data; - struct gpio_chip *chip; struct device *parent; int err; =20 @@ -994,12 +993,6 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) if (!class_is_registered(&gpio_class)) return 0; =20 - guard(srcu)(&gdev->srcu); - - chip =3D srcu_dereference(gdev->chip, &gdev->srcu); - if (!chip) - return -ENODEV; - /* * For sysfs backward compatibility we need to preserve this * preferred parenting to the gpio_chip parent field, if set. @@ -1082,7 +1075,7 @@ static int gpiofind_sysfs_register(struct gpio_chip *= gc, const void *data) struct gpio_device *gdev =3D gc->gpiodev; int ret; =20 - ret =3D gpiochip_sysfs_register(gdev); + ret =3D gpiochip_sysfs_register(gdev, gc); if (ret) gpiochip_err(gc, "failed to register the sysfs entry: %d\n", ret); =20 diff --git a/drivers/gpio/gpiolib-sysfs.h b/drivers/gpio/gpiolib-sysfs.h index 93debe8e118c..192b1ee041a6 100644 --- a/drivers/gpio/gpiolib-sysfs.h +++ b/drivers/gpio/gpiolib-sysfs.h @@ -7,13 +7,14 @@ struct gpio_device; =20 #ifdef CONFIG_GPIO_SYSFS =20 -int gpiochip_sysfs_register(struct gpio_device *gdev); +int gpiochip_sysfs_register(struct gpio_device *gdev, struct gpio_chip *ch= ip); void gpiochip_sysfs_unregister(struct gpio_device *gdev, struct gpio_chip *chip); =20 #else =20 -static inline int gpiochip_sysfs_register(struct gpio_device *gdev) +static inline int gpiochip_sysfs_register(struct gpio_device *gdev, + struct gpio_chip *chip) { return 0; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 3137e6f1108a..7885dcd1e49d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -882,14 +882,15 @@ static const struct device_type gpio_dev_type =3D { }; =20 #ifdef CONFIG_GPIO_CDEV -#define gcdev_register(gdev, devt) gpiolib_cdev_register((gdev), (devt)) +#define gcdev_register(gdev, gc, devt) \ + gpiolib_cdev_register((gdev), (gc), (devt)) #define gcdev_unregister(gdev) gpiolib_cdev_unregister((gdev)) #else /* * gpiolib_cdev_register() indirectly calls device_add(), which is still * required even when cdev is not selected. */ -#define gcdev_register(gdev, devt) device_add(&(gdev)->dev) +#define gcdev_register(gdev, gc, devt) device_add(&(gdev)->dev) #define gcdev_unregister(gdev) device_del(&(gdev)->dev) #endif =20 @@ -897,7 +898,7 @@ static const struct device_type gpio_dev_type =3D { * An initial reference count has been held in gpiochip_add_data_with_key(= ). * The caller should drop the reference via gpio_device_put() on errors. */ -static int gpiochip_setup_dev(struct gpio_device *gdev) +static int gpiochip_setup_dev(struct gpio_device *gdev, struct gpio_chip *= gc) { struct fwnode_handle *fwnode =3D dev_fwnode(&gdev->dev); int ret; @@ -911,11 +912,11 @@ static int gpiochip_setup_dev(struct gpio_device *gde= v) if (fwnode && !fwnode->dev) fwnode_dev_initialized(fwnode, false); =20 - ret =3D gcdev_register(gdev, gpio_devt); + ret =3D gcdev_register(gdev, gc, gpio_devt); if (ret) return ret; =20 - ret =3D gpiochip_sysfs_register(gdev); + ret =3D gpiochip_sysfs_register(gdev, gc); if (ret) goto err_remove_device; =20 @@ -962,13 +963,22 @@ static void machine_gpiochip_add(struct gpio_chip *gc) static void gpiochip_setup_devs(void) { struct gpio_device *gdev; + struct gpio_chip *gc; int ret; =20 guard(srcu)(&gpio_devices_srcu); =20 list_for_each_entry_srcu(gdev, &gpio_devices, list, srcu_read_lock_held(&gpio_devices_srcu)) { - ret =3D gpiochip_setup_dev(gdev); + guard(srcu)(&gdev->srcu); + + gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + if (!gc) { + dev_err(&gdev->dev, "Underlying GPIO chip is gone\n"); + continue; + } + + ret =3D gpiochip_setup_dev(gdev, gc); if (ret) { gpio_device_put(gdev); dev_err(&gdev->dev, @@ -1221,7 +1231,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, * (i.e., `gpio_bus_type` is ready). Otherwise, defer until later. */ if (gpiolib_initialized) { - ret =3D gpiochip_setup_dev(gdev); + ret =3D gpiochip_setup_dev(gdev, gc); if (ret) goto err_teardown_shared; } --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2F8F36C5B7; Tue, 3 Feb 2026 06:12:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099124; cv=none; b=qnjOxmu73yHRJFGX7s3wJy3kvLT7QiNplCM0ahZwgs8LrJveUlirRtfenW+JCAHnuhcUBkQ0NWlO9H3y8BqD7o1D++bkiEKAmZl3Beotn9DHJ44ZaA5Lwp3AD/LnrjxiI+psM84W6Y8r68znE8auX0i1q6kd2aVs/9pkjEkc7mA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099124; c=relaxed/simple; bh=lULAaQy6hHP7Jw8IDjREwCCMFUDk+XOS0cHztpd2ANo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W/qVc51fjOLAI6wEhYQw/W10BBpSB1id2vbhX08gdeyKQqSwaukka2uE5u8xIrb5oS3EcJZnuXvqArK+vD+NYgoUACuIzMBtqbF9144UMWA5jxnWsAxOeOzJgc/WE7gGaTX3u1+sW02BJ34q1qsiV7ZX3YU5+BujacgzKbUnUKU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lFBFrqux; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lFBFrqux" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6157C116D0; Tue, 3 Feb 2026 06:12:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099124; bh=lULAaQy6hHP7Jw8IDjREwCCMFUDk+XOS0cHztpd2ANo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lFBFrquxN4C1UXvD0NdpSSsE+0DhnxsIJnbPHDeaS142lPpncCO4icLDwIfck34Tj r18/MVqeTH0d4toQE8rySLETldquJrw47B54NgW0YFJaC6SM7SFm63ng9UfYWzOgws Mh7MUAUC/oBMJ5+JERA8r2THEpQFzV2Acsu5m3UzSpIPt9aoRV+S1iRn13hzNG0epb Au2VzEaB4ye6Ma+MBj21Nu6KYfflf0rEEVxmUPbSnGj5cIeNSQ/hrJ3JroLrFiBUCG PExWsY8xfFa5jHSJMRMPqhNCT2yuJ9wq68wREVxQo46U0nHKQK2XeXf6lui3IVZBzo PqamnM242zH+w== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 05/11] gpio: cdev: Don't check struct gpio_chip in gpio_chrdev_open() Date: Tue, 3 Feb 2026 06:10:52 +0000 Message-ID: <20260203061059.975605-6-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It's harmless even if: chrdev_open() and cdev_device_del() run at the same time, and gpio_chrdev_open() gets called after the underlying GPIO chip has gone. The subsequent file operations check the availability of struct gpio_chip anyway. Don't check struct gpio_chip in gpio_chrdev_open(). Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-11-tzungbi@kernel.org drivers/gpio/gpiolib-cdev.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index b89201578516..aaa5de814468 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2689,12 +2689,6 @@ static int gpio_chrdev_open(struct inode *inode, str= uct file *file) struct gpio_chardev_data *cdev; int ret =3D -ENOMEM; =20 - guard(srcu)(&gdev->srcu); - - /* Fail on open if the backing gpiochip is gone */ - if (!rcu_access_pointer(gdev->chip)) - return -ENODEV; - cdev =3D kzalloc(sizeof(*cdev), GFP_KERNEL); if (!cdev) return -ENOMEM; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2877636D4FA; Tue, 3 Feb 2026 06:12:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099127; cv=none; b=RuYzvJo4fnIr9DAGbeSj8E+zhz2+BRic5xTF/qQKRM7KKyH2/itVODjaxRy9oyo4OLakvvHjbTCxyeZT1JH5Gja8dEuJKXBha4edmE2bkMdNqBTmrOw1jV2rZbredxEajQRsNEe2sF1bw1w04eAMuSa4PNGWNQhc8Oemb7WTMQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099127; c=relaxed/simple; bh=q4CPLmejv1/cWQkqo1Ssx6UbxBRF9iXRvnw2vIQAgBo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mEiL+jAn3RUd0p0IeDmDL8Je6gdt8UBU8IlDMEsb0gaCTWZ+m3QdhNhGoKbR0+v3P4jHsTwD2AH7KuJuqRE/bldGhxldQGdVoL0vhTAWwfXm99+BG8O49090/VpBlcImov0Xo4/kX8m20rvrcDSK5vC2fPa9INxiZWtxEMcfh2w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YYmEBer8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YYmEBer8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A1D49C2BC9E; Tue, 3 Feb 2026 06:12:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099127; bh=q4CPLmejv1/cWQkqo1Ssx6UbxBRF9iXRvnw2vIQAgBo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YYmEBer8jR460EnuitVFhkD88OwLpgjbYHtZMnehjgy7xLgl20HF5S9u2h80wICpL MP+w/t+ra9WypIEKE87nK60mSFAXGpHhmmJCDH72T5YJZ23XOf1xU9mauqma1YFSth haly3vHE1rawOyEAgIZfAqMAXnAL3UxErPGlHPB6lW3KOqqYn1IrlVFQsGVawefxZB egHxHcz9D2FKiGANRdAWf0u2iAvpDAbC3m9lJH6++/bY1ymihV0mh0gx53sstphmUg nLYci1MJl+RxypFBpFe/1/rTCpr6YVXOIrPgjcGqiCjlIZ4D2sRluUvAeDg67u+nEg aTvWww67AopRw== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 06/11] selftests: gpio: Add gpio-cdev-uaf tests Date: Tue, 3 Feb 2026 06:10:53 +0000 Message-ID: <20260203061059.975605-7-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add tests for gpiolib-cdev to make sure accessing to dangling resources via the opening file descriptor won't crash the system after the underlying resource providers have gone. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - Remove fdinfo test which is redundant. v1: https://lore.kernel.org/all/20260116081036.352286-12-tzungbi@kernel.org tools/testing/selftests/gpio/Makefile | 5 +- tools/testing/selftests/gpio/gpio-cdev-uaf.c | 292 ++++++++++++++++++ tools/testing/selftests/gpio/gpio-cdev-uaf.sh | 63 ++++ 3 files changed, 358 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/gpio/gpio-cdev-uaf.c create mode 100755 tools/testing/selftests/gpio/gpio-cdev-uaf.sh diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftest= s/gpio/Makefile index 7bfe315f7001..741ab21e1260 100644 --- a/tools/testing/selftests/gpio/Makefile +++ b/tools/testing/selftests/gpio/Makefile @@ -1,8 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 =20 -TEST_PROGS :=3D gpio-mockup.sh gpio-sim.sh gpio-aggregator.sh +TEST_PROGS :=3D gpio-mockup.sh gpio-sim.sh gpio-aggregator.sh gpio-cdev-ua= f.sh TEST_FILES :=3D gpio-mockup-sysfs.sh -TEST_GEN_PROGS_EXTENDED :=3D gpio-mockup-cdev gpio-chip-info gpio-line-name +TEST_GEN_PROGS_EXTENDED :=3D gpio-mockup-cdev gpio-chip-info gpio-line-nam= e \ + gpio-cdev-uaf CFLAGS +=3D -O2 -g -Wall $(KHDR_INCLUDES) =20 include ../lib.mk diff --git a/tools/testing/selftests/gpio/gpio-cdev-uaf.c b/tools/testing/s= elftests/gpio/gpio-cdev-uaf.c new file mode 100644 index 000000000000..765d3cc4f0ef --- /dev/null +++ b/tools/testing/selftests/gpio/gpio-cdev-uaf.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * GPIO character device helper for UAF tests. + * + * Copyright 2026 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONFIGFS_DIR "/sys/kernel/config/gpio-sim" +#define PROCFS_DIR "/proc" + +static void print_usage(void) +{ + printf("usage:\n"); + printf(" gpio-cdev-uaf [chip|handle|event|req] [poll|read|ioctl]\n"); +} + +static int _create_chip(const char *name, int create) +{ + char path[64]; + + snprintf(path, sizeof(path), CONFIGFS_DIR "/%s", name); + + if (create) + return mkdir(path, 0755); + else + return rmdir(path); +} + +static int create_chip(const char *name) +{ + return _create_chip(name, 1); +} + +static void remove_chip(const char *name) +{ + _create_chip(name, 0); +} + +static int _create_bank(const char *chip_name, const char *name, int creat= e) +{ + char path[64]; + + snprintf(path, sizeof(path), CONFIGFS_DIR "/%s/%s", chip_name, name); + + if (create) + return mkdir(path, 0755); + else + return rmdir(path); +} + +static int create_bank(const char *chip_name, const char *name) +{ + return _create_bank(chip_name, name, 1); +} + +static void remove_bank(const char *chip_name, const char *name) +{ + _create_bank(chip_name, name, 0); +} + +static int _enable_chip(const char *name, int enable) +{ + char path[64]; + int fd, ret; + + snprintf(path, sizeof(path), CONFIGFS_DIR "/%s/live", name); + + fd =3D open(path, O_WRONLY); + if (fd =3D=3D -1) + return fd; + + if (enable) + ret =3D write(fd, "1", 1); + else + ret =3D write(fd, "0", 1); + + close(fd); + return ret =3D=3D 1 ? 0 : -1; +} + +static int enable_chip(const char *name) +{ + return _enable_chip(name, 1); +} + +static void disable_chip(const char *name) +{ + _enable_chip(name, 0); +} + +static int open_chip(const char *chip_name, const char *bank_name) +{ + char path[64], dev_name[32]; + int ret, fd; + + ret =3D create_chip(chip_name); + if (ret) { + fprintf(stderr, "failed to create chip\n"); + return ret; + } + + ret =3D create_bank(chip_name, bank_name); + if (ret) { + fprintf(stderr, "failed to create bank\n"); + goto err_remove_chip; + } + + ret =3D enable_chip(chip_name); + if (ret) { + fprintf(stderr, "failed to enable chip\n"); + goto err_remove_bank; + } + + snprintf(path, sizeof(path), CONFIGFS_DIR "/%s/%s/chip_name", + chip_name, bank_name); + + fd =3D open(path, O_RDONLY); + if (fd =3D=3D -1) { + ret =3D fd; + fprintf(stderr, "failed to open %s\n", path); + goto err_disable_chip; + } + + ret =3D read(fd, dev_name, sizeof(dev_name) - 1); + close(fd); + if (ret =3D=3D -1) { + fprintf(stderr, "failed to read %s\n", path); + goto err_disable_chip; + } + dev_name[ret] =3D '\0'; + if (ret && dev_name[ret - 1] =3D=3D '\n') + dev_name[ret - 1] =3D '\0'; + + snprintf(path, sizeof(path), "/dev/%s", dev_name); + + fd =3D open(path, O_RDWR); + if (fd =3D=3D -1) { + ret =3D fd; + fprintf(stderr, "failed to open %s\n", path); + goto err_disable_chip; + } + + return fd; +err_disable_chip: + disable_chip(chip_name); +err_remove_bank: + remove_bank(chip_name, bank_name); +err_remove_chip: + remove_chip(chip_name); + return ret; +} + +static void close_chip(const char *chip_name, const char *bank_name) +{ + disable_chip(chip_name); + remove_bank(chip_name, bank_name); + remove_chip(chip_name); +} + +static int test_poll(int fd) +{ + struct pollfd pfds; + + pfds.fd =3D fd; + pfds.events =3D POLLIN; + pfds.revents =3D 0; + + if (poll(&pfds, 1, 0) =3D=3D -1) + return -1; + + return (pfds.revents & ~(POLLHUP | POLLERR)) ? -1 : 0; +} + +static int test_read(int fd) +{ + char data; + + if (read(fd, &data, 1) =3D=3D -1 && errno =3D=3D ENODEV) + return 0; + return -1; +} + +static int test_ioctl(int fd) +{ + if (ioctl(fd, 0, NULL) =3D=3D -1 && errno =3D=3D ENODEV) + return 0; + return -1; +} + +int main(int argc, char **argv) +{ + int cfd, fd, ret; + int (*test_func)(int); + + if (argc !=3D 3) { + print_usage(); + return EXIT_FAILURE; + } + + if (strcmp(argv[1], "chip") =3D=3D 0 || + strcmp(argv[1], "event") =3D=3D 0 || + strcmp(argv[1], "req") =3D=3D 0) { + if (strcmp(argv[2], "poll") && + strcmp(argv[2], "read") && + strcmp(argv[2], "ioctl")) { + fprintf(stderr, "unknown command: %s\n", argv[2]); + return EXIT_FAILURE; + } + } else if (strcmp(argv[1], "handle") =3D=3D 0) { + if (strcmp(argv[2], "ioctl")) { + fprintf(stderr, "unknown command: %s\n", argv[2]); + return EXIT_FAILURE; + } + } else { + fprintf(stderr, "unknown command: %s\n", argv[1]); + return EXIT_FAILURE; + } + + if (strcmp(argv[2], "poll") =3D=3D 0) + test_func =3D test_poll; + else if (strcmp(argv[2], "read") =3D=3D 0) + test_func =3D test_read; + else /* strcmp(argv[2], "ioctl") =3D=3D 0 */ + test_func =3D test_ioctl; + + cfd =3D open_chip("chip", "bank"); + if (cfd =3D=3D -1) { + fprintf(stderr, "failed to open chip\n"); + return EXIT_FAILURE; + } + + /* Step 1: Hold a FD to the test target. */ + if (strcmp(argv[1], "chip") =3D=3D 0) { + fd =3D cfd; + } else if (strcmp(argv[1], "handle") =3D=3D 0) { + struct gpiohandle_request req =3D {0}; + + req.lines =3D 1; + if (ioctl(cfd, GPIO_GET_LINEHANDLE_IOCTL, &req) =3D=3D -1) { + fprintf(stderr, "failed to get handle FD\n"); + goto err_close_chip; + } + + close(cfd); + fd =3D req.fd; + } else if (strcmp(argv[1], "event") =3D=3D 0) { + struct gpioevent_request req =3D {0}; + + if (ioctl(cfd, GPIO_GET_LINEEVENT_IOCTL, &req) =3D=3D -1) { + fprintf(stderr, "failed to get event FD\n"); + goto err_close_chip; + } + + close(cfd); + fd =3D req.fd; + } else { /* strcmp(argv[1], "req") =3D=3D 0 */ + struct gpio_v2_line_request req =3D {0}; + + req.num_lines =3D 1; + if (ioctl(cfd, GPIO_V2_GET_LINE_IOCTL, &req) =3D=3D -1) { + fprintf(stderr, "failed to get req FD\n"); + goto err_close_chip; + } + + close(cfd); + fd =3D req.fd; + } + + /* Step 2: Free the chip. */ + close_chip("chip", "bank"); + + /* Step 3: Access the dangling FD to trigger UAF. */ + ret =3D test_func(fd); + close(fd); + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +err_close_chip: + close(cfd); + close_chip("chip", "bank"); + return EXIT_FAILURE; +} diff --git a/tools/testing/selftests/gpio/gpio-cdev-uaf.sh b/tools/testing/= selftests/gpio/gpio-cdev-uaf.sh new file mode 100755 index 000000000000..6e47533019cf --- /dev/null +++ b/tools/testing/selftests/gpio/gpio-cdev-uaf.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright 2026 Google LLC + +BASE_DIR=3D`dirname $0` +MODULE=3D"gpio-cdev-uaf" + +fail() { + echo "$*" >&2 + echo "GPIO $MODULE test FAIL" + exit 1 +} + +skip() { + echo "$*" >&2 + echo "GPIO $MODULE test SKIP" + exit 4 +} + +# Load the gpio-sim module. This will pull in configfs if needed too. +modprobe gpio-sim || skip "unable to load the gpio-sim module" +# Make sure configfs is mounted at /sys/kernel/config. Wait a bit if neede= d. +for _ in `seq 5`; do + mountpoint -q /sys/kernel/config && break + mount -t configfs none /sys/kernel/config + sleep 0.1 +done +mountpoint -q /sys/kernel/config || \ + skip "configfs not mounted at /sys/kernel/config" + +echo "1. GPIO" + +echo "1.1. poll" +$BASE_DIR/gpio-cdev-uaf chip poll || fail "failed to test chip poll" +echo "1.2. read" +$BASE_DIR/gpio-cdev-uaf chip read || fail "failed to test chip read" +echo "1.3. ioctl" +$BASE_DIR/gpio-cdev-uaf chip ioctl || fail "failed to test chip ioctl" + +echo "2. linehandle" + +echo "2.1. ioctl" +$BASE_DIR/gpio-cdev-uaf handle ioctl || fail "failed to test handle ioctl" + +echo "3. lineevent" + +echo "3.1. read" +$BASE_DIR/gpio-cdev-uaf event read || fail "failed to test event read" +echo "3.2. poll" +$BASE_DIR/gpio-cdev-uaf event poll || fail "failed to test event poll" +echo "3.3. ioctl" +$BASE_DIR/gpio-cdev-uaf event ioctl || fail "failed to test event ioctl" + +echo "4. linereq" + +echo "4.1. read" +$BASE_DIR/gpio-cdev-uaf req read || fail "failed to test req read" +echo "4.2. poll" +$BASE_DIR/gpio-cdev-uaf req poll || fail "failed to test req poll" +echo "4.3. ioctl" +$BASE_DIR/gpio-cdev-uaf req ioctl || fail "failed to test req ioctl" + +echo "GPIO $MODULE test PASS" --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E0FC36B04D; Tue, 3 Feb 2026 06:12:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099130; cv=none; b=GkFQ5Yz9Iw1zsCL5ykCpwgpxZj4xrf/oYNGi4wDLCdtzVtDQ5Gr1YfEHykOfRKfBzfLKhFx0qYzsh8PrqbHexeXC0SLGWorh3wfyyjNv1eJZHhOTf0FPGqr8D5bxydDuOSEL5qzuUkGUx2fE4scVvJ1Z0sU/5YOk1mAJBAGa61A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099130; c=relaxed/simple; bh=GShNgLrfw5AGXnpJDchEQqstj+ZhEH+iv4NR8Iw7sOk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i1/UCca0C+dMFqFU3uZ5zcWitQlk1N2Pnonb0cZJV7RxpDh5N1X0wiLAkrPHXP1Is3AWojPhQCVb0zrM7H1Z9BpUqfM9e4k5vkgAFh09ysv+T46oX5atA49tqsbmf9U8zXbgipVirdVskHr2E/nfuMz2izshKbdZmjTDdExtfps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iU/6X18K; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iU/6X18K" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5EBA2C19425; Tue, 3 Feb 2026 06:12:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099129; bh=GShNgLrfw5AGXnpJDchEQqstj+ZhEH+iv4NR8Iw7sOk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iU/6X18KmXOgVfT+J0b8LVmdk5ir+wOYclDA55dWi8JyqqFvcoYf8LF4LPzmZhQLZ TeVdSWDRgPR38rgTGEDnrRquyj8IHzsvPHBnvXgonDTmQYNv+DW0VuoDjEqUteie7X 9bPrJs5bVAkBQczBU7N+2ETunZaXAYp0tA6KeuKyYB7Jw2rqAkC6JegPESEwDddpEP DAUqG1iIbmHcyRWGmEf2sVLsEWqNZgdaSmbxu0Vpo6zIlIaj1M3ihYO270/Sig+yL3 FPExWP3PDiWT06ze1RqJwYeuNw0uOvvYx/7dpCpnZiu8IE33zMs8BT03FbKu9jJ3Kr A4jcYllGZw1bQ== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 07/11] gpio: Add revocable provider handle for struct gpio_chip Date: Tue, 3 Feb 2026 06:10:54 +0000 Message-ID: <20260203061059.975605-8-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The underlying chip can be removed asynchronously. `gdev->srcu` is used to ensure the synchronization before accessing `gdev->chip`. Revocable encapsulates the details. Add revocable provider handle for the corresponding struct gpio_chip in struct gpio_device so that it can start to hide the synchronization details. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - Change usages accordingly after applying https://lore.kernel.org/all/20260129143733.45618-2-tzungbi@kernel.org. - Add __rcu for `chip_rp`. - Pass pointer of pointer to revocable_provider_revoke(). - Rebase accordingly after applying https://lore.kernel.org/all/20260203060210.972243-1-tzungbi@kernel.org. v1: https://lore.kernel.org/all/20260116081036.352286-13-tzungbi@kernel.org drivers/gpio/gpiolib.c | 20 ++++++++++++++++++-- drivers/gpio/gpiolib.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7885dcd1e49d..fdae10ec3a17 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1110,6 +1111,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc,= void *data, goto err_put_device; } =20 + gdev->chip_rp =3D revocable_provider_alloc(gc); + if (!gdev->chip_rp) { + ret =3D -ENOMEM; + goto err_put_device; + } + gdev->can_sleep =3D gc->can_sleep; rwlock_init(&gdev->line_state_lock); RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier); @@ -1139,7 +1146,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, if (base < 0) { ret =3D base; base =3D 0; - goto err_put_device; + goto err_free_rp; } =20 /* @@ -1159,7 +1166,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, ret =3D gpiodev_add_to_list_unlocked(gdev); if (ret) { gpiochip_err(gc, "GPIO integer space overlap, cannot add chip\n"); - goto err_put_device; + goto err_free_rp; } } =20 @@ -1256,6 +1263,14 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc,= void *data, scoped_guard(mutex, &gpio_devices_lock) list_del_rcu(&gdev->list); synchronize_srcu(&gpio_devices_srcu); +err_free_rp: + /* + * Unlike other allocated resources for `gdev` can be freed + * in gpiodev_release(). Call revocable_provider_revoke() + * here as it's designed to be called when the chip is gone + * (i.e., gpiochip_remove()). + */ + revocable_provider_revoke(&gdev->chip_rp); err_put_device: gpio_device_put(gdev); goto err_print_message; @@ -1302,6 +1317,7 @@ void gpiochip_remove(struct gpio_chip *gc) /* Numb the device, cancelling all outstanding operations */ rcu_assign_pointer(gdev->chip, NULL); synchronize_srcu(&gdev->srcu); + revocable_provider_revoke(&gdev->chip_rp); gpio_device_teardown_shared(gdev); gpiochip_irqchip_remove(gc); acpi_gpiochip_remove(gc); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 3abb90385829..cd136d5b52e9 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -52,6 +52,7 @@ * @device_notifier: used to notify character device wait queues about the= GPIO * device being unregistered * @srcu: protects the pointer to the underlying GPIO chip + * @chip_rp: revocable provider handle for the corresponding struct gpio_c= hip. * @pin_ranges: range of pins served by the GPIO driver * * This state container holds most of the runtime variable data @@ -79,6 +80,7 @@ struct gpio_device { struct workqueue_struct *line_state_wq; struct blocking_notifier_head device_notifier; struct srcu_struct srcu; + struct revocable_provider __rcu *chip_rp; =20 #ifdef CONFIG_PINCTRL /* --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC70E36C0B4; Tue, 3 Feb 2026 06:12:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099133; cv=none; b=gwVAJK66SnYJCpUbHyiWB1dtsx4AETzWFNXpC68kwoOSZZAY9gQ340F3sbuiZh61mdn4oP8YfWKe9z4iWulbi5zC2igUOKBOQ0Na17v++2M0/+LWtLgCR71YmZx71M9z677w22/icbc6TATur7Gu7LYBcKv8bVqayBgaEyxN3N4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099133; c=relaxed/simple; bh=yQiJynIAbuFeeRMS6x1JyTsW8237/zPmWVWr/0DAPzU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t9mHp3tFuuS5P2AuilrSS/pNGTlg8rngx7b57t5+b38z/cBctKZY/akKHN+8KuNqdiMetYjtDjV1VsZ4O0ecieic64iVvQ0fwspFbVXQzjmXIz8tcxPc9iWiAGPUK4o5KrwgFfpGbz0OaABGlwK8J0gAGp16tz5IHoywAgPNyY4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oNxCY7OD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oNxCY7OD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 19089C116D0; Tue, 3 Feb 2026 06:12:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099132; bh=yQiJynIAbuFeeRMS6x1JyTsW8237/zPmWVWr/0DAPzU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oNxCY7OD/rcNlfOqxqyeEKrKEjgKPwe2bzveNeFWKBcmaxeVr4CsM87UPeZN8IUtW poPT581dLhXD++sPmqr4Ng9yw0rTmb7XKWhYF0T/Qi5Mda12glpmxKX5bWrENR8f5/ 3PdttxuXXSUhQfGoeZiS4+uB+Xg3j1R1agqlsM7O8EFMpfTGqvWKOrDUlwPQhsPQyv 4kPrVDIXukCYhTx0wLs4CKPfkxdgN0Pi68PabF2Lh+y/gTqoD8Fu+xC4MbOf66WuoR 7xj1ZEEsuZPFbFwhqAIX9v49ZXctKdZWRoUhMFTqXxmWgZyocpiOjh0gnzdm4VR7V9 f3g7qJgRnocaA== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 08/11] gpio: cdev: Leverage revocable for accessing struct gpio_chip Date: Tue, 3 Feb 2026 06:10:55 +0000 Message-ID: <20260203061059.975605-9-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Struct gpio_device now provides a revocable provider to the underlying struct gpio_chip. Leverage revocable for accessing the struct gpio_chip. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - Change usages accordingly after applying https://lore.kernel.org/all/20260129143733.45618-4-tzungbi@kernel.org. - Preserve a local storage for `struct revocable`. - Combine multiple patches (see "v1:"). v1: - https://lore.kernel.org/all/20260116081036.352286-14-tzungbi@kernel.org - https://lore.kernel.org/all/20260116081036.352286-15-tzungbi@kernel.org - https://lore.kernel.org/all/20260116081036.352286-16-tzungbi@kernel.org - https://lore.kernel.org/all/20260116081036.352286-17-tzungbi@kernel.org - https://lore.kernel.org/all/20260116081036.352286-18-tzungbi@kernel.org drivers/gpio/gpiolib-cdev.c | 70 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index aaa5de814468..ca9c04765df4 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -210,10 +211,10 @@ static long linehandle_ioctl(struct file *file, unsig= ned int cmd, DECLARE_BITMAP(vals, GPIOHANDLES_MAX); unsigned int i; int ret; + struct gpio_chip *gc; =20 - guard(srcu)(&lh->gdev->srcu); - - if (!rcu_access_pointer(lh->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(lh->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 switch (cmd) { @@ -1432,10 +1433,10 @@ static long linereq_ioctl(struct file *file, unsign= ed int cmd, { struct linereq *lr =3D file->private_data; void __user *ip =3D (void __user *)arg; + struct gpio_chip *gc; =20 - guard(srcu)(&lr->gdev->srcu); - - if (!rcu_access_pointer(lr->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(lr->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 switch (cmd) { @@ -1463,10 +1464,10 @@ static __poll_t linereq_poll(struct file *file, { struct linereq *lr =3D file->private_data; __poll_t events =3D 0; + struct gpio_chip *gc; =20 - guard(srcu)(&lr->gdev->srcu); - - if (!rcu_access_pointer(lr->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(lr->gdev->chip_rp, gc); + if (!gc) return EPOLLHUP | EPOLLERR; =20 poll_wait(file, &lr->wait, wait); @@ -1485,10 +1486,10 @@ static ssize_t linereq_read(struct file *file, char= __user *buf, struct gpio_v2_line_event le; ssize_t bytes_read =3D 0; int ret; + struct gpio_chip *gc; =20 - guard(srcu)(&lr->gdev->srcu); - - if (!rcu_access_pointer(lr->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(lr->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (count < sizeof(le)) @@ -1781,10 +1782,10 @@ static __poll_t lineevent_poll(struct file *file, { struct lineevent_state *le =3D file->private_data; __poll_t events =3D 0; + struct gpio_chip *gc; =20 - guard(srcu)(&le->gdev->srcu); - - if (!rcu_access_pointer(le->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(le->gdev->chip_rp, gc); + if (!gc) return EPOLLHUP | EPOLLERR; =20 poll_wait(file, &le->wait, wait); @@ -1819,10 +1820,10 @@ static ssize_t lineevent_read(struct file *file, ch= ar __user *buf, ssize_t bytes_read =3D 0; ssize_t ge_size; int ret; + struct gpio_chip *gc; =20 - guard(srcu)(&le->gdev->srcu); - - if (!rcu_access_pointer(le->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(le->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 /* @@ -1901,10 +1902,10 @@ static long lineevent_ioctl(struct file *file, unsi= gned int cmd, struct lineevent_state *le =3D file->private_data; void __user *ip =3D (void __user *)arg; struct gpiohandle_data ghd; + struct gpio_chip *gc; =20 - guard(srcu)(&le->gdev->srcu); - - if (!rcu_access_pointer(le->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(le->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 /* @@ -2434,11 +2435,11 @@ static long gpio_ioctl(struct file *file, unsigned = int cmd, unsigned long arg) struct gpio_chardev_data *cdev =3D file->private_data; struct gpio_device *gdev =3D cdev->gdev; void __user *ip =3D (void __user *)arg; - - guard(srcu)(&gdev->srcu); + struct gpio_chip *gc; =20 /* We fail any subsequent ioctl():s when the chip is gone */ - if (!rcu_access_pointer(gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 /* Fill in the struct and pass to userspace */ @@ -2497,12 +2498,9 @@ static void lineinfo_changed_func(struct work_struct= *work) * Pin functions are in general much more static and while it's * not 100% bullet-proof, it's good enough for most cases. */ - scoped_guard(srcu, &ctx->gdev->srcu) { - gc =3D srcu_dereference(ctx->gdev->chip, &ctx->gdev->srcu); - if (gc && - !pinctrl_gpio_can_use_line(gc, ctx->chg.info.offset)) - ctx->chg.info.flags |=3D GPIO_V2_LINE_FLAG_USED; - } + REVOCABLE_TRY_ACCESS_WITH(ctx->gdev->chip_rp, gc); + if (gc && !pinctrl_gpio_can_use_line(gc, ctx->chg.info.offset)) + ctx->chg.info.flags |=3D GPIO_V2_LINE_FLAG_USED; } =20 ret =3D kfifo_in_spinlocked(&ctx->cdev->events, &ctx->chg, 1, @@ -2583,10 +2581,10 @@ static __poll_t lineinfo_watch_poll(struct file *fi= le, { struct gpio_chardev_data *cdev =3D file->private_data; __poll_t events =3D 0; + struct gpio_chip *gc; =20 - guard(srcu)(&cdev->gdev->srcu); - - if (!rcu_access_pointer(cdev->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(cdev->gdev->chip_rp, gc); + if (!gc) return EPOLLHUP | EPOLLERR; =20 poll_wait(file, &cdev->wait, pollt); @@ -2606,10 +2604,10 @@ static ssize_t lineinfo_watch_read(struct file *fil= e, char __user *buf, ssize_t bytes_read =3D 0; int ret; size_t event_size; + struct gpio_chip *gc; =20 - guard(srcu)(&cdev->gdev->srcu); - - if (!rcu_access_pointer(cdev->gdev->chip)) + REVOCABLE_TRY_ACCESS_WITH(cdev->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 #ifndef CONFIG_GPIO_CDEV_V1 --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A554F36BCF9; Tue, 3 Feb 2026 06:12:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099137; cv=none; b=IuXr6iXCjOL32huQsAXZtNftlf2X7kNNMVoqPzmvVmHSpPtel0o129cs+as7/XiMhVZefssxli1Kvnq9fpMyBUEEW/dn8+/fwGRUWRZUoZs6rCJCYStm6Yj8YYb8mALeU6VE3CfuepjKm09oHSphxc6oNzs8G1I0aPaJOFVxrrw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099137; c=relaxed/simple; bh=LNNcXTZQHk/+3fRrFw1I6SBO34jkPzOh+DbCeBtkGNY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bywArK6AQ6Vws53xuujDHTa16i+GAF7VOzzpPthUrh3l8KLrUtA/ETFDDNhTL0O7+ZKinGx3GdfUpEbHJS8ZdjAGcjJTz5DD6F1PE9PApzU2pssD+VJ+3YzAhb3CaVMkbmhN75NoU8cZrQwE+RvfcafUa5kyv8td2DZuO9syV0A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QlKsie3O; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QlKsie3O" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C863CC16AAE; Tue, 3 Feb 2026 06:12:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099135; bh=LNNcXTZQHk/+3fRrFw1I6SBO34jkPzOh+DbCeBtkGNY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QlKsie3OPyYG8dJef+RhNzLu2/rOsBUrORSpGA2mGfQASD6ztgjNwYjMZQLqOiyUu HVQNXa92UIesXJWhFBk/3nhwTNfgPFkYjz9M6DCTYHelKgiZCFybdST+/1fkWY5aFO 2JCpANLEk2vDWNhj/8cHRPOjKoifhTgx4g4zA02rDQo64IbJfyJwPHp9wE0WKJRS+v 2UaGHrhfO6MZa4NxVC/amQrfwyyF3bnvYSL7CvLhRWeSw/sRErv3hv/M6Hn3PYlnWQ 1Lvsno8z6loam7UCYOd10ZknbLblrGY2gnXj3aVrYeHe3RoaigSO7o3CjxL6R5L3j/ bJek11ol57P9A== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 09/11] gpio: Remove gpio_chip_guard by using revocable Date: Tue, 3 Feb 2026 06:10:56 +0000 Message-ID: <20260203061059.975605-10-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Struct gpio_device now provides a revocable provider to the underlying struct gpio_chip. Leverage revocable for accessing the struct gpio_chip instead of using gpio_chip_guard. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - Separate from v1 for including gpio_chip_guard only. v1: https://lore.kernel.org/all/20260116081036.352286-23-tzungbi@kernel.org drivers/gpio/gpiolib-cdev.c | 9 +- drivers/gpio/gpiolib-sysfs.c | 30 ++++--- drivers/gpio/gpiolib.c | 165 ++++++++++++++++++----------------- drivers/gpio/gpiolib.h | 21 ----- 4 files changed, 109 insertions(+), 116 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index ca9c04765df4..270ec6ad639e 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2215,9 +2215,10 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *= desc, u32 debounce_period_us; unsigned long dflags; const char *label; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return; =20 memset(info, 0, sizeof(*info)); @@ -2251,10 +2252,10 @@ static void gpio_desc_to_lineinfo(struct gpio_desc = *desc, test_bit(GPIOD_FLAG_IS_HOGGED, &dflags) || test_bit(GPIOD_FLAG_EXPORT, &dflags) || test_bit(GPIOD_FLAG_SYSFS, &dflags) || - !gpiochip_line_is_valid(guard.gc, info->offset)) { + !gpiochip_line_is_valid(gc, info->offset)) { info->flags |=3D GPIO_V2_LINE_FLAG_USED; } else if (!atomic) { - if (!pinctrl_gpio_can_use_line(guard.gc, info->offset)) + if (!pinctrl_gpio_can_use_line(gc, info->offset)) info->flags |=3D GPIO_V2_LINE_FLAG_USED; } =20 diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index a4427a5cfa85..566fdda2c5d9 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -215,9 +215,10 @@ static int gpio_sysfs_request_irq(struct gpiod_data *d= ata, unsigned char flags) struct gpio_desc *desc =3D data->desc; unsigned long irq_flags; int ret; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 data->irq =3D gpiod_to_irq(desc); @@ -244,7 +245,7 @@ static int gpio_sysfs_request_irq(struct gpiod_data *da= ta, unsigned char flags) * Remove this redundant call (along with the corresponding unlock) * when those drivers have been fixed. */ - ret =3D gpiochip_lock_as_irq(guard.gc, gpiod_hwgpio(desc)); + ret =3D gpiochip_lock_as_irq(gc, gpiod_hwgpio(desc)); if (ret < 0) goto err_clr_bits; =20 @@ -258,7 +259,7 @@ static int gpio_sysfs_request_irq(struct gpiod_data *da= ta, unsigned char flags) return 0; =20 err_unlock: - gpiochip_unlock_as_irq(guard.gc, gpiod_hwgpio(desc)); + gpiochip_unlock_as_irq(gc, gpiod_hwgpio(desc)); err_clr_bits: clear_bit(GPIOD_FLAG_EDGE_RISING, &desc->flags); clear_bit(GPIOD_FLAG_EDGE_FALLING, &desc->flags); @@ -273,14 +274,15 @@ static int gpio_sysfs_request_irq(struct gpiod_data *= data, unsigned char flags) static void gpio_sysfs_free_irq(struct gpiod_data *data) { struct gpio_desc *desc =3D data->desc; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return; =20 data->irq_flags =3D 0; free_irq(data->irq, data); - gpiochip_unlock_as_irq(guard.gc, gpiod_hwgpio(desc)); + gpiochip_unlock_as_irq(gc, gpiod_hwgpio(desc)); clear_bit(GPIOD_FLAG_EDGE_RISING, &desc->flags); clear_bit(GPIOD_FLAG_EDGE_FALLING, &desc->flags); } @@ -473,13 +475,14 @@ static DEVICE_ATTR_RO(ngpio); static int export_gpio_desc(struct gpio_desc *desc) { int offset, ret; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 offset =3D gpiod_hwgpio(desc); - if (!gpiochip_line_is_valid(guard.gc, offset)) { + if (!gpiochip_line_is_valid(gc, offset)) { pr_debug_ratelimited("%s: GPIO %d masked\n", __func__, gpiod_hwgpio(desc)); return -EINVAL; @@ -732,6 +735,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction= _may_change) struct gpio_device *gdev; struct attribute **attrs; int status; + struct gpio_chip *gc; =20 /* can't export until sysfs is available ... */ if (!class_is_registered(&gpio_class)) { @@ -744,8 +748,8 @@ int gpiod_export(struct gpio_desc *desc, bool direction= _may_change) return -EINVAL; } =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (test_and_set_bit(GPIOD_FLAG_EXPORT, &desc->flags)) @@ -769,7 +773,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction= _may_change) =20 desc_data->desc =3D desc; mutex_init(&desc_data->mutex); - if (guard.gc->direction_input && guard.gc->direction_output) + if (gc->direction_input && gc->direction_output) desc_data->direction_can_change =3D direction_may_change; else desc_data->direction_can_change =3D false; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fdae10ec3a17..e62b00191d59 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -449,13 +449,14 @@ int gpiod_get_direction(struct gpio_desc *desc) unsigned long flags; unsigned int offset; int ret; + struct gpio_chip *gc; =20 ret =3D validate_desc(desc, __func__); if (ret <=3D 0) return -EINVAL; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 offset =3D gpiod_hwgpio(desc); @@ -469,7 +470,7 @@ int gpiod_get_direction(struct gpio_desc *desc) test_bit(GPIOD_FLAG_IS_OUT, &flags)) return 0; =20 - ret =3D gpiochip_get_direction(guard.gc, offset); + ret =3D gpiochip_get_direction(gc, offset); if (ret < 0) return ret; =20 @@ -2474,31 +2475,32 @@ int gpiod_request_commit(struct gpio_desc *desc, co= nst char *label) { unsigned int offset; int ret; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (test_and_set_bit(GPIOD_FLAG_REQUESTED, &desc->flags)) return -EBUSY; =20 offset =3D gpiod_hwgpio(desc); - if (!gpiochip_line_is_valid(guard.gc, offset)) + if (!gpiochip_line_is_valid(gc, offset)) return -EINVAL; =20 /* NOTE: gpio_request() can be called in early boot, * before IRQs are enabled, for non-sleeping (SOC) GPIOs. */ =20 - if (guard.gc->request) { - ret =3D guard.gc->request(guard.gc, offset); + if (gc->request) { + ret =3D gc->request(gc, offset); if (ret > 0) ret =3D -EBADE; if (ret) goto out_clear_bit; } =20 - if (guard.gc->get_direction) + if (gc->get_direction) gpiod_get_direction(desc); =20 ret =3D desc_set_label(desc, label ? : "?"); @@ -2535,16 +2537,19 @@ int gpiod_request(struct gpio_desc *desc, const cha= r *label) void gpiod_free_commit(struct gpio_desc *desc) { unsigned long flags; + struct gpio_chip *gc; =20 might_sleep(); =20 - CLASS(gpio_chip_guard, guard)(desc); + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) + return; =20 flags =3D READ_ONCE(desc->flags); =20 - if (guard.gc && test_bit(GPIOD_FLAG_REQUESTED, &flags)) { - if (guard.gc->free) - guard.gc->free(guard.gc, gpiod_hwgpio(desc)); + if (test_bit(GPIOD_FLAG_REQUESTED, &flags)) { + if (gc->free) + gc->free(gc, gpiod_hwgpio(desc)); =20 clear_bit(GPIOD_FLAG_ACTIVE_LOW, &flags); clear_bit(GPIOD_FLAG_REQUESTED, &flags); @@ -2696,15 +2701,16 @@ EXPORT_SYMBOL_GPL(gpiochip_free_own_desc); int gpio_do_set_config(struct gpio_desc *desc, unsigned long config) { int ret; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 - if (!guard.gc->set_config) + if (!gc->set_config) return -ENOTSUPP; =20 - ret =3D guard.gc->set_config(guard.gc, gpiod_hwgpio(desc), config); + ret =3D gc->set_config(gc, gpiod_hwgpio(desc), config); if (ret > 0) ret =3D -EBADE; =20 @@ -2873,9 +2879,10 @@ EXPORT_SYMBOL_GPL(gpiod_direction_input); int gpiod_direction_input_nonotify(struct gpio_desc *desc) { int ret =3D 0, dir; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 /* @@ -2883,7 +2890,7 @@ int gpiod_direction_input_nonotify(struct gpio_desc *= desc) * the chip is output-only, but you can't specify .direction_input() * and not support the .get() operation, that doesn't make sense. */ - if (!guard.gc->get && guard.gc->direction_input) { + if (!gc->get && gc->direction_input) { gpiod_warn(desc, "%s: missing get() but have direction_input()\n", __func__); @@ -2896,11 +2903,10 @@ int gpiod_direction_input_nonotify(struct gpio_desc= *desc) * direction (if .get_direction() is supported) else we silently * assume we are in input mode after this. */ - if (guard.gc->direction_input) { - ret =3D gpiochip_direction_input(guard.gc, - gpiod_hwgpio(desc)); - } else if (guard.gc->get_direction) { - dir =3D gpiochip_get_direction(guard.gc, gpiod_hwgpio(desc)); + if (gc->direction_input) { + ret =3D gpiochip_direction_input(gc, gpiod_hwgpio(desc)); + } else if (gc->get_direction) { + dir =3D gpiochip_get_direction(gc, gpiod_hwgpio(desc)); if (dir < 0) return dir; =20 @@ -2940,9 +2946,10 @@ static int gpiochip_set(struct gpio_chip *gc, unsign= ed int offset, int value) static int gpiod_direction_output_raw_commit(struct gpio_desc *desc, int v= alue) { int val =3D !!value, ret =3D 0, dir; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 /* @@ -2950,21 +2957,19 @@ static int gpiod_direction_output_raw_commit(struct= gpio_desc *desc, int value) * output-only, but if there is then not even a .set() operation it * is pretty tricky to drive the output line. */ - if (!guard.gc->set && !guard.gc->direction_output) { + if (!gc->set && !gc->direction_output) { gpiod_warn(desc, "%s: missing set() and direction_output() operations\n", __func__); return -EIO; } =20 - if (guard.gc->direction_output) { - ret =3D gpiochip_direction_output(guard.gc, - gpiod_hwgpio(desc), val); + if (gc->direction_output) { + ret =3D gpiochip_direction_output(gc, gpiod_hwgpio(desc), val); } else { /* Check that we are in output mode if we can */ - if (guard.gc->get_direction) { - dir =3D gpiochip_get_direction(guard.gc, - gpiod_hwgpio(desc)); + if (gc->get_direction) { + dir =3D gpiochip_get_direction(gc, gpiod_hwgpio(desc)); if (dir < 0) return dir; =20 @@ -2979,7 +2984,7 @@ static int gpiod_direction_output_raw_commit(struct g= pio_desc *desc, int value) * If we can't actively set the direction, we are some * output-only chip, so just drive the output as desired. */ - ret =3D gpiochip_set(guard.gc, gpiod_hwgpio(desc), val); + ret =3D gpiochip_set(gc, gpiod_hwgpio(desc), val); if (ret) return ret; } @@ -3117,20 +3122,20 @@ int gpiod_direction_output_nonotify(struct gpio_des= c *desc, int value) int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long fla= gs) { int ret; + struct gpio_chip *gc; =20 VALIDATE_DESC(desc); =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 - if (!guard.gc->en_hw_timestamp) { + if (!gc->en_hw_timestamp) { gpiod_warn(desc, "%s: hw ts not supported\n", __func__); return -ENOTSUPP; } =20 - ret =3D guard.gc->en_hw_timestamp(guard.gc, - gpiod_hwgpio(desc), flags); + ret =3D gc->en_hw_timestamp(gc, gpiod_hwgpio(desc), flags); if (ret) gpiod_warn(desc, "%s: hw ts request failed\n", __func__); =20 @@ -3150,20 +3155,20 @@ EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns); int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long fl= ags) { int ret; + struct gpio_chip *gc; =20 VALIDATE_DESC(desc); =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 - if (!guard.gc->dis_hw_timestamp) { + if (!gc->dis_hw_timestamp) { gpiod_warn(desc, "%s: hw ts not supported\n", __func__); return -ENOTSUPP; } =20 - ret =3D guard.gc->dis_hw_timestamp(guard.gc, gpiod_hwgpio(desc), - flags); + ret =3D gc->dis_hw_timestamp(gc, gpiod_hwgpio(desc), flags); if (ret) gpiod_warn(desc, "%s: hw ts release failed\n", __func__); =20 @@ -3423,31 +3428,31 @@ int gpiod_get_array_value_complex(bool raw, bool ca= n_sleep, unsigned long *mask, *bits; int first, j; =20 - CLASS(gpio_chip_guard, guard)(desc_array[i]); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc_array[i]->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 - if (likely(guard.gc->ngpio <=3D FASTPATH_NGPIO)) { + if (likely(gc->ngpio <=3D FASTPATH_NGPIO)) { mask =3D fastpath_mask; bits =3D fastpath_bits; } else { gfp_t flags =3D can_sleep ? GFP_KERNEL : GFP_ATOMIC; =20 - mask =3D bitmap_alloc(guard.gc->ngpio, flags); + mask =3D bitmap_alloc(gc->ngpio, flags); if (!mask) return -ENOMEM; =20 - bits =3D bitmap_alloc(guard.gc->ngpio, flags); + bits =3D bitmap_alloc(gc->ngpio, flags); if (!bits) { bitmap_free(mask); return -ENOMEM; } } =20 - bitmap_zero(mask, guard.gc->ngpio); + bitmap_zero(mask, gc->ngpio); =20 if (!can_sleep) - WARN_ON(guard.gc->can_sleep); + WARN_ON(gc->can_sleep); =20 /* collect all inputs belonging to the same chip */ first =3D i; @@ -3462,9 +3467,9 @@ int gpiod_get_array_value_complex(bool raw, bool can_= sleep, i =3D find_next_zero_bit(array_info->get_mask, array_size, i); } while ((i < array_size) && - gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc)); + gpio_device_chip_cmp(desc_array[i]->gdev, gc)); =20 - ret =3D gpio_chip_get_multiple(guard.gc, mask, bits); + ret =3D gpio_chip_get_multiple(gc, mask, bits); if (ret) { if (mask !=3D fastpath_mask) bitmap_free(mask); @@ -3613,15 +3618,16 @@ EXPORT_SYMBOL_GPL(gpiod_get_array_value); static int gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool v= alue) { int ret =3D 0, offset =3D gpiod_hwgpio(desc); + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (value) { - ret =3D gpiochip_direction_input(guard.gc, offset); + ret =3D gpiochip_direction_input(gc, offset); } else { - ret =3D gpiochip_direction_output(guard.gc, offset, 0); + ret =3D gpiochip_direction_output(gc, offset, 0); if (!ret) set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); } @@ -3642,17 +3648,18 @@ static int gpio_set_open_drain_value_commit(struct = gpio_desc *desc, bool value) static int gpio_set_open_source_value_commit(struct gpio_desc *desc, bool = value) { int ret =3D 0, offset =3D gpiod_hwgpio(desc); + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (value) { - ret =3D gpiochip_direction_output(guard.gc, offset, 1); + ret =3D gpiochip_direction_output(gc, offset, 1); if (!ret) set_bit(GPIOD_FLAG_IS_OUT, &desc->flags); } else { - ret =3D gpiochip_direction_input(guard.gc, offset); + ret =3D gpiochip_direction_input(gc, offset); } trace_gpio_direction(desc_to_gpio(desc), !value, ret); if (ret < 0) @@ -3665,15 +3672,17 @@ static int gpio_set_open_source_value_commit(struct= gpio_desc *desc, bool value) =20 static int gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value) { + struct gpio_chip *gc; + if (unlikely(!test_bit(GPIOD_FLAG_IS_OUT, &desc->flags))) return -EPERM; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 trace_gpio_value(desc_to_gpio(desc), 0, value); - return gpiochip_set(guard.gc, gpiod_hwgpio(desc), value); + return gpiochip_set(gc, gpiod_hwgpio(desc), value); } =20 /* @@ -3768,31 +3777,31 @@ int gpiod_set_array_value_complex(bool raw, bool ca= n_sleep, unsigned long *mask, *bits; int count =3D 0; =20 - CLASS(gpio_chip_guard, guard)(desc_array[i]); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc_array[i]->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 - if (likely(guard.gc->ngpio <=3D FASTPATH_NGPIO)) { + if (likely(gc->ngpio <=3D FASTPATH_NGPIO)) { mask =3D fastpath_mask; bits =3D fastpath_bits; } else { gfp_t flags =3D can_sleep ? GFP_KERNEL : GFP_ATOMIC; =20 - mask =3D bitmap_alloc(guard.gc->ngpio, flags); + mask =3D bitmap_alloc(gc->ngpio, flags); if (!mask) return -ENOMEM; =20 - bits =3D bitmap_alloc(guard.gc->ngpio, flags); + bits =3D bitmap_alloc(gc->ngpio, flags); if (!bits) { bitmap_free(mask); return -ENOMEM; } } =20 - bitmap_zero(mask, guard.gc->ngpio); + bitmap_zero(mask, gc->ngpio); =20 if (!can_sleep) - WARN_ON(guard.gc->can_sleep); + WARN_ON(gc->can_sleep); =20 do { struct gpio_desc *desc =3D desc_array[i]; @@ -3831,10 +3840,10 @@ int gpiod_set_array_value_complex(bool raw, bool ca= n_sleep, i =3D find_next_zero_bit(array_info->set_mask, array_size, i); } while ((i < array_size) && - gpio_device_chip_cmp(desc_array[i]->gdev, guard.gc)); + gpio_device_chip_cmp(desc_array[i]->gdev, gc)); /* push collected bits to outputs */ if (count !=3D 0) { - ret =3D gpiochip_set_multiple(guard.gc, mask, bits); + ret =3D gpiochip_set_multiple(gc, mask, bits); if (ret) return ret; } @@ -5050,9 +5059,10 @@ int gpiod_hog(struct gpio_desc *desc, const char *na= me, struct gpio_desc *local_desc; int hwnum; int ret; + struct gpio_chip *gc; =20 - CLASS(gpio_chip_guard, guard)(desc); - if (!guard.gc) + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); + if (!gc) return -ENODEV; =20 if (test_and_set_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags)) @@ -5060,8 +5070,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *nam= e, =20 hwnum =3D gpiod_hwgpio(desc); =20 - local_desc =3D gpiochip_request_own_desc(guard.gc, hwnum, name, - lflags, dflags); + local_desc =3D gpiochip_request_own_desc(gc, hwnum, name, lflags, dflags); if (IS_ERR(local_desc)) { clear_bit(GPIOD_FLAG_IS_HOGGED, &desc->flags); ret =3D PTR_ERR(local_desc); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index cd136d5b52e9..ce6273cc74f2 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -224,27 +224,6 @@ struct gpio_desc { =20 #define gpiod_not_found(desc) (IS_ERR(desc) && PTR_ERR(desc) =3D=3D -ENOE= NT) =20 -struct gpio_chip_guard { - struct gpio_device *gdev; - struct gpio_chip *gc; - int idx; -}; - -DEFINE_CLASS(gpio_chip_guard, - struct gpio_chip_guard, - srcu_read_unlock(&_T.gdev->srcu, _T.idx), - ({ - struct gpio_chip_guard _guard; - - _guard.gdev =3D desc->gdev; - _guard.idx =3D srcu_read_lock(&_guard.gdev->srcu); - _guard.gc =3D srcu_dereference(_guard.gdev->chip, - &_guard.gdev->srcu); - - _guard; - }), - struct gpio_desc *desc) - int gpiod_request(struct gpio_desc *desc, const char *label); int gpiod_request_commit(struct gpio_desc *desc, const char *label); void gpiod_free(struct gpio_desc *desc); --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E62E36D4EB; Tue, 3 Feb 2026 06:12:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099138; cv=none; b=efqP0aBCDG3F017JOGe19NdGJsfZHfz9IMmmXpjXwa+7qlDTDH83U3QdLHpvsZ33LzzNw0IqKqBCqjcJu+aO1ZaE2pbURarGZIOE0e7oAEZse7kXrVrJSIPcdxX4L5+3TUI5fB9Ac+LomtGD/iPDe+HhOvOtDHmLMg+6K6gmMXk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099138; c=relaxed/simple; bh=j5Gnn7+c1X37ns/z5KIpWlTK7fXC/RscFmd1ERfs39k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rPN4EoXtK+izRcItvSlk/AmllQDdv7lhuaVd6UR0BCR9142NgygnKSu4UVGEmjOBjCpPLdMt4uJXLuLNoQkHOPyblNSLPVdH0SKpcCRn/RESCfFkPGfy9x4kstAYpXIJJgOBeJP4I1pJTuLwbvH8wIlT4MhOUKnNnqLoiYvry2s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sPqWCkra; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sPqWCkra" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB094C19425; Tue, 3 Feb 2026 06:12:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099138; bh=j5Gnn7+c1X37ns/z5KIpWlTK7fXC/RscFmd1ERfs39k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sPqWCkrapoxbenRDSg4g+fy0bZBBYESjoEJYMxUv7+RCvN5mpy3JCEJvXC+yc7FPg lk41fZhQ+Cd4Y/dxBZ5uEZjIw+bobBRiiwIIimdSZS/eTTtNLh4vWS5LKG2EnjL2Ov pQDCZ57zweLXHXX+sIlQxROsiJGOZTTUY4BpbYFabySLfx/D/lTH/txXf2tQ/KLyui yc47thwTv9Lq9ZnyMm2Lce1qoAyr9cAsX9+haBZDKvgOVIFfCHEKnMNo7ReYsGMsdm jA1o91XeeEVI/UFZQkHrX+vp9fPxiQ+/aADGUV+dli6zfmgAE4wMiuQNEUzAPpg9sn MTjsGrdW7/9wA== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 10/11] gpio: Leverage revocable for accessing struct gpio_chip Date: Tue, 3 Feb 2026 06:10:57 +0000 Message-ID: <20260203061059.975605-11-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Struct gpio_device now provides a revocable provider to the underlying struct gpio_chip. Leverage revocable for accessing the struct gpio_chip. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - Separate from v1(a) for excluding gpio_chip_guard and combine v1(b). v1(a): - https://lore.kernel.org/all/20260116081036.352286-23-tzungbi@kernel.org v1(b): - https://lore.kernel.org/all/20260116081036.352286-19-tzungbi@kernel.org drivers/gpio/gpiolib.c | 52 +++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e62b00191d59..347ff456858f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -338,7 +338,10 @@ EXPORT_SYMBOL(gpio_device_get_label); */ struct gpio_chip *gpio_device_get_chip(struct gpio_device *gdev) { - return rcu_dereference_check(gdev->chip, 1); + struct gpio_chip *gc; + + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); + return gc; } EXPORT_SYMBOL_GPL(gpio_device_get_chip); =20 @@ -558,9 +561,7 @@ static struct gpio_desc *gpio_name_to_desc(const char *= const name) =20 list_for_each_entry_srcu(gdev, &gpio_devices, list, srcu_read_lock_held(&gpio_devices_srcu)) { - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); if (!gc) continue; =20 @@ -972,9 +973,7 @@ static void gpiochip_setup_devs(void) =20 list_for_each_entry_srcu(gdev, &gpio_devices, list, srcu_read_lock_held(&gpio_devices_srcu)) { - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); if (!gc) { dev_err(&gdev->dev, "Underlying GPIO chip is gone\n"); continue; @@ -1379,11 +1378,11 @@ struct gpio_device *gpio_device_find(const void *da= ta, if (!device_is_registered(&gdev->dev)) continue; =20 - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); + if (!gc) + continue; =20 - if (gc && match(gc, data)) + if (match(gc, data)) return gpio_device_get(gdev); } =20 @@ -3325,16 +3324,10 @@ static int gpio_chip_get_value(struct gpio_chip *gc= , const struct gpio_desc *des =20 static int gpiod_get_raw_value_commit(const struct gpio_desc *desc) { - struct gpio_device *gdev; struct gpio_chip *gc; int value; =20 - /* FIXME Unable to use gpio_chip_guard due to const desc. */ - gdev =3D desc->gdev; - - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); if (!gc) return -ENODEV; =20 @@ -3375,9 +3368,10 @@ static int gpio_chip_get_multiple(struct gpio_chip *= gc, /* The 'other' chip must be protected with its GPIO device's SRCU. */ static bool gpio_device_chip_cmp(struct gpio_device *gdev, struct gpio_chi= p *gc) { - guard(srcu)(&gdev->srcu); + struct gpio_chip *chip; =20 - return gc =3D=3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, chip); + return chip ? chip =3D=3D gc : false; } =20 int gpiod_get_array_value_complex(bool raw, bool can_sleep, @@ -3400,9 +3394,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_= sleep, if (!can_sleep) WARN_ON(array_info->gdev->can_sleep); =20 - guard(srcu)(&array_info->gdev->srcu); - gc =3D srcu_dereference(array_info->gdev->chip, - &array_info->gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(array_info->gdev->chip_rp, gc); if (!gc) return -ENODEV; =20 @@ -3749,9 +3741,7 @@ int gpiod_set_array_value_complex(bool raw, bool can_= sleep, return -EPERM; } =20 - guard(srcu)(&array_info->gdev->srcu); - gc =3D srcu_dereference(array_info->gdev->chip, - &array_info->gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(array_info->gdev->chip_rp, gc); if (!gc) return -ENODEV; =20 @@ -4049,7 +4039,6 @@ EXPORT_SYMBOL_GPL(gpiod_is_shared); */ int gpiod_to_irq(const struct gpio_desc *desc) { - struct gpio_device *gdev; struct gpio_chip *gc; int offset; int ret; @@ -4058,10 +4047,7 @@ int gpiod_to_irq(const struct gpio_desc *desc) if (ret <=3D 0) return -EINVAL; =20 - gdev =3D desc->gdev; - /* FIXME Cannot use gpio_chip_guard due to const desc. */ - guard(srcu)(&gdev->srcu); - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(desc->gdev->chip_rp, gc); if (!gc) return -ENODEV; =20 @@ -5440,9 +5426,7 @@ static int gpiolib_seq_show(struct seq_file *s, void = *v) if (priv->newline) seq_putc(s, '\n'); =20 - guard(srcu)(&gdev->srcu); - - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); + REVOCABLE_TRY_ACCESS_WITH(gdev->chip_rp, gc); if (!gc) { seq_printf(s, "%s: (dangling chip)\n", dev_name(&gdev->dev)); return 0; --=20 2.53.0.rc2.204.g2597b5adb4-goog From nobody Sat Feb 7 17:20:14 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FE5636BCEB; Tue, 3 Feb 2026 06:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099141; cv=none; b=KATSqR3XyUZErm1UAQpUZC+Kn21uVvU6QmFUBCh5QoWzZjvQ/x5ebDmXAka0UNVBfkIE7mWSYsM3DTKL+POLE42nFIkS1BQsRrBn9QUhQ3//WArT5rqMXo5ni2Tgb97EHPL0Niev6XmqB72HMs0Zhj8rumwJZEwvZJNn8TJrwpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770099141; c=relaxed/simple; bh=ldihWY52VOZDRWgJtWxRIOsufAG6wBHd6sUeYExdgBs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=etNfeBJ2DF5NiI4X0cWmA6TSQw6mo2z66P/AhZCInAqDOmFYzoLZWAaPygHvnv6fvPKdG/+tIz/4nveqGVeqX7EVuWgsU6/mLnpgMRL3b2nzcz457X4DKN+10n087qZlctY7pA/l+UAEog2YDAQykN/Ve8e/9G1rF3xfsR7+TKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mJaGHU3j; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mJaGHU3j" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6678BC2BC86; Tue, 3 Feb 2026 06:12:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770099140; bh=ldihWY52VOZDRWgJtWxRIOsufAG6wBHd6sUeYExdgBs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mJaGHU3jljibqPDab6tqYZlsKfG93kZu5gLYchcbaMnxi3EKmS9UeFjbj6PyRQV6g 1XZkfhQiY/N7nNlFOnoin4EuJNz42ZCXn8UL/ImGiGbpeNhLOUcgSHD3Ly/aoFb4v1 RL5Owm1F60a6syEOCzm/j3T2ixOoNgy+CJoxpyWbVEunRsJSVUBPRBPGUyQb5bgP3w iwwLOoSoGxUfUS1ln6et1hW9alBSe2AtUxKmEiC70JmhZx2RZ4RWSWpNG1yHXFJeLg G0iweisPLWg+a2nVB2FftXjIZNpdeOXjFcxlVN5hZobq4VRX/WKBw9u6m9TEsG1C/e 1KEURwkzu4WYw== From: Tzung-Bi Shih To: Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , Laurent Pinchart , Wolfram Sang , Jason Gunthorpe , Johan Hovold , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, chrome-platform@lists.linux.dev, tzungbi@kernel.org, Dan Williams , linux-gpio@vger.kernel.org Subject: [PATCH v2 11/11] gpio: Remove unused `chip` and `srcu` in struct gpio_device Date: Tue, 3 Feb 2026 06:10:58 +0000 Message-ID: <20260203061059.975605-12-tzungbi@kernel.org> X-Mailer: git-send-email 2.53.0.rc2.204.g2597b5adb4-goog In-Reply-To: <20260203061059.975605-1-tzungbi@kernel.org> References: <20260203061059.975605-1-tzungbi@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" `chip` and `srcu` in struct gpio_device are unused as their usages are replaced to use revocable. Remove them. Signed-off-by: Tzung-Bi Shih Tested-by: Bartosz Golaszewski --- v2: - No changes. v1: https://lore.kernel.org/all/20260116081036.352286-24-tzungbi@kernel.org drivers/gpio/gpiolib.c | 26 +------------------------- drivers/gpio/gpiolib.h | 4 ---- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 347ff456858f..bcc7834b2362 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -423,8 +423,6 @@ static int gpiochip_get_direction(struct gpio_chip *gc,= unsigned int offset) { int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(!gc->get_direction)) return -EOPNOTSUPP; =20 @@ -875,7 +873,6 @@ static void gpiodev_release(struct device *dev) ida_free(&gpio_ida, gdev->id); kfree_const(gdev->label); kfree(gdev->descs); - cleanup_srcu_struct(&gdev->srcu); kfree(gdev); } =20 @@ -1076,14 +1073,9 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc,= void *data, goto err_free_gdev; gdev->id =3D ret; =20 - ret =3D init_srcu_struct(&gdev->srcu); - if (ret) - goto err_free_ida; - rcu_assign_pointer(gdev->chip, gc); - ret =3D init_srcu_struct(&gdev->desc_srcu); if (ret) - goto err_cleanup_gdev_srcu; + goto err_free_ida; =20 ret =3D dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id); if (ret) @@ -1277,8 +1269,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, = void *data, =20 err_cleanup_desc_srcu: cleanup_srcu_struct(&gdev->desc_srcu); -err_cleanup_gdev_srcu: - cleanup_srcu_struct(&gdev->srcu); err_free_ida: ida_free(&gpio_ida, gdev->id); err_free_gdev: @@ -1315,8 +1305,6 @@ void gpiochip_remove(struct gpio_chip *gc) synchronize_srcu(&gpio_devices_srcu); =20 /* Numb the device, cancelling all outstanding operations */ - rcu_assign_pointer(gdev->chip, NULL); - synchronize_srcu(&gdev->srcu); revocable_provider_revoke(&gdev->chip_rp); gpio_device_teardown_shared(gdev); gpiochip_irqchip_remove(gc); @@ -2822,8 +2810,6 @@ static int gpiochip_direction_input(struct gpio_chip = *gc, unsigned int offset) { int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(!gc->direction_input)) return -EOPNOTSUPP; =20 @@ -2839,8 +2825,6 @@ static int gpiochip_direction_output(struct gpio_chip= *gc, unsigned int offset, { int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(!gc->direction_output)) return -EOPNOTSUPP; =20 @@ -2930,8 +2914,6 @@ static int gpiochip_set(struct gpio_chip *gc, unsigne= d int offset, int value) { int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(unlikely(!gc->set))) return -EOPNOTSUPP; =20 @@ -3285,8 +3267,6 @@ static int gpiochip_get(struct gpio_chip *gc, unsigne= d int offset) { int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - /* Make sure this is called after checking for gc->get(). */ ret =3D gc->get(gc, offset); if (ret > 1) @@ -3340,8 +3320,6 @@ static int gpiod_get_raw_value_commit(const struct gp= io_desc *desc) static int gpio_chip_get_multiple(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits) { - lockdep_assert_held(&gc->gpiodev->srcu); - if (gc->get_multiple) { int ret; =20 @@ -3695,8 +3673,6 @@ static int gpiochip_set_multiple(struct gpio_chip *gc, unsigned int i; int ret; =20 - lockdep_assert_held(&gc->gpiodev->srcu); - if (gc->set_multiple) { ret =3D gc->set_multiple(gc, mask, bits); if (ret > 0) diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index ce6273cc74f2..2179074d2362 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -28,7 +28,6 @@ * @chrdev: character device for the GPIO device * @id: numerical ID number for the GPIO chip * @owner: helps prevent removal of modules exporting active GPIOs - * @chip: pointer to the corresponding gpiochip, holding static * data for this device * @descs: array of ngpio descriptors. * @valid_mask: If not %NULL, holds bitmask of GPIOs which are valid to be @@ -51,7 +50,6 @@ * process context * @device_notifier: used to notify character device wait queues about the= GPIO * device being unregistered - * @srcu: protects the pointer to the underlying GPIO chip * @chip_rp: revocable provider handle for the corresponding struct gpio_c= hip. * @pin_ranges: range of pins served by the GPIO driver * @@ -65,7 +63,6 @@ struct gpio_device { struct cdev chrdev; int id; struct module *owner; - struct gpio_chip __rcu *chip; struct gpio_desc *descs; unsigned long *valid_mask; struct srcu_struct desc_srcu; @@ -79,7 +76,6 @@ struct gpio_device { rwlock_t line_state_lock; struct workqueue_struct *line_state_wq; struct blocking_notifier_head device_notifier; - struct srcu_struct srcu; struct revocable_provider __rcu *chip_rp; =20 #ifdef CONFIG_PINCTRL --=20 2.53.0.rc2.204.g2597b5adb4-goog