From patchwork Fri Apr 11 07:26:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071386 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 4ZYpF63hz4z1yHt for ; Fri, 11 Apr 2025 17:28:10 +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 1u38oH-0005mt-E8; Fri, 11 Apr 2025 07:28:21 +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 1u38o3-0004G5-9B for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:07 +0000 Received: from mail-pg1-f200.google.com (mail-pg1-f200.google.com [209.85.215.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 6F7AF3FB77 for ; Fri, 11 Apr 2025 07:28:05 +0000 (UTC) Received: by mail-pg1-f200.google.com with SMTP id 41be03b00d2f7-af8e645a1d1so1258820a12.3 for ; Fri, 11 Apr 2025 00:28:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356483; x=1744961283; 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=qgUk4oLMpCzEgd1KDpf8WgELB7Rs5MGoUdTl6bs2XXY=; b=eAK0t3wmllna92nK74lzDHF4gUDu0Qez8t4OucEBhcLxr4ljGWROUgrO1Jy2ntifoY i6pw60ewhoUJvAv5xrcFou82Bid8FQQLjDJJMuIRhoYiDbLCPwAtWZeTdgagxpP9Rcm/ QaCCqUYOtX97hNniyPeXxNR8CSMZef1Y8mmXLZBSorGZI2MSuGqJSPr0cZqSMj/560Lo bsWu8H3KHHI9h0x41/uR4p9bECpRwYbNGEjTVRXTcmYUpABjtava3xIqbHdQVJ4X2aMU Lp/iCcQcgRu5NrhPlEqHeX+U5AWb/120kbd88bBiSIO5x1bnWnEYN8Q1o4VtcyvhvxSM jCDQ== X-Gm-Message-State: AOJu0YynbFDVfvI2w3xzGwyBnymf4FaEgM5ry23t62sXhgfkgZGD69U9 +9VskrvicjfAdnnhEgXGxW/mv6hOSl4ELlm2P7bwNfFLhuSHgA/K2n4wkpBsWkIlYHkhBamJMB0 dfOkwC4oJ6AtEjuC9Ywl6rDZgU0KQFzLJ5gZnE3aQNJKl0aC94MvMdeG9v6FUU2AWWod3w2xkC9 M6clGQQfghAQ== X-Gm-Gg: ASbGncse9H/8Aqj0qKQd+No5amfDPa+ECzm7H6y6EB/YVMlKvF0ah1b2CP+IqUtcaAA rl8st6w+1YQioXWVjGzAOF9suR52UQG+40/C9yqb7YQlb4eUDgYG/y+1wIjR9vzui0uQVy1BAE0 FHgvrBT9TfSHDVKtUjFVx8Rq2U1zFqBRjSYE/FUGJKurxQsXuN+lUoLl2AYY0U4X+VFXqYC5CNE zB4HpqNGYpnnGsYJYdP4Z7oWNchIENzzNn9pK26kKEZoxZlZ4g86kXn/8DNfpQkKCbCud3zBowJ K7uiVZkBSuRixxD3UHw9xP03NmjXKA== X-Received: by 2002:a17:902:f706:b0:221:85:f384 with SMTP id d9443c01a7336-22bea4adfadmr26087025ad.16.1744356483509; Fri, 11 Apr 2025 00:28:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFlqFATC8AiUVf41G5IVYH4nUu98DKutwRvQDGSYU9q3KRidK4izw2y7S25NB9myjhPuarXeg== X-Received: by 2002:a17:902:f706:b0:221:85:f384 with SMTP id d9443c01a7336-22bea4adfadmr26086785ad.16.1744356483122; Fri, 11 Apr 2025 00:28:03 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:02 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 01/12] gpio: introduce utilities for synchronous fake device creation Date: Fri, 11 Apr 2025 16:26:52 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit eb5ab6ffb4ca2d28121455dd7452061367ed5588) [koichiroden: add explicit #include ] Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 3 ++ drivers/gpio/Makefile | 3 ++ drivers/gpio/dev-sync-probe.c | 98 +++++++++++++++++++++++++++++++++++ drivers/gpio/dev-sync-probe.h | 25 +++++++++ 4 files changed, 129 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 46f6dd10ba50..53725c0da764 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1713,3 +1713,6 @@ config GPIO_VIRTIO endmenu endif + +config DEV_SYNC_PROBE + tristate diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ed76dc626698..6f4bddd8eb88 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -18,6 +18,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..49fab00357dd --- /dev/null +++ b/drivers/gpio/dev-sync-probe.c @@ -0,0 +1,98 @@ +// 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 + +#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 Fri Apr 11 07:26:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071387 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 4ZYpF83wDzz1yHt for ; Fri, 11 Apr 2025 17:28:12 +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 1u38oJ-000656-SY; Fri, 11 Apr 2025 07:28:23 +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 1u38o3-0004Iu-Iq for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:07 +0000 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.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-0.canonical.com (Postfix) with ESMTPS id 61E813F169 for ; Fri, 11 Apr 2025 07:28:06 +0000 (UTC) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2242ade807fso27280415ad.2 for ; Fri, 11 Apr 2025 00:28:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356484; x=1744961284; 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=k4U7taaPrHCRW6OaDkyr1ijgqs7CrbdF+c2QhhBAoe4=; b=QmUOi40SyWRFMsVdrGRw0gzVzPFaRha9dI2N2voDP0EYIidjqvVEkIKEdm/iaOghyN JkaMIeVjxmxIbqRoB4J39xSj4nMjJkaLomCcdCZRTPozcyhh1CbHC0o0sE9fky8B4WWe E73Iwsncj0EkBhdvq/6s1Huv+QasgoOjA3XChB/cvs8icMYn7JQZa1mY5tj650JAw3Qn jGtfFABzyUOFnw+ztBN75yB6jdl8EqNNeLLMrtOv2TOLsLOdDyfqE/wtbTqdao5L44YT +dk++6GfQjYSJ7qcbFVyas7lthQVP0nCEKfcyMsRAJaFyiR2DM4TfYadBsCNctMWIiHo Y+UQ== X-Gm-Message-State: AOJu0YxnbTX0hpVebshk1Py0336/UvwHjUumcUi/DrbbN7QerV5s9iYx nLFz8RnQ3mqEiQk6K4fXaBFPw2HZ5fRWVLU6yekbkttV0OdMxyaYQQHo+J7657AUPKC9n7oyuDd GpQKbtq0A9RJ8tZahUr6/Cvihlg/xxoWhDabzSDtMk4e8xdNI0NsWaVRtzAUmPq+LEIZwja5bFe NHjh28dYh3HA== X-Gm-Gg: ASbGncvNNKKi9zOPaVS/nXLo6dcpYJuAKYZMy/1kfwQyXF7R3V0n+jmpIrAa3C++3cw IWQlivyhUxGc9Sy4F/BckJ+aAyhqD6yWcwmrrU90+NxILuRl9ZMma8JyjOmSqOsU6QgRSO6diD5 WgLrTba5XuQBjgV73zwvjzeUgT3fdKoZMv2LJowmJck6PUMLo2qj7sT6Wn6Rf+V8AhaU8CRMqph q78YBcDkdF9b4hCrcPIwc/nPjo/Lucc0N2oQkvF0LiKfUj8nKSIIg2YZKAhJXoFjtUJ/ZDHqgWd pi5ppPu+36dafXDXvMS6LyvFGaVzMQ== X-Received: by 2002:a17:903:41cd:b0:224:26f5:9c1e with SMTP id d9443c01a7336-22bea4955d3mr23818165ad.2.1744356484675; Fri, 11 Apr 2025 00:28:04 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGUC1VLjeej5fTMrBMY7loppMM8Xu8nUl6IEn8qW1YY1772xdc2d/NjUhSLTDvldfw+/UoxOA== X-Received: by 2002:a17:903:41cd:b0:224:26f5:9c1e with SMTP id d9443c01a7336-22bea4955d3mr23817965ad.2.1744356484344; Fri, 11 Apr 2025 00:28:04 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:04 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 02/12] gpio: aggregator: Stop using ARCH_NR_GPIOS Date: Fri, 11 Apr 2025 16:26:53 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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: Christophe Leroy BugLink: https://bugs.launchpad.net/bugs/2103496 ARCH_NR_GPIOS is used locally in aggr_parse() as the maximum number of GPIOs to be aggregated together by the driver since commit ec75039d5550 ("gpio: aggregator: Use bitmap_parselist() for parsing GPIO offsets"). Don't rely on the total possible number of GPIOs in the system but define a local arbitrary macro for that, set to 512 which should be large enough as it is also the default value for ARCH_NR_GPIOS. Signed-off-by: Christophe Leroy Reviewed-by: Geert Uytterhoeven Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski (cherry picked from commit 95b39792c6646322e0684f1a1aa395ee82b6f3fb) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 4cd80d42bcc0..43e7112c35cd 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -23,6 +23,7 @@ #include #include +#define AGGREGATOR_MAX_GPIOS 512 /* * GPIO Aggregator sysfs interface @@ -64,7 +65,7 @@ static int aggr_parse(struct gpio_aggregator *aggr) unsigned int i, n = 0; int error = 0; - bitmap = bitmap_alloc(ARCH_NR_GPIOS, GFP_KERNEL); + bitmap = bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); if (!bitmap) return -ENOMEM; @@ -84,13 +85,13 @@ static int aggr_parse(struct gpio_aggregator *aggr) } /* GPIO chip + offset(s) */ - error = bitmap_parselist(offsets, bitmap, ARCH_NR_GPIOS); + error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); if (error) { pr_err("Cannot parse %s: %d\n", offsets, error); goto free_bitmap; } - for_each_set_bit(i, bitmap, ARCH_NR_GPIOS) { + for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { error = aggr_add_gpio(aggr, name, i, &n); if (error) goto free_bitmap; From patchwork Fri Apr 11 07:26:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071385 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 4ZYpF53flHz1yHt for ; Fri, 11 Apr 2025 17:28:09 +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 1u38oF-0005au-QS; Fri, 11 Apr 2025 07:28:19 +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 1u38o5-0004Kp-TB for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:09 +0000 Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) (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 69EAC3FB7B for ; Fri, 11 Apr 2025 07:28:07 +0000 (UTC) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-306b51e30ffso1532159a91.1 for ; Fri, 11 Apr 2025 00:28:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356486; x=1744961286; 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=7hlrV5ViUFW/zN8Z8qW/z36B6UY4IZLwLXISwZtMIl8=; b=KuwAYsSP6zzGPASpTecaDVjX3YExqGJVqeNHMAdYfKmsREFhMUMFq9rB8846qpmK0Y 65vqLPS9536btIPgP8XnRRiEs90MinkGXN92uBxGuhd7SORWkAvrZzHDRah7kG8mQsrA C/Imcx3WNrB8MWHbfe/uB5bN91DdBlA2gA02O4l8Mg9GKY9lNZ/Ktm103Rz7JDwfMFH/ kJlEu1X9sgTNhLpf/BepO7ilYZUbnRDfIBsJKixW32RGTB9xwbXBxH8pwpTK0Yd/HYw/ BK0gJCGkdRnNnZa8USEtQP71ElDaCbLSockXmeaDnBhYAq0uuH3awRlCwbVlweOAiCtg JtUg== X-Gm-Message-State: AOJu0Yz59kZmOHm+ZO8IG8XordzQyDNpDsMPyvqdsCAhBmUQ1ETSQoul B+0zTEuh5j2ovbd76f2Jf2Xfat3EO5WVLyzWL7vpUZ7HzJO9YuGPlzPV1hLb3RAGQL8wbNO23VB GhjWB132jthSVsPaMorKSufj+CsxSwTQMrt9gTUBm6nSiJ77Vtuh87clDE0xX/DyBzxHmf9m6+C yXZOAP4k9l3Q== X-Gm-Gg: ASbGncuH9cUvVZmctTDS9N03F2nYg+Hlxmn0kr9QOSubLnKsTNTH2Sk55BNN3pGhlSd LrCgxFT/hJnpaYi/q9IfM71Grhqo2VHbj08mNXLSL6WZmRVhNBKz6KDcF2ZPum1mUpwZDvtIlDt D0vMEo/1if77P0Mk9TuKvAFEgZkZAds+KvDQFB0idvLaKVkUUlDDJHQBb4uhK6B360siG3KgIYl xKqN4QmQ3OCCgUF1rNC2uDUwRfAz1J8XudU7P8ry5oWMOsqP/OHHRui3t9ax+rUmTv7gtLpzrYT p1w6PmQxOwm37MnDXoFjjmrJzs3ChQ== X-Received: by 2002:a17:90b:2891:b0:2ee:db8a:2a01 with SMTP id 98e67ed59e1d1-308237ce137mr2771302a91.30.1744356485882; Fri, 11 Apr 2025 00:28:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEjplZOzFW9N8UGQMPG/fezEfu2/TA77aGdOBWyr6p+GxtsDi8R7CEbJWmkAeb73XlALtoAdw== X-Received: by 2002:a17:90b:2891:b0:2ee:db8a:2a01 with SMTP id 98e67ed59e1d1-308237ce137mr2771282a91.30.1744356485501; Fri, 11 Apr 2025 00:28:05 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:05 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 03/12] gpio: aggregator: Add missing header(s) Date: Fri, 11 Apr 2025 16:26:54 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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: Andy Shevchenko BugLink: https://bugs.launchpad.net/bugs/2103496 Do not imply that some of the generic headers may be always included. Instead, include explicitly what we are direct user of. While at it, drop unused linux/gpio.h and split out the GPIO group of headers. Signed-off-by: Andy Shevchenko Reviewed-by: Geert Uytterhoeven (cherry picked from commit 39ebbd52b73db8598e3399ba3ac9333902251975) Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 43e7112c35cd..577e4e4a77a6 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -10,19 +10,20 @@ #include #include #include -#include -#include -#include -#include #include #include #include #include #include #include +#include #include #include +#include +#include +#include + #define AGGREGATOR_MAX_GPIOS 512 /* From patchwork Fri Apr 11 07:26:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071388 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 4ZYpFB1BFmz1yHt for ; Fri, 11 Apr 2025 17:28:14 +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 1u38oL-0006Hi-Lg; Fri, 11 Apr 2025 07:28:25 +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 1u38o8-0004UK-Ef for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:12 +0000 Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (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 B534D3FB7D for ; Fri, 11 Apr 2025 07:28:08 +0000 (UTC) Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-2ff78dd28ecso2011854a91.1 for ; Fri, 11 Apr 2025 00:28:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356487; x=1744961287; 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=f8V1z2utMO1DVMBNwrglPV/fCn9K1o3m1BUMx1Uvmto=; b=QLmsHybKurNxMeszkKK5A7m2gS+pXyJR0YDyc+ZSRl1j0PwSU6P3F56y3+fGmlWP0M uez2M/mnI5N4FeiLBPPcFinPg25Y3AKHvTJva3RAOp29T5fYxztVZm7+kMnIvX4upI/+ k8fczS7w98wUacO62MmVmdODj0UUaAieY2VWOL3l7WMh86UfEGdniEFIqHvG2QWl4igv PCAVOtLEFb8eUNhw4Sh7PcWCO+MCnTLYaeToZPydH80Hv1JP8lRVeb6GlDqgfaO5GJ9I FD5/B5g5rBp2kQcJ+Tpx5tQPhnVG4DwTqRY1SiX8cnciM0PoQvQGYE7AZfEXtgipSoCA 9oQQ== X-Gm-Message-State: AOJu0Yz1JoRcpHLAWs5N5QQKAHUnjFplNpmAtD/Ass2+5OLWrNTZVw1Q LpRKK+uFmjpvH8MnCdl8eL2ZAq8i5tll7hBY5o6Qe7kQIAgZJY4mZPqXXrzP7aLLxayru9CD/3p tB6yReq3cYzgArn7WMuxLleDXHqSJbuhnUB2NlSOr0IhToEKsCwmH/lVNWvkG4N/9R08mGN3/yN qWrdRRNGyLUw== X-Gm-Gg: ASbGncueRdpMMQBC80RpjiafbIS07yTnNwphaE2sXy2C5kK2s4yre0TNxy4MxMcqJcY fsCoxKUsgkyhqZoqp7IPVjMMlsehd7/RXqU2dvI5l812Vt3Ci0dt+B3edIku4nQE3S/VS/t5ABT zGKAB7/4VzRTv9MayHleJH0bQ42i8b6KB9Ex3EtT5heaLunLAKvZt4tIWNat6IATWwgJfkZuypO F7w9PPncUbjcKxbzAIebSPqAiSJZv632UCuX0nyYfmlga7A8zgoAwuJZubZRlygA7WTnD7siveN sQZMxomKZXH72VsO+Vpf3LUHbQVk5g== X-Received: by 2002:a17:90b:582b:b0:2fe:a515:4a98 with SMTP id 98e67ed59e1d1-3082378416bmr2671329a91.31.1744356487102; Fri, 11 Apr 2025 00:28:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFmkm44r8Guz8LHNqmlUb+W2z1RYWPj4yGHNWH6HJtbs3J6QDKXQCveozxdBNIFKXPvs/790Q== X-Received: by 2002:a17:90b:582b:b0:2fe:a515:4a98 with SMTP id 98e67ed59e1d1-3082378416bmr2671312a91.31.1744356486685; Fri, 11 Apr 2025 00:28:06 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:06 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 04/12] gpio: aggregator: reorder functions to prepare for configfs introduction Date: Fri, 11 Apr 2025 16:26:55 +0900 Message-ID: <7afa035932f72762b89d6babc2d71e516a34f9b3.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit 7a56efeabffd13a162073068b8e29113c65f9e64 linux-next) [koichiroden: adjusted context due to missing commit: 22dec5aa596e ("gpio: aggregator: simplify aggr_parse() with scoped bitmap")] Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 384 +++++++++++++++++---------------- 1 file changed, 194 insertions(+), 190 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 577e4e4a77a6..efab5aa2035a 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -58,196 +58,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 long *bitmap; - unsigned int i, n = 0; - int error = 0; - - 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) - goto free_bitmap; - - 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); - goto free_bitmap; - } - - for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error = aggr_add_gpio(aggr, name, i, &n); - if (error) - goto free_bitmap; - } - - args = next_arg(args, &name, &p); - } - - if (!n) { - pr_err("No GPIOs specified\n"); - error = -EINVAL; - } - -free_bitmap: - bitmap_free(bitmap); - return error; -} - -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 @@ -475,6 +285,186 @@ 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 long *bitmap; + unsigned int i, n = 0; + int error = 0; + + 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) + goto free_bitmap; + + 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); + goto free_bitmap; + } + + for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { + error = aggr_add_gpio(aggr, name, i, &n); + if (error) + goto free_bitmap; + } + + args = next_arg(args, &name, &p); + } + + if (!n) { + pr_err("No GPIOs specified\n"); + error = -EINVAL; + } + +free_bitmap: + bitmap_free(bitmap); + return error; +} + +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 */ @@ -528,6 +518,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 Fri Apr 11 07:26:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071389 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 4ZYpFD4Jn6z1yHt for ; Fri, 11 Apr 2025 17:28:16 +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 1u38oO-0006eN-0B; Fri, 11 Apr 2025 07:28:28 +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 1u38o9-0004Xx-2E for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:13 +0000 Received: from mail-pj1-f69.google.com (mail-pj1-f69.google.com [209.85.216.69]) (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 766493F169 for ; Fri, 11 Apr 2025 07:28:10 +0000 (UTC) Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-2ff78dd28ecso2011859a91.1 for ; Fri, 11 Apr 2025 00:28:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356488; x=1744961288; 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=ekdCTHOChLK4n+U4195dnbTZ3FrZ/bcIjxT/RLMDoNA=; b=OJDtoCPeMmjR5Z/t8M2eNeJZnTfTi1inIZpZbaSufxNvtO12i0a7R7MewlX1zdKDmu G2ccnMMes9XXuPpizS91ekgV4K862m0UbF/mc+8FiackuPN+vDZR3g+7a1KiQxxafSqC 7N6C5zcPOxf7rxT1EafdVm20d0+6e80XDpa+l5wg8l+b0LIcOYAiBhSBVaLwis0vVPMp rriLhGA3jToGGkE/w2H0d7q39Ed/mP2fjhj0F9qbGiGyehwr1P/F84mMsBGTSxX/GBng CZCukgcCLZoxCQrFjHteIPofKrR4tWW9ZRIljBUdku24lFkBW23bjtvLFEepiqqm2Q3r 61QQ== X-Gm-Message-State: AOJu0YyPmYIaEueZDwJUvCAk4++LyuFLPZxjE2NWcV/CCHdB/gx03d5h bqBqbhyWrtFQeaFFsdgvHRVEJwEWCnK1n0ipcS3zSxzzXVrIioUMZNu+hKAeaS+BxMrFmKKE9jI DEv1p1zDRBBRCISzR7HJP4IRWqZQy44f30teG2Uy1jBC5smVD5AQU595tA9TQJEZb0TTP7NmFRI qCB9YFwIb/ww== X-Gm-Gg: ASbGncvYtQu0oyw7osABOE/D8gBBp8NcFYc2gqk8qYhZ0DTUDGknObfsKqpxIRsc+L4 u3wNAyB+S51Tmn8CCYbBU1GczCXOmI2o4He8Mqv1UrFkGvLvRtx+wxolmmXuvVBYo6VLRBlWL5n IPeIyKU3huN04O3XDXkB72TcAdz5s9J8lfHj2fykGI82YxW9AYAoSuvHm7AwNtaYL8SWyWAuzug VbaF2SSdKrs2mvjaiBBx8DLQti1NbvyuehctBUVwFpmmJ5GVe65U2T+1u2n18XmSmXBk/p02e8p Sk76uWZtt4fmGMTvMJT5n5myht9rJQ== X-Received: by 2002:a17:90b:2dd2:b0:2ff:72f8:3708 with SMTP id 98e67ed59e1d1-3082365241fmr3446748a91.17.1744356488204; Fri, 11 Apr 2025 00:28:08 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGFALxM2cUuqY159zB1O895wYxEqXvmILDJDY1HYnoXtmN49Vr9Y2Aaq1QdqaaHcLKqBTc1OQ== X-Received: by 2002:a17:90b:2dd2:b0:2ff:72f8:3708 with SMTP id 98e67ed59e1d1-3082365241fmr3446723a91.17.1744356487834; Fri, 11 Apr 2025 00:28:07 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:07 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 05/12] gpio: aggregator: unify function naming Date: Fri, 11 Apr 2025 16:26:56 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 efab5aa2035a..8d3ba67fa85f 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -39,8 +39,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; @@ -288,7 +288,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; @@ -307,7 +307,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) goto free_bitmap; @@ -323,7 +323,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) goto free_bitmap; } @@ -341,8 +341,8 @@ static int aggr_parse(struct gpio_aggregator *aggr) return error; } -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; @@ -382,7 +382,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; @@ -415,9 +415,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); @@ -426,8 +427,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; @@ -451,15 +452,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); @@ -520,7 +523,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 Fri Apr 11 07:26:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071390 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 4ZYpFF3Pp1z1yHt for ; Fri, 11 Apr 2025 17:28:17 +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 1u38oP-0006mG-2M; Fri, 11 Apr 2025 07:28:29 +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 1u38o9-0004g2-7z for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:13 +0000 Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) (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 B8B7B3FB77 for ; Fri, 11 Apr 2025 07:28:11 +0000 (UTC) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-3011bee1751so1549826a91.1 for ; Fri, 11 Apr 2025 00:28:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356489; x=1744961289; 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=dCMlgGSwIS7aAJtpEG0nysZ8s0/IzOdc+VHujcBPi9w=; b=tPI0o0o4H7C+iqKqLXR3g2PjEGIvRtWJO1CZOzTYnkAzhQy4epHdrlef79I2s/baig YFf+PAgSd5+ONyS8QKlGQkNQPZSWUJaiAqKN0e1eg2hRXbYvCMy2CNH9eq1Bc6zWZgvs qTSeYRkdtcVcRu/oUwMC5G++uNm0Gisd7amp0HQ0m56JED0QUSEUpbpWiVuLZ20zS2a2 WXyGEIa8w5jJS4m+vjlS7QxN8R52UQXN/dzyu9Ke8Duiee7VclDUUTDmBgmYlTVWDB3l lJBDWBrfy4iPxUEDk1r3DvORymhNbLct1FiDPVcdh6Pq4AUfPLqMcux5nHekqwcIwbq3 xgag== X-Gm-Message-State: AOJu0Yx+BwBnE0SkkiRAwSdGa7LmrPm9mlg3mQo0FKr59NxXqs/+h/4w 6VGFsepy1HKPYM7BLsv4v4L4Z3Hf/oo1Lj+BGAKoUaJ/FDacD6RAHClIYwKg3SFYuxTDys8Z8vP zy29u7jNczEWy18P/aX1pFNrbPMiLUHGdqfYjX5c3y6jDAf70IMleL1eYWl/p6ICjmpAiioUnqC aPPKCqTVT/iQ== X-Gm-Gg: ASbGncuHYG94EuWcz/9CmKOJcmUkrWme46Gpg9X9/bNJPMX+uSv399z5CkZVsr93sir MvOoMLzENUbGlspmCdqr6UlZlaaqJWz8w/ii/0WJ7wNZW2SiZAoMIlv8Eew8KDeqoWRGUd2+M8c oJ9lpjeqgciC1ug2R5/j5rkP5ydznYaFmjpjAkuhyDNrET9IKl4NYen+40JVGJ2HBJr9Qx5P9Ld TrcmGML2V7LPdkvugTWiWBHekU8maRfIt4jC13eiF3gsBzQxCgipMz6f8fIExNWUOysdbJTaTLd LYp4GAimbEKWGUU5BVwt0vuoRN22wA== X-Received: by 2002:a17:90b:2e4f:b0:2fa:15ab:4de7 with SMTP id 98e67ed59e1d1-3082363439emr3461868a91.12.1744356489447; Fri, 11 Apr 2025 00:28:09 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHEo+tOTX5HMH5smNPyQy+LTYeh87M+vUnGloJFRlDGlHr6ppkAPzFYd2QUHYS7lwl7fq+haw== X-Received: by 2002:a17:90b:2e4f:b0:2fa:15ab:4de7 with SMTP id 98e67ed59e1d1-3082363439emr3461840a91.12.1744356489040; Fri, 11 Apr 2025 00:28:09 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:08 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 06/12] gpio: aggregator: add gpio_aggregator_{alloc, free}() Date: Fri, 11 Apr 2025 16:26:57 +0900 Message-ID: X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit 88fe1d1a646b3b01dcc335c44e7b33ea510f620e linux-next) [koichiroden: * adjusted patch to avoid using __free/guard/scoped_guard, which are unavailable due to the missing commit: 54da6a092431 ("locking: Introduce __cleanup() based infrastructure"). * adjusted patch to avoid using list_count_nodes, which is unavailable due to the missing commit: 4d70c74659d9 ("i915: Move list_count() to list.h as list_count_nodes() for broader use")] Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 60 +++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 8d3ba67fa85f..a81dfb401afa 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -33,12 +33,43 @@ 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) +{ + struct gpio_aggregator *new = NULL; + int ret; + + new = kzalloc(sizeof(*new) + arg_size, GFP_KERNEL); + if (!new) + return -ENOMEM; + + mutex_lock(&gpio_aggregator_lock); + ret = idr_alloc(&gpio_aggregator_idr, new, 0, 0, GFP_KERNEL); + mutex_unlock(&gpio_aggregator_lock); + if (ret < 0) { + kfree(new); + return ret; + } + + new->id = ret; + *aggr = new; + return 0; +} + +static void gpio_aggregator_free(struct gpio_aggregator *aggr) +{ + mutex_lock(&gpio_aggregator_lock); + idr_remove(&gpio_aggregator_idr, aggr->id); + mutex_unlock(&gpio_aggregator_lock); + kfree(aggr); +} + static int gpio_aggregator_add_gpio(struct gpio_aggregator *aggr, const char *key, int hwnum, unsigned int *n) { @@ -346,17 +377,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); @@ -367,19 +396,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); @@ -388,7 +408,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; @@ -402,14 +422,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 Fri Apr 11 07:26:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071391 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 4ZYpFG4mMpz1yHt for ; Fri, 11 Apr 2025 17:28:18 +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 1u38oP-0006qm-Kh; Fri, 11 Apr 2025 07:28:29 +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 1u38o9-0004n5-TV for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:14 +0000 Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.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 E6116400AF for ; Fri, 11 Apr 2025 07:28:12 +0000 (UTC) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-ad50a3a9766so1289776a12.0 for ; Fri, 11 Apr 2025 00:28:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356491; x=1744961291; 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=V7X8euJpWVwCvUFGJxM5ibEjyM8HWwfI/tE9G2yRJi8=; b=kmNUgRgTLfOVSxU/1lMqCLDvKnT0QkgbgjWdAS39dNgGpxnnBBSWtS7tdzsmY09Gv/ cCo6CAh8a17nH/tyPi/tcm5Ws/07SgwYO4ZUvllHkIgF7mgNPeqjmqpcqQiy1mQbF5Fi IFHaul3aLXMXbTCcWTovIRjOsCEEHJQ0tnBOHSWMx+22CrMI+MTog/WlG3iDuhw9C/Iq ZrgPNn2IRrCvzkT5Hx7LIwDwoWGHuxlvpw+hMvmTtpUWCZ3yctcDAL1FAsM6Wz873PbX FrAcPmLuM4p0eRa9/sPg8Ugx0nJpXMXEETEP98lVAActkt3oGwi+B73px1Kx+KrTfEBu 8AAQ== X-Gm-Message-State: AOJu0YwRRnHToVWpuLjTdBVFFlmwu709isJ33eC1k4hwGUWQda2dURqR GXctliuVdFvgVF5fRpR6/rMoDPOtQR8S3TQMA4J4J2LdRr0dsl72Hh+udH/POGsV6QdpQ72IyCX skc3zoRhtjIKshBFqOOND5uirfry+JIaty8XW1Bl7rwGm6EzNPAwK1Zl1gwoaJrtozP/tetiTxj 8UW8KEy42RmA== X-Gm-Gg: ASbGnctjoTdcXBl+PKk3IHtcEB9aEXuq6r24/3vlz1i5dDq5/jZIE3k/dPLraGLpDWA 25qqmnjePBNfIeEm3wpYaB+tU4p4LgM3C6pk0yQsb/u8HgMGRSJHxN1WlUYUy3STWw6BMV05+AT FciAeY4AAwhivHvQX6yQp/YExNqkQ9PBskWmw9HsIKDdtj/Z3fBSdhmxKY47G8D7DXKgX8kbJEn 3P/z5QPgrKppSNHpCA2LX3dME4iLPAWRGORcsfpNxj/7X+poHti3eLxySvEUSPfzJWDAYSLAzjg 2EdBrMT2KPGC3wvDywMi/FyWJ5qP1w== X-Received: by 2002:a17:902:d585:b0:223:4d7e:e52c with SMTP id d9443c01a7336-22bea49583amr28336825ad.5.1744356491171; Fri, 11 Apr 2025 00:28:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHimcOnVTWoo9ne9xBGjaFElnpz6udgYofT2RywzorNa+RqNp838+rd2nEYs0hHpP9KZFmZww== X-Received: by 2002:a17:902:d585:b0:223:4d7e:e52c with SMTP id d9443c01a7336-22bea49583amr28336255ad.5.1744356490254; Fri, 11 Apr 2025 00:28:10 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:09 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 07/12] gpio: aggregator: introduce basic configfs interface Date: Fri, 11 Apr 2025 16:26:58 +0900 Message-ID: <1998f41a6808a62947cc214a2e2fc2a919c0f292.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit 86f162e73d2d81ef6d819c06a3b6c2fda77a79b8 linux-next) [koichiroden: * resolved conflict around header includes due to missing commit: b89a9e9890d4 ("gpio: aggregator: Remove CONFIG_OF and of_match_ptr() protections") * adjusted patch to avoid using __free/guard/scoped_guard, which are unavailable due to the missing commit: 54da6a092431 ("locking: Introduce __cleanup() based infrastructure"). * adjusted patch to avoid using list_count_nodes, which is unavailable due to the missing commit: 4d70c74659d9 ("i915: Move list_count() to list.h as list_count_nodes() for broader use")] Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 2 + drivers/gpio/gpio-aggregator.c | 674 ++++++++++++++++++++++++++++++++- 2 files changed, 663 insertions(+), 13 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 53725c0da764..e5e0d8b19ea1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1681,6 +1681,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 a81dfb401afa..22c47ac01c08 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -9,9 +9,12 @@ #include #include +#include #include #include #include +#include +#include #include #include #include @@ -24,6 +27,8 @@ #include #include +#include "dev-sync-probe.h" + #define AGGREGATOR_MAX_GPIOS 512 /* @@ -31,12 +36,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); @@ -58,6 +89,8 @@ static int gpio_aggregator_alloc(struct gpio_aggregator **aggr, size_t arg_size) } new->id = ret; + INIT_LIST_HEAD(&new->list_head); + mutex_init(&new->lock); *aggr = new; return 0; } @@ -67,6 +100,7 @@ static void gpio_aggregator_free(struct gpio_aggregator *aggr) mutex_lock(&gpio_aggregator_lock); idr_remove(&gpio_aggregator_idr, aggr->id); mutex_unlock(&gpio_aggregator_lock); + mutex_destroy(&aggr->lock); kfree(aggr); } @@ -89,6 +123,77 @@ 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) +{ + unsigned long count = 0; + struct list_head *pos; + + lockdep_assert_held(&aggr->lock); + + list_for_each(pos, &aggr->list_head) + count++; + + return count; +} + +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 @@ -315,6 +420,504 @@ 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; + const char **line_names = NULL; + struct fwnode_handle *handle; + 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; + + line_names = 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); + + handle = fwnode_create_software_node(properties, NULL); + kfree(line_names); + return handle; +} + +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; + int len; + + mutex_lock(&aggr->lock); + len = sysfs_emit(page, "%s\n", line->key ?: ""); + mutex_unlock(&aggr->lock); + + return len; +} + +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 = kstrndup(skip_spaces(page), count, GFP_KERNEL); + if (!key) + return -ENOMEM; + + strim(key); + + mutex_lock(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) { + mutex_unlock(&aggr->lock); + kfree(key); + return -EBUSY; + } + + kfree(line->key); + line->key = key; + mutex_unlock(&aggr->lock); + + 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; + int len; + + mutex_lock(&aggr->lock); + len = sysfs_emit(page, "%s\n", line->name ?: ""); + mutex_unlock(&aggr->lock); + + return len; +} + +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 = kstrndup(skip_spaces(page), count, GFP_KERNEL); + if (!name) + return -ENOMEM; + + strim(name); + + mutex_lock(&aggr->lock); + + if (gpio_aggregator_is_active(aggr)) { + mutex_unlock(&aggr->lock); + kfree(name); + return -EBUSY; + } + + kfree(line->name); + line->name = name; + mutex_unlock(&aggr->lock); + + 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; + unsigned int offset; + + mutex_lock(&aggr->lock); + offset = line->offset; + mutex_unlock(&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; + + mutex_lock(&aggr->lock); + if (gpio_aggregator_is_active(aggr)) { + mutex_unlock(&aggr->lock); + return -EBUSY; + } + + line->offset = offset; + mutex_unlock(&aggr->lock); + + 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; + int len; + + mutex_lock(&aggr->lock); + pdev = aggr->probe_data.pdev; + if (pdev) + len = sysfs_emit(page, "%s\n", dev_name(&pdev->dev)); + else + len = sysfs_emit(page, "%s.%d\n", DRV_NAME, aggr->id); + mutex_unlock(&aggr->lock); + return len; +} +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); + int len; + + mutex_lock(&aggr->lock); + len = sysfs_emit(page, "%c\n", + gpio_aggregator_is_active(aggr) ? '1' : '0'); + mutex_unlock(&aggr->lock); + return len; +} + +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); + + mutex_lock(&aggr->lock); + if (live == gpio_aggregator_is_active(aggr)) + ret = -EPERM; + else if (live) + ret = gpio_aggregator_activate(aggr); + else + gpio_aggregator_deactivate(aggr); + mutex_unlock(&aggr->lock); + + /* + * 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; + + mutex_lock(&aggr->lock); + gpio_aggregator_line_del(aggr, line); + kfree(line->key); + kfree(line->name); + kfree(line); + mutex_unlock(&aggr->lock); +} + +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); + + mutex_lock(&aggr->lock); + if (gpio_aggregator_is_active(aggr)) { + mutex_unlock(&aggr->lock); + return ERR_PTR(-EBUSY); + } + + list_for_each_entry(line, &aggr->list_head, entry) { + if (line->idx == idx) { + mutex_unlock(&aggr->lock); + return ERR_PTR(-EINVAL); + } + } + + line = gpio_aggregator_line_alloc(aggr, idx, NULL, -1); + if (!line) { + mutex_unlock(&aggr->lock); + return ERR_PTR(-ENOMEM); + } + + config_group_init_type_name(&line->group, name, &gpio_aggregator_line_type); + + gpio_aggregator_line_add(aggr, line); + mutex_unlock(&aggr->lock); + + 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 @@ -389,6 +992,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) { @@ -414,7 +1018,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; @@ -436,10 +1040,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); } @@ -461,12 +1062,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); @@ -483,7 +1091,6 @@ static struct attribute *gpio_aggregator_attrs[] = { }; ATTRIBUTE_GROUPS(gpio_aggregator); - /* * GPIO Aggregator platform device */ @@ -539,21 +1146,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); @@ -561,6 +1208,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 Fri Apr 11 07:26:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071393 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 4ZYpFJ3g0Nz1yHt for ; Fri, 11 Apr 2025 17:28:20 +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 1u38oR-00074r-KO; Fri, 11 Apr 2025 07:28:31 +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 1u38oC-0004oE-Kg for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:16 +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-1.canonical.com (Postfix) with ESMTPS id 5824E40139 for ; Fri, 11 Apr 2025 07:28:13 +0000 (UTC) Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-224347aef79so22624135ad.2 for ; Fri, 11 Apr 2025 00:28:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356492; x=1744961292; 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=wQ6hcXJFb4w1KTVCN9fXBBR17t1pisKwiDNdaC1DQ6g=; b=IbjqYRiE4BkGuqFrerR/SE4RKZb/ueedIn8LyL5316iZxZgDcKWgPHxd+6UdixKu3o 0dpb/ODg6Pl3wDQfkhCkZS6sF3owwYETkJLVz2MU1sa1/xWzuT0a/k56YNtaRHk8tlNm 2BatjjkwA4ftJUV/4kXHM0DrkySgwLBhVYGnNJEJU5wfFmLtQA4vA/+8Mr8vnLuzXqFO moxb3VO6w4XqRVOz2UUD/nkHB8Ym0DFqN/xeCPvGLVZ8/kq3PYNy9//GiMwAhzLcKFDC Ul48Yg68Y2ovE0T10omoO+FwffHwK7BtArW4hIRLIAG17ARTiXQ42Ye4zISVodgtADbR T0Xw== X-Gm-Message-State: AOJu0Yzvty9WWTxDutlgQ1r7w4kGISN31KKKqUJ/i32bQL/26mpavGvJ kbAZxW4aiOZonN7hZQLHkc514Z46C4CHaNtz/bABu/wjhC2gJC1ejTOCdirT8ZYpN+XRzUO6jh1 WI3BbCnYN+zAwrGuv9DySdVEwT3HvlSLf2OyWegZj3Dd9Mg2NnQY7fWL8JB+FvNHUADFUlUC1dP w942ElK3fctg== X-Gm-Gg: ASbGncvy8lj75gYQdxdxaELDz4687EY+ctaa91XykdyRVUkPbKXp7lmxJ7eJaxRRA6V Y+L62BXYisAgn3cPClW7N/sY1NtAY5PIHEJnThnrSRW7JqN0IkLCwb50H3XMMQWx6ZosdinPlv9 8FeLDXwF1pR/wzTjYkVR1na0E1GSshM21c5i/FRM8Kids7h9rvQScxHQ8q4g8AgAI1bQ8crtvTY sVPdUd3wNZuKpWon2xBWgwpvUwnZ1k52tYEJjaX18dM5DMN3fTU/uNoYBLKLp9VbkGL5S8ywGYU h040VthU1bojfsq82edAamAzpZY0ig== X-Received: by 2002:a17:902:f712:b0:21f:35fd:1b6c with SMTP id d9443c01a7336-22bea4fc93emr28994545ad.45.1744356491800; Fri, 11 Apr 2025 00:28:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGRp7UAW9rva7tSEphjnVIP7rco6//HY2IRO7u5uHFxdWk5ka9HgNvt0+qbK8JErS8wb0A4zA== X-Received: by 2002:a17:902:f712:b0:21f:35fd:1b6c with SMTP id d9443c01a7336-22bea4fc93emr28994235ad.45.1744356491435; Fri, 11 Apr 2025 00:28:11 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:11 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 08/12] UBUNTU: [Config] updateconfigs for DEV_SYNC_PROBE Date: Fri, 11 Apr 2025 16:26:59 +0900 Message-ID: <6f72688c0d905d362d43c393bd44da97a48ddf4c.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 318d0019fba5..453fcae8373e 100644 --- a/debian.master/config/annotations +++ b/debian.master/config/annotations @@ -3591,6 +3591,7 @@ CONFIG_DEV_DAX_KMEM policy<{'amd64': 'm', 'arm64': ' CONFIG_DEV_DAX_PMEM policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> CONFIG_DEV_DAX_PMEM_COMPAT policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> CONFIG_DEV_PAGEMAP_OPS policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_DEV_SYNC_PROBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 's390x': 'm'}> CONFIG_DHT11 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> CONFIG_DIAG288_WATCHDOG policy<{'s390x': 'm'}> CONFIG_DIMLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> From patchwork Fri Apr 11 07:27:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071392 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 4ZYpFH5Dx4z1yJZ for ; Fri, 11 Apr 2025 17:28:19 +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 1u38oQ-0006zc-Oq; Fri, 11 Apr 2025 07:28:30 +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 1u38oB-00053K-W5 for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:16 +0000 Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.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 99A523F169 for ; Fri, 11 Apr 2025 07:28:14 +0000 (UTC) Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-af9b25da540so1163074a12.2 for ; Fri, 11 Apr 2025 00:28:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356493; x=1744961293; 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=fMgihkgIGUi7H77lMiDDfrnxpAJF7Aq4yhwhl5Cjl9E=; b=KxwsckuQtNqHpfizgvoMLyU2UyFlO4M8UCoNOFaPk7mb0U4iH66MGfJ7O/sQtV9wdd j/4z50/JMCL8geB9Vj+yH3ahUyfqWOsh/3bXik9ysjziegWmu1sQXoXoRsMQNz4AzOvY JlBDnYyEnm74LcHmsY1auW4/l4pVh8aT2vjB8ar0HQZ6zDV6jkOl2sp+FGffXy3JbxWa o56QhkU3sgFAduLH2kd7hRmFXTOzreEMHbHMIz2Iz8DXqPxG7tEl+FmXNL9i3+CxMAx5 2jbAH+SqadOKhHh56Cr9/gtSBY26c9aAz/CEz/dzRRm6opAgbAm0hlVwxLCRJO3hq4X4 9khQ== X-Gm-Message-State: AOJu0Ywje7AnBZicOMH0D6sskXMAjmCKt2hxjocgtCzan4kk8BmjiRck tKlK+iuZM4d99nV1IbO8gvBXUiH7uvR6zRF5jS1zlbrOfgNdik3+kSF/JvhAuEGUn2fEDgmQUYx cr0ydTilxwwBkXvVPelkRiWqmUC6weI92hx0bDCdRiGHdkOGYYOf8PyiytA5YDtAq3p4POpI5J2 rljV7Gld8WKQ== X-Gm-Gg: ASbGncssj1vA69fENeP9djtHulNCkCbLoIPTy2Yflcm46Qe6j8VeR/luui39MlKaQ9h gNh463oHldyWS7kdiHIT6NfHxltTMfJ0gRPP3w3yhsjwe5UbgF6heSsGd4MSxJtd1DSFh2Pi064 EWuMVQkl++Lc1pKq4ARRWXgUM5cu8rrx5xEgl5bYv+7Bho6DM3axXm8Qzp4abRgqsID2HGUzPZM Gt3cmUBDak1WPSenho2LE0hRm1g2iIuThZ1/NZamCmvsXUfYI3cjc8ukwTmHSBrXdxNwzCDtz2i 1QAzbaVM2XUtZ2LQcqHcsdNDcyD38w== X-Received: by 2002:a17:903:46c7:b0:225:adf8:8634 with SMTP id d9443c01a7336-22bea505634mr26065735ad.51.1744356493005; Fri, 11 Apr 2025 00:28:13 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFeKJkP3NedmiYaFqyJMyWMubrhspJRgZ56IH7w5X/dt1B2e7zgVQdixIM66/e1jMMUfK+Q3g== X-Received: by 2002:a17:903:46c7:b0:225:adf8:8634 with SMTP id d9443c01a7336-22bea505634mr26065535ad.51.1744356492673; Fri, 11 Apr 2025 00:28:12 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:12 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 09/12] gpio: aggregator: rename 'name' to 'key' in gpio_aggregator_parse() Date: Fri, 11 Apr 2025 16:27:00 +0900 Message-ID: <72276cc6ab3584dfa989361d3f68655414ea4194.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit 4ec2315d7fabeb08e9ad7995bd16f34118e4633b linux-next) [koichiroden: adjusted context due to the missing commit: 22dec5aa596e ("gpio: aggregator: simplify aggr_parse() with scoped bitmap")] Signed-off-by: Bartosz Golaszewski --- 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 22c47ac01c08..2c7fce670f6c 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -925,7 +925,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 long *bitmap; unsigned int i, n = 0; int error = 0; @@ -934,18 +934,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) goto free_bitmap; - name = offsets; + key = offsets; continue; } @@ -957,12 +957,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) goto free_bitmap; } - args = next_arg(args, &name, &p); + args = next_arg(args, &key, &p); } if (!n) { From patchwork Fri Apr 11 07:27:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071394 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 4ZYpFK5V4Rz1yHt for ; Fri, 11 Apr 2025 17:28:21 +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 1u38oT-0007CJ-4C; Fri, 11 Apr 2025 07:28:33 +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 1u38oD-0005Ge-Ec for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:17 +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-1.canonical.com (Postfix) with ESMTPS id EF48F400AF for ; Fri, 11 Apr 2025 07:28:16 +0000 (UTC) Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-229668c8659so13357735ad.3 for ; Fri, 11 Apr 2025 00:28:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356494; x=1744961294; 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=CenZE8TqY2KPXTYmpS8Tfv1EoG6RcbKwOHDsZKPdQmo=; b=oKznX3aVSlVAvX85F6MzIsb9/iiFNsHQ20TswxIw8CYlgmeUZsDl3xgglWqMh7B9dY ulWHaoh2IZKYGFLwHxYqzKlJA2pHd0CxasVKgZ0e2usGNnKs8kn5xmwmBvmMnbRNhyf4 cYSIniDqgul6ELwv3eVcty2p5v5k4foHEb6CnxrH6yd5VKLB8aQ2xHVjhprWLszqtwfi P2m4vMH4XAOZpie6OeldozWYh/7PHbRvbEwF+HfFE9MdwUtnOuDFQzQ6pU/wotnPjI+/ qHx+pWElDrVSwvpEORfGIdyf/UJ/sEgIYR/FqS3Rg/anGIvYUyEAX/tWGAr/8r6rBcrv ZmUQ== X-Gm-Message-State: AOJu0Yw37D1XWo8sGcDPywmQx52mKgfZQVoJDiD3D7QG9hmnjYG2pC4l elEeHhKRdNcfVCF/HgOUMItXX1sRQYosVqb4hKz+OjSOwmzpaTF66M7mOWYLUMKH2ubcWbcIqMo wJ0Lwyx3WRpYm/kR/YMkAVFGgUJvLErRkTssWAxLQiPsd4Ubph4e+24mweyhkqyywUtujqIdDdB V6tgu0XjZ6bA== X-Gm-Gg: ASbGncsM2sGYoVs6RvMPIXIBnBTJsagDXXTi/gl2KE7UFQWg4VFDlhrwqI1Ps/3XXUH L6rOcxh9mFpfIL4MKMGIyisfrWPU0btY7bB3NL09+tPzQ+hihw1sEDnjTbWL0IXMtsjOBYTmSV2 vG6tPLTyp4Uj1GDwxzbT7uUV2AQrgXGpvIOgl2IbRLvnwzRyeTaikcIjpqgu4DEt1V/kLZvW9rl 3XdRxCVH021MvGxOdY7bMIuBa1wRSDMliAWq9vDRnCTfgMaIny5iCNTPnCacrdctIMb4bbDHm+1 w4a1eespwR8O71Sd3pl//wOW4dvOKA== X-Received: by 2002:a17:902:cf05:b0:220:ec62:7dc8 with SMTP id d9443c01a7336-22bea4a33acmr27483715ad.2.1744356494351; Fri, 11 Apr 2025 00:28:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEXfbs/BlieRRnrFfmZGGStAafSSJOVbxkiN2lovUjs4WjD75Vh0AsDcCBUQjQbGDFhdYWYjw== X-Received: by 2002:a17:902:cf05:b0:220:ec62:7dc8 with SMTP id d9443c01a7336-22bea4a33acmr27483455ad.2.1744356493869; Fri, 11 Apr 2025 00:28:13 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:13 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 10/12] gpio: aggregator: expose aggregator created via legacy sysfs to configfs Date: Fri, 11 Apr 2025 16:27:01 +0900 Message-ID: <2403aeac908c728501c57f5dd8ea0a290a512a7c.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 (backported from commit 83c8e3df642f5fde320278a5e6ce9e46f9689d1a linux-next) [koichiroden: * adjusted context due to missing commit: 22dec5aa596e ("gpio: aggregator: simplify aggr_parse() with scoped bitmap") * adjusted patch to avoid using __free/guard/scoped_guard, which are unavailable due to the missing commit: 54da6a092431 ("locking: Introduce __cleanup() based infrastructure")] Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 133 ++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 2c7fce670f6c..f23afa06a7f3 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -30,6 +30,7 @@ #include "dev-sync-probe.h" #define AGGREGATOR_MAX_GPIOS 512 +#define AGGREGATOR_LEGACY_PREFIX "_sysfs" /* * GPIO Aggregator sysfs interface @@ -130,6 +131,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) { unsigned long count = 0; @@ -194,6 +203,31 @@ 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. + */ + mutex_lock(&aggr->lock); + gpio_aggregator_line_del(aggr, line); + mutex_unlock(&aggr->lock); + kfree(line->key); + kfree(line->name); + kfree(line); + } +} + /* * GPIO Forwarder @@ -604,7 +638,8 @@ gpio_aggregator_line_key_store(struct config_item *item, const char *page, mutex_lock(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) { + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) { mutex_unlock(&aggr->lock); kfree(key); return -EBUSY; @@ -647,7 +682,8 @@ gpio_aggregator_line_name_store(struct config_item *item, const char *page, mutex_lock(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) { + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) { mutex_unlock(&aggr->lock); kfree(name); return -EBUSY; @@ -699,7 +735,8 @@ gpio_aggregator_line_offset_store(struct config_item *item, const char *page, return -EINVAL; mutex_lock(&aggr->lock); - if (gpio_aggregator_is_active(aggr)) { + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) { mutex_unlock(&aggr->lock); return -EBUSY; } @@ -764,11 +801,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); mutex_lock(&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); @@ -780,7 +818,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); @@ -824,7 +862,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); @@ -846,6 +884,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); + mutex_lock(&aggr->lock); if (gpio_aggregator_is_active(aggr)) { mutex_unlock(&aggr->lock); @@ -890,6 +937,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) @@ -925,6 +980,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 long *bitmap; unsigned int i, n = 0; @@ -941,6 +998,22 @@ 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 free_bitmap; + } + config_group_init_type_name(&line->group, name, + &gpio_aggregator_line_type); + error = configfs_register_group(&aggr->group, + &line->group); + if (error) + goto free_bitmap; + mutex_lock(&aggr->lock); + gpio_aggregator_line_add(aggr, line); + mutex_unlock(&aggr->lock); + error = gpio_aggregator_add_gpio(aggr, key, U16_MAX, &n); if (error) goto free_bitmap; @@ -957,6 +1030,22 @@ 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 free_bitmap; + } + config_group_init_type_name(&line->group, name, + &gpio_aggregator_line_type); + error = configfs_register_group(&aggr->group, + &line->group); + if (error) + goto free_bitmap; + mutex_lock(&aggr->lock); + gpio_aggregator_line_add(aggr, line); + mutex_unlock(&aggr->lock); + error = gpio_aggregator_add_gpio(aggr, key, i, &n); if (error) goto free_bitmap; @@ -972,12 +1061,15 @@ static int gpio_aggregator_parse(struct gpio_aggregator *aggr) free_bitmap: bitmap_free(bitmap); + if (error) + 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; @@ -1006,10 +1098,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); @@ -1024,6 +1131,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: @@ -1040,7 +1149,13 @@ static struct driver_attribute driver_attr_gpio_aggregator_new_device = static void gpio_aggregator_destroy(struct gpio_aggregator *aggr) { - gpio_aggregator_deactivate(aggr); + mutex_lock(&aggr->lock); + if (gpio_aggregator_is_activating(aggr) || + gpio_aggregator_is_active(aggr)) + gpio_aggregator_deactivate(aggr); + mutex_unlock(&aggr->lock); + gpio_aggregator_free_lines(aggr); + configfs_unregister_group(&aggr->group); kfree(aggr); } From patchwork Fri Apr 11 07:27:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071395 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 4ZYpFL6Rt6z1yJZ for ; Fri, 11 Apr 2025 17:28:22 +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 1u38oU-0007ME-Q2; Fri, 11 Apr 2025 07:28:34 +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 1u38oD-0005Hg-Q8 for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:17 +0000 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.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 345C240139 for ; Fri, 11 Apr 2025 07:28:17 +0000 (UTC) Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2255ae39f8fso25914025ad.0 for ; Fri, 11 Apr 2025 00:28:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356495; x=1744961295; 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=zr7zK4tTVhz4ma/0sTmqBA+6LbsChM6NSSnS1KSMKL8=; b=MLEOgciJegzaLw0c3ngnpIjzlnepMxONCULMGSDp0aYw/R17G/NITncEoTf6DrEbBP ZB9cvejxIS1GqBihHL8qB5WOtrvlOJDXRbXq6UczpW0NADokSu2UW59kUKHwH5fxObK6 qNNWsI310WRfnJNEJebUI/9Mhwat8+wlKyDq7gje0fio9InyUILYJGCDV+y+b9oSTtwi fjzPCsVaOsNh1wD4eE3PWKPHJZYnem+uLR/NLn7HeKurMkaMDPwb70cVTihM7fiPZ1Bn HfLh9A/Ag2mDBjM0p72sRZHIFdY2tCPza6zzL5zuSB3uL0M/h2D7wHodN1dWlrGBOtS1 J6XA== X-Gm-Message-State: AOJu0YwxfjC/NV38zhyaRCKb23lGnxkIuyfTwfVkxqbX3cpJ4Tz2rE/E 57YjFs3AqH7p4RNfc0MLGo/1qPyxSZygd5im5Q4HzxDsmojq1GaCbMNYmlRvGNEQprV00XKhJR6 9aY5tfYRgov6fJNVzG7qNLJd7xaP2n9RLSlK3La2DP9kQ4lHwqkqVZ3WTGRrd95uxmcdJH7QWA9 Q//PabE3RLdA== X-Gm-Gg: ASbGncsSujHkkLsFttm2Z3bbWZre5xOiPBgntINKVUUtAbnecGnO1Jm9vZWfYXqvnr0 g8MSUtBZWQXdlLBqeYNi14+wH2ZtLUgRtinBu0xqhXInds0ZaVcwfftB1N19tA4uUizJUnMpcAt bL6Xx+CTTkTQY52D/LMGdOBXvpaI+0EoL6BTi2E5ChqAZbqgWXYpL+9LbIREBPnIi2i/0VHpGlC UOwX/Zi1vRn+HqITmV07iEB0u0iLZNhiuQx8H8Bpd00xdDAs0EA4OYO13dYvQJImP/9IRB5CD6r LJnW1jkYa//WKZYlwEtehhTW7epbdQ== X-Received: by 2002:a17:902:ec84:b0:223:4d5e:7592 with SMTP id d9443c01a7336-22b7f91b908mr73483875ad.21.1744356495482; Fri, 11 Apr 2025 00:28:15 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFHqh7AE736vog6d32Bt8KH6Jwd1rtefR9sbpevYQHW4/chDHLwz/2o/8XmhDa+69hi8T/J5A== X-Received: by 2002:a17:902:ec84:b0:223:4d5e:7592 with SMTP id d9443c01a7336-22b7f91b908mr73483665ad.21.1744356495074; Fri, 11 Apr 2025 00:28:15 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:14 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 11/12] gpio: aggregator: cancel deferred probe for devices created via configfs Date: Fri, 11 Apr 2025 16:27:02 +0900 Message-ID: <0141ca747c512720fcbbcce85f8edc41a437670f.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 f23afa06a7f3..f578ac1312e8 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -69,6 +69,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); @@ -1069,6 +1073,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; @@ -1119,7 +1124,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; @@ -1212,7 +1217,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; int i, n; @@ -1225,10 +1232,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]); + } } fwd = gpiochip_fwd_create(dev, n, descs); From patchwork Fri Apr 11 07:27:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koichiro Den X-Patchwork-Id: 2071396 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 4ZYpFN48Glz1yHt for ; Fri, 11 Apr 2025 17:28:24 +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 1u38oW-0007X5-92; Fri, 11 Apr 2025 07:28:36 +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 1u38oF-0005ST-8C for kernel-team@lists.ubuntu.com; Fri, 11 Apr 2025 07:28:19 +0000 Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) (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 656233F138 for ; Fri, 11 Apr 2025 07:28:18 +0000 (UTC) Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-2ff68033070so1538221a91.2 for ; Fri, 11 Apr 2025 00:28:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744356497; x=1744961297; 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=WBRdejtt3pYtTc/p+Bb4zzTRqk5th3kRlB+u98TCDXA2TJRybP1YuUVzAOQ/tKejOU OjhLZTohZQVbhywKi3ygEGgT3mOS0FehwCDWUXQCgKokbFGtqLBKL/B9ojT301nqH53s KvuFtINmfd3ML6g1Rv0GSV89ODIjPcngCWWIOjl+sC/SyWWRkT9MvRrCGFZPQFBKLiU0 BCujxMJnJvceuAOA/Gshgud1XfmPKJ8hnVKcm914tSbalsANLok0MuDg5q0N24Uib7XL uijiJoIYCgo0NMRB46ZrwxCBFbT+asKPiKtXwnaqmABsmMUCddoMXJS7sIHrxcugyaab smnQ== X-Gm-Message-State: AOJu0YyhVepMU14lU8GcPwfmTE8pyGkIEcOpzmEfKtVI9tTqgp8Q4DPe uenXmnsce4N+V7Um9tn5FRTGBb1OHgks/OxB4uaogaEvFT2La6FucmURJ1KgJlwExZ89IU0mlnT qLzQDUm3OEb5ILhL1zT7hMke7znKAE23vK6hLtAvnav5ESdbHwfOsuQcS5AzLUgTvva/vhrBpPj 2Gjdl1F3lH4w== X-Gm-Gg: ASbGncstJWRxtJdhKSvIFmU+DcYg3GCWIS4rIPP/AqVIF40me2M8bqnb9Pi7DcP9c08 p+wVDS7ZAk9lqHz/sHhJzwoOOq8fzc/TvhSMPGaxQyh8M8CGdnPb0aX+bA5HY3dkhRToWOX6XPP CWHVs4ncqCMRFfQt0/rDXgveog2GOpvQzYWvtGXQ02ZOm+KMNs5Ey5R2LudsukKv9B6Yfnc6t07 G6nLEF2vPq4ZbTbxBD7n7+m8yYc1y+uY3r1NENBk9WX2zunCJnHBpp6ix8JBb5V7Xin1eG5ctMl 90FOvGSardVmw+rAFlS4NNn49EoF4Q== X-Received: by 2002:a17:90b:4d0c:b0:2ee:d371:3227 with SMTP id 98e67ed59e1d1-3082367dbe8mr2936432a91.17.1744356496738; Fri, 11 Apr 2025 00:28:16 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEG9ycVpHfb29dw7h9XLbrVInG/HkkBxVrpNmDMK9gsBxUualHJN3K44+EKTqio3OLHz5pXWw== X-Received: by 2002:a17:90b:4d0c:b0:2ee:d371:3227 with SMTP id 98e67ed59e1d1-3082367dbe8mr2936396a91.17.1744356496239; Fri, 11 Apr 2025 00:28:16 -0700 (PDT) Received: from localhost.localdomain ([240f:74:7be:1:f99c:bbee:3855:787c]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22ac7cda517sm42421105ad.250.2025.04.11.00.28.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Apr 2025 00:28:15 -0700 (PDT) From: Koichiro Den To: kernel-team@lists.ubuntu.com Subject: [SRU][J][PATCH 12/12] Documentation: gpio: document configfs interface for gpio-aggregator Date: Fri, 11 Apr 2025 16:27:03 +0900 Message-ID: <85b6d12c217becdfac833175e803e73401cecf14.1744350647.git.koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: <174435057828.183979.10447742120666677608@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 -------------------