From patchwork Tue Apr 15 06:13:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQL15xQz1yJ9 for ; Tue, 15 Apr 2025 16:14:34 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZG-0004DP-Uk; Tue, 15 Apr 2025 06:14:46 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZF-000480-68 for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:45 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id DEBCA3F1E4 for ; Tue, 15 Apr 2025 06:14:44 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-736abba8c5cso6177923b3a.2 for ; Mon, 14 Apr 2025 23:14:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697683; x=1745302483; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4PnBRjoOaysJwVSD9B99HMnOOI4wmq3OVb+j0eXmd38=; b=qBTODv2YSdElbQ5m4tdFM7Wj6DEQD+m0vTCo0/UuHzxhhN/OaHULtEqf3fWJOUUF1K k3HBi8d0ZdIUEAWjwC607MV7gWRH+TLzOfaEhjdwh+3bA9Am7cqBcSrZ6rRTPcrMWD8p de4atetooooqdv40Azun0FI2ffklKyLXGG9by523adUIrnuJB+j+Qi+AIclC30kzss9q lLQ/uOqQN1AhcudjYllHYojbioLVgxQaEQHhAClf1P5yULZTD5uXHlrf864OB0jk3UKm yFaOtY9BMhM1dZio4AOyiVJ34aT1lmZtybg+r+JUk10e+EI5XxL95pfg4kRrCjxwQ85k t21A== X-Gm-Message-State: AOJu0YwkI+TgEvsMKxkegTWPaDGMhLvZWpH8WOASkASvTgN6l1SZkseU VlTk3CdeDgF/j0jkAqnKEl3xL4iYqduFDjDFu3JSZp3RQr/0JWI5fMaSAZgHadKY2p5d7dLYN4t spe2h5pjgd0xtXBtilxuna6qWtshvHZNNkYgG7rhmkhUO1IuySSleMJ344p7MB6YU3vOHC7z2Yt gAsggAQecpwg== X-Gm-Gg: ASbGncsW/zoqceQoIht+FxYpybQOh41rMQdKsbw5B1VHm7Z6/u7IFy8VGyDlCNKySGY occj3V2LybRBuw4d/BZdhBDSQm4sVR2hEEOhIYaZNvEaNxhuTQD2+BUdYkTpIynWAY+z95VOLjz 9O+rtSTPXVyKKCPBBTA2wH9zUVGE5clecvwKywFkrSDk9POupCMxeScVzbq4w19WHAqL1fbnIOI 5ZrasABF3Z5PKM2GEF6yd3TS1oszcMY2aVcyD07bX3ihkHbEI596wUe9D4//RI93/7kz6T2rHMN ENdekSGN5i6TLgT8ScEJnI5xVFaCTA== X-Received: by 2002:a05:6a00:4653:b0:736:5b85:a911 with SMTP id d2e1a72fcca58-73bd11f84a1mr22842107b3a.8.1744697683313; Mon, 14 Apr 2025 23:14:43 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGPg5lkYvOysX1MOkElUe/b+E/09VGbHoVoBj6jQBp7DDavvJ4aDISoxvIzeORg+jhmktlHGQ== X-Received: by 2002:a05:6a00:4653:b0:736:5b85:a911 with SMTP id d2e1a72fcca58-73bd11f84a1mr22842073b3a.8.1744697682825; Mon, 14 Apr 2025 23:14:42 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:42 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 01/19] gpio: introduce utilities for synchronous fake device creation Date: Tue, 15 Apr 2025 15:13:27 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Both gpio-sim and gpio-virtuser share a mechanism to instantiate a platform device, wait for probe completion, and retrieve the probe success or error status synchronously. With gpio-aggregator planned to adopt this approach for its configfs interface, it's time to factor out the common code. Add dev-sync-probe.[ch] to house helper functions used by all such implementations. No functional change. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250221133501.2203897-2-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit eb5ab6ffb4ca2d28121455dd7452061367ed5588) Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 3 ++ drivers/gpio/Makefile | 3 ++ drivers/gpio/dev-sync-probe.c | 97 +++++++++++++++++++++++++++++++++++ drivers/gpio/dev-sync-probe.h | 25 +++++++++ 4 files changed, 128 insertions(+) create mode 100644 drivers/gpio/dev-sync-probe.c create mode 100644 drivers/gpio/dev-sync-probe.h diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2be612f9ce55..21ac40bde9c4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1935,3 +1935,6 @@ config GPIO_VIRTUSER endmenu endif + +config DEV_SYNC_PROBE + tristate diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index e6b6355c66d4..a18cf557eca6 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -19,6 +19,9 @@ obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o # directly supported by gpio-generic gpio-generic-$(CONFIG_GPIO_GENERIC) += gpio-mmio.o +# Utilities for drivers that need synchronous fake device creation +obj-$(CONFIG_DEV_SYNC_PROBE) += dev-sync-probe.o + obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o diff --git a/drivers/gpio/dev-sync-probe.c b/drivers/gpio/dev-sync-probe.c new file mode 100644 index 000000000000..9ea733b863b2 --- /dev/null +++ b/drivers/gpio/dev-sync-probe.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Common code for drivers creating fake platform devices. + * + * Provides synchronous device creation: waits for probe completion and + * returns the probe success or error status to the device creator. + * + * Copyright (C) 2021 Bartosz Golaszewski + * Copyright (C) 2025 Koichiro Den + */ + +#include +#include + +#include "dev-sync-probe.h" + +static int dev_sync_probe_notifier_call(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct dev_sync_probe_data *pdata; + struct device *dev = data; + + pdata = container_of(nb, struct dev_sync_probe_data, bus_notifier); + if (!device_match_name(dev, pdata->name)) + return NOTIFY_DONE; + + switch (action) { + case BUS_NOTIFY_BOUND_DRIVER: + pdata->driver_bound = true; + break; + case BUS_NOTIFY_DRIVER_NOT_BOUND: + pdata->driver_bound = false; + break; + default: + return NOTIFY_DONE; + } + + complete(&pdata->probe_completion); + return NOTIFY_OK; +} + +void dev_sync_probe_init(struct dev_sync_probe_data *data) +{ + memset(data, 0, sizeof(*data)); + init_completion(&data->probe_completion); + data->bus_notifier.notifier_call = dev_sync_probe_notifier_call; +} +EXPORT_SYMBOL_GPL(dev_sync_probe_init); + +int dev_sync_probe_register(struct dev_sync_probe_data *data, + struct platform_device_info *pdevinfo) +{ + struct platform_device *pdev; + char *name; + + name = kasprintf(GFP_KERNEL, "%s.%d", pdevinfo->name, pdevinfo->id); + if (!name) + return -ENOMEM; + + data->driver_bound = false; + data->name = name; + reinit_completion(&data->probe_completion); + bus_register_notifier(&platform_bus_type, &data->bus_notifier); + + pdev = platform_device_register_full(pdevinfo); + if (IS_ERR(pdev)) { + bus_unregister_notifier(&platform_bus_type, &data->bus_notifier); + kfree(data->name); + return PTR_ERR(pdev); + } + + wait_for_completion(&data->probe_completion); + bus_unregister_notifier(&platform_bus_type, &data->bus_notifier); + + if (!data->driver_bound) { + platform_device_unregister(pdev); + kfree(data->name); + return -ENXIO; + } + + data->pdev = pdev; + return 0; +} +EXPORT_SYMBOL_GPL(dev_sync_probe_register); + +void dev_sync_probe_unregister(struct dev_sync_probe_data *data) +{ + platform_device_unregister(data->pdev); + kfree(data->name); + data->pdev = NULL; +} +EXPORT_SYMBOL_GPL(dev_sync_probe_unregister); + +MODULE_AUTHOR("Bartosz Golaszewski "); +MODULE_AUTHOR("Koichiro Den "); +MODULE_DESCRIPTION("Utilities for synchronous fake device creation"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpio/dev-sync-probe.h b/drivers/gpio/dev-sync-probe.h new file mode 100644 index 000000000000..4b3d52b70519 --- /dev/null +++ b/drivers/gpio/dev-sync-probe.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef DEV_SYNC_PROBE_H +#define DEV_SYNC_PROBE_H + +#include +#include +#include + +struct dev_sync_probe_data { + struct platform_device *pdev; + const char *name; + + /* Synchronize with probe */ + struct notifier_block bus_notifier; + struct completion probe_completion; + bool driver_bound; +}; + +void dev_sync_probe_init(struct dev_sync_probe_data *data); +int dev_sync_probe_register(struct dev_sync_probe_data *data, + struct platform_device_info *pdevinfo); +void dev_sync_probe_unregister(struct dev_sync_probe_data *data); + +#endif /* DEV_SYNC_PROBE_H */ From patchwork Tue Apr 15 06:13:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072659 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQM5jYDz1yJ9 for ; Tue, 15 Apr 2025 16:14:35 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZI-0004GX-7R; Tue, 15 Apr 2025 06:14:48 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZG-0004Ck-PI for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:46 +0000 Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 73EE43F091 for ; Tue, 15 Apr 2025 06:14:46 +0000 (UTC) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-736cd27d51fso4294331b3a.2 for ; Mon, 14 Apr 2025 23:14:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697685; x=1745302485; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m5b2WrwstZXzBBtKnhaqZo7EjBKygUuwpAfg2ky8XNw=; b=oOYQleTEeZgNsx6434J+6PKq18vq6drP4aEhuENkBnluJIetfEmFqHZ3pLQTYZJaTl jRP2HKKX3lhxg/dlIRebJJGuP8mugBx1endtmhZMOVHwBmtb9rb+ty7J09/cKdDEHp5e tmB9CUPoxyTKO2JNW7TYRt9SEMhT3pfrxKKZms6hlc09f8JqSWb2Vi1G0bZQYuJgtpP2 V7k8blkk3GMhdl+b3AjKT+KlIJmQ1INlj2MW01QOugKXSbnct//3HeBva5Sf6KlgyM2X n9y8Om+aLltv6teea1LVhT4uZ+3p8SnKhR5iesXKNgQDCNd4ACYL9HjlXcEFgkr0iMV/ PzAQ== X-Gm-Message-State: AOJu0YykhIMWk7WITLOHoI/Y3EkffH+74JI4TsXlZZVp+g2RybhRb6Ew 7s6IOgLgNPqsI5lQwsbWVVjeN1UqX+PmQ3F5r6oTfvT7+W+q6edpIVv2Fm5K8PHfIC/6aJFMpir y2MiHlZ1CM/X+Z3adENXXcW6iQkP0QGLTFQmYrZORbgfBWkNA7mUyedc6vN3evPa8D16SYQYtd4 coz3KCQojt1g== X-Gm-Gg: ASbGncsZp1PYLkJDpAqJa53k0aAsNEWTrIOugEQv3Lk+o+/nCOmOBd3r7OOWs9NSMHO EClNVxhClSJ3kBOrhuzeWwHuQiyK+pAd6YZGvjhAanJ8t3q3pjyORSD8XNO3Pk/oEWmkL5uq8Su is8ujntbp82iaUc0yAXBl3tQLZmJzcdioZvJ5sZ4zPL/gi1LFNH5yVguqD0hOsMnjbP+RuWb9Yg PNG0RP9CbOPpg/rjeaIF9kpMBWecvS4uMovfHIY2Ise0oyzpHTm1hL9Igp9EAYGYuMLkckCuXLc PliDPDc8OPu5T1VbSyyw1eLqDv7dZQ== X-Received: by 2002:a05:6a00:240b:b0:736:a694:1a0c with SMTP id d2e1a72fcca58-73bd12bef8dmr20620921b3a.21.1744697684755; Mon, 14 Apr 2025 23:14:44 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHzi/2Uzl53fXUlwNEhccbOGneG3jYNwvTTrngdP7mnJsvlzE89fCEQDK9gMWXjVeH48ZwUnA== X-Received: by 2002:a05:6a00:240b:b0:736:a694:1a0c with SMTP id d2e1a72fcca58-73bd12bef8dmr20620890b3a.21.1744697684318; Mon, 14 Apr 2025 23:14:44 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:43 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 02/19] gpio: aggregator: simplify aggr_parse() with scoped bitmap Date: Tue, 15 Apr 2025 15:13:28 +0900 Message-ID: <07880b95524cd53bd42dbd3e1fc6676bfeb0f6e5.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Bartosz Golaszewski BugLink: https://bugs.launchpad.net/bugs/2103496 The bitmap allocated in aggr_parse() is always freed before the function returns so use __free(bitmap) to simplify it and drop the goto label. Reviewed-by: Linus Walleij Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20240930163207.80276-1-brgl@bgdev.pl Signed-off-by: Bartosz Golaszewski (cherry picked from commit 22dec5aa596ef805cccbcd3fbe5ebffbcb4fa559) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 38e0fff9afe7..65f41cc3eafc 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -65,11 +65,11 @@ static int aggr_parse(struct gpio_aggregator *aggr) { char *args = skip_spaces(aggr->args); char *name, *offsets, *p; - unsigned long *bitmap; unsigned int i, n = 0; int error = 0; - bitmap = bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); + unsigned long *bitmap __free(bitmap) = + bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); if (!bitmap) return -ENOMEM; @@ -82,7 +82,7 @@ static int aggr_parse(struct gpio_aggregator *aggr) /* Named GPIO line */ error = aggr_add_gpio(aggr, name, U16_MAX, &n); if (error) - goto free_bitmap; + return error; name = offsets; continue; @@ -92,13 +92,13 @@ static int aggr_parse(struct gpio_aggregator *aggr) error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); if (error) { pr_err("Cannot parse %s: %d\n", offsets, error); - goto free_bitmap; + return error; } for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { error = aggr_add_gpio(aggr, name, i, &n); if (error) - goto free_bitmap; + return error; } args = next_arg(args, &name, &p); @@ -106,12 +106,10 @@ static int aggr_parse(struct gpio_aggregator *aggr) if (!n) { pr_err("No GPIOs specified\n"); - error = -EINVAL; + return -EINVAL; } -free_bitmap: - bitmap_free(bitmap); - return error; + return 0; } static ssize_t new_device_store(struct device_driver *driver, const char *buf, From patchwork Tue Apr 15 06:13:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072660 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQQ6BF6z1yJ9 for ; Tue, 15 Apr 2025 16:14:38 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZK-0004Md-MF; Tue, 15 Apr 2025 06:14:50 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZI-0004GB-5e for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:48 +0000 Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id DD5833F1E4 for ; Tue, 15 Apr 2025 06:14:47 +0000 (UTC) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-736b22717f1so3886910b3a.1 for ; Mon, 14 Apr 2025 23:14:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697686; x=1745302486; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=512ty5KKynv5bozfQVKcLi1tWYbnfRanlAvdcNmnRTk=; b=rbKo22xyNXAg1swz23Xa8gCNxr4RZ0P3hAmJ0QHzegTvLCJlH1dtKOCWi84DnWz12J A/KcFFF0Fp9rqbaN72r6sYImRmcnMNz3wvH9nrSd5/1cMfg5kkU2ykj4xCf/VRWIC16H bn4kY0ESSIcbvM3fkbNOX5OwjGh1DIj8UvIFpFqC3JptiRA9L3Thku4FcG27zPdarYmZ Z+/tBDQf5H2garVry1tw0pH1WiltAyWthmGaItw+c8y4dMt4/ay399BlXtMoQlDucx/b VYGn96VXLOCuX/BAdo3vabmaUiC0R4MQzA8CKwYPmDJl7CRX9SKUGMBQCLiF95LhZ+h6 Ebvw== X-Gm-Message-State: AOJu0YxxIa/9RWG7e5amBc9ASTd5ew62qyGZ0JG1As+d/BcNv2nAEobb VDFltNq8euAZgM0kASUpyE8Oswe9hAPht62+Ie7EyYxBYz7KRUgVhCkKEtyGlLr0oFQeI8ILaUh arWZ4P2d2cE3qyD7ckSOiNQCSpJP9cPgMBGi4qru1NmFDHFsZ132x5qmtuOwbk3kjsxlFSAZ23Y fr69lQDeI6VQ== X-Gm-Gg: ASbGncsfuuSv+ZTwjOfmZJUW61C87KhQGP0eWkXZ4juFd1nfzNN9HCPcv2xMiMwMQO0 ha0zxpMj1Jj040XvsS+2j8QeWDU1AFXtY8Ip/o1AaLl/2NiZ84k2PDpWARtiC/aVegxLujDPhs3 p05u79bcCyc9C5VISBScFMy/y0isXM79+NYpgD5MdIomo8EQ5shiMNAcd5jg7US1/0WdKOkD5Ow +14neSXiGH6IzoWLB6nCZm1p3vBLZfCVjThHlKHWowCAOTzMx/Aadz4gLIKycptKCyBwEk+gDqd xpRkcsTpLuU6n9HrTOLq7bY/N+o3xw== X-Received: by 2002:a05:6a00:f0a:b0:734:26c6:26d3 with SMTP id d2e1a72fcca58-73c0c8d3ffbmr4060441b3a.5.1744697686292; Mon, 14 Apr 2025 23:14:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFXRau/vicrt7lW78LvAyTi4RpH2RWLQ3HIBCKdBRw2XT2IyY4UkGgGN8GBVICnQx115RALCA== X-Received: by 2002:a05:6a00:f0a:b0:734:26c6:26d3 with SMTP id d2e1a72fcca58-73c0c8d3ffbmr4060396b3a.5.1744697685795; Mon, 14 Apr 2025 23:14:45 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:45 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 03/19] gpio: aggregator: protect driver attr handlers against module unload Date: Tue, 15 Apr 2025 15:13:29 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Both new_device_store and delete_device_store touch module global resources (e.g. gpio_aggregator_lock). To prevent race conditions with module unload, a reference needs to be held. Add try_module_get() in these handlers. For new_device_store, this eliminates what appears to be the most dangerous scenario: if an id is allocated from gpio_aggregator_idr but platform_device_register has not yet been called or completed, a concurrent module unload could fail to unregister/delete the device, leaving behind a dangling platform device/GPIO forwarder. This can result in various issues. The following simple reproducer demonstrates these problems: #!/bin/bash while :; do # note: whether 'gpiochip0 0' exists or not does not matter. echo 'gpiochip0 0' > /sys/bus/platform/drivers/gpio-aggregator/new_device done & while :; do modprobe gpio-aggregator modprobe -r gpio-aggregator done & wait Starting with the following warning, several kinds of warnings will appear and the system may become unstable: ------------[ cut here ]------------ list_del corruption, ffff888103e2e980->next is LIST_POISON1 (dead000000000100) WARNING: CPU: 1 PID: 1327 at lib/list_debug.c:56 __list_del_entry_valid_or_report+0xa3/0x120 [...] RIP: 0010:__list_del_entry_valid_or_report+0xa3/0x120 [...] Call Trace: ? __list_del_entry_valid_or_report+0xa3/0x120 ? __warn.cold+0x93/0xf2 ? __list_del_entry_valid_or_report+0xa3/0x120 ? report_bug+0xe6/0x170 ? __irq_work_queue_local+0x39/0xe0 ? handle_bug+0x58/0x90 ? exc_invalid_op+0x13/0x60 ? asm_exc_invalid_op+0x16/0x20 ? __list_del_entry_valid_or_report+0xa3/0x120 gpiod_remove_lookup_table+0x22/0x60 new_device_store+0x315/0x350 [gpio_aggregator] kernfs_fop_write_iter+0x137/0x1f0 vfs_write+0x262/0x430 ksys_write+0x60/0xd0 do_syscall_64+0x6c/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e [...] ---[ end trace 0000000000000000 ]--- Fixes: 828546e24280 ("gpio: Add GPIO Aggregator") Cc: stable@vger.kernel.org Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250224143134.3024598-2-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 12f65d1203507f7db3ba59930fe29a3b8eee9945) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 65f41cc3eafc..d668ddb2e81d 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -119,10 +119,15 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, struct platform_device *pdev; int res, id; + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + /* kernfs guarantees string termination, so count + 1 is safe */ aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) - return -ENOMEM; + if (!aggr) { + res = -ENOMEM; + goto put_module; + } memcpy(aggr->args, buf, count + 1); @@ -161,6 +166,7 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, } aggr->pdev = pdev; + module_put(THIS_MODULE); return count; remove_table: @@ -175,6 +181,8 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, kfree(aggr->lookups); free_ga: kfree(aggr); +put_module: + module_put(THIS_MODULE); return res; } @@ -203,13 +211,19 @@ static ssize_t delete_device_store(struct device_driver *driver, if (error) return error; + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + mutex_lock(&gpio_aggregator_lock); aggr = idr_remove(&gpio_aggregator_idr, id); mutex_unlock(&gpio_aggregator_lock); - if (!aggr) + if (!aggr) { + module_put(THIS_MODULE); return -ENOENT; + } gpio_aggregator_free(aggr); + module_put(THIS_MODULE); return count; } static DRIVER_ATTR_WO(delete_device); From patchwork Tue Apr 15 06:13:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072661 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQR5ZWnz1yJ9 for ; Tue, 15 Apr 2025 16:14:39 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZL-0004P7-Js; Tue, 15 Apr 2025 06:14:51 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZJ-0004Kr-RB for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:49 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 74A753F091 for ; Tue, 15 Apr 2025 06:14:49 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-736abba8c5cso6178017b3a.2 for ; Mon, 14 Apr 2025 23:14:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697688; x=1745302488; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CNbq/NpJ4KheRhANvZjV/MLV/ZCYE0gS1Y/uJVreU70=; b=DoxmDK5xYkfyAAFbnw3FE/NbPBJIUWtloy6aOtXoW88Ee1hXucr8JPf902e1jSdwjz jVJcj76Xw31l+U539Wje6BpYPU7IRhpKRQQ4sBvKHlRoNS/tul4oieeE/iIbSn9Ev7lc 0GShdKLKhUB3ln2Ez2Ax8UPECmrilBq23DMeKMs7p8O/eiQd/e7BaVlUaMX3ZHU8EiVy F5TjBP6dqLfVui5cnIG/OYgV86beD+gfWRGsliTSOgOWK72Kd0cFJo1uhICL/v1WG3V5 PhT6ScPm9J6IF0lamuxdH0mxwCAkmm426jr4CEZYQyX/wZfR8Dp76OK4DBj061TNqnDS Qn5g== X-Gm-Message-State: AOJu0YwzhDRbMntgYBa91o57CCR3pGuEsk6AaQvbWQpnreBbWxd3lhQn tldsE3FxNq15HPWXHU4MxQ6gtIMr1xzPpCp8kIpZ6l/cJjVrK8BNzayDyNSfrKD8gYW95s6twyH X8vS/i4DCqW+8skBCW+UZkwto8zceI7FHUCkGsXFKdgXtV+BW+tPW7SbAJaSeYCj4vjpjCkE6NZ xwBE3Av7ytSg== X-Gm-Gg: ASbGncu9CTwemSR2O1ObZnGc5AKUx1y7iohEsozjwgCKrUg6qi4zM0xzwYBr33yVpR1 2ixtqUuqIqMLb3seMYoz3Szv+u+sHKuBdSKz/ZyOCFoZaj2FZILSC97EZHTJrdzPz/2H5uAklZ+ hZw5+6O8Lh7EQhEBt/HrXlQT0ZPNBEU7ehbS4avLYNgwSGPGxObuMo3DzMGB0xTEfCgnPYvW3Hq Bs5Q3FAoA7/vIuMUVpIdX0VbjyBT29gO1/HvxTPq8bdPngHrAKz32vEQM/Nx4gW4/xTmXDMElBN ZCRCtngoJZO1zykHUTsvGp24yxcR5g== X-Received: by 2002:a05:6a00:8d4:b0:736:73ad:365b with SMTP id d2e1a72fcca58-73bd12121b5mr19036611b3a.14.1744697687769; Mon, 14 Apr 2025 23:14:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFSKIEM17ev3Ql11j+VDUM+8SZMFTFsTUWdkS2ef1cNX4MIrlnAiMVa9Mzqve2Jqk6rc0sA9g== X-Received: by 2002:a05:6a00:8d4:b0:736:73ad:365b with SMTP id d2e1a72fcca58-73bd12121b5mr19036588b3a.14.1744697687299; Mon, 14 Apr 2025 23:14:47 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:46 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 04/19] gpio: aggregator: reorder functions to prepare for configfs introduction Date: Tue, 15 Apr 2025 15:13:30 +0900 Message-ID: <2b3d5fcd7c6d37111b1de52f8a3f85dfd3ed597e.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Reorder functions in drivers/gpio/gpio-aggregator.c to prepare for the configfs-based interface additions in subsequent commits. Arrange the code so that the configfs implementations will appear above the existing sysfs-specific code, since the latter will partly depend on the configfs interface implementations when it starts to expose the settings to configfs. The order in drivers/gpio/gpio-aggregator.c will be as follows: * Basic gpio_aggregator/gpio_aggregator_line representations * Common utility functions * GPIO Forwarder implementations * Configfs interface implementations * Sysfs interface implementations * Platform device implementations * Module init/exit implementations This separate commit ensures a clean diff for the subsequent commits. No functional change. Reviewed-by: Geert Uytterhoeven Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-2-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 7a56efeabffd13a162073068b8e29113c65f9e64 linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 380 +++++++++++++++++---------------- 1 file changed, 192 insertions(+), 188 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index d668ddb2e81d..893cd56de867 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -61,194 +61,6 @@ static int aggr_add_gpio(struct gpio_aggregator *aggr, const char *key, return 0; } -static int aggr_parse(struct gpio_aggregator *aggr) -{ - char *args = skip_spaces(aggr->args); - char *name, *offsets, *p; - unsigned int i, n = 0; - int error = 0; - - unsigned long *bitmap __free(bitmap) = - bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); - if (!bitmap) - return -ENOMEM; - - args = next_arg(args, &name, &p); - while (*args) { - args = next_arg(args, &offsets, &p); - - p = get_options(offsets, 0, &error); - if (error == 0 || *p) { - /* Named GPIO line */ - error = aggr_add_gpio(aggr, name, U16_MAX, &n); - if (error) - return error; - - name = offsets; - continue; - } - - /* GPIO chip + offset(s) */ - error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); - if (error) { - pr_err("Cannot parse %s: %d\n", offsets, error); - return error; - } - - for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error = aggr_add_gpio(aggr, name, i, &n); - if (error) - return error; - } - - args = next_arg(args, &name, &p); - } - - if (!n) { - pr_err("No GPIOs specified\n"); - return -EINVAL; - } - - return 0; -} - -static ssize_t new_device_store(struct device_driver *driver, const char *buf, - size_t count) -{ - struct gpio_aggregator *aggr; - struct platform_device *pdev; - int res, id; - - if (!try_module_get(THIS_MODULE)) - return -ENOENT; - - /* kernfs guarantees string termination, so count + 1 is safe */ - aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) { - res = -ENOMEM; - goto put_module; - } - - memcpy(aggr->args, buf, count + 1); - - aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), - GFP_KERNEL); - if (!aggr->lookups) { - res = -ENOMEM; - goto free_ga; - } - - mutex_lock(&gpio_aggregator_lock); - id = idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); - mutex_unlock(&gpio_aggregator_lock); - - if (id < 0) { - res = id; - goto free_table; - } - - aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); - if (!aggr->lookups->dev_id) { - res = -ENOMEM; - goto remove_idr; - } - - res = aggr_parse(aggr); - if (res) - goto free_dev_id; - - gpiod_add_lookup_table(aggr->lookups); - - pdev = platform_device_register_simple(DRV_NAME, id, NULL, 0); - if (IS_ERR(pdev)) { - res = PTR_ERR(pdev); - goto remove_table; - } - - aggr->pdev = pdev; - module_put(THIS_MODULE); - return count; - -remove_table: - gpiod_remove_lookup_table(aggr->lookups); -free_dev_id: - kfree(aggr->lookups->dev_id); -remove_idr: - mutex_lock(&gpio_aggregator_lock); - idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); -free_table: - kfree(aggr->lookups); -free_ga: - kfree(aggr); -put_module: - module_put(THIS_MODULE); - return res; -} - -static DRIVER_ATTR_WO(new_device); - -static void gpio_aggregator_free(struct gpio_aggregator *aggr) -{ - platform_device_unregister(aggr->pdev); - gpiod_remove_lookup_table(aggr->lookups); - kfree(aggr->lookups->dev_id); - kfree(aggr->lookups); - kfree(aggr); -} - -static ssize_t delete_device_store(struct device_driver *driver, - const char *buf, size_t count) -{ - struct gpio_aggregator *aggr; - unsigned int id; - int error; - - if (!str_has_prefix(buf, DRV_NAME ".")) - return -EINVAL; - - error = kstrtouint(buf + strlen(DRV_NAME "."), 10, &id); - if (error) - return error; - - if (!try_module_get(THIS_MODULE)) - return -ENOENT; - - mutex_lock(&gpio_aggregator_lock); - aggr = idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); - if (!aggr) { - module_put(THIS_MODULE); - return -ENOENT; - } - - gpio_aggregator_free(aggr); - module_put(THIS_MODULE); - return count; -} -static DRIVER_ATTR_WO(delete_device); - -static struct attribute *gpio_aggregator_attrs[] = { - &driver_attr_new_device.attr, - &driver_attr_delete_device.attr, - NULL -}; -ATTRIBUTE_GROUPS(gpio_aggregator); - -static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) -{ - gpio_aggregator_free(p); - return 0; -} - -static void __exit gpio_aggregator_remove_all(void) -{ - mutex_lock(&gpio_aggregator_lock); - idr_for_each(&gpio_aggregator_idr, gpio_aggregator_idr_remove, NULL); - idr_destroy(&gpio_aggregator_idr); - mutex_unlock(&gpio_aggregator_lock); -} - /* * GPIO Forwarder @@ -573,6 +385,184 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, } +/* + * Sysfs interface + */ +static int aggr_parse(struct gpio_aggregator *aggr) +{ + char *args = skip_spaces(aggr->args); + char *name, *offsets, *p; + unsigned int i, n = 0; + int error = 0; + + unsigned long *bitmap __free(bitmap) = + bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + args = next_arg(args, &name, &p); + while (*args) { + args = next_arg(args, &offsets, &p); + + p = get_options(offsets, 0, &error); + if (error == 0 || *p) { + /* Named GPIO line */ + error = aggr_add_gpio(aggr, name, U16_MAX, &n); + if (error) + return error; + + name = offsets; + continue; + } + + /* GPIO chip + offset(s) */ + error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); + if (error) { + pr_err("Cannot parse %s: %d\n", offsets, error); + return error; + } + + for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { + error = aggr_add_gpio(aggr, name, i, &n); + if (error) + return error; + } + + args = next_arg(args, &name, &p); + } + + if (!n) { + pr_err("No GPIOs specified\n"); + return -EINVAL; + } + + return 0; +} + +static ssize_t new_device_store(struct device_driver *driver, const char *buf, + size_t count) +{ + struct gpio_aggregator *aggr; + struct platform_device *pdev; + int res, id; + + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + + /* kernfs guarantees string termination, so count + 1 is safe */ + aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); + if (!aggr) { + res = -ENOMEM; + goto put_module; + } + + memcpy(aggr->args, buf, count + 1); + + aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), + GFP_KERNEL); + if (!aggr->lookups) { + res = -ENOMEM; + goto free_ga; + } + + mutex_lock(&gpio_aggregator_lock); + id = idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); + mutex_unlock(&gpio_aggregator_lock); + + if (id < 0) { + res = id; + goto free_table; + } + + aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); + if (!aggr->lookups->dev_id) { + res = -ENOMEM; + goto remove_idr; + } + + res = aggr_parse(aggr); + if (res) + goto free_dev_id; + + gpiod_add_lookup_table(aggr->lookups); + + pdev = platform_device_register_simple(DRV_NAME, id, NULL, 0); + if (IS_ERR(pdev)) { + res = PTR_ERR(pdev); + goto remove_table; + } + + aggr->pdev = pdev; + module_put(THIS_MODULE); + return count; + +remove_table: + gpiod_remove_lookup_table(aggr->lookups); +free_dev_id: + kfree(aggr->lookups->dev_id); +remove_idr: + mutex_lock(&gpio_aggregator_lock); + idr_remove(&gpio_aggregator_idr, id); + mutex_unlock(&gpio_aggregator_lock); +free_table: + kfree(aggr->lookups); +free_ga: + kfree(aggr); +put_module: + module_put(THIS_MODULE); + return res; +} + +static DRIVER_ATTR_WO(new_device); + +static void gpio_aggregator_free(struct gpio_aggregator *aggr) +{ + platform_device_unregister(aggr->pdev); + gpiod_remove_lookup_table(aggr->lookups); + kfree(aggr->lookups->dev_id); + kfree(aggr->lookups); + kfree(aggr); +} + +static ssize_t delete_device_store(struct device_driver *driver, + const char *buf, size_t count) +{ + struct gpio_aggregator *aggr; + unsigned int id; + int error; + + if (!str_has_prefix(buf, DRV_NAME ".")) + return -EINVAL; + + error = kstrtouint(buf + strlen(DRV_NAME "."), 10, &id); + if (error) + return error; + + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + + mutex_lock(&gpio_aggregator_lock); + aggr = idr_remove(&gpio_aggregator_idr, id); + mutex_unlock(&gpio_aggregator_lock); + if (!aggr) { + module_put(THIS_MODULE); + return -ENOENT; + } + + gpio_aggregator_free(aggr); + module_put(THIS_MODULE); + return count; +} +static DRIVER_ATTR_WO(delete_device); + +static struct attribute *gpio_aggregator_attrs[] = { + &driver_attr_new_device.attr, + &driver_attr_delete_device.attr, + NULL +}; +ATTRIBUTE_GROUPS(gpio_aggregator); + + /* * GPIO Aggregator platform device */ @@ -630,6 +620,20 @@ static struct platform_driver gpio_aggregator_driver = { }, }; +static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) +{ + gpio_aggregator_free(p); + return 0; +} + +static void __exit gpio_aggregator_remove_all(void) +{ + mutex_lock(&gpio_aggregator_lock); + idr_for_each(&gpio_aggregator_idr, gpio_aggregator_idr_remove, NULL); + idr_destroy(&gpio_aggregator_idr); + mutex_unlock(&gpio_aggregator_lock); +} + static int __init gpio_aggregator_init(void) { return platform_driver_register(&gpio_aggregator_driver); From patchwork Tue Apr 15 06:13:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072662 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQT497fz1yJ9 for ; Tue, 15 Apr 2025 16:14:41 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZN-0004Vx-K7; Tue, 15 Apr 2025 06:14:53 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZL-0004Nq-1u for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:51 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id BF1A43F1E4 for ; Tue, 15 Apr 2025 06:14:50 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-736c0306242so6322095b3a.1 for ; Mon, 14 Apr 2025 23:14:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697689; x=1745302489; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tV2PFa98tVyrVVP+npSmDplUBtTKAnGTyIxrNUDrPw0=; b=F8Ma5Z6uDGFrP8GJQ6WjAylYb5bNwojdYI0IQ+3Vb9/PzfJ59Jmbam85f7GSWsQux+ R+IHOtEWTMEn4/4dSjW2efHR+bkjra+r/USDvPIN2DUdqkYnpz6ShBsyD/wVP7ulgaJU BT+HmM2AoifkAypLCWDw29meikPVM1ULeGQHYaFpKGHIlrycf9Zotx/OXN/X5FLnfZxA 3PaBQsfzKTSmldohrmaTy7I4XmSyrAAf23OvdVi3WcMvgUsmEfAoTqyOZyj20D3fwLpH tOCDj8t87VEVAV2gVsORV5ADTshTEuSPTX5V77J3udyWrv+8dEdwlHkLaSYFSwzZ2rgq FNaw== X-Gm-Message-State: AOJu0YxmXvRqfjvPE2obk8iw44wE5Q07KclLP81CEHAAqqT+FRwzcDGf bY224noLZY93AdAfIffnWhvbsKdWRbR4uzSXYhI28No59bc4T2Mwcjv3in46hVtMmg0eA8A/v/p vj7Y8KMTZyI18daOeGXgkYPLwaP0+ZVTd6iVQzDWbiabMXyfzEsBYWw/a+NfGEcpkoD3EUktbS3 i2QUXFZVev0w== X-Gm-Gg: ASbGncv3D5MBwrAOSLaKJcHlI7bw03khzrgVKlRxuuhxNGjLLJGR4hY3nUkC9MxxY2G Uy1dZHN5djnxb8ZhkKOXCGmN7S/9P20NUHTPSDzdt+QXc+qGMcj58E1AjU0gEt3ID61KIv5Q3pk mA39irOhrx0eXbSOwM5vrq8KGKTqb90r492v1qKuQg3pIO4/kbKqF7KfnRlhwGgAIavpooRm9AF 4HJdRjkRou+jSoFpxb+ROJJG33Agxo17SVzAVLNy0KGMaz4UMC99GVI9yVJ/aufXHz4IhewLRek KBUmP3aFRTV9IX3TrjMIB1T2YlWGiw== X-Received: by 2002:a05:6a00:1908:b0:737:e73:f64b with SMTP id d2e1a72fcca58-73bd119460emr18068966b3a.1.1744697689148; Mon, 14 Apr 2025 23:14:49 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF743NZllJwmEy5uuB/8dhKQMZ5bkO0eLyE5SwMOocK0bdi0ZYmCGBnqDdotRida+m5k38Hog== X-Received: by 2002:a05:6a00:1908:b0:737:e73:f64b with SMTP id d2e1a72fcca58-73bd119460emr18068949b3a.1.1744697688651; Mon, 14 Apr 2025 23:14:48 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:48 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 05/19] gpio: aggregator: unify function naming Date: Tue, 15 Apr 2025 15:13:31 +0900 Message-ID: <4cdce3d7145899ca5b80fdc56c4f7180e2d68e65.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Unify function names to use gpio_aggregator_ prefix (except GPIO forwarder implementations, which remain unchanged in subsequent commits). While at it, rename the pre-existing gpio_aggregator_free() to gpio_aggregator_destory(), since that name will be used by new alloc/free functions introduced in the next commit, for which the name is more appropriate. No functional change. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-3-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 7616dd97ae22e5f69b24774455673d183d4191c9 linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 37 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 893cd56de867..92cb18830d42 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -42,8 +42,8 @@ struct gpio_aggregator { static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); -static int aggr_add_gpio(struct gpio_aggregator *aggr, const char *key, - int hwnum, unsigned int *n) +static int gpio_aggregator_add_gpio(struct gpio_aggregator *aggr, + const char *key, int hwnum, unsigned int *n) { struct gpiod_lookup_table *lookups; @@ -388,7 +388,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, /* * Sysfs interface */ -static int aggr_parse(struct gpio_aggregator *aggr) +static int gpio_aggregator_parse(struct gpio_aggregator *aggr) { char *args = skip_spaces(aggr->args); char *name, *offsets, *p; @@ -407,7 +407,7 @@ static int aggr_parse(struct gpio_aggregator *aggr) p = get_options(offsets, 0, &error); if (error == 0 || *p) { /* Named GPIO line */ - error = aggr_add_gpio(aggr, name, U16_MAX, &n); + error = gpio_aggregator_add_gpio(aggr, name, U16_MAX, &n); if (error) return error; @@ -423,7 +423,7 @@ static int aggr_parse(struct gpio_aggregator *aggr) } for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error = aggr_add_gpio(aggr, name, i, &n); + error = gpio_aggregator_add_gpio(aggr, name, i, &n); if (error) return error; } @@ -439,8 +439,8 @@ static int aggr_parse(struct gpio_aggregator *aggr) return 0; } -static ssize_t new_device_store(struct device_driver *driver, const char *buf, - size_t count) +static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, + const char *buf, size_t count) { struct gpio_aggregator *aggr; struct platform_device *pdev; @@ -480,7 +480,7 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, goto remove_idr; } - res = aggr_parse(aggr); + res = gpio_aggregator_parse(aggr); if (res) goto free_dev_id; @@ -513,9 +513,10 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf, return res; } -static DRIVER_ATTR_WO(new_device); +static struct driver_attribute driver_attr_gpio_aggregator_new_device = + __ATTR(new_device, 0200, NULL, gpio_aggregator_new_device_store); -static void gpio_aggregator_free(struct gpio_aggregator *aggr) +static void gpio_aggregator_destroy(struct gpio_aggregator *aggr) { platform_device_unregister(aggr->pdev); gpiod_remove_lookup_table(aggr->lookups); @@ -524,8 +525,8 @@ static void gpio_aggregator_free(struct gpio_aggregator *aggr) kfree(aggr); } -static ssize_t delete_device_store(struct device_driver *driver, - const char *buf, size_t count) +static ssize_t gpio_aggregator_delete_device_store(struct device_driver *driver, + const char *buf, size_t count) { struct gpio_aggregator *aggr; unsigned int id; @@ -549,15 +550,17 @@ static ssize_t delete_device_store(struct device_driver *driver, return -ENOENT; } - gpio_aggregator_free(aggr); + gpio_aggregator_destroy(aggr); module_put(THIS_MODULE); return count; } -static DRIVER_ATTR_WO(delete_device); + +static struct driver_attribute driver_attr_gpio_aggregator_delete_device = + __ATTR(delete_device, 0200, NULL, gpio_aggregator_delete_device_store); static struct attribute *gpio_aggregator_attrs[] = { - &driver_attr_new_device.attr, - &driver_attr_delete_device.attr, + &driver_attr_gpio_aggregator_new_device.attr, + &driver_attr_gpio_aggregator_delete_device.attr, NULL }; ATTRIBUTE_GROUPS(gpio_aggregator); @@ -622,7 +625,7 @@ static struct platform_driver gpio_aggregator_driver = { static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) { - gpio_aggregator_free(p); + gpio_aggregator_destroy(p); return 0; } From patchwork Tue Apr 15 06:13:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072663 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQW5KYzz1yJ9 for ; Tue, 15 Apr 2025 16:14:43 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZQ-0004hB-Ar; Tue, 15 Apr 2025 06:14:56 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZM-0004SL-Jx for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:52 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 4A02B3F1E4 for ; Tue, 15 Apr 2025 06:14:52 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-73720b253fcso3919449b3a.2 for ; Mon, 14 Apr 2025 23:14:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697691; x=1745302491; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EjT+z9DhbLon52nrw+r9YMwREsiKYQZHkZRglAKRCQI=; b=YRI8QhCBhNwStaAaWfsmCLlkVSE476tsyxNIKi7zNTAPAnSZQjn82p8to/C9kMzO2k 9H8dAcX5fU+FVoflLkSgad3IUViIkkCA6iBcY9g51i8R0FlbibERFk/SrSYip6AauY+P rMTwif/QIRLAzZXDjol0g1ZxjbOvLLvpvtu+DY5Mlw81s9Cukj3oUOJcm/ZiWnHsfpoo LHpkH/4AYtp1i7aNihAkNtRKS5ML6+KE5wYz55tCgS/uQHBi6kKyd7UnqY2DviBwuBvd p4iwlKdY7r3DjdSzX3etuQ01OfhBOOAANAnweH6KH/QYaiyppuwOE9+WsoeGskg+21qq 1cng== X-Gm-Message-State: AOJu0Ywy5cWUw2WJXgTEgBby/O6BywFSb+vvuc7ZvccHvPj1UgXrT8xi kas6JAFwq6GEqAkhWFZ8f0iMaAKD/3RAnadxFQi9wFEkFDk/zDznYQxkTkN8dlmgAHclo1zOgtQ BlEg0ZDV+l6tmL0ZeLhdzgvCKHZtCmFpWb/NONEpN5D8qw6NVutxbFkiaHTcvG0AyMSxrcy3DWK qIV2Uadga7og== X-Gm-Gg: ASbGnct1ACpTKIvoUdG66QJz6jEKqMzkcnRnc9LFsu/+IutXBsbdmtZkbTxPDoaDAI6 pQ85gtDqnznUYkYKMDiO8QKMnqRak+KPqw4x5h3aQh1Zft0PAarUBL0++BerDkiY+2GC88+/2bf IgsA0+5tBUsKiiNKyu5+Xiw6MPF67+311gF5ZmvrHHjFVO3hMGQptHqmQdFAtNnjio6le1abZkb rRYG13IcVORm1z/4C8H0dnqXhubDoXFOdXQ1MXoZpnXcnzq4lrW0aH8yg8EoclLzUQ5aCoC1eLS mgV80qC1QhXfRtu1nrEkPq2i8v1PYA== X-Received: by 2002:a05:6a00:2351:b0:732:5164:3cc with SMTP id d2e1a72fcca58-73bd126583dmr20990790b3a.19.1744697690785; Mon, 14 Apr 2025 23:14:50 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGGAZ5wHxDgVcu3Rbjlz/CVdh9/KjFYqK5GbAp+jsCPIMKxYgLM/stk0o64EWZ1Mawsh/resQ== X-Received: by 2002:a05:6a00:2351:b0:732:5164:3cc with SMTP id d2e1a72fcca58-73bd126583dmr20990761b3a.19.1744697690377; Mon, 14 Apr 2025 23:14:50 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:49 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 06/19] gpio: aggregator: add gpio_aggregator_{alloc, free}() Date: Tue, 15 Apr 2025 15:13:32 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Prepare for the upcoming configfs interface. These functions will be used by both the existing sysfs interface and the new configfs interface, reducing code duplication. No functional change. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-4-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 88fe1d1a646b3b01dcc335c44e7b33ea510f620e linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 58 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 92cb18830d42..f34581a76b06 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -36,12 +36,41 @@ struct gpio_aggregator { struct gpiod_lookup_table *lookups; struct platform_device *pdev; + int id; char args[]; }; static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); +static int gpio_aggregator_alloc(struct gpio_aggregator **aggr, size_t arg_size) +{ + int ret; + + struct gpio_aggregator *new __free(kfree) = kzalloc( + sizeof(*new) + arg_size, GFP_KERNEL); + if (!new) + return -ENOMEM; + + scoped_guard(mutex, &gpio_aggregator_lock) + ret = idr_alloc(&gpio_aggregator_idr, new, 0, 0, GFP_KERNEL); + + if (ret < 0) + return ret; + + new->id = ret; + *aggr = no_free_ptr(new); + return 0; +} + +static void gpio_aggregator_free(struct gpio_aggregator *aggr) +{ + scoped_guard(mutex, &gpio_aggregator_lock) + idr_remove(&gpio_aggregator_idr, aggr->id); + + kfree(aggr); +} + static int gpio_aggregator_add_gpio(struct gpio_aggregator *aggr, const char *key, int hwnum, unsigned int *n) { @@ -444,17 +473,15 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, { struct gpio_aggregator *aggr; struct platform_device *pdev; - int res, id; + int res; if (!try_module_get(THIS_MODULE)) return -ENOENT; /* kernfs guarantees string termination, so count + 1 is safe */ - aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) { - res = -ENOMEM; + res = gpio_aggregator_alloc(&aggr, count + 1); + if (res) goto put_module; - } memcpy(aggr->args, buf, count + 1); @@ -465,19 +492,10 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, goto free_ga; } - mutex_lock(&gpio_aggregator_lock); - id = idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); - mutex_unlock(&gpio_aggregator_lock); - - if (id < 0) { - res = id; - goto free_table; - } - - aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); + aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->id); if (!aggr->lookups->dev_id) { res = -ENOMEM; - goto remove_idr; + goto free_table; } res = gpio_aggregator_parse(aggr); @@ -486,7 +504,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, id, NULL, 0); + pdev = platform_device_register_simple(DRV_NAME, aggr->id, NULL, 0); if (IS_ERR(pdev)) { res = PTR_ERR(pdev); goto remove_table; @@ -500,14 +518,10 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, gpiod_remove_lookup_table(aggr->lookups); free_dev_id: kfree(aggr->lookups->dev_id); -remove_idr: - mutex_lock(&gpio_aggregator_lock); - idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); free_table: kfree(aggr->lookups); free_ga: - kfree(aggr); + gpio_aggregator_free(aggr); put_module: module_put(THIS_MODULE); return res; From patchwork Tue Apr 15 06:13:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072664 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQY1Wgvz1yJ9 for ; Tue, 15 Apr 2025 16:14:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZQ-0004iJ-Ko; Tue, 15 Apr 2025 06:14:56 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZP-0004dD-Ep for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:55 +0000 Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id C1F623F091 for ; Tue, 15 Apr 2025 06:14:54 +0000 (UTC) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2240a960f9cso47201995ad.0 for ; Mon, 14 Apr 2025 23:14:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697693; x=1745302493; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pdY0YyClgf+x1DfmCoSURwe78TDo+PWav0t27CbFiz8=; b=azygwQfbWmaSB39I5UZ1PK006Rn2z26igPBewdQFdMCmjKbi9V0awHxfHw3q5f2M5y 0dBHzyFy9uNpt0a95M5kH+IWJ8WI82bGHnA/fzBXLGYZN2Eofh9QjQttqc4ZBsyOabdN lWsDj7X0mzuJaoDGdTMMuU7GloIKb5qHlR20OTMuppKNr/VS1T61smdmg8lMaLIlpDcP +xQGVLbob3mWJJYz9+zdUnZEwlLbQnb2+WCY/qsxwbrQVveJQq1enR9GWHXjHsqdx3w6 4iyy79DE+Y2UWtOR8VISD4H7ighhz/k6W8RNsJ5cpy8qxxnb2zmecSkGUeK4Bxo1aI6W Rt5A== X-Gm-Message-State: AOJu0YyoCRN6D2fB23idkaQ/JgtSRQfL7FxFpY3cCulZzxrDi+YhGgr0 VUnAp0fo7liM+7aiguZ7uLo4I2qxePpHTYdaerbXZYfH00vSNWQzmn71Tdhwo42fwdWdgpADyQK cRG7uiUXuZIsljydJ+DmUWtIMQdiMHi914WgpC6YkdWd4K4fhjn2+JQjJjW8JpaqB2mLVPQluF8 OIHSl7f9rHxg== X-Gm-Gg: ASbGnct0nY7MFmN6dzwYyCf5xSIcdJlbRG+GBAAM+lajjOGXycVwod/18j0ZOlgG+3a E4N94OZnAbMD+NdGEXkpPbTiC/63WMtFdhddj1fV+YTCg4ttnWNmolhh89/f+uzRyylGQMrgDIb 1lZR2514p36mtMTDj61I+y4/62Xe2b3SHvHMcvS0V1cPuY6rPy2Z9SqyIsJYHE6vlO2C33onHi2 jA0/i1rrkjWaSJl3Q/T5ZQN00KyJ6cPB7wRl3byuED4nhqgtd/EDJGUUPjZVIrF0XR+n4H6UelF JFiVqPBoPoYC6iUHdZWQuJIAZ3NdPA== X-Received: by 2002:a17:902:cec4:b0:224:e33:889b with SMTP id d9443c01a7336-22bea4ade03mr234546065ad.12.1744697692775; Mon, 14 Apr 2025 23:14:52 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGW3F5MsJQOYfauj122QY1ea29KyL03PRmQdtdbUge829kCpdBy+XCHwYojAYY387xLxfLC0Q== X-Received: by 2002:a17:902:cec4:b0:224:e33:889b with SMTP id d9443c01a7336-22bea4ade03mr234545465ad.12.1744697692017; Mon, 14 Apr 2025 23:14:52 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:51 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 07/19] gpio: aggregator: introduce basic configfs interface Date: Tue, 15 Apr 2025 15:13:33 +0900 Message-ID: <36ac58d66c776cb5beb7c9f2a80d2283c815daa3.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 The existing sysfs 'new_device' interface has several limitations: * No way to determine when GPIO aggregator creation is complete. * No way to retrieve errors when creating a GPIO aggregator. * No way to trace a GPIO line of an aggregator back to its corresponding physical device. * The 'new_device' echo does not indicate which virtual gpiochip was created. * No way to assign names to GPIO lines exported through an aggregator. Introduce the new configfs interface for gpio-aggregator to address these limitations. It provides a more streamlined, modern, and extensible configuration method. For backward compatibility, the 'new_device' interface and its behavior is retained for now. This commit implements basic functionalities: /config/gpio-aggregator// /config/gpio-aggregator//live /config/gpio-aggregator//dev_name /config/gpio-aggregator/// /config/gpio-aggregator///key /config/gpio-aggregator///offset /config/gpio-aggregator///name Basic setup flow is: 1. Create a directory for a GPIO aggregator. 2. Create subdirectories for each line you want to instantiate. 3. In each line directory, configure the key and offset. The key/offset semantics are as follows: * If offset is >= 0: - key specifies the name of the chip this GPIO belongs to - offset specifies the line offset within that chip. * If offset is <0: - key needs to specify the GPIO line name. 4. Return to the aggregator's root directory and write '1' to the live attribute. For example, the command in the existing kernel doc: echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device is equivalent to: mkdir /sys/kernel/config/gpio-aggregator/ # Change to name of your choice (e.g. "aggr0") cd /sys/kernel/config/gpio-aggregator/ mkdir line0 line1 line2 # Only "line" naming allowed. echo e6052000.gpio > line0/key echo 19 > line0/offset echo e6050000.gpio > line1/key echo 20 > line1/offset echo e6050000.gpio > line2/key echo 21 > line2/offset echo 1 > live The corresponding gpio_device id can be identified as follows: cd /sys/kernel/config/gpio-aggregator/ ls -d /sys/devices/platform/`cat dev_name`/gpiochip* Also, via configfs, custom GPIO line name can be set like this: cd /sys/kernel/config/gpio-aggregator/ echo "abc" > line1/name Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-5-koichiro.den@canonical.com [Bartosz: remove stray newlines] Signed-off-by: Bartosz Golaszewski (cherry picked from commit 86f162e73d2d81ef6d819c06a3b6c2fda77a79b8 linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 2 + drivers/gpio/gpio-aggregator.c | 637 ++++++++++++++++++++++++++++++++- 2 files changed, 626 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 21ac40bde9c4..f8682b580a22 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1855,6 +1855,8 @@ 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. diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index f34581a76b06..f492b7259ec5 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -9,10 +9,13 @@ #include #include +#include #include #include #include #include +#include +#include #include #include #include @@ -27,6 +30,8 @@ #include #include +#include "dev-sync-probe.h" + #define AGGREGATOR_MAX_GPIOS 512 /* @@ -34,12 +39,38 @@ */ struct gpio_aggregator { + struct dev_sync_probe_data probe_data; + struct config_group group; struct gpiod_lookup_table *lookups; - struct platform_device *pdev; + struct mutex lock; int id; + + /* List of gpio_aggregator_line. Always added in order */ + struct list_head list_head; + + /* used by legacy sysfs interface only */ + bool init_via_sysfs; char args[]; }; +struct gpio_aggregator_line { + struct config_group group; + struct gpio_aggregator *parent; + struct list_head entry; + + /* Line index within the aggregator device */ + unsigned int idx; + + /* Custom name for the virtual line */ + const char *name; + /* GPIO chip label or line name */ + const char *key; + /* Can be negative to indicate lookup by line name */ + int offset; + + enum gpio_lookup_flags flags; +}; + static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); @@ -59,6 +90,8 @@ static int gpio_aggregator_alloc(struct gpio_aggregator **aggr, size_t arg_size) return ret; new->id = ret; + INIT_LIST_HEAD(&new->list_head); + mutex_init(&new->lock); *aggr = no_free_ptr(new); return 0; } @@ -68,6 +101,7 @@ static void gpio_aggregator_free(struct gpio_aggregator *aggr) scoped_guard(mutex, &gpio_aggregator_lock) idr_remove(&gpio_aggregator_idr, aggr->id); + mutex_destroy(&aggr->lock); kfree(aggr); } @@ -90,6 +124,71 @@ static int gpio_aggregator_add_gpio(struct gpio_aggregator *aggr, return 0; } +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); +} + +static size_t gpio_aggregator_count_lines(struct gpio_aggregator *aggr) +{ + lockdep_assert_held(&aggr->lock); + + return list_count_nodes(&aggr->list_head); +} + +static struct gpio_aggregator_line * +gpio_aggregator_line_alloc(struct gpio_aggregator *parent, unsigned int idx, + char *key, int offset) +{ + struct gpio_aggregator_line *line; + + line = kzalloc(sizeof(*line), GFP_KERNEL); + if (!line) + return ERR_PTR(-ENOMEM); + + if (key) { + line->key = kstrdup(key, GFP_KERNEL); + if (!line->key) { + kfree(line); + return ERR_PTR(-ENOMEM); + } + } + + line->flags = GPIO_LOOKUP_FLAGS_DEFAULT; + line->parent = parent; + line->idx = idx; + line->offset = offset; + INIT_LIST_HEAD(&line->entry); + + return line; +} + +static void gpio_aggregator_line_add(struct gpio_aggregator *aggr, + struct gpio_aggregator_line *line) +{ + struct gpio_aggregator_line *tmp; + + lockdep_assert_held(&aggr->lock); + + list_for_each_entry(tmp, &aggr->list_head, entry) { + if (tmp->idx > line->idx) { + list_add_tail(&line->entry, &tmp->entry); + return; + } + } + list_add_tail(&line->entry, &aggr->list_head); +} + +static void gpio_aggregator_line_del(struct gpio_aggregator *aggr, + struct gpio_aggregator_line *line) +{ + lockdep_assert_held(&aggr->lock); + + list_del(&line->entry); +} + /* * GPIO Forwarder @@ -413,6 +512,473 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, return fwd; } +/* + * Configfs interface + */ + +static struct gpio_aggregator * +to_gpio_aggregator(struct config_item *item) +{ + struct config_group *group = to_config_group(item); + + return container_of(group, struct gpio_aggregator, group); +} + +static struct gpio_aggregator_line * +to_gpio_aggregator_line(struct config_item *item) +{ + struct config_group *group = to_config_group(item); + + return container_of(group, struct gpio_aggregator_line, group); +} + +static struct fwnode_handle * +gpio_aggregator_make_device_sw_node(struct gpio_aggregator *aggr) +{ + struct property_entry properties[2]; + struct gpio_aggregator_line *line; + size_t num_lines; + int n = 0; + + memset(properties, 0, sizeof(properties)); + + num_lines = gpio_aggregator_count_lines(aggr); + if (num_lines == 0) + return NULL; + + const char **line_names __free(kfree) = kcalloc( + num_lines, sizeof(*line_names), GFP_KERNEL); + if (!line_names) + return ERR_PTR(-ENOMEM); + + /* The list is always sorted as new elements are inserted in order. */ + list_for_each_entry(line, &aggr->list_head, entry) + line_names[n++] = line->name ?: ""; + + properties[0] = PROPERTY_ENTRY_STRING_ARRAY_LEN( + "gpio-line-names", + line_names, num_lines); + + return fwnode_create_software_node(properties, NULL); +} + +static int gpio_aggregator_activate(struct gpio_aggregator *aggr) +{ + struct platform_device_info pdevinfo; + struct gpio_aggregator_line *line; + struct fwnode_handle *swnode; + unsigned int n = 0; + int ret = 0; + + if (gpio_aggregator_count_lines(aggr) == 0) + return -EINVAL; + + aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), + GFP_KERNEL); + if (!aggr->lookups) + return -ENOMEM; + + swnode = gpio_aggregator_make_device_sw_node(aggr); + if (IS_ERR(swnode)) + goto err_remove_lookups; + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.name = DRV_NAME; + pdevinfo.id = aggr->id; + pdevinfo.fwnode = swnode; + + /* The list is always sorted as new elements are inserted in order. */ + list_for_each_entry(line, &aggr->list_head, entry) { + /* + * - Either GPIO chip label or line name must be configured + * (i.e. line->key must be non-NULL) + * - Line directories must be named with sequential numeric + * suffixes starting from 0. (i.e. ./line0, ./line1, ...) + */ + if (!line->key || line->idx != n) { + ret = -EINVAL; + goto err_remove_swnode; + } + + if (line->offset < 0) + ret = gpio_aggregator_add_gpio(aggr, line->key, + U16_MAX, &n); + else + ret = gpio_aggregator_add_gpio(aggr, line->key, + line->offset, &n); + if (ret) + goto err_remove_swnode; + } + + aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->id); + if (!aggr->lookups->dev_id) { + ret = -ENOMEM; + goto err_remove_swnode; + } + + gpiod_add_lookup_table(aggr->lookups); + + ret = dev_sync_probe_register(&aggr->probe_data, &pdevinfo); + if (ret) + goto err_remove_lookup_table; + + return 0; + +err_remove_lookup_table: + kfree(aggr->lookups->dev_id); + gpiod_remove_lookup_table(aggr->lookups); +err_remove_swnode: + fwnode_remove_software_node(swnode); +err_remove_lookups: + kfree(aggr->lookups); + + return ret; +} + +static void gpio_aggregator_deactivate(struct gpio_aggregator *aggr) +{ + dev_sync_probe_unregister(&aggr->probe_data); + gpiod_remove_lookup_table(aggr->lookups); + kfree(aggr->lookups->dev_id); + kfree(aggr->lookups); +} + +static void gpio_aggregator_lockup_configfs(struct gpio_aggregator *aggr, + bool lock) +{ + struct configfs_subsystem *subsys = aggr->group.cg_subsys; + struct gpio_aggregator_line *line; + + /* + * The device only needs to depend on leaf lines. This is + * sufficient to lock up all the configfs entries that the + * instantiated, alive device depends on. + */ + list_for_each_entry(line, &aggr->list_head, entry) { + if (lock) + configfs_depend_item_unlocked( + subsys, &line->group.cg_item); + else + configfs_undepend_item_unlocked( + &line->group.cg_item); + } +} + +static ssize_t +gpio_aggregator_line_key_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + guard(mutex)(&aggr->lock); + + return sysfs_emit(page, "%s\n", line->key ?: ""); +} + +static ssize_t +gpio_aggregator_line_key_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + char *key __free(kfree) = kstrndup(skip_spaces(page), count, + GFP_KERNEL); + if (!key) + return -ENOMEM; + + strim(key); + + guard(mutex)(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) + return -EBUSY; + + kfree(line->key); + line->key = no_free_ptr(key); + + return count; +} +CONFIGFS_ATTR(gpio_aggregator_line_, key); + +static ssize_t +gpio_aggregator_line_name_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + guard(mutex)(&aggr->lock); + + return sysfs_emit(page, "%s\n", line->name ?: ""); +} + +static ssize_t +gpio_aggregator_line_name_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + char *name __free(kfree) = kstrndup(skip_spaces(page), count, + GFP_KERNEL); + if (!name) + return -ENOMEM; + + strim(name); + + guard(mutex)(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) + return -EBUSY; + + kfree(line->name); + line->name = no_free_ptr(name); + + return count; +} +CONFIGFS_ATTR(gpio_aggregator_line_, name); + +static ssize_t +gpio_aggregator_line_offset_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + guard(mutex)(&aggr->lock); + + return sysfs_emit(page, "%d\n", line->offset); +} + +static ssize_t +gpio_aggregator_line_offset_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + int offset, ret; + + ret = kstrtoint(page, 0, &offset); + if (ret) + return ret; + + /* + * When offset == -1, 'key' represents a line name to lookup. + * When 0 <= offset < 65535, 'key' represents the label of the chip with + * the 'offset' value representing the line within that chip. + * + * GPIOLIB uses the U16_MAX value to indicate lookup by line name so + * the greatest offset we can accept is (U16_MAX - 1). + */ + if (offset > (U16_MAX - 1) || offset < -1) + return -EINVAL; + + guard(mutex)(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) + return -EBUSY; + + line->offset = offset; + + return count; +} +CONFIGFS_ATTR(gpio_aggregator_line_, offset); + +static struct configfs_attribute *gpio_aggregator_line_attrs[] = { + &gpio_aggregator_line_attr_key, + &gpio_aggregator_line_attr_name, + &gpio_aggregator_line_attr_offset, + NULL +}; + +static ssize_t +gpio_aggregator_device_dev_name_show(struct config_item *item, char *page) +{ + struct gpio_aggregator *aggr = to_gpio_aggregator(item); + struct platform_device *pdev; + + guard(mutex)(&aggr->lock); + + pdev = aggr->probe_data.pdev; + if (pdev) + return sysfs_emit(page, "%s\n", dev_name(&pdev->dev)); + + return sysfs_emit(page, "%s.%d\n", DRV_NAME, aggr->id); +} +CONFIGFS_ATTR_RO(gpio_aggregator_device_, dev_name); + +static ssize_t +gpio_aggregator_device_live_show(struct config_item *item, char *page) +{ + struct gpio_aggregator *aggr = to_gpio_aggregator(item); + + guard(mutex)(&aggr->lock); + + return sysfs_emit(page, "%c\n", + gpio_aggregator_is_active(aggr) ? '1' : '0'); +} + +static ssize_t +gpio_aggregator_device_live_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator *aggr = to_gpio_aggregator(item); + int ret = 0; + bool live; + + ret = kstrtobool(page, &live); + if (ret) + return ret; + + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + + if (live) + gpio_aggregator_lockup_configfs(aggr, true); + + scoped_guard(mutex, &aggr->lock) { + if (live == gpio_aggregator_is_active(aggr)) + ret = -EPERM; + else if (live) + ret = gpio_aggregator_activate(aggr); + else + gpio_aggregator_deactivate(aggr); + } + + /* + * Undepend is required only if device disablement (live == 0) + * succeeds or if device enablement (live == 1) fails. + */ + if (live == !!ret) + gpio_aggregator_lockup_configfs(aggr, false); + + module_put(THIS_MODULE); + + return ret ?: count; +} +CONFIGFS_ATTR(gpio_aggregator_device_, live); + +static struct configfs_attribute *gpio_aggregator_device_attrs[] = { + &gpio_aggregator_device_attr_dev_name, + &gpio_aggregator_device_attr_live, + NULL +}; + +static void +gpio_aggregator_line_release(struct config_item *item) +{ + struct gpio_aggregator_line *line = to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr = line->parent; + + guard(mutex)(&aggr->lock); + + gpio_aggregator_line_del(aggr, line); + kfree(line->key); + kfree(line->name); + kfree(line); +} + +static struct configfs_item_operations gpio_aggregator_line_item_ops = { + .release = gpio_aggregator_line_release, +}; + +static const struct config_item_type gpio_aggregator_line_type = { + .ct_item_ops = &gpio_aggregator_line_item_ops, + .ct_attrs = gpio_aggregator_line_attrs, + .ct_owner = THIS_MODULE, +}; + +static void gpio_aggregator_device_release(struct config_item *item) +{ + struct gpio_aggregator *aggr = to_gpio_aggregator(item); + + /* + * If the aggregator is active, this code wouldn't be reached, + * so calling gpio_aggregator_deactivate() is always unnecessary. + */ + gpio_aggregator_free(aggr); +} + +static struct configfs_item_operations gpio_aggregator_device_item_ops = { + .release = gpio_aggregator_device_release, +}; + +static struct config_group * +gpio_aggregator_device_make_group(struct config_group *group, const char *name) +{ + struct gpio_aggregator *aggr = to_gpio_aggregator(&group->cg_item); + struct gpio_aggregator_line *line; + unsigned int idx; + int ret, nchar; + + ret = sscanf(name, "line%u%n", &idx, &nchar); + if (ret != 1 || nchar != strlen(name)) + return ERR_PTR(-EINVAL); + + guard(mutex)(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) + return ERR_PTR(-EBUSY); + + list_for_each_entry(line, &aggr->list_head, entry) + if (line->idx == idx) + return ERR_PTR(-EINVAL); + + line = gpio_aggregator_line_alloc(aggr, idx, NULL, -1); + if (!line) + return ERR_PTR(-ENOMEM); + + config_group_init_type_name(&line->group, name, &gpio_aggregator_line_type); + + gpio_aggregator_line_add(aggr, line); + + return &line->group; +} + +static struct configfs_group_operations gpio_aggregator_device_group_ops = { + .make_group = gpio_aggregator_device_make_group, +}; + +static const struct config_item_type gpio_aggregator_device_type = { + .ct_group_ops = &gpio_aggregator_device_group_ops, + .ct_item_ops = &gpio_aggregator_device_item_ops, + .ct_attrs = gpio_aggregator_device_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct config_group * +gpio_aggregator_make_group(struct config_group *group, const char *name) +{ + struct gpio_aggregator *aggr; + int ret; + + /* arg space is unneeded */ + ret = gpio_aggregator_alloc(&aggr, 0); + if (ret) + 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; +} + +static struct configfs_group_operations gpio_aggregator_group_ops = { + .make_group = gpio_aggregator_make_group, +}; + +static const struct config_item_type gpio_aggregator_type = { + .ct_group_ops = &gpio_aggregator_group_ops, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem gpio_aggregator_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = DRV_NAME, + .ci_type = &gpio_aggregator_type, + }, + }, +}; /* * Sysfs interface @@ -485,6 +1051,7 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, memcpy(aggr->args, buf, count + 1); + aggr->init_via_sysfs = true; aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), GFP_KERNEL); if (!aggr->lookups) { @@ -510,7 +1077,7 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, goto remove_table; } - aggr->pdev = pdev; + aggr->probe_data.pdev = pdev; module_put(THIS_MODULE); return count; @@ -532,10 +1099,7 @@ static struct driver_attribute driver_attr_gpio_aggregator_new_device = static void gpio_aggregator_destroy(struct gpio_aggregator *aggr) { - platform_device_unregister(aggr->pdev); - gpiod_remove_lookup_table(aggr->lookups); - kfree(aggr->lookups->dev_id); - kfree(aggr->lookups); + gpio_aggregator_deactivate(aggr); kfree(aggr); } @@ -557,12 +1121,19 @@ static ssize_t gpio_aggregator_delete_device_store(struct device_driver *driver, return -ENOENT; mutex_lock(&gpio_aggregator_lock); - aggr = idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); - if (!aggr) { + aggr = idr_find(&gpio_aggregator_idr, id); + /* + * For simplicity, devices created via configfs cannot be deleted + * via sysfs. + */ + if (aggr && aggr->init_via_sysfs) + idr_remove(&gpio_aggregator_idr, id); + else { + mutex_unlock(&gpio_aggregator_lock); module_put(THIS_MODULE); return -ENOENT; } + mutex_unlock(&gpio_aggregator_lock); gpio_aggregator_destroy(aggr); module_put(THIS_MODULE); @@ -579,7 +1150,6 @@ static struct attribute *gpio_aggregator_attrs[] = { }; ATTRIBUTE_GROUPS(gpio_aggregator); - /* * GPIO Aggregator platform device */ @@ -639,21 +1209,61 @@ static struct platform_driver gpio_aggregator_driver = { static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) { + /* + * There should be no aggregator created via configfs, as their + * presence would prevent module unloading. + */ gpio_aggregator_destroy(p); return 0; } static void __exit gpio_aggregator_remove_all(void) { - mutex_lock(&gpio_aggregator_lock); + /* + * Configfs callbacks acquire gpio_aggregator_lock when accessing + * gpio_aggregator_idr, so to prevent lock inversion deadlock, we + * cannot protect idr_for_each invocation here with + * gpio_aggregator_lock, as gpio_aggregator_idr_remove() accesses + * configfs groups. Fortunately, the new_device/delete_device path + * and the module unload path are mutually exclusive, thanks to an + * explicit try_module_get inside of those driver attr handlers. + * Also, when we reach here, no configfs entries present or being + * created. Therefore, no need to protect with gpio_aggregator_lock + * below. + */ idr_for_each(&gpio_aggregator_idr, gpio_aggregator_idr_remove, NULL); idr_destroy(&gpio_aggregator_idr); - mutex_unlock(&gpio_aggregator_lock); } static int __init gpio_aggregator_init(void) { - return platform_driver_register(&gpio_aggregator_driver); + int ret = 0; + + config_group_init(&gpio_aggregator_subsys.su_group); + mutex_init(&gpio_aggregator_subsys.su_mutex); + ret = configfs_register_subsystem(&gpio_aggregator_subsys); + if (ret) { + pr_err("Failed to register the '%s' configfs subsystem: %d\n", + gpio_aggregator_subsys.su_group.cg_item.ci_namebuf, ret); + mutex_destroy(&gpio_aggregator_subsys.su_mutex); + return ret; + } + + /* + * CAVEAT: This must occur after configfs registration. Otherwise, + * a race condition could arise: driver attribute groups might be + * exposed and accessed by users before configfs registration + * completes. new_device_store() does not expect a partially + * initialized configfs state. + */ + ret = platform_driver_register(&gpio_aggregator_driver); + if (ret) { + pr_err("Failed to register the platform driver: %d\n", ret); + mutex_destroy(&gpio_aggregator_subsys.su_mutex); + configfs_unregister_subsystem(&gpio_aggregator_subsys); + } + + return ret; } module_init(gpio_aggregator_init); @@ -661,6 +1271,7 @@ static void __exit gpio_aggregator_exit(void) { gpio_aggregator_remove_all(); platform_driver_unregister(&gpio_aggregator_driver); + configfs_unregister_subsystem(&gpio_aggregator_subsys); } module_exit(gpio_aggregator_exit); From patchwork Tue Apr 15 06:13:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQY6PzLz1yMl for ; Tue, 15 Apr 2025 16:14:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZS-0004mR-0G; Tue, 15 Apr 2025 06:14:58 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZP-0004eZ-Lf for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:55 +0000 Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 6FA6C3F1E4 for ; Tue, 15 Apr 2025 06:14:55 +0000 (UTC) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-af9564001cbso3443300a12.3 for ; Mon, 14 Apr 2025 23:14:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697694; x=1745302494; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gYt1RG+kTh3F+xrckj6T4AuQ9DrghbrrtWm3G+eIz1w=; b=w5SBQaxVvnWxUXDUtk+yqyEqzamd2GLfIzmVTxY5DaQ16fRYqUoqi3175RU75OkKet bZZMzpj8wrr+Kqi+dLqBp1eDXc84BYh5PepCHGoIdnLBEirmmYuU/sq3UXAHD7VQh+JK +IiR7RwEKcMnj5L9pLhxcnLxVOH+fMxkkk6gk3MG57uLJ1hseAlLZYtenpc/w10gReHp ALhRSSPUE3S+fTdJxR5R6naFKkvUo4Lx2N/HToGZMoUaWJSQ9GI9zvfLC8pfPaowUoip fJtIqn1jFXtc9YlYRb2RbZiaTfyXGQsQgf1yCVMslrWribQqf6CxN4S6OXBdsD4TAR6x W70g== X-Gm-Message-State: AOJu0YyhMzUmDvRjb9z45JEnUVgt3uzjJ1ih8cNqBrhqBG+eIheVj+sv WmOK3Y+z/00xCmWJeuD09VsUplHAPFTMD7ZNGAM+MNx2UZsBkzQXSEczwcFl6gjDdMoBk6SOYs0 CJRdY2pKErDa/10TzKON3sVJBqMgHsgQV6+/mC8mkFFCYLt5GY5tFXDR+AQP2qCASk0prVCshGQ MW4H07otJWcQ== X-Gm-Gg: ASbGncvvdh/088d9zPleuLvOXi/xRUXIkovx5zEfJ59+9UC/syT6MJMDzwCd59FMcJz 8A4vbOTFTaLeEiPC3bPBesLmVNDLbUIOAEawQXtk+vrgtYf1T3aQFipxYPKe9JUhLpEek2sQFj0 NespzloHdeQjIGVjRXi6HxH214sX+P/mR/Lawm2X6Sy+A3xQ2jSenD2tgaJtNaPLoOv7/XW5VNR dzgP+A9FFSq3oKLsxNvsRpu6ov+iiXX9cYhRFIF4jTK3YTXTl6kbacfSUmH+nkCDjW2diKC+YsX mI4EZWhH3zOvppJt6IvgS7asKSxorw== X-Received: by 2002:a17:903:1447:b0:223:5c33:56a2 with SMTP id d9443c01a7336-22bea4bd57fmr250789875ad.28.1744697693952; Mon, 14 Apr 2025 23:14:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEQzIazQMqDw9wBhF5EFheqgO2uY8yZ1Sy20z+PC1y484159JVVGaDOaqytpHbDfrJSzpSsaQ== X-Received: by 2002:a17:903:1447:b0:223:5c33:56a2 with SMTP id d9443c01a7336-22bea4bd57fmr250789555ad.28.1744697693530; Mon, 14 Apr 2025 23:14:53 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:53 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 08/19] UBUNTU: [Config] updateconfigs for DEV_SYNC_PROBE Date: Tue, 15 Apr 2025 15:13:34 +0900 Message-ID: <9bf4bb36a3a5a227a31398f3ccae1b57b53adc9d.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Signed-off-by: Koichiro Den --- debian.master/config/annotations | 1 + 1 file changed, 1 insertion(+) diff --git a/debian.master/config/annotations b/debian.master/config/annotations index c134dd85a7f8..ef8a398a62e3 100644 --- a/debian.master/config/annotations +++ b/debian.master/config/annotations @@ -3995,6 +3995,7 @@ CONFIG_DEV_DAX_HMEM policy<{'amd64': 'm', 'arm64': ' CONFIG_DEV_DAX_HMEM_DEVICES policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}> CONFIG_DEV_DAX_KMEM policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_DEV_DAX_PMEM policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_DEV_SYNC_PROBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_DHT11 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_DIAG288_WATCHDOG policy<{'s390x': 'm'}> CONFIG_DIMLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> From patchwork Tue Apr 15 06:13:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072666 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQZ3fwrz1yJ9 for ; Tue, 15 Apr 2025 16:14:46 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZS-0004q3-9s; Tue, 15 Apr 2025 06:14:58 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZR-0004jl-2d for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:57 +0000 Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id E201B3F1E4 for ; Tue, 15 Apr 2025 06:14:56 +0000 (UTC) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-739071bdf2eso3577267b3a.2 for ; Mon, 14 Apr 2025 23:14:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697695; x=1745302495; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9ibUL46XsePE9Hd3Oo4uyW5f2muyPr3RQ83B9Vp9zG8=; b=xCddQ2LRSVWV5lzK+/0zWdeU/FtJ3znP137mHofUkfCy8JTvagXqjsWHNVuMQV6xxa IoetCcSOV4BURT82qd5DKpAQfjjZEIPrYZNu9LGF0qrXrj5nICqKmOIMRap5kjIUF0LP 5qGBeNeBaWmKzViofMbKqUa9Ray3OS0shTw2cV+IzqO/+EMsbxbj6ZwLGLyDiH39fDVY mxy41IW8c+B5PvJkAhJbcg+Fq6E7sVIKEQsLDG0dL3LvIEkiBYClBUQTpdJ8sHsm2byJ r4j9JaTH+KxldH3K1ubb4OPWY2nXHyRTeXCKsfcXngB27c334K7Ls7bFn6WkmoQampDk Qtrw== X-Gm-Message-State: AOJu0Yy7seqNeaMG55LdNS1nd5HxjVFlStb8e1cj2c1W/K85leJT2MPD Zw6/Chyj0BaSQ7FLkcjP+xpr/uOLPH1FyTr5lm02o8rn0JB8+y6LMWktIpqv8ddMieBYxSa2lmI tYOpThjusHf9G3KDdRH2CflSRPggKSyiminSBBloXBJ2mDKUD1gT3jy6sn1o1IMsHZIC99iEocS BR668/Sfql9Q== X-Gm-Gg: ASbGncuW6aN3eh2R59wl3lxXmkbktT24/yBCYzHHEzWQFvmZCVVefjjg9uSldy7st8m ii1n4zrL1QTEPEAc0VVoB1eV3LlxTy/rO21B+m9RWR8JAFIHqKxT67bZxzCa+h5xF2/4tzapfeF uDQsJFjo6GZQs3glIb1UzokaQ7NWkMIEQEBUHCLW4TvpWYzCIgvWfLgCvdfDEuwazaiILPu61Fn ai4xSws/Ccz1e/rTt0clORVeN0rdSj44YbdDDIkMSVOmB3YGBvyls6f2GMRSsE4Q6078yPJPYys zeqdqG7ixqo0/u1SiOqRlhrl83W1Zw== X-Received: by 2002:a05:6a00:a91:b0:739:4a93:a5df with SMTP id d2e1a72fcca58-73bd1202e30mr20746456b3a.12.1744697695371; Mon, 14 Apr 2025 23:14:55 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEPBRJ1ieKl7bIc591ufS7FJX5wpoe4aVQmCTYzrQ9i0R4B5w9Z8lY1vTS7FbMmJpUn9O55mA== X-Received: by 2002:a05:6a00:a91:b0:739:4a93:a5df with SMTP id d2e1a72fcca58-73bd1202e30mr20746439b3a.12.1744697695024; Mon, 14 Apr 2025 23:14:55 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:54 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 09/19] UBUNTU: SAUCE: gpio: aggregator: Fix error code in gpio_aggregator_activate() Date: Tue, 15 Apr 2025 15:13:35 +0900 Message-ID: <47607acb445deaf615f17220cb0410cfdf330811.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dan Carpenter BugLink: https://bugs.launchpad.net/bugs/2103496 Propagate the error code if gpio_aggregator_make_device_sw_node() fails. Don't return success. Fixes: 86f162e73d2d ("gpio: aggregator: introduce basic configfs interface") Signed-off-by: Dan Carpenter Acked-by: Koichiro Den Link: https://lore.kernel.org/r/79b804a0769a434698616bebedacc0e5d5605fdc.1744452787.git.dan.carpenter@linaro.org Signed-off-by: Bartosz Golaszewski (cherry picked from commit 05b43de95add3d787a7a88378086bf01c10b3f40 gpio/for-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index f492b7259ec5..14dfbeb5f112 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -579,8 +579,10 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr) return -ENOMEM; swnode = gpio_aggregator_make_device_sw_node(aggr); - if (IS_ERR(swnode)) + if (IS_ERR(swnode)) { + ret = PTR_ERR(swnode); goto err_remove_lookups; + } memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.name = DRV_NAME; From patchwork Tue Apr 15 06:13:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072667 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQf2R9zz1yJ9 for ; Tue, 15 Apr 2025 16:14:50 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZV-000503-Qm; Tue, 15 Apr 2025 06:15:01 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZS-0004qN-FN for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:14:58 +0000 Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 4552E3F091 for ; Tue, 15 Apr 2025 06:14:58 +0000 (UTC) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-739731a2c25so3105730b3a.1 for ; Mon, 14 Apr 2025 23:14:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697697; x=1745302497; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Bk7yXsC7NRTef6+gidPYlDtYXptk3RPyO0dCT9Z4vjs=; b=bOwyTHaSA6sMaF5XVYDeWQPTaxzes5jRakqz/EjnUW7JhKjEpy7CJzo86+ge7XHyOd I0iMoszX+BzuqICbOdrh05GKjbVEnKPK4Uy6PKY6pS7nKQEL0zFlDfF3g3qSuMgPFoLP SD2nQzX+xIwMU4KPF2F0aDmqToNWzmD5o/qWWp8Pm8MFNwjPH2w/Nund/fpdCbzN+LJx vwb3wLeXGxDi6kZOIpP1nwtnY+WBb/2MA/sfsEElPg5SJYxszCcCJZj1n5Gumkx3OPsh gsVHPMQ6EjL7qbox7lzUyagmbZJLacymg8NMsXFgK6YoDFcdTamduSeR5HV3DrnRaZ+t AJQw== X-Gm-Message-State: AOJu0YyIcaPd0OW/bdqlUH9lU47feVRmVAFoJQGbvX06UNz9fJxeozCR eDSbNv7YJOtC5Dn+6EGHq2YZLE1/7fkbNTHL9p09wWUAKO5wsCZxTAqZOPNvOkTFLuJ5stNpkyS 4f5fDbBT7qfmlztfi5cZGF8fqPcp6MnxZrzRSmWYW9yNokSwQPpYinwKcSq3E5elR64yjdOWOZ8 s0LbPSEOjyWA== X-Gm-Gg: ASbGncukkFDMXuaNesiD205a7eqAfQb3wZitFTgj51ueAakMRAX84cUBZmzNHBuAvv4 fgdUdxd/6808Wpl2A/Qk4ZVKsMBcVi2n79+D5HTkV88FGRy/g5OCcmmqWHim/vQuTkKQDRTdWDH EgFxsuwZASKysde9y8234+c78dqQUX5iYsQoeML82LM9L2wMkQQvW3cTvxE6HdQZVpG/hnJEHHL f9JC87MKehMykCoyCjumQWFRvKQE2cfeyMEZV1NHBQwGwyJFSBP4EKCD2loX9ziZlyjk9tF97CY S2NPI56oo/qx/QikDKgE59FJ+bUXZA== X-Received: by 2002:a05:6a00:399d:b0:730:79bf:c893 with SMTP id d2e1a72fcca58-73bd11a7b50mr20736630b3a.4.1744697696750; Mon, 14 Apr 2025 23:14:56 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHw+FMdms3gpkSG/9Wichl2V8BrtirZ6FNEK7eJSoOzousspztp3TcT1cZeeaSUaSPIl4e3aQ== X-Received: by 2002:a05:6a00:399d:b0:730:79bf:c893 with SMTP id d2e1a72fcca58-73bd11a7b50mr20736611b3a.4.1744697696342; Mon, 14 Apr 2025 23:14:56 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:56 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 10/19] gpio: aggregator: rename 'name' to 'key' in gpio_aggregator_parse() Date: Tue, 15 Apr 2025 15:13:36 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Rename the local variable 'name' in gpio_aggregator_parse() to 'key' because struct gpio_aggregator_line now uses the 'name' field for the custom line name and the local variable actually represents a 'key'. This change prepares for the next but one commit. No functional change. Reviewed-by: Geert Uytterhoeven Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-6-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 4ec2315d7fabeb08e9ad7995bd16f34118e4633b linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 14dfbeb5f112..06c39ebc9bbb 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -988,7 +988,7 @@ static struct configfs_subsystem gpio_aggregator_subsys = { static int gpio_aggregator_parse(struct gpio_aggregator *aggr) { char *args = skip_spaces(aggr->args); - char *name, *offsets, *p; + char *key, *offsets, *p; unsigned int i, n = 0; int error = 0; @@ -997,18 +997,18 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) if (!bitmap) return -ENOMEM; - args = next_arg(args, &name, &p); + args = next_arg(args, &key, &p); while (*args) { args = next_arg(args, &offsets, &p); p = get_options(offsets, 0, &error); if (error == 0 || *p) { /* Named GPIO line */ - error = gpio_aggregator_add_gpio(aggr, name, U16_MAX, &n); + error = gpio_aggregator_add_gpio(aggr, key, U16_MAX, &n); if (error) return error; - name = offsets; + key = offsets; continue; } @@ -1020,12 +1020,12 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) } for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error = gpio_aggregator_add_gpio(aggr, name, i, &n); + error = gpio_aggregator_add_gpio(aggr, key, i, &n); if (error) return error; } - args = next_arg(args, &name, &p); + args = next_arg(args, &key, &p); } if (!n) { From patchwork Tue Apr 15 06:13:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072668 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQg57H2z1yHt for ; Tue, 15 Apr 2025 16:14:51 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZX-00056i-9W; Tue, 15 Apr 2025 06:15:03 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZU-0004wL-8Y for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:00 +0000 Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id E91C43F1E4 for ; Tue, 15 Apr 2025 06:14:59 +0000 (UTC) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-7375e2642b4so3772476b3a.2 for ; Mon, 14 Apr 2025 23:14:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697698; x=1745302498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vdHJExmI2/7VCS0ChwfJPNvYNNGV0Za9BvuS5DnPA7E=; b=Bbg8gefJDe2YJOI2723IR3mOQO7iFyi7UmjxVtKiUgE79AKaHqU9wngdvPZrU96l6g 0Rj5aOaV/ev1c3zXHoSSRAyY4EduEOyTTrNK04tRI5VCYGKxbhLotbMNADvDGfLw6ax2 JkRue/jV10yC/IEtwNG629PPu5o2XMm934TqMkQwgbTRPP4F+3BvW48Wl0/cvsOfCUH0 6JSMa0UnpWO7tx4YZZWQcvXLRk+NTc/MoRWeqxf0YDk3nbvx/h4SNqXk7VEWU3hjR9Tz O1PM7Q0Uin1qYPeJkc3dUKQ6cz4HabUWItopZEdfJlvJqjaqnXV9oUA7uaCtc3D911tb y8ZA== X-Gm-Message-State: AOJu0YzcUHoaN+iV9cEOLbLRZCqUsdsCFnYLdLR/3exGGz/gklXgedEw wM+vSxMBIDPGLbJOm1qENTo2uycu5qOZu0e2csIQ1+jYofLazh7dXMnC1npuLZPq1NCwMpNm2Ym vjrhc85I0snelaU7IZWRG4DA6ptINd/P4SiSqPiMk/nU/OgFdgTawoo1jw/hboaeZqMzw9Lbvkn +SphlurXEcaA== X-Gm-Gg: ASbGncub0KnEZFonVYN0k/uZMBfkSdwJDKdSgIn864TUKrIo5/rbiVDYbXcbXrY4xW7 An98rZ2ygKx3bkvOzi4zu0YjxjGvsQphwVQnjW5SKKGiWfj0aGr75D3RI32BY7gBe+oCwjF/Z9A KexwVOFDoAr1eH7Kk8IWOIpqeSFqDtRG1Ps1HgfYWQ1pqIAxV90AkED7Dd4HvVBfuK71a1RouSg ++/rkWdZezSSjgjeEe11/TyMoh+qYClEmgML0MX2OEMv9A3vj0+MLBb4h45aD321n1Xe04mgG9S ZZvvtXBoFwNDsPTeZaQxYxgZ5gZLkQ== X-Received: by 2002:a05:6a00:885:b0:736:6ecd:8e32 with SMTP id d2e1a72fcca58-73bd12afc65mr19756048b3a.21.1744697698208; Mon, 14 Apr 2025 23:14:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHh+RZ6q+iDoLQPCgX6QI3KhCMzoQvcqavNwLSc3AMXsCjip/U3qE1PydXRJZiHtXvAZbZvVg== X-Received: by 2002:a05:6a00:885:b0:736:6ecd:8e32 with SMTP id d2e1a72fcca58-73bd12afc65mr19756024b3a.21.1744697697708; Mon, 14 Apr 2025 23:14:57 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:57 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 11/19] gpio: aggregator: expose aggregator created via legacy sysfs to configfs Date: Tue, 15 Apr 2025 15:13:37 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Expose settings for aggregators created using the sysfs 'new_device' interface to configfs. Once written to 'new_device', an "_sysfs." path appears in the configfs regardless of whether the probe succeeds. Consequently, users can no longer use that prefix for custom GPIO aggregator names. The 'live' attribute changes to 1 when the probe succeeds and the GPIO forwarder is instantiated. Note that the aggregator device created via sysfs is asynchronous, i.e. writing into 'new_device' returns without waiting for probe completion, and the probe may succeed, fail, or eventually succeed via deferred probe. Thus, the 'live' attribute may change from 0 to 1 asynchronously without notice. So, editing key/offset/name while it's waiting for deferred probe is prohibited. The configfs auto-generation relies on create_default_group(), which inherently prohibits rmdir(2). To align with the limitation, this commit also prohibits mkdir(2) for them. When users want to change the number of lines for an aggregator initialized via 'new_device', they need to tear down the device using 'delete_device' and reconfigure it from scratch. This does not break previous behavior; users of legacy sysfs interface simply gain additional almost read-only configfs exposure. Still, users can write to the 'live' attribute to toggle the device unless it's waiting for deferred probe. So once probe succeeds, they can deactivate it in the same manner as the devices initialized via configfs. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-7-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 83c8e3df642f5fde320278a5e6ce9e46f9689d1a linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 138 ++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 06c39ebc9bbb..a51b01a058bd 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -33,6 +33,7 @@ #include "dev-sync-probe.h" #define AGGREGATOR_MAX_GPIOS 512 +#define AGGREGATOR_LEGACY_PREFIX "_sysfs" /* * GPIO Aggregator sysfs interface @@ -131,6 +132,14 @@ static bool gpio_aggregator_is_active(struct gpio_aggregator *aggr) return aggr->probe_data.pdev && platform_get_drvdata(aggr->probe_data.pdev); } +/* Only aggregators created via legacy sysfs can be "activating". */ +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); +} + static size_t gpio_aggregator_count_lines(struct gpio_aggregator *aggr) { lockdep_assert_held(&aggr->lock); @@ -189,6 +198,30 @@ static void gpio_aggregator_line_del(struct gpio_aggregator *aggr, list_del(&line->entry); } +static void gpio_aggregator_free_lines(struct gpio_aggregator *aggr) +{ + struct gpio_aggregator_line *line, *tmp; + + list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) { + configfs_unregister_group(&line->group); + /* + * Normally, we acquire aggr->lock within the configfs + * callback. However, in the legacy sysfs interface case, + * calling configfs_(un)register_group while holding + * aggr->lock could cause a deadlock. Fortunately, this is + * unnecessary because the new_device/delete_device path + * and the module unload path are mutually exclusive, + * thanks to an explicit try_module_get. That's why this + * minimal scoped_guard suffices. + */ + scoped_guard(mutex, &aggr->lock) + gpio_aggregator_line_del(aggr, line); + kfree(line->key); + kfree(line->name); + kfree(line); + } +} + /* * GPIO Forwarder @@ -693,7 +726,8 @@ gpio_aggregator_line_key_store(struct config_item *item, const char *page, guard(mutex)(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) return -EBUSY; kfree(line->key); @@ -730,7 +764,8 @@ gpio_aggregator_line_name_store(struct config_item *item, const char *page, guard(mutex)(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) return -EBUSY; kfree(line->name); @@ -776,7 +811,8 @@ gpio_aggregator_line_offset_store(struct config_item *item, const char *page, guard(mutex)(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) return -EBUSY; line->offset = offset; @@ -834,11 +870,12 @@ gpio_aggregator_device_live_store(struct config_item *item, const char *page, if (!try_module_get(THIS_MODULE)) return -ENOENT; - if (live) + if (live && !aggr->init_via_sysfs) gpio_aggregator_lockup_configfs(aggr, true); scoped_guard(mutex, &aggr->lock) { - if (live == gpio_aggregator_is_active(aggr)) + if (gpio_aggregator_is_activating(aggr) || + (live == gpio_aggregator_is_active(aggr))) ret = -EPERM; else if (live) ret = gpio_aggregator_activate(aggr); @@ -850,7 +887,7 @@ gpio_aggregator_device_live_store(struct config_item *item, const char *page, * Undepend is required only if device disablement (live == 0) * succeeds or if device enablement (live == 1) fails. */ - if (live == !!ret) + if (live == !!ret && !aggr->init_via_sysfs) gpio_aggregator_lockup_configfs(aggr, false); module_put(THIS_MODULE); @@ -894,7 +931,7 @@ static void gpio_aggregator_device_release(struct config_item *item) struct gpio_aggregator *aggr = to_gpio_aggregator(item); /* - * If the aggregator is active, this code wouldn't be reached, + * At this point, aggr is neither active nor activating, * so calling gpio_aggregator_deactivate() is always unnecessary. */ gpio_aggregator_free(aggr); @@ -916,6 +953,15 @@ gpio_aggregator_device_make_group(struct config_group *group, const char *name) if (ret != 1 || nchar != strlen(name)) return ERR_PTR(-EINVAL); + if (aggr->init_via_sysfs) + /* + * Aggregators created via legacy sysfs interface are exposed as + * default groups, which means rmdir(2) is prohibited for them. + * For simplicity, and to avoid confusion, we also prohibit + * mkdir(2). + */ + return ERR_PTR(-EPERM); + guard(mutex)(&aggr->lock); if (gpio_aggregator_is_active(aggr)) @@ -953,6 +999,14 @@ gpio_aggregator_make_group(struct config_group *group, const char *name) struct gpio_aggregator *aggr; int ret; + /* + * "_sysfs" prefix is reserved for auto-generated config group + * for devices create via legacy sysfs interface. + */ + if (strncmp(name, AGGREGATOR_LEGACY_PREFIX, + sizeof(AGGREGATOR_LEGACY_PREFIX)) == 0) + return ERR_PTR(-EINVAL); + /* arg space is unneeded */ ret = gpio_aggregator_alloc(&aggr, 0); if (ret) @@ -988,6 +1042,8 @@ static struct configfs_subsystem gpio_aggregator_subsys = { static int gpio_aggregator_parse(struct gpio_aggregator *aggr) { char *args = skip_spaces(aggr->args); + struct gpio_aggregator_line *line; + char name[CONFIGFS_ITEM_NAME_LEN]; char *key, *offsets, *p; unsigned int i, n = 0; int error = 0; @@ -1004,9 +1060,24 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) p = get_options(offsets, 0, &error); if (error == 0 || *p) { /* Named GPIO line */ + scnprintf(name, sizeof(name), "line%u", n); + line = gpio_aggregator_line_alloc(aggr, n, key, -1); + if (!line) { + error = -ENOMEM; + goto err; + } + config_group_init_type_name(&line->group, name, + &gpio_aggregator_line_type); + error = configfs_register_group(&aggr->group, + &line->group); + if (error) + goto err; + scoped_guard(mutex, &aggr->lock) + gpio_aggregator_line_add(aggr, line); + error = gpio_aggregator_add_gpio(aggr, key, U16_MAX, &n); if (error) - return error; + goto err; key = offsets; continue; @@ -1020,9 +1091,24 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) } for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { + scnprintf(name, sizeof(name), "line%u", n); + line = gpio_aggregator_line_alloc(aggr, n, key, i); + if (!line) { + error = -ENOMEM; + goto err; + } + config_group_init_type_name(&line->group, name, + &gpio_aggregator_line_type); + error = configfs_register_group(&aggr->group, + &line->group); + if (error) + goto err; + scoped_guard(mutex, &aggr->lock) + gpio_aggregator_line_add(aggr, line); + error = gpio_aggregator_add_gpio(aggr, key, i, &n); if (error) - return error; + goto err; } args = next_arg(args, &key, &p); @@ -1030,15 +1116,20 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) if (!n) { pr_err("No GPIOs specified\n"); - return -EINVAL; + goto err; } return 0; + +err: + gpio_aggregator_free_lines(aggr); + return error; } static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, const char *buf, size_t count) { + char name[CONFIGFS_ITEM_NAME_LEN]; struct gpio_aggregator *aggr; struct platform_device *pdev; int res; @@ -1067,10 +1158,25 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, goto free_table; } - res = gpio_aggregator_parse(aggr); + 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); if (res) goto free_dev_id; + res = gpio_aggregator_parse(aggr); + if (res) + goto unregister_group; + gpiod_add_lookup_table(aggr->lookups); pdev = platform_device_register_simple(DRV_NAME, aggr->id, NULL, 0); @@ -1085,6 +1191,8 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, remove_table: gpiod_remove_lookup_table(aggr->lookups); +unregister_group: + configfs_unregister_group(&aggr->group); free_dev_id: kfree(aggr->lookups->dev_id); free_table: @@ -1101,7 +1209,13 @@ static struct driver_attribute driver_attr_gpio_aggregator_new_device = static void gpio_aggregator_destroy(struct gpio_aggregator *aggr) { - gpio_aggregator_deactivate(aggr); + scoped_guard(mutex, &aggr->lock) { + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) + gpio_aggregator_deactivate(aggr); + } + gpio_aggregator_free_lines(aggr); + configfs_unregister_group(&aggr->group); kfree(aggr); } From patchwork Tue Apr 15 06:13:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQj2cVnz1yHt for ; Tue, 15 Apr 2025 16:14:53 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZZ-0005DL-JM; Tue, 15 Apr 2025 06:15:05 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZW-0004zW-MM for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:02 +0000 Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 20F813F1E4 for ; Tue, 15 Apr 2025 06:15:01 +0000 (UTC) Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-7395d07a3dcso3780027b3a.3 for ; Mon, 14 Apr 2025 23:15:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697699; x=1745302499; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bqtE/Ny7Q24fkjlMIOle97nnd9xmT38xVGc2ofQjE/s=; b=vqySBETiJzT1orMY4eFmkwmQ1RWEOlLJwNQKVk/2u13AngmdBkKdq1/jZT7fBALxC1 WRt1onwUsbAVqkMYn7PwauLyD8bzJ5J7UYNUwEuu/WHx45O36I3Rn8eGxqDmjFR27ik6 /TppnA4gdqri/09R9gJRuEVgRRS9D0cOdyYjz2Nbp/L8Epw+1CID3vNxDwKJ7phocqex +swCu/8RicCNv28HuaxZp01K4Vd0EQUHvi08y+5wjpZjTGMjqEQt0tnpT2APFn2DD8yt j9X/jDz11A+rD2IZ5Ci7WUotIPJYot4Vmx5oCAcXQOKaEeZb5KBQH4k1Ka9PbCxOZXs7 QMSA== X-Gm-Message-State: AOJu0Yx8dJII82Hws3/CB0OeBQkAC/kFvDMCDVSLvd7akT7wh/FvmPoq gcMKIKn3kfJ79R9vx2yfxH5iSogIre3t1UWiNvjRaolkNdx8z2pUNCQenHXlusxR2iUafajeHRN 0SZ0IosZ+Lxp4e5CIhjtdD17mWPOGznBqEEFmw39CeQKrOOXyGFLduoA4tqlOr38hCnPc4RsM++ 8PgJyhlVMN5Q== X-Gm-Gg: ASbGncvhT/3oIwIh8613lZHc4fnKvyZFSMPzzGGmb8KHixV4oTC7Q0bPRagnYPOYjzG NpmonKeyjSplWGaWcQr9/jYSVCG98kasp34f7rklkDdUQFx41bWyHBZFOI8IihPJcuY4kzI8gNr J/LNH5nZAuAEC92z8nfJ7Twoza82mZBx+uYvhtv6OE3IKtendE+UsON5Zd0ejyCB6cNhGES+Al/ YSzJoUW1Q2JqRO3Z50FQ0aZCOr+CRJR/35qwZyZK2mGE8KpSyddAUVpGJx+CacZ4AsxBKgIYveC IQrTx8MiVza8EMYGsf6EAWmc/R3sMA== X-Received: by 2002:a05:6a00:ad0:b0:736:4a5b:7f08 with SMTP id d2e1a72fcca58-73bd12a29c9mr18195037b3a.22.1744697699544; Mon, 14 Apr 2025 23:14:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IELr4RzZYtERKmgkIRbHItUOlGAx5Cd/DVW4Wk37FaVCCAh2eHbwGbNCagHWqPsy4cZ+BsZ2g== X-Received: by 2002:a05:6a00:ad0:b0:736:4a5b:7f08 with SMTP id d2e1a72fcca58-73bd12a29c9mr18195007b3a.22.1744697699064; Mon, 14 Apr 2025 23:14:59 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:14:58 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 12/19] UBUNTU: SAUCE: gpio: aggregator: fix "_sysfs" prefix check in gpio_aggregator_make_group() Date: Tue, 15 Apr 2025 15:13:38 +0900 Message-ID: <354e8e6be3ddbb0d565e8db87acfa676726cae56.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dan Carpenter BugLink: https://bugs.launchpad.net/bugs/2103496 This code is intended to reject strings that start with "_sysfs" but the strcmp() limit is wrong so checks the whole string instead of the prefix. Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs") Signed-off-by: Dan Carpenter Reviewed-by: Geert Uytterhoeven Acked-by: Koichiro Den Link: https://lore.kernel.org/r/30210ed77b40b4b6629de659cb56b9ec7832c447.1744452787.git.dan.carpenter@linaro.org Signed-off-by: Bartosz Golaszewski (cherry picked from commit eebfcb98cdc0228f5e1b7407f9db1c602bd8e545 gpio/for-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index a51b01a058bd..bbcb33bcaa9d 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1004,7 +1004,7 @@ gpio_aggregator_make_group(struct config_group *group, const char *name) * for devices create via legacy sysfs interface. */ if (strncmp(name, AGGREGATOR_LEGACY_PREFIX, - sizeof(AGGREGATOR_LEGACY_PREFIX)) == 0) + sizeof(AGGREGATOR_LEGACY_PREFIX) - 1) == 0) return ERR_PTR(-EINVAL); /* arg space is unneeded */ From patchwork Tue Apr 15 06:13:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQm23mDz1yJH for ; Tue, 15 Apr 2025 16:14:56 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZc-0005MF-KO; Tue, 15 Apr 2025 06:15:08 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZX-00054U-0Y for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:03 +0000 Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 818893F091 for ; Tue, 15 Apr 2025 06:15:02 +0000 (UTC) Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2265a09dbfcso74763545ad.0 for ; Mon, 14 Apr 2025 23:15:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697701; x=1745302501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P+0VLbg2JGOSKYhf+AjVAbpOcdfnjmaj4ynbHGsmdfQ=; b=CcHElFj8Y3z5RDLomfBmd0D9EFyJcO9ZjC5lZGxLTLRNyHzEp0uPcIrKaa3Ba56CxN 5JURKNGAVbJeo9htpQfBOPYjgQUT8aW9MEUNasX+f9yvnypRwoGukULfNGTZboMNiuhE mqfCXSgXuP5C4BCkaKn8Vp1LFcEBWA8ZoemXS6WRWTMHShRBqsb1rj38JY9Mj96Amkn5 3Ct5sv4oQVPteTClXQgWDPwXtmNii8Nzzmv6Xgguu7U0WCkPN0+CBi7QI27QSZRYfbPQ XyEKKFuMYnY5fV6Ced8eDzMtBu3h/Zw2uTufeCgWxR12Ek+asnQZJBdOhLvaKAANjp6b zn8A== X-Gm-Message-State: AOJu0YzsQiA1AH9+5Ehc2KlNNrwmCQc5bv6v0A/fu3gmxN8FjqP9GGQ0 iDYTto6ctLJ7bY+3HduEe/QUp+RnpqNP+TPNABSth/z2szLgC5dtfZTwUKJ02DWpLxZXgrCndCC KYuxbIkhTu5CsGdpdOx4bbGYbI0U+3b/Co+bczCKuezlNo8epaNfsCuD/aJUxeuXhwnwlMQ/B0I qMrkYfIJYrzQ== X-Gm-Gg: ASbGncsdbM/7YdssD8EluFZe6ipf0QdSTm5ctE39mYwXT/g3P6M8VMi7op3n9DWW1zV 7G5MGWnEFDztOIyw6897SeCE/mzL0iKXFINxJFgbJI/xULDqrUepTdz/ybgXGnSOQLR9oLjutxw xKdRK2blrwBf/ZnMWi9BAmMSMe8vlBGl7BbSGDz2+5Pi/A774yxAsoADohp81pUtl3jC+Lv4DMc s1WX6Scqr9ZVZuRYEmZiYCf+HIf5MutKzLpns2iBNqOLAdcF5z3iR8ixIZ3Cj5W3OYUfkc2glFH AUw7Q+88rV3uu08nvE4MSuH3zKgIsQ== X-Received: by 2002:a17:903:41c3:b0:223:5a6e:b16 with SMTP id d9443c01a7336-22bea49542dmr227084415ad.5.1744697700894; Mon, 14 Apr 2025 23:15:00 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEgr+F+PfnbwSedYWcKHYbffQ3h9fPRu0L+D+HJedhhyVWEAjMeq/GlOoZTRmb3dfiHLgtyHg== X-Received: by 2002:a17:903:41c3:b0:223:5a6e:b16 with SMTP id d9443c01a7336-22bea49542dmr227084205ad.5.1744697700542; Mon, 14 Apr 2025 23:15:00 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.14.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:00 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 13/19] UBUNTU: SAUCE: gpio: aggregator: Fix gpio_aggregator_line_alloc() checking Date: Tue, 15 Apr 2025 15:13:39 +0900 Message-ID: <55ca5db8a945aeed71b884219c11864286917348.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dan Carpenter BugLink: https://bugs.launchpad.net/bugs/2103496 The gpio_aggregator_line_alloc() function returns error pointers, but the callers check for NULL. Update the error checking in the callers. Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs") Signed-off-by: Dan Carpenter Acked-by: Koichiro Den Link: https://lore.kernel.org/r/cc71d8cf6e9bb4bb8cd9ae5050100081891d9345.1744452787.git.dan.carpenter@linaro.org Signed-off-by: Bartosz Golaszewski (cherry picked from commit 2e8636ca340002f3ac31383622911a1aa75fb086 gpio/for-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index bbcb33bcaa9d..db001f765aa0 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -972,8 +972,8 @@ gpio_aggregator_device_make_group(struct config_group *group, const char *name) return ERR_PTR(-EINVAL); line = gpio_aggregator_line_alloc(aggr, idx, NULL, -1); - if (!line) - return ERR_PTR(-ENOMEM); + if (IS_ERR(line)) + return ERR_CAST(line); config_group_init_type_name(&line->group, name, &gpio_aggregator_line_type); @@ -1062,8 +1062,8 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) /* Named GPIO line */ scnprintf(name, sizeof(name), "line%u", n); line = gpio_aggregator_line_alloc(aggr, n, key, -1); - if (!line) { - error = -ENOMEM; + if (IS_ERR(line)) { + error = PTR_ERR(line); goto err; } config_group_init_type_name(&line->group, name, @@ -1093,8 +1093,8 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { scnprintf(name, sizeof(name), "line%u", n); line = gpio_aggregator_line_alloc(aggr, n, key, i); - if (!line) { - error = -ENOMEM; + if (IS_ERR(line)) { + error = PTR_ERR(line); goto err; } config_group_init_type_name(&line->group, name, From patchwork Tue Apr 15 06:13:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQq0s8hz1yHt for ; Tue, 15 Apr 2025 16:14:59 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZf-0005UN-40; Tue, 15 Apr 2025 06:15:11 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZY-00059N-6h for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:04 +0000 Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id B86B23F091 for ; Tue, 15 Apr 2025 06:15:03 +0000 (UTC) Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-739731a2c25so3105767b3a.1 for ; Mon, 14 Apr 2025 23:15:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697702; x=1745302502; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TrtBoNcAP2ry1sG0FolSO4eJN85t2BtxRi21t0VbzaM=; b=YLzuAlhZwxJsiaDlVcDmhriOJ/rkkfFd+4ubvZde5+e7CbK3xZ5uSbD9SThDdMRgp4 zAtHunrGSoTtwjTKYCrva91r9fUUwc4N+aJJ70K5gAuL4aqDqGYYaguLsYJ9brpa+pBj PxCbA8vrgR8ddXT8UbUsStASrmswZRTy+fMxf+ZxXbqN5ROnljUVFXr9Y84Saq0BodNz t7LXyzmErER1D/DFBBfv/4i4d6hwCEocJWc+sEDYCij5WsVXrbiDcUqWqYBfs8xuzx70 TAZee3Br7zRD6Mz6tkwQ96iC8tdTYqWFpdcxWKVlW4Tsnn17H2VcGOUN2IMTQKNTtjq5 mxMA== X-Gm-Message-State: AOJu0YyU+H3PZv+Ml9iBc9gRtWYswiiU8OqoMyu5+YhMlUWkWK3a6dJ/ cr7ML++z62RXEA2rrP9ZJ6gaNYHWMhnfQquzVHzKzQH7WJZDRAsivAStC/c/BSR25u10fjLfBp1 rLzb2be8JxQld5Rxckhr0wtzyQloSrvcgI3kNTrc+7hly4IyTgH4vNlZ3k1YE31xDI+IYyK3N5c /UofkjDQs+lA== X-Gm-Gg: ASbGnctgAqa0hFuKouJlnESSwEUZ6mNNypo1o3sdKqP4IWrj9v8W+0TiG/gE8DW1ep5 WM2AMVs9LbXNu5vBes7pjaPx7b3Kmw1yZrue6o/0Rk8XxtBm7hXTTZOEtWQLdbG0jrC05r02gkb Jx3OyMIjeBdjJvOdthwzHroq9NLGlWgX03xc3A88N1is6XVnQKUfyJ0zCs+Ezj23neprA8dkNwz MlrpEqYRiJS/79iVgdsG3kqauEENOTmPlvKwPZBvs3mGl6mJpJErHvZfs7XisK3X2zxpp4bvfYf F3X7D1MudErdMd0/JNP8X5p4n4kb2Q== X-Received: by 2002:a05:6a21:4a4b:b0:1f3:48d5:7303 with SMTP id adf61e73a8af0-2017996f6f5mr24875955637.31.1744697702238; Mon, 14 Apr 2025 23:15:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEvF2QrR8RHhwrTrKT6kRDylcPqCbvzd6LH7NFNT17/v3Of37If6feSS74mlB1iDbmVRMx1xQ== X-Received: by 2002:a05:6a21:4a4b:b0:1f3:48d5:7303 with SMTP id adf61e73a8af0-2017996f6f5mr24875906637.31.1744697701906; Mon, 14 Apr 2025 23:15:01 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:01 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 14/19] UBUNTU: SAUCE: gpio: aggregator: Return an error if there are no GPIOs in gpio_aggregator_parse() Date: Tue, 15 Apr 2025 15:13:40 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dan Carpenter BugLink: https://bugs.launchpad.net/bugs/2103496 The error handling in gpio_aggregator_parse() was re-written. It now returns success if there are no GPIOs. Restore the previous behavior and return -EINVAL instead. Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs") Signed-off-by: Dan Carpenter Acked-by: Koichiro Den Link: https://lore.kernel.org/r/9dcd5fda7a3819e896d9eee4156e7c46c9a64595.1744452787.git.dan.carpenter@linaro.org Signed-off-by: Bartosz Golaszewski (cherry picked from commit db1baf69e563fc222a75c0add5c76f437c717ac0 gpio/for-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index db001f765aa0..03e0011b3836 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1116,6 +1116,7 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) if (!n) { pr_err("No GPIOs specified\n"); + error = -EINVAL; goto err; } From patchwork Tue Apr 15 06:13:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072670 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQl72lGz1yHt for ; Tue, 15 Apr 2025 16:14:55 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZb-0005IE-Bx; Tue, 15 Apr 2025 06:15:07 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZZ-0005DF-L9 for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:05 +0000 Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 410583F091 for ; Tue, 15 Apr 2025 06:15:05 +0000 (UTC) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-227a8cdd272so43403465ad.2 for ; Mon, 14 Apr 2025 23:15:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697704; x=1745302504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RYm6QWBaeC+V00UUPpyLbgCRTabtUeZez62VXlN/RCg=; b=vYWSMdW7P4eEY+8EthgD4alxCaQI2Qo+JfzkrleIvDu9zU2Zl3lLGQiRpuWz+UJQEf u0F9haIzbvJJLLOsm8WoN4xnEMELScQ6MfXCfkOG6NziJHoIDqBUj2/4GDsvTk7WdODz kaujrgNIBwIqbZVzRSroUb2dcqqY17izpvONUbh1eG1My/EI3GWEd9nW3uC93mHurfa9 ++hPwrG91T0RrrYBuRJnz4TZ05qEJXb5ZKs4hWP/ndd4/nSBWcQUHFjFSdIxBbE9VEx8 m/whHdGXI9ujtoSB3sQs9uYlbHLPMfaXajd15iTnoChYp7+acxerhta3S2c78tOvK2SO iewA== X-Gm-Message-State: AOJu0YznnQLfNRmNWRFbi+7/lPjBBuZG+V5XY2sXgumzyYIGIzjeLhXy nTXPzRPzrsdF4pIX3wcYdrjglWfi7N8vIIdLzGcwXx5MrdSYBq85TC1ZEzjtD8sh+jlodQvWq5p vyrJP1Z2Cwt0htRFSwndGIZz4lJPqH5goddcx1pv4c1HnDaZ9bD+ZehWjC4gUPZxcfXuvhsidcm eJR3XoedBaIQ== X-Gm-Gg: ASbGncuaBAgTCLkcw1MjC8M1wbtzjXY7KPsoQMLlMZYIxu4bQplmpk+KZiO47thGTU+ 79SmNHr7ZLsdZngZC/JHeIbkNGwAre6XPgj7ID5300wTFrcgTQlPPUZOpB+KQDNLPsz3gpLi3+0 3qt8KVumfprgYCg5fy8ilKa7+HRj14AIadcMMBcCe8tiSuZgGu9uGSkHqtc5Z1nUc89LZGdOImw OKRhu2PpGO086k0I+vKDu1OQYu8M04NQATeO/5KAGLR3M/YduFVJnRPHpxQ/UZzBayztEvJMjRn BAEmkU2beNHCZN0JPCYUqpYB7n+6xQ== X-Received: by 2002:a17:902:e788:b0:223:4c09:20b8 with SMTP id d9443c01a7336-22bea4f0043mr208278045ad.37.1744697703680; Mon, 14 Apr 2025 23:15:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFOUFL61n9maOBdOPpb81u3qUKnTq3dZHvJRTxYm3eWAl9KYpxf2fIfb89Grs7QTnSSYjuT0A== X-Received: by 2002:a17:902:e788:b0:223:4c09:20b8 with SMTP id d9443c01a7336-22bea4f0043mr208277865ad.37.1744697703265; Mon, 14 Apr 2025 23:15:03 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:02 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 15/19] UBUNTU: SAUCE: gpio: aggregator: Fix leak in gpio_aggregator_parse() Date: Tue, 15 Apr 2025 15:13:41 +0900 Message-ID: <97ec7711b675ae1e6a7df722f98df56a1b3e369d.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dan Carpenter BugLink: https://bugs.launchpad.net/bugs/2103496 Call gpio_aggregator_free_lines() before returning on this error path. Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs") Signed-off-by: Dan Carpenter Acked-by: Koichiro Den Link: https://lore.kernel.org/r/e023bfe52509ce1bef6209ec7c47e99279c551dd.1744452787.git.dan.carpenter@linaro.org Signed-off-by: Bartosz Golaszewski (cherry picked from commit d945ff52642d98eb6fa191f88a9cfde729129395 gpio/for-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 03e0011b3836..7a15432d0bef 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1087,7 +1087,7 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); if (error) { pr_err("Cannot parse %s: %d\n", offsets, error); - return error; + goto err; } for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { From patchwork Tue Apr 15 06:13:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072672 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQn2fj7z1yHt for ; Tue, 15 Apr 2025 16:14:57 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZd-0005Op-8d; Tue, 15 Apr 2025 06:15:09 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZb-0005I2-3x for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:07 +0000 Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id B5EA53F1E4 for ; Tue, 15 Apr 2025 06:15:06 +0000 (UTC) Received: by mail-pf1-f197.google.com with SMTP id d2e1a72fcca58-736c7df9b6cso6131953b3a.3 for ; Mon, 14 Apr 2025 23:15:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697705; x=1745302505; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Y4clEjlaRHgbV32K4YVg7+S6HstaPqyfkTijaTpLUNI=; b=o2itlqpQw/rfWm/FB5a/xsipVsuUJGrduyhlnAefmUPqlDdy+3k5vQ2gn+wvllrp8G 6x/o3aOx9cvlPsR+1vUbslSicm7GvY+tXFUbqO+E3xwkSxuDZMGpVqyDAqymy55fqbBJ gA4yp9zu2jfEQTo9gY+pwynWvHRwQcb38BWl0YwR5w7JkKuZ3hzZmZfFLmKVxi1Lb8Zo Mk79Bl9ynWjypXyB64pek+cdeUMgovUUykIfGfYIc5IWeo2Ls9OfcD0OY6BWvSiKO5c5 h8YQ9XkG/NK4hX0llQBqc54A4n7doOLNL3QHC13BvvkHS15SWBuIN8zaFdAkWuth5PoV p+fw== X-Gm-Message-State: AOJu0YxDm74qDDdRWICNYpvpe/4nDIEwhZdGmd/9rSTUlq3Q8yHexZNc v+ZeOsbZ6TIBSZ23ElvaSTNy0RLjaKWv4Lwo363eCdmhZP9STaVZ+moNe9BQkS5nk3g3nXQhGOy YChWovY+oCU9IU0V+PJ2RR120uxb+GKLedyJ43OgaMrWyxxA/+dbq6o+LwIHG9ddWauDyXiC98M cN6dji30tNfA== X-Gm-Gg: ASbGncuAa5KXd+XoLPgeezCYDLBcof4gd+SSDA2AsUkHJ2rIoEZtJ8cB/cPyfELGqHz +4H5WuxY3Rp2u/m1HRJW1KgBvBsBIU1pIyNjbY2sxUoSTtW8XTI2sjKjW38kDjdkJm7CIk1UdcO +dY07iiXpQBVdhJhGz6TsqjL6UpQ9HS+YbWcxVu+joR5JCwG6orFoCsKsMSxnGrTVvaCdhazaeO 1Ne8uDzlu8E+8sWkce1nZ+jSUi3AnrxElxzmIKjCoRdntSsy9pU8XU+QNMGMplpBefmFicRW6N2 33rjS38kqaxlVfgEREfnJ+NM2+YwJw== X-Received: by 2002:a05:6a00:a91:b0:736:42a8:a742 with SMTP id d2e1a72fcca58-73bd1200139mr19219243b3a.11.1744697705079; Mon, 14 Apr 2025 23:15:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEkY27czOtNzXwP1JBuja4JNsUkcv8FoashtXFriqdBZgmeXi2BH7DFkpnUZvWcper3USzwIQ== X-Received: by 2002:a05:6a00:a91:b0:736:42a8:a742 with SMTP id d2e1a72fcca58-73bd1200139mr19219219b3a.11.1744697704631; Mon, 14 Apr 2025 23:15:04 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:04 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 16/19] gpio: aggregator: cancel deferred probe for devices created via configfs Date: Tue, 15 Apr 2025 15:13:42 +0900 Message-ID: <15790c14831adaa2c2592748bfd0dfbd2aba5350.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 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 Link: https://lore.kernel.org/r/20250407043019.4105613-8-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 0269c768de1b5e430c3f9a6869261606c82abe90 linux-next) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 7a15432d0bef..d4e746e88eab 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); @@ -1130,6 +1134,7 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) 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; @@ -1180,7 +1185,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; @@ -1273,7 +1278,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; @@ -1287,10 +1294,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); From patchwork Tue Apr 15 06:13:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072675 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQv2hNDz1yHt for ; Tue, 15 Apr 2025 16:15:03 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZj-0005gT-0V; Tue, 15 Apr 2025 06:15:15 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZc-0005M3-II for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:08 +0000 Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 4A52E3F091 for ; Tue, 15 Apr 2025 06:15:08 +0000 (UTC) Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-739525d4d7bso3689860b3a.2 for ; Mon, 14 Apr 2025 23:15:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697706; x=1745302506; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CZ6kElinfxeAlNz/rA9L6uEGTm7s2zy36MrQb/qdn0I=; b=XyYi4WK9T0uC0m8EgzktvjRTtr05NvZHyxSHKaSj5tHWHs4fZMZdZ7EnzImUnQjYJj 1/6Oiud/2FeshpYIavsCntsv3Gg/tMaNeToKHXAqvyUCLPwAB8ufs2GdsL2Xa7RCUNLS S8JmRkyoefUawBcUNZ/BHnmtFTA9JOn7T5diHXAIjDXFFMYp3diMRQ0hWm3dzi3UfSft 0Xl0RddYzuu3nG4WUaLYp/s5ryQHab6MjIOhY216b6E3wizIa0/mTjajag8eSziuDJCx XwwstseKcbK2Xa4hgF/m2pClMpM1XhabHsZP9PbV5K6SAnJtvh29j6LNORZQzk7h08C5 WS2g== X-Gm-Message-State: AOJu0Yy5RHT37ll0GB8upSaY8i4Ccn4ekg/smIgv0HTMzf7/xPideXCe 63syva+uIeEqcuRjq94LCWHLogUeZDdTGRJ21M63QA1aMBHwLKSPMigxO/peLFk6AwNzr5kicPj T08WAGaOoS0WWp8i+PcMxXSD4sW2FCz3HLdOcLuV8bNC1ikqrqckHL4etji7b+8vYWtJV3iwX9p KckZdtuBiJOA== X-Gm-Gg: ASbGncvT/Xt9ifwJBEa4WP8UKdak/toDdbUbDvvqCh9DUrHvTwYWFfWdijtvO/B1TtZ 3NJuhH1TvvjvnB/p5xSoxzjONdO591hF9RR8Y3sxf8i1eOft505Wtb2FUHC8LXVVB6UbHTIA+kk eJsRzh0C4SUCEy0/bHdNN9XEHlQCGreE3itqWo2PztMnmyjjuUrTSQQc2aJYqJYUFnmNcLeYGAs vPC71Ucxvv9LMcUEYu4jDGhMENSrI+4Zj98ckUKqVJok96zS8QCo/OLj122tPrc1J12Pazh2Yef qZtAQOj1i9CnX1ZWJkU88Jqf+yPvbw== X-Received: by 2002:aa7:8895:0:b0:736:a4ca:62e1 with SMTP id d2e1a72fcca58-73bd11cee6fmr16267206b3a.6.1744697706489; Mon, 14 Apr 2025 23:15:06 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHDm347/XX3a5KU3gsF8W89Fw9XYDVg5PREOT5VYSYvcZm7z47Ph8NqMzjkDAUt5l2Lf6fqIQ== X-Received: by 2002:aa7:8895:0:b0:736:a4ca:62e1 with SMTP id d2e1a72fcca58-73bd11cee6fmr16267178b3a.6.1744697705937; Mon, 14 Apr 2025 23:15:05 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:05 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 17/19] Documentation: gpio: document configfs interface for gpio-aggregator Date: Tue, 15 Apr 2025 15:13:43 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Add documentation for the newly added configfs-based interface for GPIO aggregator. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-9-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 10f94d092bba9ab08004c624c604e976e6e3cd22 linux-next) Signed-off-by: Koichiro Den --- .../admin-guide/gpio/gpio-aggregator.rst | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/Documentation/admin-guide/gpio/gpio-aggregator.rst b/Documentation/admin-guide/gpio/gpio-aggregator.rst index 5cd1e7221756..8374a9df9105 100644 --- a/Documentation/admin-guide/gpio/gpio-aggregator.rst +++ b/Documentation/admin-guide/gpio/gpio-aggregator.rst @@ -69,6 +69,113 @@ write-only attribute files in sysfs. $ echo gpio-aggregator.0 > delete_device +Aggregating GPIOs using Configfs +-------------------------------- + +**Group:** ``/config/gpio-aggregator`` + + This is the root directory of the gpio-aggregator configfs tree. + +**Group:** ``/config/gpio-aggregator/`` + + This directory represents a GPIO aggregator device. You can assign any + name to ```` (e.g. ``agg0``), except names starting with + ``_sysfs`` prefix, which are reserved for auto-generated configfs + entries corresponding to devices created via Sysfs. + +**Attribute:** ``/config/gpio-aggregator//live`` + + The ``live`` attribute allows to trigger the actual creation of the device + once it's fully configured. Accepted values are: + + * ``1``, ``yes``, ``true`` : enable the virtual device + * ``0``, ``no``, ``false`` : disable the virtual device + +**Attribute:** ``/config/gpio-aggregator//dev_name`` + + The read-only ``dev_name`` attribute exposes the name of the device as it + will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``). + This is useful for identifying a character device for the newly created + aggregator. If it's ``gpio-aggregator.0``, + ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the + GPIO device id is ``X``. + +You must create subdirectories for each virtual line you want to +instantiate, named exactly as ``line0``, ``line1``, ..., ``lineY``, when +you want to instantiate ``Y+1`` (Y >= 0) lines. Configure all lines before +activating the device by setting ``live`` to 1. + +**Group:** ``/config/gpio-aggregator///`` + + This directory represents a GPIO line to include in the aggregator. + +**Attribute:** ``/config/gpio-aggregator///key`` + +**Attribute:** ``/config/gpio-aggregator///offset`` + + The default values after creating the ```` directory are: + + * ``key`` : + * ``offset`` : -1 + + ``key`` must always be explicitly configured, while ``offset`` depends. + Two configuration patterns exist for each ````: + + (a). For lookup by GPIO line name: + + * Set ``key`` to the line name. + * Ensure ``offset`` remains -1 (the default). + + (b). For lookup by GPIO chip name and the line offset within the chip: + + * Set ``key`` to the chip name. + * Set ``offset`` to the line offset (0 <= ``offset`` < 65535). + +**Attribute:** ``/config/gpio-aggregator///name`` + + The ``name`` attribute sets a custom name for lineY. If left unset, the + line will remain unnamed. + +Once the configuration is done, the ``'live'`` attribute must be set to 1 +in order to instantiate the aggregator device. It can be set back to 0 to +destroy the virtual device. The module will synchronously wait for the new +aggregator device to be successfully probed and if this doesn't happen, writing +to ``'live'`` will result in an error. This is a different behaviour from the +case when you create it using sysfs ``new_device`` interface. + +.. note:: + + For aggregators created via Sysfs, the configfs entries are + auto-generated and appear as ``/config/gpio-aggregator/_sysfs./``. You + cannot add or remove line directories with mkdir(2)/rmdir(2). To modify + lines, you must use the "delete_device" interface to tear down the + existing device and reconfigure it from scratch. However, you can still + toggle the aggregator with the ``live`` attribute and adjust the + ``key``, ``offset``, and ``name`` attributes for each line when ``live`` + is set to 0 by hand (i.e. it's not waiting for deferred probe). + +Sample configuration commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: sh + + # Create a directory for an aggregator device + $ mkdir /sys/kernel/config/gpio-aggregator/agg0 + + # Configure each line + $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0 + $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key + $ echo 6 > /sys/kernel/config/gpio-aggregator/agg0/line0/offset + $ echo test0 > /sys/kernel/config/gpio-aggregator/agg0/line0/name + $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1 + $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key + $ echo 7 > /sys/kernel/config/gpio-aggregator/agg0/line1/offset + $ echo test1 > /sys/kernel/config/gpio-aggregator/agg0/line1/name + + # Activate the aggregator device + $ echo 1 > /sys/kernel/config/gpio-aggregator/agg0/live + + Generic GPIO Driver ------------------- From patchwork Tue Apr 15 06:13:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072674 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQt1T52z1yHt for ; Tue, 15 Apr 2025 16:15:02 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZi-0005dk-27; Tue, 15 Apr 2025 06:15:14 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZf-0005Wj-Pu for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:11 +0000 Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 3D2BA3F1ED for ; Tue, 15 Apr 2025 06:15:11 +0000 (UTC) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-736bf7eb149so3805295b3a.0 for ; Mon, 14 Apr 2025 23:15:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697710; x=1745302510; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IZ/lLH1g7ZBdFIghO7vkn0UTastMX5NLJd4EZFr6sDA=; b=d9zccfWX7JPsxNFiQtZppFOO5Gm0SeswXXOgxzypAVb/wAA6rF4qZOzJSvbPr+KhdQ sHVeLmT11ROHh3uSWluN/xL6xBx8ld7Z+C7JfofGsEWIJrYQWZ1EkN+DABAq7MfxpdiR 9HVHv5HNntI2UQx7/DynaJpmUi86QDcG2H+/WhOdWaxRdWYXrXpGuaCe4YlmZSbfSb4G lZ6glcz0FpGCc461sfO8CbOczEUkW2Ns7YvWYRrCY8CiIrsvCvICEkUjKYlQe2o6J//r rbBSatud3+Vo/7gpif4ykZ8VDkI35ubVDUvSoWHf+HkTQGF59zZVLu4MEtbMNh3vR3ZX Sa+w== X-Gm-Message-State: AOJu0YxcEIvIXd0290l+SWgmdVs8ElodyGpTpdgNTF5ahwknJgTpmfmY DcS8Q5NNFefDdEN4gw6TVgmuEmkoLOpRw42gBKJ6fzRzJ9Bn2sHsMBYGVXBUH3JeibHvyGWegLq j6TCY7BgcLZU3KVTQTYWdYzexySUJ42xjiPH1uP2HOtkuh8E05HhYbzGGpmLC/rIA3sbttAcp3m p9HhB45T4oFA== X-Gm-Gg: ASbGncuULKL+zSJisU6SH+SW5nFs0j1kxtaQQMb89FuEsHwtPrb9a/jr6g7SMeW+yKv MGpM3zs7viZL2sPVjdCXrP8lqwWUycD8m/15xcxFeSl2pATjkTHqhAhQ7pXx8wyqy0tj41Txzks AGDta/cyEApt7Gb9HpJ5wjy6sGShEG0LMxNqiEmg4fg+NjZnYEsroOv1Xi0tKi+jh2D3VaWmIvo VjwqAGFhfqMjFYUaAlIJnWlu+90j2qmTFRKSdAPkNKiceW9V4i7NYSfDQUvfRLyfmDhqswYnDuz Ic+tJMBDeuPCbFR1fDi9g0viMUqpBQ== X-Received: by 2002:aa7:8881:0:b0:739:4902:e364 with SMTP id d2e1a72fcca58-73bd127278amr20751717b3a.19.1744697709010; Mon, 14 Apr 2025 23:15:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFiWxKnymomq2fv3GY1ZslJ+90PpYHIVL0c/Qb5ai60fmNp2n18UlzUcc4vwpEOWZmWJp9r4Q== X-Received: by 2002:aa7:8881:0:b0:739:4902:e364 with SMTP id d2e1a72fcca58-73bd127278amr20751654b3a.19.1744697707920; Mon, 14 Apr 2025 23:15:07 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:07 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 18/19] selftests: gpio: add test cases for gpio-aggregator Date: Tue, 15 Apr 2025 15:13:44 +0900 Message-ID: <4b15577e412e5b0f39c3989d7300f8be4a72f4d5.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 Add a set of tests for gpio-aggregator module. This test covers both pre-existing new_device/delete_device interface and new configfs-based interface. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250407043019.4105613-10-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 6d7f0c1103ef3935eb3f302d09af4ef9e85212a3 linux-next) Signed-off-by: Koichiro Den --- tools/testing/selftests/gpio/Makefile | 2 +- tools/testing/selftests/gpio/config | 1 + .../testing/selftests/gpio/gpio-aggregator.sh | 723 ++++++++++++++++++ 3 files changed, 725 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/gpio/gpio-aggregator.sh diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile index e0884390447d..7bfe315f7001 100644 --- a/tools/testing/selftests/gpio/Makefile +++ b/tools/testing/selftests/gpio/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -TEST_PROGS := gpio-mockup.sh gpio-sim.sh +TEST_PROGS := gpio-mockup.sh gpio-sim.sh gpio-aggregator.sh TEST_FILES := gpio-mockup-sysfs.sh TEST_GEN_PROGS_EXTENDED := gpio-mockup-cdev gpio-chip-info gpio-line-name CFLAGS += -O2 -g -Wall $(KHDR_INCLUDES) diff --git a/tools/testing/selftests/gpio/config b/tools/testing/selftests/gpio/config index 409a8532facc..1287abeaac7e 100644 --- a/tools/testing/selftests/gpio/config +++ b/tools/testing/selftests/gpio/config @@ -2,3 +2,4 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_CDEV=y CONFIG_GPIO_MOCKUP=m CONFIG_GPIO_SIM=m +CONFIG_GPIO_AGGREGATOR=m diff --git a/tools/testing/selftests/gpio/gpio-aggregator.sh b/tools/testing/selftests/gpio/gpio-aggregator.sh new file mode 100755 index 000000000000..f1bab62c4cd2 --- /dev/null +++ b/tools/testing/selftests/gpio/gpio-aggregator.sh @@ -0,0 +1,723 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 Bartosz Golaszewski +# Copyright (C) 2025 Koichiro Den + +BASE_DIR=$(dirname "$0") +CONFIGFS_SIM_DIR="/sys/kernel/config/gpio-sim" +CONFIGFS_AGG_DIR="/sys/kernel/config/gpio-aggregator" +SYSFS_AGG_DIR="/sys/bus/platform/drivers/gpio-aggregator" +MODULE="gpio-aggregator" + +fail() { + echo "$*" >&2 + echo "GPIO $MODULE test FAIL" + exit 1 +} + +skip() { + echo "$*" >&2 + echo "GPIO $MODULE test SKIP" + exit 4 +} + +# gpio-sim +sim_enable_chip() { + local CHIP=$1 + + echo 1 > "$CONFIGFS_SIM_DIR/$CHIP/live" || fail "Unable to enable the chip" +} + +sim_disable_chip() { + local CHIP=$1 + + echo 0 > "$CONFIGFS_SIM_DIR/$CHIP/live" || fail "Unable to disable the chip" +} + +sim_configfs_cleanup() { + local NOCHECK=${1:-0} + + for CHIP_DIR in "$CONFIGFS_SIM_DIR"/*; do + [ -d "$CHIP_DIR" ] || continue + echo 0 > "$CHIP_DIR/live" + find "$CHIP_DIR" -depth -type d -exec rmdir {} \; + done + [ "$NOCHECK" -eq 1 ] && return; + remaining=$(find "$CONFIGFS_SIM_DIR" -mindepth 1 -type d 2> /dev/null) + if [ -n "$remaining" ]; then + fail "Directories remain in $CONFIGFS_SIM_DIR: $remaining" + fi +} + +sim_get_chip_label() { + local CHIP=$1 + local BANK=$2 + local CHIP_NAME=$(cat "$CONFIGFS_SIM_DIR/$CHIP/$BANK/chip_name" 2> /dev/null) || \ + fail "Unable to read the chip name from configfs" + + $BASE_DIR/gpio-chip-info "/dev/$CHIP_NAME" label || \ + fail "Unable to read the chip label from the character device" +} + +# gpio-aggregator +agg_create_chip() { + local CHIP=$1 + + mkdir "$CONFIGFS_AGG_DIR/$CHIP" +} + +agg_remove_chip() { + local CHIP=$1 + + find "$CONFIGFS_AGG_DIR/$CHIP/" -depth -type d -exec rmdir {} \; || \ + fail "Unable to remove $CONFIGFS_AGG_DIR/$CHIP" +} + +agg_create_line() { + local CHIP=$1 + local LINE=$2 + + mkdir "$CONFIGFS_AGG_DIR/$CHIP/$LINE" +} + +agg_remove_line() { + local CHIP=$1 + local LINE=$2 + + rmdir "$CONFIGFS_AGG_DIR/$CHIP/$LINE" +} + +agg_set_key() { + local CHIP=$1 + local LINE=$2 + local KEY=$3 + + echo "$KEY" > "$CONFIGFS_AGG_DIR/$CHIP/$LINE/key" || fail "Unable to set the lookup key" +} + +agg_set_offset() { + local CHIP=$1 + local LINE=$2 + local OFFSET=$3 + + echo "$OFFSET" > "$CONFIGFS_AGG_DIR/$CHIP/$LINE/offset" || \ + fail "Unable to set the lookup offset" +} + +agg_set_line_name() { + local CHIP=$1 + local LINE=$2 + local NAME=$3 + + echo "$NAME" > "$CONFIGFS_AGG_DIR/$CHIP/$LINE/name" || fail "Unable to set the line name" +} + +agg_enable_chip() { + local CHIP=$1 + + echo 1 > "$CONFIGFS_AGG_DIR/$CHIP/live" || fail "Unable to enable the chip" +} + +agg_disable_chip() { + local CHIP=$1 + + echo 0 > "$CONFIGFS_AGG_DIR/$CHIP/live" || fail "Unable to disable the chip" +} + +agg_configfs_cleanup() { + local NOCHECK=${1:-0} + + for CHIP_DIR in "$CONFIGFS_AGG_DIR"/*; do + [ -d "$CHIP_DIR" ] || continue + echo 0 > "$CHIP_DIR/live" 2> /dev/null + find "$CHIP_DIR" -depth -type d -exec rmdir {} \; + done + [ "$NOCHECK" -eq 1 ] && return; + remaining=$(find "$CONFIGFS_AGG_DIR" -mindepth 1 -type d 2> /dev/null) + if [ -n "$remaining" ]; then + fail "Directories remain in $CONFIGFS_AGG_DIR: $remaining" + fi +} + +agg_configfs_dev_name() { + local CHIP=$1 + + cat "$CONFIGFS_AGG_DIR/$CHIP/dev_name" 2> /dev/null || \ + fail "Unable to read the device name from configfs" +} + +agg_configfs_chip_name() { + local CHIP=$1 + local DEV_NAME=$(agg_configfs_dev_name "$CHIP") + local CHIP_LIST=$(find "/sys/devices/platform/$DEV_NAME" \ + -maxdepth 1 -type d -name "gpiochip[0-9]*" 2> /dev/null) + local CHIP_COUNT=$(echo "$CHIP_LIST" | wc -l) + + if [ -z "$CHIP_LIST" ]; then + fail "No gpiochip in /sys/devices/platform/$DEV_NAME/" + elif [ "$CHIP_COUNT" -ne 1 ]; then + fail "Multiple gpiochips unexpectedly found: $CHIP_LIST" + fi + basename "$CHIP_LIST" +} + +agg_get_chip_num_lines() { + local CHIP=$1 + local N_DIR=$(ls -d $CONFIGFS_AGG_DIR/$CHIP/line[0-9]* 2> /dev/null | wc -l) + local N_LINES + + if [ "$(cat $CONFIGFS_AGG_DIR/$CHIP/live)" = 0 ]; then + echo "$N_DIR" + else + N_LINES=$( + $BASE_DIR/gpio-chip-info \ + "/dev/$(agg_configfs_chip_name "$CHIP")" num-lines + ) || fail "Unable to read the number of lines from the character device" + if [ $N_DIR != $N_LINES ]; then + fail "Discrepancy between two sources for the number of lines" + fi + echo "$N_LINES" + fi +} + +agg_get_chip_label() { + local CHIP=$1 + + $BASE_DIR/gpio-chip-info "/dev/$(agg_configfs_chip_name "$CHIP")" label || \ + fail "Unable to read the chip label from the character device" +} + +agg_get_line_name() { + local CHIP=$1 + local OFFSET=$2 + local NAME_CONFIGFS=$(cat "$CONFIGFS_AGG_DIR/$CHIP/line${OFFSET}/name") + local NAME_CDEV + + if [ "$(cat "$CONFIGFS_AGG_DIR/$CHIP/live")" = 0 ]; then + echo "$NAME_CONFIGFS" + else + NAME_CDEV=$( + $BASE_DIR/gpio-line-name \ + "/dev/$(agg_configfs_chip_name "$CHIP")" "$OFFSET" + ) || fail "Unable to read the line name from the character device" + if [ "$NAME_CONFIGFS" != "$NAME_CDEV" ]; then + fail "Discrepancy between two sources for the name of line" + fi + echo "$NAME_CDEV" + fi +} + + +# Load the modules. This will pull in configfs if needed too. +modprobe gpio-sim || skip "unable to load the gpio-sim module" +modprobe gpio-aggregator || skip "unable to load the gpio-aggregator module" + +# Make sure configfs is mounted at /sys/kernel/config. Wait a bit if needed. +for IDX in $(seq 5); do + if [ "$IDX" -eq "5" ]; then + skip "configfs not mounted at /sys/kernel/config" + fi + + mountpoint -q /sys/kernel/config && break + sleep 0.1 +done + +# If the module was already loaded: remove all previous chips +agg_configfs_cleanup +sim_configfs_cleanup + +trap "exit 1" SIGTERM SIGINT +trap "agg_configfs_cleanup 1; sim_configfs_cleanup 1" EXIT + +# Use gpio-sim chips as the test backend +for CHIP in $(seq -f "chip%g" 0 1); do + mkdir $CONFIGFS_SIM_DIR/$CHIP + for BANK in $(seq -f "bank%g" 0 1); do + mkdir -p "$CONFIGFS_SIM_DIR/$CHIP/$BANK" + echo "${CHIP}_${BANK}" > "$CONFIGFS_SIM_DIR/$CHIP/$BANK/label" || \ + fail "unable to set the chip label" + echo 16 > "$CONFIGFS_SIM_DIR/$CHIP/$BANK/num_lines" || \ + fail "unable to set the number of lines" + for IDX in $(seq 0 15); do + LINE_NAME="${CHIP}${BANK}_${IDX}" + LINE_DIR="$CONFIGFS_SIM_DIR/$CHIP/$BANK/line$IDX" + mkdir -p $LINE_DIR + echo "$LINE_NAME" > "$LINE_DIR/name" || fail "unable to set the line name" + done + done + sim_enable_chip "$CHIP" +done + +echo "1. GPIO aggregator creation/deletion" + +echo "1.1. Creation/deletion via configfs" + +echo "1.1.1. Minimum creation/deletion" +agg_create_chip agg0 +agg_create_line agg0 line0 +agg_set_key agg0 line0 "$(sim_get_chip_label chip0 bank0)" +agg_set_offset agg0 line0 5 +agg_set_line_name agg0 line0 test0 +agg_enable_chip agg0 +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 1 || fail "chip unexpectedly dead" +test "$(agg_get_chip_label agg0)" = "$(agg_configfs_dev_name agg0)" || \ + fail "label is inconsistent" +test "$(agg_get_chip_num_lines agg0)" = "1" || fail "number of lines is not 1" +test "$(agg_get_line_name agg0 0)" = "test0" || fail "line name is unset" +agg_disable_chip agg0 +agg_remove_line agg0 line0 +agg_remove_chip agg0 + +echo "1.1.2. Complex creation/deletion" +agg_create_chip agg0 +agg_create_line agg0 line0 +agg_create_line agg0 line1 +agg_create_line agg0 line2 +agg_create_line agg0 line3 +agg_set_key agg0 line0 "$(sim_get_chip_label chip0 bank0)" +agg_set_key agg0 line1 "$(sim_get_chip_label chip0 bank1)" +agg_set_key agg0 line2 "$(sim_get_chip_label chip1 bank0)" +agg_set_key agg0 line3 "$(sim_get_chip_label chip1 bank1)" +agg_set_offset agg0 line0 1 +agg_set_offset agg0 line1 3 +agg_set_offset agg0 line2 5 +agg_set_offset agg0 line3 7 +agg_set_line_name agg0 line0 test0 +agg_set_line_name agg0 line1 test1 +agg_set_line_name agg0 line2 test2 +agg_set_line_name agg0 line3 test3 +agg_enable_chip agg0 +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 1 || fail "chip unexpectedly dead" +test "$(agg_get_chip_label agg0)" = "$(agg_configfs_dev_name agg0)" || \ + fail "label is inconsistent" +test "$(agg_get_chip_num_lines agg0)" = "4" || fail "number of lines is not 1" +test "$(agg_get_line_name agg0 0)" = "test0" || fail "line name is unset" +test "$(agg_get_line_name agg0 1)" = "test1" || fail "line name is unset" +test "$(agg_get_line_name agg0 2)" = "test2" || fail "line name is unset" +test "$(agg_get_line_name agg0 3)" = "test3" || fail "line name is unset" +agg_disable_chip agg0 +agg_remove_line agg0 line0 +agg_remove_line agg0 line1 +agg_remove_line agg0 line2 +agg_remove_line agg0 line3 +agg_remove_chip agg0 + +echo "1.1.3. Can't instantiate a chip without any line" +agg_create_chip agg0 +echo 1 > "$CONFIGFS_AGG_DIR/agg0/live" 2> /dev/null && fail "chip unexpectedly enabled" +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 0 || fail "chip unexpectedly alive" +agg_remove_chip agg0 + +echo "1.1.4. Can't instantiate a chip with invalid configuration" +agg_create_chip agg0 +agg_create_line agg0 line0 +agg_set_key agg0 line0 "chipX_bankX" +agg_set_offset agg0 line0 99 +agg_set_line_name agg0 line0 test0 +echo 1 > "$CONFIGFS_AGG_DIR/agg0/live" 2> /dev/null && fail "chip unexpectedly enabled" +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 0 || fail "chip unexpectedly alive" +agg_remove_line agg0 line0 +agg_remove_chip agg0 + +echo "1.1.5. Can't instantiate a chip asynchronously via deferred probe" +agg_create_chip agg0 +agg_create_line agg0 line0 +agg_set_key agg0 line0 "chip0_bank0" +agg_set_offset agg0 line0 5 +agg_set_line_name agg0 line0 test0 +sim_disable_chip chip0 +echo 1 > "$CONFIGFS_AGG_DIR/agg0/live" 2> /dev/null && fail "chip unexpectedly enabled" +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 0 || fail "chip unexpectedly alive" +sim_enable_chip chip0 +sleep 1 +test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 0 || \ + fail "chip unexpectedly transitioned to 'live' state" +agg_remove_line agg0 line0 +agg_remove_chip agg0 + +echo "1.2. Creation/deletion via sysfs" + +echo "1.2.1. Minimum creation/deletion" +echo "chip0_bank0 0" > "$SYSFS_AGG_DIR/new_device" +CHIPNAME=$(agg_configfs_chip_name _sysfs.0) +test "$(cat "$CONFIGFS_AGG_DIR/_sysfs.0/live")" = 1 || fail "chip unexpectedly dead" +test "$(agg_get_chip_label _sysfs.0)" = "$(agg_configfs_dev_name _sysfs.0)" || \ + fail "label is inconsistent" +test "$(agg_get_chip_num_lines _sysfs.0)" = "1" || fail "number of lines is not 1" +test "$(agg_get_line_name _sysfs.0 0)" = "" || fail "line name is unset" +echo "$(agg_configfs_dev_name _sysfs.0)" > "$SYSFS_AGG_DIR/delete_device" +test -d $CONFIGFS_AGG_DIR/_sysfs.0 && fail "_sysfs.0 unexpectedly remains" +test -d /dev/${CHIPNAME} && fail "/dev/${CHIPNAME} unexpectedly remains" + +echo "1.2.2. Complex creation/deletion" +echo "chip0bank0_0 chip1_bank1 10-11" > "$SYSFS_AGG_DIR/new_device" +CHIPNAME=$(agg_configfs_chip_name _sysfs.0) +test "$(cat "$CONFIGFS_AGG_DIR/_sysfs.0/live")" = 1 || fail "chip unexpectedly dead" +test "$(agg_get_chip_label _sysfs.0)" = "$(agg_configfs_dev_name _sysfs.0)" || \ + fail "label is inconsistent" +test "$(agg_get_chip_num_lines _sysfs.0)" = "3" || fail "number of lines is not 3" +test "$(agg_get_line_name _sysfs.0 0)" = "" || fail "line name is unset" +test "$(agg_get_line_name _sysfs.0 1)" = "" || fail "line name is unset" +test "$(agg_get_line_name _sysfs.0 2)" = "" || fail "line name is unset" +echo "$(agg_configfs_dev_name _sysfs.0)" > "$SYSFS_AGG_DIR/delete_device" +test -d $CONFIGFS_AGG_DIR/_sysfs.0 && fail "_sysfs.0 unexpectedly remains" +test -d /dev/${CHIPNAME} && fail "/dev/${CHIPNAME} unexpectedly remains" + +echo "1.2.3. Asynchronous creation with deferred probe" +sim_disable_chip chip0 +echo 'chip0_bank0 0' > $SYSFS_AGG_DIR/new_device +sleep 1 +test "$(cat "$CONFIGFS_AGG_DIR/_sysfs.0/live")" = 0 || fail "chip unexpectedly alive" +sim_enable_chip chip0 +sleep 1 +CHIPNAME=$(agg_configfs_chip_name _sysfs.0) +test "$(cat "$CONFIGFS_AGG_DIR/_sysfs.0/live")" = 1 || fail "chip unexpectedly remains dead" +test "$(agg_get_chip_label _sysfs.0)" = "$(agg_configfs_dev_name _sysfs.0)" || \ + fail "label is inconsistent" +test "$(agg_get_chip_num_lines _sysfs.0)" = "1" || fail "number of lines is not 1" +test "$(agg_get_line_name _sysfs.0 0)" = "" || fail "line name unexpectedly set" +echo "$(agg_configfs_dev_name _sysfs.0)" > "$SYSFS_AGG_DIR/delete_device" +test -d $CONFIGFS_AGG_DIR/_sysfs.0 && fail "_sysfs.0 unexpectedly remains" +test -d /dev/${CHIPNAME} && fail "/dev/${CHIPNAME} unexpectedly remains" + +echo "1.2.4. Can't instantiate a chip with invalid configuration" +echo "xyz 0" > "$SYSFS_AGG_DIR/new_device" +test "$(cat $CONFIGFS_AGG_DIR/_sysfs.0/live)" = 0 || fail "chip unexpectedly alive" +echo "$(agg_configfs_dev_name _sysfs.0)" > "$SYSFS_AGG_DIR/delete_device" + +echo "2. GPIO aggregator configuration" + +echo "2.1. Configuring aggregators instantiated via configfs" +setup_2_1() { + agg_create_chip agg0 + agg_create_line agg0 line0 + agg_create_line agg0 line1 + agg_set_key agg0 line0 "$(sim_get_chip_label chip0 bank0)" + agg_set_key agg0 line1 "$(sim_get_chip_label chip1 bank0)" + agg_set_offset agg0 line0 1 + agg_set_offset agg0 line1 3 + agg_set_line_name agg0 line0 test0 + agg_set_line_name agg0 line1 test1 + agg_enable_chip agg0 +} +teardown_2_1() { + agg_configfs_cleanup +} + +echo "2.1.1. While offline" + +echo "2.1.1.1. Line can be added/removed" +setup_2_1 +agg_disable_chip agg0 +agg_create_line agg0 line2 +agg_set_key agg0 line2 "$(sim_get_chip_label chip0 bank1)" +agg_set_offset agg0 line2 5 +agg_enable_chip agg0 +test "$(agg_get_chip_num_lines agg0)" = "3" || fail "number of lines is not 1" +teardown_2_1 + +echo "2.1.1.2. Line key can be modified" +setup_2_1 +agg_disable_chip agg0 +agg_set_key agg0 line0 "$(sim_get_chip_label chip0 bank1)" +agg_set_key agg0 line1 "$(sim_get_chip_label chip1 bank1)" +agg_enable_chip agg0 +teardown_2_1 + +echo "2.1.1.3. Line name can be modified" +setup_2_1 +agg_disable_chip agg0 +agg_set_line_name agg0 line0 new0 +agg_set_line_name agg0 line1 new1 +agg_enable_chip agg0 +test "$(agg_get_line_name agg0 0)" = "new0" || fail "line name is unset" +test "$(agg_get_line_name agg0 1)" = "new1" || fail "line name is unset" +teardown_2_1 + +echo "2.1.1.4. Line offset can be modified" +setup_2_1 +agg_disable_chip agg0 +agg_set_offset agg0 line0 5 +agg_set_offset agg0 line1 7 +agg_enable_chip agg0 +teardown_2_1 + +echo "2.1.1.5. Can re-enable a chip after valid reconfiguration" +setup_2_1 +agg_disable_chip agg0 +agg_set_key agg0 line0 "$(sim_get_chip_label chip1 bank1)" +agg_set_offset agg0 line0 15 +agg_set_key agg0 line1 "$(sim_get_chip_label chip0 bank1)" +agg_set_offset agg0 line0 14 +agg_create_line agg0 line2 +agg_set_key agg0 line2 "$(sim_get_chip_label chip0 bank1)" +agg_set_offset agg0 line2 13 +agg_enable_chip agg0 +test "$(agg_get_chip_num_lines agg0)" = "3" || fail "number of lines is not 1" +teardown_2_1 + +echo "2.1.1.7. Can't re-enable a chip with invalid reconfiguration" +setup_2_1 +agg_disable_chip agg0 +agg_set_key agg0 line0 invalidkey +echo 1 > "$CONFIGFS_AGG_DIR/agg0/live" 2> /dev/null && fail "chip unexpectedly enabled" +teardown_2_1 +setup_2_1 +agg_disable_chip agg0 +agg_set_offset agg0 line0 99 +echo 1 > "$CONFIGFS_AGG_DIR/agg0/live" 2> /dev/null && fail "chip unexpectedly enabled" +teardown_2_1 + +echo "2.1.2. While online" + +echo "2.1.2.1. Can't add/remove line" +setup_2_1 +mkdir "$CONFIGFS_AGG_DIR/agg0/line2" 2> /dev/null && fail "line unexpectedly added" +rmdir "$CONFIGFS_AGG_DIR/agg0/line1" 2> /dev/null && fail "line unexpectedly removed" +teardown_2_1 + +echo "2.1.2.2. Can't modify line key" +setup_2_1 +echo "chip1_bank1" > "$CONFIGFS_AGG_DIR/agg0/line0/key" 2> /dev/null && \ + fail "lookup key unexpectedly updated" +teardown_2_1 + +echo "2.1.2.3. Can't modify line name" +setup_2_1 +echo "new0" > "$CONFIGFS_AGG_DIR/agg0/line0/name" 2> /dev/null && \ + fail "name unexpectedly updated" +teardown_2_1 + +echo "2.1.2.4. Can't modify line offset" +setup_2_1 +echo "5" > "$CONFIGFS_AGG_DIR/agg0/line0/offset" 2> /dev/null && \ + fail "offset unexpectedly updated" +teardown_2_1 + +echo "2.2. Configuring aggregators instantiated via sysfs" +setup_2_2() { + echo "chip0_bank0 1 chip1_bank0 3" > "$SYSFS_AGG_DIR/new_device" +} +teardown_2_2() { + echo "$(agg_configfs_dev_name _sysfs.0)" > "$SYSFS_AGG_DIR/delete_device" +} + +echo "2.2.1. While online" + +echo "2.2.1.1. Can toggle live" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_enable_chip _sysfs.0 +teardown_2_2 + +echo "2.2.1.2. Can't add/remove line" +setup_2_2 +mkdir "$CONFIGFS_AGG_DIR/_sysfs.0/line2" 2> /dev/null && fail "line unexpectedly added" +rmdir "$CONFIGFS_AGG_DIR/_sysfs.0/line1" 2> /dev/null && fail "line unexpectedly removed" +teardown_2_2 + +echo "2.2.1.3. Can't modify line key" +setup_2_2 +echo "chip1_bank1" > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/key" 2> /dev/null && \ + fail "lookup key unexpectedly updated" +teardown_2_2 + +echo "2.2.1.4. Can't modify line name" +setup_2_2 +echo "new0" > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/name" 2> /dev/null && \ + fail "name unexpectedly updated" +teardown_2_2 + +echo "2.2.1.5. Can't modify line offset" +setup_2_2 +echo "5" > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/offset" 2> /dev/null && \ + fail "offset unexpectedly updated" +teardown_2_2 + +echo "2.2.2. While waiting for deferred probe" + +echo "2.2.2.1. Can't add/remove line despite live = 0" +sim_disable_chip chip0 +setup_2_2 +mkdir "$CONFIGFS_AGG_DIR/_sysfs.0/line2" 2> /dev/null && fail "line unexpectedly added" +rmdir "$CONFIGFS_AGG_DIR/_sysfs.0/line1" 2> /dev/null && fail "line unexpectedly removed" +teardown_2_2 +sim_enable_chip chip0 + +echo "2.2.2.2. Can't modify line key" +sim_disable_chip chip0 +setup_2_2 +echo "chip1_bank1" > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/key" 2> /dev/null && \ + fail "lookup key unexpectedly updated" +teardown_2_2 +sim_enable_chip chip0 + +echo "2.2.2.3. Can't modify line name" +sim_disable_chip chip0 +setup_2_2 +echo "new0" > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/name" 2> /dev/null && \ + fail "name unexpectedly updated" +teardown_2_2 +sim_enable_chip chip0 + +echo "2.2.2.4. Can't modify line offset" +sim_disable_chip chip0 +setup_2_2 +echo 5 > "$CONFIGFS_AGG_DIR/_sysfs.0/line0/offset" 2> /dev/null && \ + fail "offset unexpectedly updated" +teardown_2_2 +sim_enable_chip chip0 + +echo "2.2.2.5. Can't toggle live" +sim_disable_chip chip0 +setup_2_2 +test "$(cat "$CONFIGFS_AGG_DIR/_sysfs.0/live")" = 0 || fail "chip unexpectedly alive" +echo 1 > "$CONFIGFS_AGG_DIR/_sysfs.0/live" 2> /dev/null && fail "chip unexpectedly enabled" +teardown_2_2 +sim_enable_chip chip0 + +echo "2.2.3. While offline" + +echo "2.2.3.1. Can't add/remove line despite live = 0" +setup_2_2 +agg_disable_chip _sysfs.0 +mkdir "$CONFIGFS_AGG_DIR/_sysfs.0/line2" 2> /dev/null && fail "line unexpectedly added" +rmdir "$CONFIGFS_AGG_DIR/_sysfs.0/line1" 2> /dev/null && fail "line unexpectedly removed" +teardown_2_2 + +echo "2.2.3.2. Line key can be modified" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_key _sysfs.0 line0 "$(sim_get_chip_label chip0 bank1)" +agg_set_key _sysfs.0 line1 "$(sim_get_chip_label chip1 bank1)" +agg_enable_chip _sysfs.0 +teardown_2_2 + +echo "2.2.3.3. Line name can be modified" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_line_name _sysfs.0 line0 new0 +agg_set_line_name _sysfs.0 line1 new1 +agg_enable_chip _sysfs.0 +test "$(agg_get_line_name _sysfs.0 0)" = "new0" || fail "line name is unset" +test "$(agg_get_line_name _sysfs.0 1)" = "new1" || fail "line name is unset" +teardown_2_2 + +echo "2.2.3.4. Line offset can be modified" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_offset _sysfs.0 line0 5 +agg_set_offset _sysfs.0 line1 7 +agg_enable_chip _sysfs.0 +teardown_2_2 + +echo "2.2.3.5. Can re-enable a chip with valid reconfiguration" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_key _sysfs.0 line0 "$(sim_get_chip_label chip1 bank1)" +agg_set_offset _sysfs.0 line0 15 +agg_set_key _sysfs.0 line1 "$(sim_get_chip_label chip0 bank1)" +agg_set_offset _sysfs.0 line0 14 +agg_enable_chip _sysfs.0 +teardown_2_2 + +echo "2.2.3.6. Can't re-enable a chip with invalid reconfiguration" +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_key _sysfs.0 line0 invalidkey +echo 1 > "$CONFIGFS_AGG_DIR/_sysfs.0/live" 2> /dev/null && fail "chip unexpectedly enabled" +teardown_2_2 +setup_2_2 +agg_disable_chip _sysfs.0 +agg_set_offset _sysfs.0 line0 99 +echo 1 > "$CONFIGFS_AGG_DIR/_sysfs.0/live" 2> /dev/null && fail "chip unexpectedly enabled" +teardown_2_2 + +echo "3. Module unload" + +echo "3.1. Can't unload module if there is at least one device created via configfs" +agg_create_chip agg0 +modprobe -r gpio-aggregator 2> /dev/null +test -d /sys/module/gpio_aggregator || fail "module unexpectedly unloaded" +agg_remove_chip agg0 + +echo "3.2. Can unload module if there is no device created via configfs" +echo "chip0_bank0 1 chip1_bank0 3" > "$SYSFS_AGG_DIR/new_device" +modprobe -r gpio-aggregator 2> /dev/null +test -d /sys/module/gpio_aggregator && fail "module unexpectedly remains to be loaded" +modprobe gpio-aggregator 2> /dev/null + +echo "4. GPIO forwarder functional" +SETTINGS="chip0:bank0:2 chip0:bank1:4 chip1:bank0:6 chip1:bank1:8" +setup_4() { + local OFFSET=0 + agg_create_chip agg0 + for SETTING in $SETTINGS; do + CHIP=$(echo "$SETTING" | cut -d: -f1) + BANK=$(echo "$SETTING" | cut -d: -f2) + LINE=$(echo "$SETTING" | cut -d: -f3) + agg_create_line agg0 "line${OFFSET}" + agg_set_key agg0 "line${OFFSET}" "$(sim_get_chip_label "$CHIP" "$BANK")" + agg_set_offset agg0 "line${OFFSET}" "$LINE" + OFFSET=$(expr $OFFSET + 1) + done + agg_enable_chip agg0 +} +teardown_4() { + agg_configfs_cleanup +} + +echo "4.1. Forwarding set values" +setup_4 +OFFSET=0 +for SETTING in $SETTINGS; do + CHIP=$(echo "$SETTING" | cut -d: -f1) + BANK=$(echo "$SETTING" | cut -d: -f2) + LINE=$(echo "$SETTING" | cut -d: -f3) + DEVNAME=$(cat "$CONFIGFS_SIM_DIR/$CHIP/dev_name") + CHIPNAME=$(cat "$CONFIGFS_SIM_DIR/$CHIP/$BANK/chip_name") + VAL_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio${LINE}/value" + test $(cat $VAL_PATH) = "0" || fail "incorrect value read from sysfs" + $BASE_DIR/gpio-mockup-cdev -s 1 "/dev/$(agg_configfs_chip_name agg0)" "$OFFSET" & + mock_pid=$! + sleep 0.1 # FIXME Any better way? + test "$(cat $VAL_PATH)" = "1" || fail "incorrect value read from sysfs" + kill "$mock_pid" + OFFSET=$(expr $OFFSET + 1) +done +teardown_4 + +echo "4.2. Forwarding set config" +setup_4 +OFFSET=0 +for SETTING in $SETTINGS; do + CHIP=$(echo "$SETTING" | cut -d: -f1) + BANK=$(echo "$SETTING" | cut -d: -f2) + LINE=$(echo "$SETTING" | cut -d: -f3) + DEVNAME=$(cat "$CONFIGFS_SIM_DIR/$CHIP/dev_name") + CHIPNAME=$(cat "$CONFIGFS_SIM_DIR/$CHIP/$BANK/chip_name") + VAL_PATH="/sys/devices/platform/$DEVNAME/$CHIPNAME/sim_gpio${LINE}/value" + $BASE_DIR/gpio-mockup-cdev -b pull-up "/dev/$(agg_configfs_chip_name agg0)" "$OFFSET" + test $(cat "$VAL_PATH") = "1" || fail "incorrect value read from sysfs" + OFFSET=$(expr $OFFSET + 1) +done +teardown_4 + +echo "5. Race condition verification" + +echo "5.1. Stress test of new_device/delete_device and module load/unload" +for _ in $(seq 1000); do + { + echo "dummy 0" > "$SYSFS_AGG_DIR/new_device" + cat "$CONFIGFS_AGG_DIR/_sysfs.0/dev_name" > "$SYSFS_AGG_DIR/delete_device" + } 2> /dev/null +done & +writer_pid=$! +while kill -0 "$writer_pid" 2> /dev/null; do + { + modprobe gpio-aggregator + modprobe -r gpio-aggregator + } 2> /dev/null +done + +echo "GPIO $MODULE test PASS" From patchwork Tue Apr 15 06:13:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2072677 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4ZcDQw3hd6z1yHt for ; Tue, 15 Apr 2025 16:15:04 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1u4ZZk-0005lB-Dc; Tue, 15 Apr 2025 06:15:16 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1u4ZZf-0005Vr-Cb for kernel-team@lists.ubuntu.com; Tue, 15 Apr 2025 06:15:11 +0000 Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 0B8773F091 for ; Tue, 15 Apr 2025 06:15:11 +0000 (UTC) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-225429696a9so66459755ad.1 for ; Mon, 14 Apr 2025 23:15:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744697709; x=1745302509; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JLP1CjVkmPz/FlR7hyVMTN7gM21HSw9cJrWdfMsG6ro=; b=EE1eyjEA2hN2gbUw749DXfuX7ynn5eDNgRa0bDeypAfGapcxZq9Q2HkStPRmmm3oT2 GdOQbWZV3SNnb81DLv0PxfT/XvI17J559q+wRDVAnbW7+O/6hWlcBlMzK56KbveW3+GQ oQZ6YLenAqWYKD2P8SyHHl30+QE9bQzT9tGnxabXy5dbcurbGEWkt1Fl7DhbHr3h/4Cj 9UjRJGmHcdcq8N+oV9XvbMATlz9iIE8Xay7fQPcBHXhyjmZiW2g0yUFPMqX6bxp+tc65 Pl1CaDjpvcQAc0Pwkg/DjCyXYoj9/HrmfTzJo7brkPaPPOEQ5BOyGi5A6chU7RLwTujy skuQ== X-Gm-Message-State: AOJu0YyqzeZkSgTErhCw36rEW+HSKZyZSX3nga/FAPPSAYogiOhABF4E aXbRfLf9/p2DHCnTOjYxy5joYiGmFuW1jYsviZo5eqcOcREbStlwbSjtuaP4GsVk2PnM68p84ZA kbUgH1485uAxZxIYDLQxhJXWJVp6r7o+jsIZ7nuawAlnt6hh1pRt6j1lQiEWHyQ88M9qwx9oZRh vyUjy+DQS9uQ== X-Gm-Gg: ASbGncuNX1ZJKM0jNgPe/qjgRkvsRsVGL8hI+sQg9rW4wpp75a2/79ged/7Wy8rfX+m EG4ZGVZ7gxfo79LRMJz46qD/bUprypOJKRb107I1XRMKdher0mvHi+baNmz75/UPVJVDFhWVSYw uvrhlpGxcOatRQac63wI3BvpT1VTQ7QhcGQQ+eaWn9oT8eY/PQ8vMZiDrOFFoT7dJy98yY9ckGj /N+7l+06dQfI5ArHcI8JECY+0b1Mo5zDbpX0NQcRkudDECD10OdinS/xU0Ca1kVb5UWvA+qTP69 4b9gU4NoQ8Uo9msIPUMQ1Oi8u6gGzA== X-Received: by 2002:a17:903:985:b0:216:2bd7:1c4a with SMTP id d9443c01a7336-22bea4c6897mr218919785ad.26.1744697709569; Mon, 14 Apr 2025 23:15:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGIN1axZ9luUZbEMT6WsLt5zrFz0mEqG7yNc1fWWX9KWUN91TGk6qhC7yvO9VAWmtUw3fqMxA== X-Received: by 2002:a17:903:985:b0:216:2bd7:1c4a with SMTP id d9443c01a7336-22bea4c6897mr218919515ad.26.1744697709241; Mon, 14 Apr 2025 23:15:09 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:a31c:d1db:5e23:e8fb]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73bd230ddaasm7909286b3a.138.2025.04.14.23.15.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Apr 2025 23:15:08 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][O][PATCH v2 19/19] UBUNTU: SAUCE: selftests: gpio: gpio-aggregator: add a test case for _sysfs prefix reservation Date: Tue, 15 Apr 2025 15:13:45 +0900 Message-ID: <1e2a3f608c054bc3a63b0a4699b2c42d689ebf43.1744694749.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174469458477.3554672.3738856905360736202@z790sl> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2103496 The kernel doc for gpio-aggregator configfs interface, which was recently added, states that users should not be able to create an aggregator with a name prefixed by "_sysfs" via configfs. However, it was found that this guard does not function as expected (thanks to Dan Carpenter for identifying and fixing the issue). Add a test case to verify the guard. Signed-off-by: Koichiro Den Link: https://lore.kernel.org/r/20250412150119.1461023-1-koichiro.den@canonical.com Signed-off-by: Bartosz Golaszewski (cherry picked from commit 290ffcfe3042dcd5b701a98edd48d7962d35556b gpio/for-next) Signed-off-by: Koichiro Den --- tools/testing/selftests/gpio/gpio-aggregator.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/selftests/gpio/gpio-aggregator.sh b/tools/testing/selftests/gpio/gpio-aggregator.sh index f1bab62c4cd2..9b6f80ad9f8a 100755 --- a/tools/testing/selftests/gpio/gpio-aggregator.sh +++ b/tools/testing/selftests/gpio/gpio-aggregator.sh @@ -335,6 +335,10 @@ test "$(cat "$CONFIGFS_AGG_DIR/agg0/live")" = 0 || \ agg_remove_line agg0 line0 agg_remove_chip agg0 +echo "1.1.6. Can't instantiate a chip with _sysfs prefix" +mkdir "$CONFIGFS_AGG_DIR/_sysfs" 2> /dev/null && fail "chip _sysfs unexpectedly created" +mkdir "$CONFIGFS_AGG_DIR/_sysfs.foo" 2> /dev/null && fail "chip _sysfs.foo unexpectedly created" + echo "1.2. Creation/deletion via sysfs" echo "1.2.1. Minimum creation/deletion"