]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpio: sim: convert to use dev-sync-probe utilities
authorKoichiro Den <koichiro.den@canonical.com>
Fri, 21 Feb 2025 13:35:00 +0000 (22:35 +0900)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Mon, 24 Feb 2025 13:57:40 +0000 (14:57 +0100)
Update gpio-sim to use the new dev-sync-probe helper functions for
synchronized platform device creation, reducing code duplication.

No functional change.

Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250221133501.2203897-3-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/Kconfig
drivers/gpio/gpio-sim.c

index d6ac1a01c636c8bdbd35bf4cbda313aee0a485f7..5b167c4134226a652e96590088ed06c47630ee6b 100644 (file)
@@ -1910,6 +1910,7 @@ config GPIO_SIM
        tristate "GPIO Simulator Module"
        select IRQ_SIM
        select CONFIGFS_FS
+       select DEV_SYNC_PROBE
        help
          This enables the GPIO simulator - a configfs-based GPIO testing
          driver.
index b6c230fab8404d9ecc62eebdc0bcae8c4e648c25..758933fbd85b18168ebfc9158c0f883bb3d3a4d0 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/array_size.h>
 #include <linux/bitmap.h>
 #include <linux/cleanup.h>
-#include <linux/completion.h>
 #include <linux/configfs.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -37,6 +36,8 @@
 #include <linux/sysfs.h>
 #include <linux/types.h>
 
+#include "dev-sync-probe.h"
+
 #define GPIO_SIM_NGPIO_MAX     1024
 #define GPIO_SIM_PROP_MAX      4 /* Max 3 properties + sentinel. */
 #define GPIO_SIM_NUM_ATTRS     3 /* value, pull and sentinel */
@@ -541,14 +542,9 @@ static struct platform_driver gpio_sim_driver = {
 };
 
 struct gpio_sim_device {
+       struct dev_sync_probe_data probe_data;
        struct config_group group;
 
-       /*
-        * If pdev is NULL, the device is 'pending' (waiting for configuration).
-        * Once the pointer is assigned, the device has been created and the
-        * item is 'live'.
-        */
-       struct platform_device *pdev;
        int id;
 
        /*
@@ -562,46 +558,11 @@ struct gpio_sim_device {
         */
        struct mutex lock;
 
-       /*
-        * This is used to synchronously wait for the driver's probe to complete
-        * and notify the user-space about any errors.
-        */
-       struct notifier_block bus_notifier;
-       struct completion probe_completion;
-       bool driver_bound;
-
        struct gpiod_hog *hogs;
 
        struct list_head bank_list;
 };
 
-/* This is called with dev->lock already taken. */
-static int gpio_sim_bus_notifier_call(struct notifier_block *nb,
-                                     unsigned long action, void *data)
-{
-       struct gpio_sim_device *simdev = container_of(nb,
-                                                     struct gpio_sim_device,
-                                                     bus_notifier);
-       struct device *dev = data;
-       char devname[32];
-
-       snprintf(devname, sizeof(devname), "gpio-sim.%u", simdev->id);
-
-       if (!device_match_name(dev, devname))
-               return NOTIFY_DONE;
-
-       if (action == BUS_NOTIFY_BOUND_DRIVER)
-               simdev->driver_bound = true;
-       else if (action == BUS_NOTIFY_DRIVER_NOT_BOUND)
-               simdev->driver_bound = false;
-       else
-               return NOTIFY_DONE;
-
-       complete(&simdev->probe_completion);
-
-       return NOTIFY_OK;
-}
-
 static struct gpio_sim_device *to_gpio_sim_device(struct config_item *item)
 {
        struct config_group *group = to_config_group(item);
@@ -708,7 +669,7 @@ static bool gpio_sim_device_is_live(struct gpio_sim_device *dev)
 {
        lockdep_assert_held(&dev->lock);
 
-       return !!dev->pdev;
+       return !!dev->probe_data.pdev;
 }
 
 static char *gpio_sim_strdup_trimmed(const char *str, size_t count)
@@ -730,7 +691,7 @@ static ssize_t gpio_sim_device_config_dev_name_show(struct config_item *item,
 
        guard(mutex)(&dev->lock);
 
-       pdev = dev->pdev;
+       pdev = dev->probe_data.pdev;
        if (pdev)
                return sprintf(page, "%s\n", dev_name(&pdev->dev));
 
@@ -939,7 +900,6 @@ static int gpio_sim_device_activate(struct gpio_sim_device *dev)
 {
        struct platform_device_info pdevinfo;
        struct fwnode_handle *swnode;
-       struct platform_device *pdev;
        struct gpio_sim_bank *bank;
        int ret;
 
@@ -981,31 +941,13 @@ static int gpio_sim_device_activate(struct gpio_sim_device *dev)
        pdevinfo.fwnode = swnode;
        pdevinfo.id = dev->id;
 
-       reinit_completion(&dev->probe_completion);
-       dev->driver_bound = false;
-       bus_register_notifier(&platform_bus_type, &dev->bus_notifier);
-
-       pdev = platform_device_register_full(&pdevinfo);
-       if (IS_ERR(pdev)) {
-               bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier);
-               gpio_sim_remove_hogs(dev);
-               gpio_sim_remove_swnode_recursive(swnode);
-               return PTR_ERR(pdev);
-       }
-
-       wait_for_completion(&dev->probe_completion);
-       bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier);
-
-       if (!dev->driver_bound) {
-               /* Probe failed, check kernel log. */
-               platform_device_unregister(pdev);
+       ret = dev_sync_probe_register(&dev->probe_data, &pdevinfo);
+       if (ret) {
                gpio_sim_remove_hogs(dev);
                gpio_sim_remove_swnode_recursive(swnode);
-               return -ENXIO;
+               return ret;
        }
 
-       dev->pdev = pdev;
-
        return 0;
 }
 
@@ -1015,11 +957,10 @@ static void gpio_sim_device_deactivate(struct gpio_sim_device *dev)
 
        lockdep_assert_held(&dev->lock);
 
-       swnode = dev_fwnode(&dev->pdev->dev);
-       platform_device_unregister(dev->pdev);
+       swnode = dev_fwnode(&dev->probe_data.pdev->dev);
+       dev_sync_probe_unregister(&dev->probe_data);
        gpio_sim_remove_hogs(dev);
        gpio_sim_remove_swnode_recursive(swnode);
-       dev->pdev = NULL;
 }
 
 static void
@@ -1120,7 +1061,7 @@ static ssize_t gpio_sim_bank_config_chip_name_show(struct config_item *item,
        guard(mutex)(&dev->lock);
 
        if (gpio_sim_device_is_live(dev))
-               return device_for_each_child(&dev->pdev->dev, &ctx,
+               return device_for_each_child(&dev->probe_data.pdev->dev, &ctx,
                                             gpio_sim_emit_chip_name);
 
        return sprintf(page, "none\n");
@@ -1561,8 +1502,7 @@ gpio_sim_config_make_device_group(struct config_group *group, const char *name)
        mutex_init(&dev->lock);
        INIT_LIST_HEAD(&dev->bank_list);
 
-       dev->bus_notifier.notifier_call = gpio_sim_bus_notifier_call;
-       init_completion(&dev->probe_completion);
+       dev_sync_probe_init(&dev->probe_data);
 
        return &no_free_ptr(dev)->group;
 }