Commit cf674f1a authored by Tzung-Bi Shih's avatar Tzung-Bi Shih Committed by Bartosz Golaszewski
Browse files

gpio: Ensure struct gpio_chip for gpiochip_setup_dev()



Ensure struct gpio_chip for gpiochip_setup_dev().  This eliminates a few
checks for struct gpio_chip.

Signed-off-by: default avatarTzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260223061726.82161-5-tzungbi@kernel.org


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
parent 395b8e55
Loading
Loading
Loading
Loading
+4 −10
Original line number Diff line number Diff line
@@ -2733,11 +2733,13 @@ static const struct file_operations gpio_fileops = {
#endif
};

int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
int gpiolib_cdev_register(struct gpio_chip *gc, dev_t devt)
{
	struct gpio_chip *gc;
	struct gpio_device *gdev = gc->gpiodev;
	int ret;

	lockdep_assert_held(&gdev->srcu);

	cdev_init(&gdev->chrdev, &gpio_fileops);
	gdev->chrdev.owner = THIS_MODULE;
	gdev->dev.devt = MKDEV(MAJOR(devt), gdev->id);
@@ -2753,14 +2755,6 @@ int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt)
		return ret;
	}

	guard(srcu)(&gdev->srcu);
	gc = 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);

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@

struct gpio_device;

int gpiolib_cdev_register(struct gpio_device *gdev, dev_t devt);
int gpiolib_cdev_register(struct gpio_chip *gc, dev_t devt);
void gpiolib_cdev_unregister(struct gpio_device *gdev);

#endif /* GPIOLIB_CDEV_H */
+8 −13
Original line number Diff line number Diff line
@@ -983,13 +983,15 @@ void gpiod_unexport(struct gpio_desc *desc)
}
EXPORT_SYMBOL_GPL(gpiod_unexport);

int gpiochip_sysfs_register(struct gpio_device *gdev)
int gpiochip_sysfs_register(struct gpio_chip *gc)
{
	struct gpio_device *gdev = gc->gpiodev;
	struct gpiodev_data *data;
	struct gpio_chip *chip;
	struct device *parent;
	int err;

	lockdep_assert_held(&gdev->srcu);

	/*
	 * Many systems add gpio chips for SOC support very early,
	 * before driver model support is available.  In those cases we
@@ -999,18 +1001,12 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
	if (!class_is_registered(&gpio_class))
		return 0;

	guard(srcu)(&gdev->srcu);

	chip = 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.
	 */
	if (chip->parent)
		parent = chip->parent;
	if (gc->parent)
		parent = gc->parent;
	else
		parent = &gdev->dev;

@@ -1029,7 +1025,7 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
						    MKDEV(0, 0), data,
						    gpiochip_groups,
						    GPIOCHIP_NAME "%d",
						    chip->base);
						    gc->base);
	if (IS_ERR(data->cdev_base)) {
		err = PTR_ERR(data->cdev_base);
		kfree(data);
@@ -1085,10 +1081,9 @@ void gpiochip_sysfs_unregister(struct gpio_chip *gc)
 */
static int gpiofind_sysfs_register(struct gpio_chip *gc, const void *data)
{
	struct gpio_device *gdev = gc->gpiodev;
	int ret;

	ret = gpiochip_sysfs_register(gdev);
	ret = gpiochip_sysfs_register(gc);
	if (ret)
		gpiochip_err(gc, "failed to register the sysfs entry: %d\n", ret);

+2 −2
Original line number Diff line number Diff line
@@ -7,12 +7,12 @@ struct gpio_device;

#ifdef CONFIG_GPIO_SYSFS

int gpiochip_sysfs_register(struct gpio_device *gdev);
int gpiochip_sysfs_register(struct gpio_chip *gc);
void gpiochip_sysfs_unregister(struct gpio_chip *gc);

#else

static inline int gpiochip_sysfs_register(struct gpio_device *gdev)
static inline int gpiochip_sysfs_register(struct gpio_chip *gc)
{
	return 0;
}
+17 −7
Original line number Diff line number Diff line
@@ -882,14 +882,14 @@ static const struct device_type gpio_dev_type = {
};

#ifdef CONFIG_GPIO_CDEV
#define gcdev_register(gdev, devt)	gpiolib_cdev_register((gdev), (devt))
#define gcdev_register(gc, devt)	gpiolib_cdev_register((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(gc, devt)	device_add(&(gc)->gpiodev->dev)
#define gcdev_unregister(gdev)		device_del(&(gdev)->dev)
#endif

@@ -897,8 +897,9 @@ static const struct device_type gpio_dev_type = {
 * 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_chip *gc)
{
	struct gpio_device *gdev = gc->gpiodev;
	struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
	int ret;

@@ -911,11 +912,11 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
	if (fwnode && !fwnode->dev)
		fwnode_dev_initialized(fwnode, false);

	ret = gcdev_register(gdev, gpio_devt);
	ret = gcdev_register(gc, gpio_devt);
	if (ret)
		return ret;

	ret = gpiochip_sysfs_register(gdev);
	ret = gpiochip_sysfs_register(gc);
	if (ret)
		goto err_remove_device;

@@ -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;

	guard(srcu)(&gpio_devices_srcu);

	list_for_each_entry_srcu(gdev, &gpio_devices, list,
				 srcu_read_lock_held(&gpio_devices_srcu)) {
		ret = gpiochip_setup_dev(gdev);
		guard(srcu)(&gdev->srcu);

		gc = srcu_dereference(gdev->chip, &gdev->srcu);
		if (!gc) {
			dev_err(&gdev->dev, "Underlying GPIO chip is gone\n");
			continue;
		}

		ret = gpiochip_setup_dev(gc);
		if (ret) {
			gpio_device_put(gdev);
			dev_err(&gdev->dev,
@@ -1226,7 +1236,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 = gpiochip_setup_dev(gdev);
		ret = gpiochip_setup_dev(gc);
		if (ret)
			goto err_teardown_shared;
	}