]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
gpio: aggregator: stop using dev-sync-probe
authorBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Fri, 27 Mar 2026 10:31:12 +0000 (11:31 +0100)
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Tue, 7 Apr 2026 10:32:27 +0000 (12:32 +0200)
dev-err-probe is an overengineered solution to a simple problem. Use a
combination of wait_for_probe() and device_is_bound() to synchronously
wait for the platform device to probe.

Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260327-gpio-kill-dev-sync-probe-v1-2-efac254f1a1d@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
drivers/gpio/Kconfig
drivers/gpio/gpio-aggregator.c

index 0a16aa7a3a96acac0e263590cfbdcef3eea1b098..ab7ac3d62ea93441588e550aa57c3a271d950e3b 100644 (file)
@@ -2010,7 +2010,6 @@ menu "Virtual GPIO drivers"
 config GPIO_AGGREGATOR
        tristate "GPIO Aggregator"
        select CONFIGFS_FS
-       select DEV_SYNC_PROBE
        help
          Say yes here to enable the GPIO Aggregator, which provides a way to
          aggregate existing GPIO lines into a new virtual GPIO chip.
index 9adf3228c12a84e098ab7ffd543fcad58951ba99..5915209e1e2168b0932de4d16aff38074b889c2b 100644 (file)
@@ -32,8 +32,6 @@
 #include <linux/gpio/forwarder.h>
 #include <linux/gpio/machine.h>
 
-#include "dev-sync-probe.h"
-
 #define AGGREGATOR_MAX_GPIOS 512
 #define AGGREGATOR_LEGACY_PREFIX "_sysfs"
 
@@ -42,7 +40,7 @@
  */
 
 struct gpio_aggregator {
-       struct dev_sync_probe_data probe_data;
+       struct platform_device *pdev;
        struct config_group group;
        struct gpiod_lookup_table *lookups;
        struct mutex lock;
@@ -135,7 +133,7 @@ static bool gpio_aggregator_is_active(struct gpio_aggregator *aggr)
 {
        lockdep_assert_held(&aggr->lock);
 
-       return aggr->probe_data.pdev && platform_get_drvdata(aggr->probe_data.pdev);
+       return aggr->pdev && platform_get_drvdata(aggr->pdev);
 }
 
 /* Only aggregators created via legacy sysfs can be "activating". */
@@ -143,7 +141,7 @@ static bool gpio_aggregator_is_activating(struct gpio_aggregator *aggr)
 {
        lockdep_assert_held(&aggr->lock);
 
-       return aggr->probe_data.pdev && !platform_get_drvdata(aggr->probe_data.pdev);
+       return aggr->pdev && !platform_get_drvdata(aggr->pdev);
 }
 
 static size_t gpio_aggregator_count_lines(struct gpio_aggregator *aggr)
@@ -909,6 +907,7 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr)
 {
        struct platform_device_info pdevinfo;
        struct gpio_aggregator_line *line;
+       struct platform_device *pdev;
        struct fwnode_handle *swnode;
        unsigned int n = 0;
        int ret = 0;
@@ -962,12 +961,23 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr)
 
        gpiod_add_lookup_table(aggr->lookups);
 
-       ret = dev_sync_probe_register(&aggr->probe_data, &pdevinfo);
-       if (ret)
+       pdev = platform_device_register_full(&pdevinfo);
+       if (IS_ERR(pdev)) {
+               ret = PTR_ERR(pdev);
                goto err_remove_lookup_table;
+       }
 
+       wait_for_device_probe();
+       if (!device_is_bound(&pdev->dev)) {
+               ret = -ENXIO;
+               goto err_unregister_pdev;
+       }
+
+       aggr->pdev = pdev;
        return 0;
 
+err_unregister_pdev:
+       platform_device_unregister(pdev);
 err_remove_lookup_table:
        kfree(aggr->lookups->dev_id);
        gpiod_remove_lookup_table(aggr->lookups);
@@ -981,7 +991,8 @@ err_remove_lookups:
 
 static void gpio_aggregator_deactivate(struct gpio_aggregator *aggr)
 {
-       dev_sync_probe_unregister(&aggr->probe_data);
+       platform_device_unregister(aggr->pdev);
+       aggr->pdev = NULL;
        gpiod_remove_lookup_table(aggr->lookups);
        kfree(aggr->lookups->dev_id);
        kfree(aggr->lookups);
@@ -1145,7 +1156,7 @@ gpio_aggregator_device_dev_name_show(struct config_item *item, char *page)
 
        guard(mutex)(&aggr->lock);
 
-       pdev = aggr->probe_data.pdev;
+       pdev = aggr->pdev;
        if (pdev)
                return sysfs_emit(page, "%s\n", dev_name(&pdev->dev));
 
@@ -1322,7 +1333,6 @@ gpio_aggregator_make_group(struct config_group *group, const char *name)
                return ERR_PTR(ret);
 
        config_group_init_type_name(&aggr->group, name, &gpio_aggregator_device_type);
-       dev_sync_probe_init(&aggr->probe_data);
 
        return &aggr->group;
 }
@@ -1471,12 +1481,6 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
        scnprintf(name, sizeof(name), "%s.%d", AGGREGATOR_LEGACY_PREFIX, aggr->id);
        config_group_init_type_name(&aggr->group, name, &gpio_aggregator_device_type);
 
-       /*
-        * Since the device created by sysfs might be toggled via configfs
-        * 'live' attribute later, this initialization is needed.
-        */
-       dev_sync_probe_init(&aggr->probe_data);
-
        /* Expose to configfs */
        res = configfs_register_group(&gpio_aggregator_subsys.su_group,
                                      &aggr->group);
@@ -1495,7 +1499,7 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
                goto remove_table;
        }
 
-       aggr->probe_data.pdev = pdev;
+       aggr->pdev = pdev;
        module_put(THIS_MODULE);
        return count;