mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
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: Tzung-Bi Shih <tzungbi@kernel.org> Link: https://patch.msgid.link/20260223061726.82161-5-tzungbi@kernel.org Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
This commit is contained in:
parent
395b8e555d
commit
cf674f1a0c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user