From nobody Mon Feb 9 14:31:32 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 3767E2F1FED; Fri, 16 Jan 2026 08:11:34 +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=1768551099; cv=none; b=lZgPqet0ahQFd+ch1sADqJvD+MDA1LGtcwEdFM5JWw3ALMcmiPCvT+7OqpTkHSKdF7qtwfue+2HnPbAcH/Gy/k5SscGgqIBm75ffmMzKvkBPQm/eTGKm1Wl79XvzJaNSQQz8I7lK4yg62p9UG0RwpHQLIXw9XuOxAOZkay4koKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768551099; c=relaxed/simple; bh=jLMk5jOJOkev2PV84zit/QMXNzAOhBT5t5NGWW6kN1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VwDinA8fFQnmvGyb6ro9Xing1Hzkj5DQzKfRKXDcIyXAUgWoZ1MOSzjQl2Wmaxc+72aPz/SG5rXngXZ3IkXzappSc6f7trkMvxeA2tzu91zxihWhUWuUCiWl01LYxUBZ4UfpxpBWeJ2fBec02ftEizYc1uZ/5cwZNlqSIz6ULSA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VwSeG9KG; 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="VwSeG9KG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 32B07C19424; Fri, 16 Jan 2026 08:11:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1768551094; bh=jLMk5jOJOkev2PV84zit/QMXNzAOhBT5t5NGWW6kN1w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VwSeG9KGz+NSfpCSbFrHx8huxGYLoqGEUfZTatUs+S5y0CYu1/qqCZaynn4ONvoO5 TiizBFloJolOsH4gMyn3KovNqIo6umaVIcCgMoeP9VXLgqqf/jmdHG4v5e6Hj1ufik L9mSZxN6KjIDaNfBClBbLAJ5+1IyCfqumyDhCJVzfS3ypaiUqytzYik9VONSwhPxaw X4buW/2SgahdGC7T4JRjKg36K7VZtRXGoiJ7ozmKr2eQq1yCtj/jSU4KdNm+4S09jf Z4NbjXMRkTeuYYkQrVt1FIeUjHvG4HczhU+14ONaRagdDSuBoojyxQtv4daoxx189H LUCs9VFNOPZ5A== From: Tzung-Bi Shih To: Benson Leung , Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Bartosz Golaszewski , Linus Walleij Cc: Jonathan Corbet , Shuah Khan , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, chrome-platform@lists.linux.dev, linux-kselftest@vger.kernel.org, tzungbi@kernel.org, Laurent Pinchart , Wolfram Sang , Simona Vetter , Dan Williams , Jason Gunthorpe , linux-gpio@vger.kernel.org Subject: [PATCH 09/23] gpiolib: Ensure struct gpio_chip for gpiochip_setup_dev() Date: Fri, 16 Jan 2026 08:10:22 +0000 Message-ID: <20260116081036.352286-10-tzungbi@kernel.org> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog In-Reply-To: <20260116081036.352286-1-tzungbi@kernel.org> References: <20260116081036.352286-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 --- drivers/gpio/gpiolib-cdev.c | 13 ++----------- 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(+), 30 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 66bd260c68e9..24449bbe38c9 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -2784,9 +2784,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,18 +2802,9 @@ int gpiolib_cdev_register(struct gpio_device *gdev, = dev_t devt) if (ret) goto err_free_workqueue; =20 - guard(srcu)(&gdev->srcu); - gc =3D srcu_dereference(gdev->chip, &gdev->srcu); - if (!gc) { - ret =3D -ENODEV; - goto err_free_cdev; - } - gpiochip_dbg(gc, "added GPIO chardev (%d:%d)\n", MAJOR(devt), gdev->id); =20 return 0; -err_free_cdev: - cdev_device_del(&gdev->chrdev, &gdev->dev); err_free_workqueue: destroy_workqueue(gdev->line_state_wq); return ret; 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 c3e1465042c4..efe72b81e131 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, @@ -1222,7 +1232,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.52.0.457.g6b5491de43-goog