Commit 3a27f40b authored by Bartosz Golaszewski's avatar Bartosz Golaszewski
Browse files

gpio: aggregator: stop using dev-sync-probe



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: default avatarLinus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260327-gpio-kill-dev-sync-probe-v1-2-efac254f1a1d@oss.qualcomm.com


Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
parent 7fb32879
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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.
+21 −17
Original line number Diff line number Diff line
@@ -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 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr)

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;