aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorKoichiro Den <koichiro.den@canonical.com>2025-04-07 13:30:17 +0900
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2025-04-09 16:57:29 +0200
commit0269c768de1b5e430c3f9a6869261606c82abe90 (patch)
tree7738e8ee8ffa4d23cc1e89eab01ede505b731afb
parentgpio: aggregator: expose aggregator created via legacy sysfs to configfs (diff)
downloadwireguard-linux-0269c768de1b5e430c3f9a6869261606c82abe90.tar.xz
wireguard-linux-0269c768de1b5e430c3f9a6869261606c82abe90.zip
gpio: aggregator: cancel deferred probe for devices created via configfs
For aggregators initialized via configfs, write 1 to 'live' waits for probe completion and returns an error if the probe fails, unlike the legacy sysfs interface, which is asynchronous. Since users control the liveness of the aggregator device and might be editing configurations while 'live' is 0, deferred probing is both unnatural and unsafe. Cancel deferred probe for purely configfs-based aggregators when probe fails. Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Link: https://lore.kernel.org/r/20250407043019.4105613-8-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
-rw-r--r--drivers/gpio/gpio-aggregator.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index 74e0f9faeaba..dde969f29ee2 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -72,6 +72,10 @@ struct gpio_aggregator_line {
enum gpio_lookup_flags flags;
};
+struct gpio_aggregator_pdev_meta {
+ bool init_via_sysfs;
+};
+
static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */
static DEFINE_IDR(gpio_aggregator_idr);
@@ -1137,6 +1141,7 @@ err:
static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
const char *buf, size_t count)
{
+ struct gpio_aggregator_pdev_meta meta = { .init_via_sysfs = true };
char name[CONFIGFS_ITEM_NAME_LEN];
struct gpio_aggregator *aggr;
struct platform_device *pdev;
@@ -1187,7 +1192,7 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
gpiod_add_lookup_table(aggr->lookups);
- pdev = platform_device_register_simple(DRV_NAME, aggr->id, NULL, 0);
+ pdev = platform_device_register_data(NULL, DRV_NAME, aggr->id, &meta, sizeof(meta));
if (IS_ERR(pdev)) {
res = PTR_ERR(pdev);
goto remove_table;
@@ -1280,7 +1285,9 @@ ATTRIBUTE_GROUPS(gpio_aggregator);
static int gpio_aggregator_probe(struct platform_device *pdev)
{
+ struct gpio_aggregator_pdev_meta *meta;
struct device *dev = &pdev->dev;
+ bool init_via_sysfs = false;
struct gpio_desc **descs;
struct gpiochip_fwd *fwd;
unsigned long features;
@@ -1294,10 +1301,28 @@ static int gpio_aggregator_probe(struct platform_device *pdev)
if (!descs)
return -ENOMEM;
+ meta = dev_get_platdata(&pdev->dev);
+ if (meta && meta->init_via_sysfs)
+ init_via_sysfs = true;
+
for (i = 0; i < n; i++) {
descs[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
- if (IS_ERR(descs[i]))
+ if (IS_ERR(descs[i])) {
+ /*
+ * Deferred probing is not suitable when the aggregator
+ * is created via configfs. They should just retry later
+ * whenever they like. For device creation via sysfs,
+ * error is propagated without overriding for backward
+ * compatibility. .prevent_deferred_probe is kept unset
+ * for other cases.
+ */
+ if (!init_via_sysfs && !dev_of_node(dev) &&
+ descs[i] == ERR_PTR(-EPROBE_DEFER)) {
+ pr_warn("Deferred probe canceled for creation via configfs.\n");
+ return -ENODEV;
+ }
return PTR_ERR(descs[i]);
+ }
}
features = (uintptr_t)device_get_match_data(dev);