From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE31B26AE4 for ; Mon, 3 Feb 2025 03:12:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552356; cv=none; b=kNBM9OA2ZIqcI5kui/1SULiolMP/8eRV+pRDaUaza9s1Na2Ow7BH1CoXMqP3z5IbKY6h9sskCndfuRJQB6n76iMUoop83u2QgxZ83aPYhQyTZhr1pvnkBpTCACVEjjEBj4plmUn5Inwh2buhTUTOF0oOz4bXsJ6dLednAfRyx3Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552356; c=relaxed/simple; bh=ON0ehqNkL/xvxuSncxnJd1gtNg+6gWPXLCaJXpCE84w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lcOxX93J6NuXqwmivmUvYisSDZBqzjzH0sFf12th6F6qkdtmd5C0EtdOlIXxfXKb+hTJqykoCnyZWsXejRazTz8+lzuY4UZF2H5fFrzPT+575zAVwYWxYQynMr/SeGA4aFpbUzyrA39irQgKTBMaPjRY4KbPcS2RzJpF4HAcqzc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=E1rVuaV/; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="E1rVuaV/" 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 13E173F887 for ; Mon, 3 Feb 2025 03:12:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552353; bh=/dv1clno4vwekIxpQT8JlY6+oBRlXDyt/p4pqtLh8l4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E1rVuaV/5oS3iLYVJblYACYfI99RXqxUesnbMdrqYK7gBu2peAC65fTFET2p2QW+u s2umpURqy7QX9Gt3pyTyv8xBBaDv6N4oY8V1OpMcRCI6Gn3QiwNm9g9kfBnmaNoWP9 2hrQ7QiaFfMNsO43ot7RS4Ho89pW1T+9eTSR4A2FNpiwtkTTCwzto3FVgBEgBBkqCs DmusAp5AyxKI334sO2hJn9jlshX2BPhqo2sNzeq81bkst0uec/LsbWG1JToG0SX+fs +liKLRg/utQ8n321ihNt9bqbK8OXqWXJqF8gVAFDa0FS644SMjD5yxd0AY2lEP/k+M O1eG0XKMo87sg== Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-2ef80d30df1so7195375a91.1 for ; Sun, 02 Feb 2025 19:12:33 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552352; x=1739157152; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/dv1clno4vwekIxpQT8JlY6+oBRlXDyt/p4pqtLh8l4=; b=ZcZTg2W+gRxYrHBravC9ghiAihOyV6TL6TO2hIF2V6RAkZhLZeKqORNiPr/SpNf/OH tq1S5DNqLSEdpH25Ryt5h425y8HNZ4R2Q7Rpl96F0xYFKpgwudEPSL9A3pOd4fPFqLOB s67wjF0ENoKEhCmHKNwnUvHHJ27nBxCP6/qklQt89sJ3//BdHMnjEt3DlHjAqpzYu+qh FGg058wMdBWwxN5AEIr+eXAJHsT1qrotxiwvJsOYL93SyMI/Wg0mo/2kZBQTDE5XsQGo voB/QOhwbmF2JqvDrdBaHZgKQ1b9z5jW3zRdHbOjeAZnfiET8mZIcOZ7iH/jZLZIoJFp qYFQ== X-Forwarded-Encrypted: i=1; AJvYcCUQOjCtaYCAfpNMg/cD2DWxQFw5iZyz15IUhjkrG4siGyE1OWC3AU4i4MYifY6PWS+qR2UqPfyViP0mZlg=@vger.kernel.org X-Gm-Message-State: AOJu0Yz3+ig7QUrjO1jrsIJyBmYZGCl45Fr3hDeH5bCNJr3puSGm9rMZ /gPOi7+i+3juzkiGfJkeBQANs07SEmujV5xs+3VuYK3BYGIzUoZn5bVSdXlKwlevhd01/UHXYDM mAC4xtBfqoFdp2B/UTCCC+OQkRq6GdRYkspWsnLeBbIworBu48Y+zbajJoAfy5Mp7fXOXg4JPFZ sdwA== X-Gm-Gg: ASbGncvI2ZKlEmh4ZNenXw1qXwgBj7xQcpajYDLCCzVThjZaqpYQNKPXl2rJ9ecaXO0 bzyMBChaoJOuraKUtYrC7NcLVoC9a70rLAUw991hNx7/Thfd5M+OcJMfj0d0K3ERVbaMlcQQBks lUBU0t4tVvmduNKbDHOdtbEaDmPULi0rwtHblHmGvy7IQ0CFsDfl0eRE23simEfDNxLgPfX10aM AuZYreR4UyuqY1l5lOEH3/FWMSedWpHFhuBmpyuh+vj/38ox7+E2vwlLPA3eauJYqb+DTZP9KjH xWu+ X-Received: by 2002:a17:90b:5205:b0:2ee:dcf6:1c77 with SMTP id 98e67ed59e1d1-2f83abda2e7mr33880213a91.16.1738552351498; Sun, 02 Feb 2025 19:12:31 -0800 (PST) X-Google-Smtp-Source: AGHT+IFdUAqSb7O1OOtO8vdivoSMayHR6jmuOzn90tYA7R8bTGKxxPWK9+U5BDDLz3EfLgCsko/Heg== X-Received: by 2002:a17:90b:5205:b0:2ee:dcf6:1c77 with SMTP id 98e67ed59e1d1-2f83abda2e7mr33880182a91.16.1738552351109; Sun, 02 Feb 2025 19:12:31 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:30 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 01/10] gpio: aggregator: reorder functions to prepare for configfs introduction Date: Mon, 3 Feb 2025 12:12:04 +0900 Message-ID: <20250203031213.399914-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Signed-off-by: Koichiro Den Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 352 +++++++++++++++++---------------- 1 file changed, 178 insertions(+), 174 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 65f41cc3eafc..570cd1ff8cc2 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -61,180 +61,6 @@ static int aggr_add_gpio(struct gpio_aggregator *aggr, = const char *key, return 0; } =20 -static int aggr_parse(struct gpio_aggregator *aggr) -{ - char *args =3D skip_spaces(aggr->args); - char *name, *offsets, *p; - unsigned int i, n =3D 0; - int error =3D 0; - - unsigned long *bitmap __free(bitmap) =3D - bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); - if (!bitmap) - return -ENOMEM; - - args =3D next_arg(args, &name, &p); - while (*args) { - args =3D next_arg(args, &offsets, &p); - - p =3D get_options(offsets, 0, &error); - if (error =3D=3D 0 || *p) { - /* Named GPIO line */ - error =3D aggr_add_gpio(aggr, name, U16_MAX, &n); - if (error) - return error; - - name =3D offsets; - continue; - } - - /* GPIO chip + offset(s) */ - error =3D bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); - if (error) { - pr_err("Cannot parse %s: %d\n", offsets, error); - return error; - } - - for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error =3D aggr_add_gpio(aggr, name, i, &n); - if (error) - return error; - } - - args =3D next_arg(args, &name, &p); - } - - if (!n) { - pr_err("No GPIOs specified\n"); - return -EINVAL; - } - - return 0; -} - -static ssize_t new_device_store(struct device_driver *driver, const char *= buf, - size_t count) -{ - struct gpio_aggregator *aggr; - struct platform_device *pdev; - int res, id; - - /* kernfs guarantees string termination, so count + 1 is safe */ - aggr =3D kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) - return -ENOMEM; - - memcpy(aggr->args, buf, count + 1); - - aggr->lookups =3D kzalloc(struct_size(aggr->lookups, table, 1), - GFP_KERNEL); - if (!aggr->lookups) { - res =3D -ENOMEM; - goto free_ga; - } - - mutex_lock(&gpio_aggregator_lock); - id =3D idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); - mutex_unlock(&gpio_aggregator_lock); - - if (id < 0) { - res =3D id; - goto free_table; - } - - aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); - if (!aggr->lookups->dev_id) { - res =3D -ENOMEM; - goto remove_idr; - } - - res =3D aggr_parse(aggr); - if (res) - goto free_dev_id; - - gpiod_add_lookup_table(aggr->lookups); - - pdev =3D platform_device_register_simple(DRV_NAME, id, NULL, 0); - if (IS_ERR(pdev)) { - res =3D PTR_ERR(pdev); - goto remove_table; - } - - aggr->pdev =3D pdev; - 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); - 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 =3D kstrtouint(buf + strlen(DRV_NAME "."), 10, &id); - if (error) - return error; - - mutex_lock(&gpio_aggregator_lock); - aggr =3D idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); - if (!aggr) - return -ENOENT; - - gpio_aggregator_free(aggr); - return count; -} -static DRIVER_ATTR_WO(delete_device); - -static struct attribute *gpio_aggregator_attrs[] =3D { - &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); -} - =20 /* * GPIO Forwarder @@ -559,6 +385,170 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struc= t device *dev, } =20 =20 +/* + * Sysfs interface + */ +static int aggr_parse(struct gpio_aggregator *aggr) +{ + char *args =3D skip_spaces(aggr->args); + char *name, *offsets, *p; + unsigned int i, n =3D 0; + int error =3D 0; + + unsigned long *bitmap __free(bitmap) =3D + bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + args =3D next_arg(args, &name, &p); + while (*args) { + args =3D next_arg(args, &offsets, &p); + + p =3D get_options(offsets, 0, &error); + if (error =3D=3D 0 || *p) { + /* Named GPIO line */ + error =3D aggr_add_gpio(aggr, name, U16_MAX, &n); + if (error) + return error; + + name =3D offsets; + continue; + } + + /* GPIO chip + offset(s) */ + error =3D bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS); + if (error) { + pr_err("Cannot parse %s: %d\n", offsets, error); + return error; + } + + for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { + error =3D aggr_add_gpio(aggr, name, i, &n); + if (error) + return error; + } + + args =3D next_arg(args, &name, &p); + } + + if (!n) { + pr_err("No GPIOs specified\n"); + return -EINVAL; + } + + return 0; +} + +static ssize_t new_device_store(struct device_driver *driver, const char *= buf, + size_t count) +{ + struct gpio_aggregator *aggr; + struct platform_device *pdev; + int res, id; + + /* kernfs guarantees string termination, so count + 1 is safe */ + aggr =3D kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); + if (!aggr) + return -ENOMEM; + + memcpy(aggr->args, buf, count + 1); + + aggr->lookups =3D kzalloc(struct_size(aggr->lookups, table, 1), + GFP_KERNEL); + if (!aggr->lookups) { + res =3D -ENOMEM; + goto free_ga; + } + + mutex_lock(&gpio_aggregator_lock); + id =3D idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); + mutex_unlock(&gpio_aggregator_lock); + + if (id < 0) { + res =3D id; + goto free_table; + } + + aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); + if (!aggr->lookups->dev_id) { + res =3D -ENOMEM; + goto remove_idr; + } + + res =3D aggr_parse(aggr); + if (res) + goto free_dev_id; + + gpiod_add_lookup_table(aggr->lookups); + + pdev =3D platform_device_register_simple(DRV_NAME, id, NULL, 0); + if (IS_ERR(pdev)) { + res =3D PTR_ERR(pdev); + goto remove_table; + } + + aggr->pdev =3D pdev; + 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); + 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 =3D kstrtouint(buf + strlen(DRV_NAME "."), 10, &id); + if (error) + return error; + + mutex_lock(&gpio_aggregator_lock); + aggr =3D idr_remove(&gpio_aggregator_idr, id); + mutex_unlock(&gpio_aggregator_lock); + if (!aggr) + return -ENOENT; + + gpio_aggregator_free(aggr); + return count; +} +static DRIVER_ATTR_WO(delete_device); + +static struct attribute *gpio_aggregator_attrs[] =3D { + &driver_attr_new_device.attr, + &driver_attr_delete_device.attr, + NULL +}; +ATTRIBUTE_GROUPS(gpio_aggregator); + + /* * GPIO Aggregator platform device */ @@ -616,6 +606,20 @@ static struct platform_driver gpio_aggregator_driver = =3D { }, }; =20 +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); --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16AA278F44 for ; Mon, 3 Feb 2025 03:12:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552361; cv=none; b=QKo3rfn0IWfFHmjp5Q8Mc/5lANP3/I1Ok3gCKHwAqU1Cy1KmFqmFrrJMOrtZRz0GgXGmGOZc4fORNQ8XmyU2KmDHbcBJWNXeBNOJ6foouidQv+hM+SAmyLwm+dEQWv3r/Bc91ULI/T9PXXghJsYGVS/QGGhWuqyVDWvx/ER9moc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552361; c=relaxed/simple; bh=y0YJLkVr4lVblj2gbRQrUKDMiSqBTtuSw0y0f3bXkyk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PGwoVOvpnnlhPEUnw7np88VmYmOaVrShUOjjD2MTjkc+4KxeVSiDAWFQSrW6Q0FDQGPgrEp8e2OO78fgBoaFbE5i0IZDjQqvyV+CwSz2qHL2awWDE8B9xW98dbprjDdXbFhRMkFjhXZmtXwbJc0AmIkny2mfBEInzaAcMYxQamU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=AfNfLCRI; arc=none smtp.client-ip=185.125.188.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="AfNfLCRI" 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-1.canonical.com (Postfix) with ESMTPS id 8F1A63F296 for ; Mon, 3 Feb 2025 03:12:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552356; bh=qUPyy33QFnrdvY5sunjgPIPG/eZET6IBKhxsbizwt04=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AfNfLCRIkGhdoMnoFl+H4r1H++fFdHITd4BJa+ed+5plsiHCsQ5mCyB5FtU53ls1a LC0pngP634bhaDIcFt4syWSg7waSHFJyIyYhRv3xuPW9EEHSWZeoSM9vS+0KvnQyWl qdxqFjPW0/SWZwkjZ4ihNwr/eTFokFJryhbUrSsd8XgfDbCZiUCtdD7IWBCHqdY46h kIrPdBKmvvn70Bo695vzDud94mVHkjC3ADKTAhQyzIMc3+V7VoknFZjoEkBdCErpHn XTr6hjjMYHztEaSZCGSKsEzZ5T595qsPFzK6SfxUsr+k/SUc1mI2sNwb1UXlJbwN47 +VHFM1exnS9EQ== Received: by mail-pj1-f69.google.com with SMTP id 98e67ed59e1d1-2efa74481fdso7597749a91.1 for ; Sun, 02 Feb 2025 19:12:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552355; x=1739157155; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qUPyy33QFnrdvY5sunjgPIPG/eZET6IBKhxsbizwt04=; b=UJ3jB76I9wGgiZYHLs/L2yPKFWRMIIA8pDGSQ0kqSjW8QC8YaHkLV29SnRUnddPPb+ O1MuSkFou9J/3B7rCI0PjLzd3u7MFKUrxGiUlORnTGWz0T53rCrm4YjN97SDlbrWnWyN BXn2VGoD7LUua1KU4GBTKbxakB4soSfWoZpVqisn0i0qWFVp6PJMW7cSA7iLq9tzdRJV HH5xC6x4D0I9TK6XEjBnCkyjeAt3RAfIbclfXor3oIvM12PLnedUVNtaArNJagVl4j0h iiapV9hJveojXh0wBI469AFsH3B/9L7nRdpp5y86u5l3lzXQ6cOQSrz5pN6Ign8eZ9KT 5D0g== X-Forwarded-Encrypted: i=1; AJvYcCXIu1LzbtFcu2tknpIXhgj5aCDgPeWBtAXseHrP3EAbiOw79L4mg/tpmac/fIwzwS2kpM6nnXhTJR40zOQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzM/RFRGCUQWXna/XVfSLQaVAoKUwG806dKV7meecYMSmdJa6za V/4AFpYdPdko6aZrgQwitz7cw5CMyXfA4/BykxJBR6n/G1ZgPBaCphqXyf0zi+6BrBLLtCjwcuc EnHkVv1ID7VXhs9fwsOHNI3j4ewyQqH87iieJCyFu/PnJHpyXIfaT4DVhTTI6stzF7GJosnqPsl 91Ng== X-Gm-Gg: ASbGncuhNSDorJFLyqQSnLwWdlPXkFvJGRNJ9esqEdRDroT8x7DYTO8clgwP68CU6cS om9j7Gen7pId6IjrQLhrnj/cY2zOIOJtX9YFXuLCG4O3FzlPe/l8do+RM3FxQRFkOodztqWA+dR q5k/vdlWll6KksirSkNOrj/9XTnmrsuMyasV5tJTpQAoAbJVaEKMpaMfPoHHo7WkEhQLUDnwvca 4EZqCjYyTDHL44bW2DvTMfBY7nr0ghQcstTCqnjV2mTnjqtMPPOOL7XVQFQHKOzCVdnk3vp/neA qR6b X-Received: by 2002:a17:90b:2b86:b0:2ea:aa56:499 with SMTP id 98e67ed59e1d1-2f83abb3548mr28072774a91.1.1738552354884; Sun, 02 Feb 2025 19:12:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IG3pcG4hSigJFHaXRsDFTRJ6jhVQnd3BgFFQCwgFd5IgOQFhGQLmWOHFqimErndki3gBBYNTw== X-Received: by 2002:a17:90b:2b86:b0:2ea:aa56:499 with SMTP id 98e67ed59e1d1-2f83abb3548mr28072747a91.1.1738552354219; Sun, 02 Feb 2025 19:12:34 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:33 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 02/10] gpio: aggregator: introduce basic configfs interface Date: Mon, 3 Feb 2025 12:12:05 +0900 Message-ID: <20250203031213.399914-3-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 behaviour is retained for now. This commit implements minimal functionalities: /config/gpio-aggregator// /config/gpio-aggregator//live /config/gpio-aggregator/// /config/gpio-aggregator///key /config/gpio-aggregator///offset 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 >=3D 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 Signed-off-by: Koichiro Den Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 549 ++++++++++++++++++++++++++++++++- 1 file changed, 548 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 570cd1ff8cc2..c63cf3067ce7 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -9,10 +9,14 @@ =20 #include #include +#include +#include #include #include #include #include +#include +#include #include #include #include @@ -34,11 +38,39 @@ */ =20 struct gpio_aggregator { + struct config_group group; struct gpiod_lookup_table *lookups; struct platform_device *pdev; + struct mutex lock; + int id; + + /* Synchronize with probe */ + struct notifier_block bus_notifier; + struct completion probe_completion; + bool driver_bound; + + /* List of gpio_aggregator_line. Always added in order */ + struct list_head list_head; + char args[]; }; =20 +struct gpio_aggregator_line { + struct config_group group; + struct gpio_aggregator *parent; + struct list_head entry; + + /* Line index within the aggregator device */ + int idx; + + /* GPIO chip label or line name */ + 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); =20 @@ -61,6 +93,97 @@ static int aggr_add_gpio(struct gpio_aggregator *aggr, c= onst char *key, return 0; } =20 +static int aggr_notifier_call(struct notifier_block *nb, unsigned long act= ion, + void *data) +{ + struct gpio_aggregator *aggr; + struct device *dev =3D data; + + aggr =3D container_of(nb, struct gpio_aggregator, bus_notifier); + if (!device_match_name(dev, aggr->lookups->dev_id)) + return NOTIFY_DONE; + + switch (action) { + case BUS_NOTIFY_BOUND_DRIVER: + aggr->driver_bound =3D true; + break; + case BUS_NOTIFY_DRIVER_NOT_BOUND: + aggr->driver_bound =3D false; + break; + default: + return NOTIFY_DONE; + } + + complete(&aggr->probe_completion); + return NOTIFY_OK; +} + +static bool aggr_is_active(struct gpio_aggregator *aggr) +{ + lockdep_assert_held(&aggr->lock); + + return !!aggr->pdev && platform_get_drvdata(aggr->pdev); +} + +static size_t aggr_count_lines(struct gpio_aggregator *aggr) +{ + lockdep_assert_held(&aggr->lock); + + return list_count_nodes(&aggr->list_head); +} + +static struct gpio_aggregator_line *aggr_line_alloc( + struct gpio_aggregator *parent, int idx, char *key, int offset) +{ + struct gpio_aggregator_line *line; + + line =3D kzalloc(sizeof(*line), GFP_KERNEL); + if (!line) + return ERR_PTR(-ENOMEM); + + if (key) { + line->key =3D kstrdup(key, GFP_KERNEL); + if (!line->key) { + kfree(line); + return ERR_PTR(-ENOMEM); + } + } + + line->flags =3D GPIO_LOOKUP_FLAGS_DEFAULT; + line->parent =3D parent; + line->idx =3D idx; + line->offset =3D offset; + INIT_LIST_HEAD(&line->entry); + + return line; +} + +static void aggr_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 (WARN_ON(tmp->idx =3D=3D line->idx)) + return; + if (tmp->idx > line->idx) { + list_add_tail(&line->entry, &tmp->entry); + return; + } + } + list_add_tail(&line->entry, &aggr->list_head); +} + +static void aggr_line_del(struct gpio_aggregator *aggr, + struct gpio_aggregator_line *line) +{ + lockdep_assert_held(&aggr->lock); + + list_del(&line->entry); +} + =20 /* * GPIO Forwarder @@ -385,6 +508,411 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struc= t device *dev, } =20 =20 +/* + * Configfs interface + */ + +static struct gpio_aggregator * +to_gpio_aggregator(struct config_item *item) +{ + struct config_group *group =3D 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 =3D to_config_group(item); + + return container_of(group, struct gpio_aggregator_line, group); +} + +static int aggr_activate(struct gpio_aggregator *aggr) +{ + struct platform_device_info pdevinfo; + struct gpio_aggregator_line *line; + struct platform_device *pdev; + unsigned int n =3D 0; + int ret =3D 0; + + if (aggr_count_lines(aggr) =3D=3D 0) + return -EINVAL; + + aggr->lookups =3D kzalloc(struct_size(aggr->lookups, table, 1), + GFP_KERNEL); + if (!aggr->lookups) + return -ENOMEM; + + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.name =3D DRV_NAME; + pdevinfo.id =3D aggr->id; + + /* 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 !=3D n) { + ret =3D -EINVAL; + goto err_remove_lookups; + } + + if (line->offset < 0) + ret =3D aggr_add_gpio(aggr, line->key, U16_MAX, &n); + else + ret =3D aggr_add_gpio(aggr, line->key, line->offset, &n); + if (ret) + goto err_remove_lookups; + } + + aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->= id); + if (!aggr->lookups->dev_id) { + ret =3D -ENOMEM; + goto err_remove_lookups; + } + + gpiod_add_lookup_table(aggr->lookups); + + reinit_completion(&aggr->probe_completion); + aggr->driver_bound =3D false; + aggr->bus_notifier.notifier_call =3D aggr_notifier_call; + bus_register_notifier(&platform_bus_type, &aggr->bus_notifier); + + pdev =3D platform_device_register_full(&pdevinfo); + if (IS_ERR(pdev)) { + ret =3D PTR_ERR(pdev); + bus_unregister_notifier(&platform_bus_type, &aggr->bus_notifier); + goto err_remove_lookup_table; + } + + wait_for_completion(&aggr->probe_completion); + bus_unregister_notifier(&platform_bus_type, &aggr->bus_notifier); + + if (!aggr->driver_bound) { + ret =3D -ENXIO; + goto err_unregister_pdev; + } + + aggr->pdev =3D pdev; + return 0; + +err_unregister_pdev: + platform_device_unregister(pdev); +err_remove_lookup_table: + kfree(aggr->lookups->dev_id); + gpiod_remove_lookup_table(aggr->lookups); +err_remove_lookups: + kfree(aggr->lookups); + + return ret; +} + +static void aggr_deactivate(struct gpio_aggregator *aggr) +{ + platform_device_unregister(aggr->pdev); + gpiod_remove_lookup_table(aggr->lookups); + kfree(aggr->lookups->dev_id); + kfree(aggr->lookups); + aggr->pdev =3D NULL; +} + +static void aggr_lockup_configfs(struct gpio_aggregator *aggr, bool lock) +{ + struct configfs_subsystem *subsys =3D 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) + WARN_ON(configfs_depend_item_unlocked( + subsys, &line->group.cg_item)); + else + configfs_undepend_item_unlocked( + &line->group.cg_item); + } +} + +static ssize_t +gpio_aggr_line_key_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + + guard(mutex)(&aggr->lock); + + return sprintf(page, "%s\n", line->key ?: ""); +} + +static ssize_t +gpio_aggr_line_key_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + + char *key __free(kfree) =3D kstrndup(skip_spaces(page), count, + GFP_KERNEL); + if (!key) + return -ENOMEM; + + strim(key); + + guard(mutex)(&aggr->lock); + + if (aggr_is_active(aggr)) + return -EBUSY; + + kfree(line->key); + line->key =3D no_free_ptr(key); + + return count; +} + +CONFIGFS_ATTR(gpio_aggr_line_, key); + +static ssize_t +gpio_aggr_line_offset_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + unsigned int offset; + + scoped_guard(mutex, &aggr->lock) + offset =3D line->offset; + + return sprintf(page, "%d\n", offset); +} + +static ssize_t +gpio_aggr_line_offset_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + int offset, ret; + + ret =3D kstrtoint(page, 0, &offset); + if (ret) + return ret; + + /* + * Negative number here means: 'key' represents a line name to lookup. + * Non-negative means: '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)) + return -EINVAL; + + guard(mutex)(&aggr->lock); + + if (aggr_is_active(aggr)) + return -EBUSY; + + line->offset =3D offset; + + return count; +} + +CONFIGFS_ATTR(gpio_aggr_line_, offset); + +static struct configfs_attribute *gpio_aggr_line_attrs[] =3D { + &gpio_aggr_line_attr_key, + &gpio_aggr_line_attr_offset, + NULL +}; + +static ssize_t +gpio_aggr_device_live_show(struct config_item *item, char *page) +{ + struct gpio_aggregator *aggr =3D to_gpio_aggregator(item); + bool active; + + scoped_guard(mutex, &aggr->lock) + active =3D aggr_is_active(aggr); + + return sprintf(page, "%c\n", active ? '1' : '0'); +} + +static ssize_t +gpio_aggr_device_live_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator *aggr =3D to_gpio_aggregator(item); + int ret =3D 0; + bool live; + + ret =3D kstrtobool(page, &live); + if (ret) + return ret; + + if (live) + aggr_lockup_configfs(aggr, true); + + scoped_guard(mutex, &aggr->lock) { + if (live =3D=3D aggr_is_active(aggr)) + ret =3D -EPERM; + else if (live) + ret =3D aggr_activate(aggr); + else + aggr_deactivate(aggr); + } + + /* + * Undepend is required only if device disablement (live =3D=3D 0) + * succeeds or if device enablement (live =3D=3D 1) fails. + */ + if (live =3D=3D !!ret) + aggr_lockup_configfs(aggr, false); + + return ret ?: count; +} + +CONFIGFS_ATTR(gpio_aggr_device_, live); + +static struct configfs_attribute *gpio_aggr_device_attrs[] =3D { + &gpio_aggr_device_attr_live, + NULL +}; + +static void +gpio_aggr_line_release(struct config_item *item) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + + guard(mutex)(&aggr->lock); + + aggr_line_del(aggr, line); + kfree(line->key); + kfree(line); +} + +static struct configfs_item_operations gpio_aggr_line_item_ops =3D { + .release =3D gpio_aggr_line_release, +}; + +static const struct config_item_type gpio_aggr_line_type =3D { + .ct_item_ops =3D &gpio_aggr_line_item_ops, + .ct_attrs =3D gpio_aggr_line_attrs, + .ct_owner =3D THIS_MODULE, +}; + +static void gpio_aggr_device_release(struct config_item *item) +{ + struct gpio_aggregator *aggr =3D to_gpio_aggregator(item); + + guard(mutex)(&aggr->lock); + + if (aggr_is_active(aggr)) + aggr_deactivate(aggr); + + mutex_destroy(&aggr->lock); + idr_remove(&gpio_aggregator_idr, aggr->id); + kfree(aggr); +} + +static struct configfs_item_operations gpio_aggr_device_item_ops =3D { + .release =3D gpio_aggr_device_release, +}; + +static struct config_group * +gpio_aggr_device_make_group(struct config_group *group, const char *name) +{ + struct gpio_aggregator *aggr =3D to_gpio_aggregator(&group->cg_item); + struct gpio_aggregator_line *line; + unsigned int idx; + int ret, nchar; + + ret =3D sscanf(name, "line%u%n", &idx, &nchar); + if (ret !=3D 1 || nchar !=3D strlen(name)) + return ERR_PTR(-EINVAL); + + guard(mutex)(&aggr->lock); + + if (aggr_is_active(aggr)) + return ERR_PTR(-EBUSY); + + list_for_each_entry(line, &aggr->list_head, entry) + if (line->idx =3D=3D idx) + return ERR_PTR(-EINVAL); + + line =3D aggr_line_alloc(aggr, idx, NULL, -1); + if (!line) + return ERR_PTR(-ENOMEM); + + config_group_init_type_name(&line->group, name, &gpio_aggr_line_type); + + aggr_line_add(aggr, line); + + return &line->group; +} + +static struct configfs_group_operations gpio_aggr_device_group_ops =3D { + .make_group =3D gpio_aggr_device_make_group, +}; + +static const struct config_item_type gpio_aggr_device_type =3D { + .ct_group_ops =3D &gpio_aggr_device_group_ops, + .ct_item_ops =3D &gpio_aggr_device_item_ops, + .ct_attrs =3D gpio_aggr_device_attrs, + .ct_owner =3D THIS_MODULE, +}; + +static struct config_group * +gpio_aggr_make_group(struct config_group *group, const char *name) +{ + /* arg space is unneeded */ + struct gpio_aggregator *aggr =3D kzalloc(sizeof(*aggr), GFP_KERNEL); + if (!aggr) + return ERR_PTR(-ENOMEM); + + mutex_lock(&gpio_aggregator_lock); + aggr->id =3D idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); + mutex_unlock(&gpio_aggregator_lock); + + if (aggr->id < 0) { + kfree(aggr); + return ERR_PTR(aggr->id); + } + + INIT_LIST_HEAD(&aggr->list_head); + mutex_init(&aggr->lock); + config_group_init_type_name(&aggr->group, name, &gpio_aggr_device_type); + init_completion(&aggr->probe_completion); + + return &aggr->group; +} + +static struct configfs_group_operations gpio_aggr_group_ops =3D { + .make_group =3D gpio_aggr_make_group, +}; + +static const struct config_item_type gpio_aggr_type =3D { + .ct_group_ops =3D &gpio_aggr_group_ops, + .ct_owner =3D THIS_MODULE, +}; + +static struct configfs_subsystem gpio_aggr_subsys =3D { + .su_group =3D { + .cg_item =3D { + .ci_namebuf =3D DRV_NAME, + .ci_type =3D &gpio_aggr_type, + }, + }, +}; + + /* * Sysfs interface */ @@ -622,12 +1150,31 @@ static void __exit gpio_aggregator_remove_all(void) =20 static int __init gpio_aggregator_init(void) { - return platform_driver_register(&gpio_aggregator_driver); + int ret =3D 0; + + ret =3D platform_driver_register(&gpio_aggregator_driver); + if (ret) { + pr_err("Failed to register the platform driver: %d\n", ret); + return ret; + } + + config_group_init(&gpio_aggr_subsys.su_group); + mutex_init(&gpio_aggr_subsys.su_mutex); + ret =3D configfs_register_subsystem(&gpio_aggr_subsys); + if (ret) { + pr_err("Failed to register the '%s' configfs subsystem: %d\n", + gpio_aggr_subsys.su_group.cg_item.ci_namebuf, ret); + mutex_destroy(&gpio_aggr_subsys.su_mutex); + platform_driver_unregister(&gpio_aggregator_driver); + } + + return ret; } module_init(gpio_aggregator_init); =20 static void __exit gpio_aggregator_exit(void) { + configfs_unregister_subsystem(&gpio_aggr_subsys); gpio_aggregator_remove_all(); platform_driver_unregister(&gpio_aggregator_driver); } --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F44386342 for ; Mon, 3 Feb 2025 03:12:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552362; cv=none; b=aTKhJZwbZZvCvKaeW/oWoMYoRfWJgDhE2Z5QiMxlAPFVRx5h/g7r4TZWvRyAcGvnb+l1eGVwW7QvirhPTJjbiTMszognAAtR7I/OefTMsYStw9uCMac1cF0JJ6ibHqtVFJN4BbfnAz1XovHOGkdx7KRyEqAExxKp3qgGEB0+pHo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552362; c=relaxed/simple; bh=2Y6NBPCKbmP/94IPXmCJXFLpGu3HSWTII15x0rMPg2E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UYPnYFUBvhAOa32g2VLiWIc3k1Dr+TQkx/Mhbf+AqTWAWrswRf2gBGn+rtFu9SYTHMU6ijeZsjrJsczyhVHW1x1Xo9GWcD3kqSLr9rZ/hOPnvk/J5JzIyKc65keQnuxbc0lW1zg0RNmMkGkm96SC2kVK+FctJvEB6y08rWmMhk4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=LqoSZbCJ; arc=none smtp.client-ip=185.125.188.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="LqoSZbCJ" 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 A81223F2F0 for ; Mon, 3 Feb 2025 03:12:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552358; bh=qFgkZeNVoc6Ek1Z3LfuUiIv8kYJatNPIlX5PMFPOzfU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LqoSZbCJslu69Vsh0ZilO9mFeIxMW0pgzj/ZiSbwc4dM9VmyvRQsEW21dvd+S/5ea MS3yNBocA6PtoKj9XqVqIMNoBn8gtSm4ICPVndCaLJglY5jsYBfuVH8ZFTamMIH2kU 0WQ87Kptx7oP1D96jmAoSghNKvBnhys9sr1gQjUfVt+Se+AW3vJJR4hxOczhjNqFS1 ZHiPD1M4hPzgvJeCjOIRt7DM/GaG21DHhrb77fxc6CHmbXkMsGyq5T1Od97PnfPkE1 XYuK8XzWAOLREkg9dz/ZPfD3ukYaNWwlz0QCNxbDYVD7OQqfWv7eo6XxOB/qR75V56 ECT8pcsI4PICQ== Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2166a1a5cc4so80729485ad.3 for ; Sun, 02 Feb 2025 19:12:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552357; x=1739157157; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qFgkZeNVoc6Ek1Z3LfuUiIv8kYJatNPIlX5PMFPOzfU=; b=wpvStkZ9abfG2fTu7wk/H9jKCSe0o2ynKm6jzg0EP+E5wjiF9veOdzuKESScpjDXHs 8CfyfacNa7KoES4BBkzHm7OPbxHnhcUgjHrt1oXKGEnL21VE9z6jdoZCaYd4z7Ga/HOg 1bK0pvIBgUTmzaHj67NFiY1gq1yaGh8voybTRUytvf05hTnYmqH+2FQwFVTgTC+MaYmG LyFWpoma5lL/fbFfC96oxXG2m3vE+FGZTa4czlDtH6boX0tH6GAaubcG2gdmnyEociLc zAoh2lU29dj1ZZxanMuFvsjsZ+o4JCxSoxLWArhA0CyXqhKjqNpH1l7Eps7ghQFS3FnW prug== X-Forwarded-Encrypted: i=1; AJvYcCXQLSPLfu/UkRPbTLc7ie+1C/bS3sxq9+opGdUXlQ4wJHGmwNuci2qjyqKzoYMMRlcP5zjjUUdeviI13Uk=@vger.kernel.org X-Gm-Message-State: AOJu0YwT9zOPpxpR/kCvqEN+7xgQZK6nvak2+J788ymVjaTEoaj5E2A0 mqcE0wYZIOFH+pJF5a6UB8jS38XUj17NHhJnXdkG/A5hP+vp4HuFA5RclbVemiDDD4DpH85H/jc mgms7MGKCl7JLDOQLZ/fn/CaFpuHYtRoPjy7Zdwbt9c8H2GdhRlFCTIZwajLBolLGJnIsymiQ+4 K1sw== X-Gm-Gg: ASbGnct6bqGyuT2/T8pJTj4uLYfXggSkxFYBbafm/bUviovxNj0gx/hUm4U5wa8oyJA XUCD6zzftqtZkIgq5m/PeUePtgotdbKQEetYLVtwVYDIsiURpOYR1meWYblegkxNPNK5BcH4+yf osnw+vBEPYrQJ45WtJKlWYxZMsJIthThV3weoIfavGk2D/I+ewIz+1AXkQJG7TLt2eYiP01of1R d0jZAZ4F1kRli8lZcLxB4bfT5/0XQ451T13Sag+8wnls5y1vaA3K0Bg7icZRd5SE8dDPuZWxZjS tPFp X-Received: by 2002:a17:902:cec3:b0:216:7ee9:2227 with SMTP id d9443c01a7336-21dd7dd88e6mr318429435ad.36.1738552357120; Sun, 02 Feb 2025 19:12:37 -0800 (PST) X-Google-Smtp-Source: AGHT+IHDZPzII7boMUc1kYDeUFjBUUJJwRNHBS0vkC4KLHE7UxpkuO1ByD1lqZ53Aa4OOdj2fw2SCA== X-Received: by 2002:a17:902:cec3:b0:216:7ee9:2227 with SMTP id d9443c01a7336-21dd7dd88e6mr318429185ad.36.1738552356836; Sun, 02 Feb 2025 19:12:36 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:36 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 03/10] gpio: aggregator: add read-only 'dev_name' configfs attribute Date: Mon, 3 Feb 2025 12:12:06 +0900 Message-ID: <20250203031213.399914-4-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a read-only 'dev_name' attribute to configfs interface, which exposes the platform bus device name. Users can easily identify which gpiochip has been created as follows: $ cat /sys/kernel/config/gpio-aggregator//dev_name gpio-aggregator.0 $ ls -d /sys/devices/platform/gpio-aggregator.0/gpiochip* gpiochip3 Signed-off-by: Koichiro Den Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index c63cf3067ce7..76d3a8677308 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -732,6 +732,23 @@ static struct configfs_attribute *gpio_aggr_line_attrs= [] =3D { NULL }; =20 +static ssize_t +gpio_aggr_device_dev_name_show(struct config_item *item, char *page) +{ + struct gpio_aggregator *aggr =3D to_gpio_aggregator(item); + struct platform_device *pdev; + + guard(mutex)(&aggr->lock); + + pdev =3D aggr->pdev; + if (pdev) + return sprintf(page, "%s\n", dev_name(&pdev->dev)); + + return sprintf(page, "%s.%d\n", DRV_NAME, aggr->id); +} + +CONFIGFS_ATTR_RO(gpio_aggr_device_, dev_name); + static ssize_t gpio_aggr_device_live_show(struct config_item *item, char *page) { @@ -781,6 +798,7 @@ gpio_aggr_device_live_store(struct config_item *item, c= onst char *page, CONFIGFS_ATTR(gpio_aggr_device_, live); =20 static struct configfs_attribute *gpio_aggr_device_attrs[] =3D { + &gpio_aggr_device_attr_dev_name, &gpio_aggr_device_attr_live, NULL }; --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F3A2153801 for ; Mon, 3 Feb 2025 03:12:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552367; cv=none; b=JQmIzpLgxurI2gp77c1+byPxriAAzNdHPK0N+wG0dGvX4qMevv9dH7WvMT/mCvn56fF5d7eiJyvgu2f7aGUCu8R0ONV3YJhUIBy/LfWJxby2a/WUl/388X+NEK72FXlY1Dc02IgwdIZCQxWNerX8/q6k+GJ4sWynv25E4OOpa7k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552367; c=relaxed/simple; bh=D5T5KJKLkNqZuunpZaQz66egOgmq3gUBykVLiVCskVA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VsHXJkLJfLWUMFWnAEoTcNB2GVATJbGziALlOYXvpQ0k8mM3hoBUCO/V2dfvGB5cuxMlXvZPPOxqUk514oI/Bk9qbvlhoi2BNW81ljkBp/NcDo1Tvn3/Dpw2QDtXlcu25KI1y/xz0tpVEFeC0hnN89/J294TIo0KdbTzILi3rE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=YMOmdPZx; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="YMOmdPZx" Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 561363F689 for ; Mon, 3 Feb 2025 03:12:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552361; bh=CmjoqfiwFmGpVKgL8na+qeTrK73yJ3NuCGJzYY0C8p0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YMOmdPZx5KBFEKDyXoudCMJ2AIM8SAyyTfLHeocMwTtC3daFlUzCAkL9KUGl/ejsA kmYQ1WINeCH0M03j639LahZGdrWOKGG7o79usD7B3uXmRLV0RFPnC9ALeQDXgcEUXp OF9/przXHgb4Kb9Bp7s6x6fJIyrRtpb4ZFC3B/orOWYxac1KZqS4xSL66RiuZqR9/q Trw5LOZU9Rhq2vPEf/TJcJj99PnlC+d2fIQCrOoV/BVIwTCp/pEwt+PAPKpHY1uIj7 jXjXlDeBdBPy9LysVcoHSDU3COtmN9ufXRi/hKEu2tcpC+o8aTnU53f2udnUpj7FqV te+6g5uO4jD5g== Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-21648ddd461so83226805ad.0 for ; Sun, 02 Feb 2025 19:12:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552360; x=1739157160; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CmjoqfiwFmGpVKgL8na+qeTrK73yJ3NuCGJzYY0C8p0=; b=v2awvCDDuVCWJj71YlE1Douyj4joe+/rNiz5MY7+cpRRnenz5Qs6JcM2+H3wz7+Wdo ZwhtnRkBLYYEx/0OcAGl9Ao66zPxQhINIqAef+MKHQ6/cFYL7Adeq6IKIF9FXix3oAcy k6CyVo9IqC8FadANseqyAAobPUiM9CtW8/SUTmw+H2evzNCDkLBJnTuo9HGxuDptrFd/ ABVmh6TmrSKyAInyi03HReXl9M5P1deQYoha6ylavmyZSD6XvW4+oiwFSlVfgtTjB9ZG 2Eb6AhcckliKocjxTY9q71u4M7hkUyDpr9+rxUyLAue8u/ayI+kgFFVJ5Kui3Yit4uUu Q0UQ== X-Forwarded-Encrypted: i=1; AJvYcCUf5FMOPUHA1M16kEcn2LY20MhTpGmOsRdNH0ro5IT2nr9Ho5EPkHyYv1t2XwTprHedz0QIYhr7ShGP8M4=@vger.kernel.org X-Gm-Message-State: AOJu0Yyf0RyVCTjD/srK3M8h1Oxc8J4WkRLRq9SHfmDES5mcIlUAZpPz 6zdx+TBddcr15XxdzhcePi6A5C3xUTO9bhtoJstr1rYo90FMddWTNjbRB8rUpxS4RfEUBUVhsoN muFp0YFasYS1+qL81duXqbevWqXPqB+afECduv1/yiRHy0q6jgj7CD1Qmn4PlqgFH6gsYqlWzTv 6uQA== X-Gm-Gg: ASbGncsUMPJe7u+wQyovOv3tzLx7qLmJ0EFbMrT9Re1FdnmcitOZZtEdrQJOZ58Vcec Pr4LuG6FVsnec7Py6bBWUPRxTYI5p5DgbWJBkb3fJgCNc95z0+XDtO2mw+8y0jCUigZbQvPyxRy zKD+dGanLIInmGjBLStc7VE/JWNb+wW/uN86oBtlbWf9MDZRloKlVZ29U2P7PxbPvv3oWhJWIhy BFwG1PASjhOVKTu5uYPb1RYYxo9I0TdBkdCktZoYoUHz1nhYylhAhyv2gw3rMPPWzc9u1m8RwRQ paIO X-Received: by 2002:a17:903:32c4:b0:216:1543:195e with SMTP id d9443c01a7336-21dd7c46c41mr327607065ad.5.1738552360007; Sun, 02 Feb 2025 19:12:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IHp+COZgI0atxnqhzoQqDdxpFJFFAFhiXjT571bA8VSq+NYsAvBWHh/9zdb8p4Q4G2jzbXzBA== X-Received: by 2002:a17:903:32c4:b0:216:1543:195e with SMTP id d9443c01a7336-21dd7c46c41mr327606845ad.5.1738552359688; Sun, 02 Feb 2025 19:12:39 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:39 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 04/10] gpio: aggregator: add read-write 'name' attribute Date: Mon, 3 Feb 2025 12:12:07 +0900 Message-ID: <20250203031213.399914-5-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previously, there is no way to assign names to GPIO lines exported through an aggregator. Allow users to set custom line names via a 'name' attribute. Signed-off-by: Koichiro Den Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 76d3a8677308..3263d99bfe69 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -63,6 +63,8 @@ struct gpio_aggregator_line { /* Line index within the aggregator device */ int idx; =20 + /* Custom name for the virtual line */ + char *name; /* GPIO chip label or line name */ char *key; /* Can be negative to indicate lookup by line name */ @@ -678,6 +680,44 @@ gpio_aggr_line_key_store(struct config_item *item, con= st char *page, =20 CONFIGFS_ATTR(gpio_aggr_line_, key); =20 +static ssize_t +gpio_aggr_line_name_show(struct config_item *item, char *page) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + + guard(mutex)(&aggr->lock); + + return sprintf(page, "%s\n", line->name ?: ""); +} + +static ssize_t +gpio_aggr_line_name_store(struct config_item *item, const char *page, + size_t count) +{ + struct gpio_aggregator_line *line =3D to_gpio_aggregator_line(item); + struct gpio_aggregator *aggr =3D line->parent; + + char *name __free(kfree) =3D kstrndup(skip_spaces(page), count, + GFP_KERNEL); + if (!name) + return -ENOMEM; + + strim(name); + + guard(mutex)(&aggr->lock); + + if (aggr_is_active(aggr)) + return -EBUSY; + + kfree(line->name); + line->name =3D no_free_ptr(name); + + return count; +} + +CONFIGFS_ATTR(gpio_aggr_line_, name); + static ssize_t gpio_aggr_line_offset_show(struct config_item *item, char *page) { @@ -728,6 +768,7 @@ CONFIGFS_ATTR(gpio_aggr_line_, offset); =20 static struct configfs_attribute *gpio_aggr_line_attrs[] =3D { &gpio_aggr_line_attr_key, + &gpio_aggr_line_attr_name, &gpio_aggr_line_attr_offset, NULL }; @@ -813,6 +854,7 @@ gpio_aggr_line_release(struct config_item *item) =20 aggr_line_del(aggr, line); kfree(line->key); + kfree(line->name); kfree(line); } =20 --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7579F17ADF7 for ; Mon, 3 Feb 2025 03:12:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552369; cv=none; b=i0vvXMZDsBEJT+RfMg8dROM2phiBYYNYsan+EseRqPRnmO6xdDcVMMlHEyvNz9ru2RXpKzqftxCfck1VhN+SlQV9XHyAv1WE4p2loINs0S2LIUu3QKltXvd2S+YD4p4fEaEeo0UnsXnfCOhhvkvILXQKvg6MQwz1+e8zLdQdpYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552369; c=relaxed/simple; bh=zJZCZlVW5x8JMAih7JUvfHXh5728lqQKD+q8IupG77Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AfWEYk/280uBCwK8DCrLDbPlp0Jr7Iqu0KjAPwFTIBeB+vJYOHXGQzeu0NeY3a1Rs2IXDRWC73chW48mEkSYMLXZDJlmQdCNZy4LOj65dHsZa0BUY9RHR477wky9CC1pdG7PNS2ESkdo35kjlf8Bm4WgCyTVCJio0Usvf8Sv8nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=teGmnVyR; arc=none smtp.client-ip=185.125.188.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="teGmnVyR" 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 432023F2F0 for ; Mon, 3 Feb 2025 03:12:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552364; bh=xk38bDYHKHen2qoXgY/zg30zCGh3ffB/t1hQmz87YKc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=teGmnVyRGNZR5rSZdqTDIp2HEh56ctycfq2JDYGhgvqUwcvsdx4o+KFamAL2eCklg Su7jEZWGSC63iYdaZwBtMst6Zp5N8xj0GPxdRhdSb3B7JI5cApVuHS13SYw28H3078 yV+Dx/sGnzbYcCQNhM9faGo7bT8xjUwxL988rdgwbYg6vZ9Ya3H+gBABUy4IttxMr5 6jQ/mX4QObQt8Pvp91oiZBMYQEGGlD1bXYlHRSqy/2vdKNqwWGTBSRSvvkJEGL1PgZ 69fO/digb6X7O4MOET5bj9SQX63zu6731ReDNGouzFd/UU/sPFcaw5b3Jg1gSdfetN ysz5ps7TiCsLQ== Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-2ef79403c5eso11367929a91.0 for ; Sun, 02 Feb 2025 19:12:44 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552363; x=1739157163; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xk38bDYHKHen2qoXgY/zg30zCGh3ffB/t1hQmz87YKc=; b=gbsQ8huJ6xVqRBFkg0DFeQ5uR6Jnjbw/ROonPIATdn1IWWkXsGCVPpiFJ6DP6SSw6w Uv90XGBmtv9V83SwGSGPLy41v6jwz76j+dsfuezAiT5osaXAC++zF1TMHGe4MkKpc+N4 UX3qRqS4CGD6Sihk2WmSauPmdrdNXPEF5FtAdWk/1J5qR7frz7ybNQqwBQoqN9tkfoSQ j9eCRRDN/pKmBMhO30D5OSaTFqnBox+rRtd4hpBeCrvn/ZnVvctqlZp+AkRtXmUdmr6E DsGyWFEvJ7UR8np1B9H2AjdXqc8FdadZHC2HFG8WbwVp/RHoKQoWk/hH1c0gCkUkxSnc X6NA== X-Forwarded-Encrypted: i=1; AJvYcCVaNXLAiHb0WSAA4/u0MrfSRRKG608/KcSAjxPxkcUdaNayeXKkbbiCxKoOUdcVNqZOX1PNlVPGupaF174=@vger.kernel.org X-Gm-Message-State: AOJu0YxInmAZR2b2Wy0Bhv2axhlSaZfKN0HzlzMAJAOmilDiMb+J+cyg ndHQys6kNO300RUqgXG61ZpRFLdA4PDTNST/gURxfbJpLQf6Na19Scmi/X0jcPHXt7u+q2lQ7rR hMQ5WfaJu4blRDk9Qifb2CaafhCeS/IVfS+yTwdloisOCWNDui2C1w1TUZMf+8Qg8NBATxUSS5/ O4oA== X-Gm-Gg: ASbGncvuII6aL912FWE1btCHKIABiLnpPF3gc+H8KI2CJSmqC0To2rxvSpC0zS7Wo5r vPsgyRWhxxRZ6k1ciB/ZRvonaFrGtOgpwZkReCFxvYaiE2t9DNiDbhBUGL6Uf3/4ZOLM9p9ujSA xWPiSSQUOZlRrlliVDhyvDWsDgse0ZzHsrfGMaRxurVlHrcmdUlgx4h3sLTqu29goaNHV0QwH4D m8SWfGJW3kwL7C02jIarkHpWqSwQ1Wq9QBNNWP4HYOa/dmE2JRVHxpnc5LmXUEAlkI3Re7ikN+W OzIv X-Received: by 2002:a17:90b:5245:b0:2ee:ee77:2263 with SMTP id 98e67ed59e1d1-2f83abaf3f2mr32900279a91.7.1738552362630; Sun, 02 Feb 2025 19:12:42 -0800 (PST) X-Google-Smtp-Source: AGHT+IEL5amk7wG7X7fEbtisp9SfGtA8Ih1squ46R2AOCgOEoiTF0V3njAVE3SOBt2yrFziBLR0N0Q== X-Received: by 2002:a17:90b:5245:b0:2ee:ee77:2263 with SMTP id 98e67ed59e1d1-2f83abaf3f2mr32900259a91.7.1738552362361; Sun, 02 Feb 2025 19:12:42 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:42 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 05/10] gpio: aggregator: expose custom line names to forwarder gpio_chip Date: Mon, 3 Feb 2025 12:12:08 +0900 Message-ID: <20250203031213.399914-6-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previously, GPIO lines in the aggregator had empty names. Now that the configfs interface supports custom names, update the GPIO forwarder to use them. Signed-off-by: Koichiro Den Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 71 ++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 3263d99bfe69..268b9b580ada 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -425,6 +425,20 @@ static int gpiochip_fwd_setup_delay_line(struct device= *dev, struct gpio_chip *c } #endif /* !CONFIG_OF_GPIO */ =20 +static int gpiochip_fwd_line_names(struct device *dev, const char **names,= int len) +{ + int num =3D device_property_string_array_count(dev, "gpio-line-names"); + if (!num) + return 0; + if (num > len) { + pr_warn("gpio-line-names contains %d lines while %d expected", + num, len); + num =3D len; + } + return device_property_read_string_array(dev, "gpio-line-names", + names, num); +} + /** * gpiochip_fwd_create() - Create a new GPIO forwarder * @dev: Parent device pointer @@ -447,6 +461,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct = device *dev, { const char *label =3D dev_name(dev); struct gpiochip_fwd *fwd; + const char **line_names; struct gpio_chip *chip; unsigned int i; int error; @@ -458,6 +473,16 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct= device *dev, =20 chip =3D &fwd->chip; =20 + if (!dev_of_node(dev)) { + line_names =3D devm_kcalloc(dev, sizeof(*line_names), ngpios, GFP_KERNEL= ); + if (!line_names) + return ERR_PTR(-ENOMEM); + + error =3D gpiochip_fwd_line_names(dev, line_names, ngpios); + if (error < 0) + return ERR_PTR(-ENOMEM); + } + /* * If any of the GPIO lines are sleeping, then the entire forwarder * will be sleeping. @@ -491,6 +516,9 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct = device *dev, chip->ngpio =3D ngpios; fwd->descs =3D descs; =20 + if (!dev_of_node(dev)) + chip->names =3D line_names; + if (chip->can_sleep) mutex_init(&fwd->mlock); else @@ -530,10 +558,40 @@ to_gpio_aggregator_line(struct config_item *item) return container_of(group, struct gpio_aggregator_line, group); } =20 +static struct fwnode_handle *aggr_make_device_swnode(struct gpio_aggregato= r *aggr) +{ + char **line_names __free(kfree) =3D NULL; + struct property_entry properties[2]; + struct gpio_aggregator_line *line; + size_t num_lines; + int n =3D 0; + + memset(properties, 0, sizeof(properties)); + + num_lines =3D aggr_count_lines(aggr); + if (num_lines =3D=3D 0) + return NULL; + + line_names =3D 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++] =3D line->name ?: ""; + + properties[0] =3D PROPERTY_ENTRY_STRING_ARRAY_LEN( + "gpio-line-names", + line_names, num_lines); + + return fwnode_create_software_node(properties, NULL); +} + static int aggr_activate(struct gpio_aggregator *aggr) { struct platform_device_info pdevinfo; struct gpio_aggregator_line *line; + struct fwnode_handle *swnode; struct platform_device *pdev; unsigned int n =3D 0; int ret =3D 0; @@ -546,9 +604,14 @@ static int aggr_activate(struct gpio_aggregator *aggr) if (!aggr->lookups) return -ENOMEM; =20 + swnode =3D aggr_make_device_swnode(aggr); + if (IS_ERR(swnode)) + goto err_remove_lookups; + memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.name =3D DRV_NAME; pdevinfo.id =3D aggr->id; + pdevinfo.fwnode =3D swnode; =20 /* The list is always sorted as new elements are inserted in order. */ list_for_each_entry(line, &aggr->list_head, entry) { @@ -560,7 +623,7 @@ static int aggr_activate(struct gpio_aggregator *aggr) */ if (!line->key || line->idx !=3D n) { ret =3D -EINVAL; - goto err_remove_lookups; + goto err_remove_swnode; } =20 if (line->offset < 0) @@ -568,13 +631,13 @@ static int aggr_activate(struct gpio_aggregator *aggr) else ret =3D aggr_add_gpio(aggr, line->key, line->offset, &n); if (ret) - goto err_remove_lookups; + goto err_remove_swnode; } =20 aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->= id); if (!aggr->lookups->dev_id) { ret =3D -ENOMEM; - goto err_remove_lookups; + goto err_remove_swnode; } =20 gpiod_add_lookup_table(aggr->lookups); @@ -607,6 +670,8 @@ static int aggr_activate(struct gpio_aggregator *aggr) 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); =20 --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09826199236 for ; Mon, 3 Feb 2025 03:12:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552370; cv=none; b=eYd/K4ac065yzcNl5V4kJfHDig/T9Zo7SVNO4i0l4ul8G7vQHD/QOjG5U0z7POfQ2t7LGqgSBx5ZAPSlSHnET4yJsHrynKDCQgBLmr8U42YDL7JT27ebEfV/YJ8L3g94JCndSwk72zX+ZnjTDaeJ/rpsa+cERDOhHvOyQL8JHMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552370; c=relaxed/simple; bh=xUaAXI8fxS5jnD6rs8+ieKbRO/Ilyx8EwwFvd0xi7HQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PFw3FboXPcn2LcI5tfJJZIOxtIb7Ch6MXDtb0lBNdx/SZed/v9oMWpWQv2cqpuwaodyjOX9a2wxAOZbkO0qX85cpDwBisjS2XFyn7gs1Xzn5hIfiodHFBW8A/1MIk1xOHziucGGhsSCq94gIJCDHQD5zkCVG8XnSJXI29oCUuNM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=FTwHTZBu; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="FTwHTZBu" Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 911413FA50 for ; Mon, 3 Feb 2025 03:12:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552366; bh=LIuVEkc8rnRPhn+h/+NDwPhAevSLWZ5xYAHN11UW6Cw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FTwHTZBuhp0Me9o+b17Fn+pE86cJ62H5v5TNAen6uIhTWs2TLsjXa0sPQNuib+nPN jljtvNU2DI7EloyeYws7cAup/A5IXBILQzFKHm9l8Q/VDxZU1oeEwfDnqQxWHXgHLL cYnPkMONeGC0OAvoqYWI7tSDAYyinEistnjLz3aqwgDs/Uer6I12UgmExI48x8X9or PN/GQVRNuZo1jCu/jxk4ztQlw594KmC+LobgVSb1BQ2XOHaBfKMANX9dI7LF5Bxoyh kwNXQn/i8ktmPa4vsGDOPaPsQ6qWNHkC0YxejFkkES4WyguCysB29Gzc1AzYv/S/v5 Df6BHELd51J1w== Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-216717543b7so32354305ad.0 for ; Sun, 02 Feb 2025 19:12:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552365; x=1739157165; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LIuVEkc8rnRPhn+h/+NDwPhAevSLWZ5xYAHN11UW6Cw=; b=i+EjfemjRPRP8Ocjf6Edk6nRCQ0OsOI3lXFr1ONrvwKqgGlidUE2x8b7qJB/ucf6u4 7LEfqsqywBQNh4tfgtwsWflGc2zuqN54ap7BXlY9S339niVri00mfiwMbLWab04eKBxH PkXTgSE6xq4VLN1af15fPyAFc4IuD9HN8Ji50Z8ybLTAugdDXFDb7bFOS5RQx25GrgCR 3K8SDJA2ahpX2CJnXPIaacYSDcL5v/i2PJYJvHWtyVwUMhm/tgoh5a3u0RcwASJHrU5C zi0Qe96IC29EoT68crShn6H2vkuJGifMufvizvaqTlJfJpjdYTt6EgTPdLj+2R56WuKI jddw== X-Forwarded-Encrypted: i=1; AJvYcCUuJdDkI3MBhf4Nm5iaD5HQ9zCqxfyxppA8Sng+Bt837FvYC0QYZoDtX/aH095TvwcXpSG+KDpWA4DwRPA=@vger.kernel.org X-Gm-Message-State: AOJu0YwGRhHSU/XNfhcW+zxbwt+buN57ERd/yFHsmaSblHnLF05qfwnq DRAwnUDM2kpadHydCM98xuvhfWZkjjJbwqf6SVyYNYqWE4QiXJdhoj+cvnYJB6MlyZEUSM+M2dF nXDj7Pd4ap0BrsgJXlNVdQJA2JP2bAtYhGKyJR3lN+zrB1iFomputZMHKhW28oYzIbrGV5qUscy H2KA== X-Gm-Gg: ASbGnct2h9eaaPhCc29+VkF6lAJDZpC1bqYLoBwR4IkO4K8A9J/6ZzYguPhZeh0JeQT ofwg4c7sLG0nGX4dAgdTgTQm6utwWFHjF7CDEwiveD8czYgGTRInonF0d7TG+EL3nrJC9ttedw7 aa3t9Yiofg4EReqn3sPjsDXErFf0Q4Y/nIYLiciP3dBo0Cgpbe4mI738of44Ccu1d8zILkW98Hw W8KKd368mK6MQzknswIUwL6tQuvsxTrGc7qN+raiw3QsOPD9M/ePja1QPghqnAs0EwNeMQT9kv+ xtx7 X-Received: by 2002:a17:902:d504:b0:216:4e9f:4ec9 with SMTP id d9443c01a7336-21dd7dcb178mr370336775ad.38.1738552365210; Sun, 02 Feb 2025 19:12:45 -0800 (PST) X-Google-Smtp-Source: AGHT+IGJZzJYjztg3YXA5nCzi8TiQrALpMwbavZ1V1gbQ1oxOD5vRmSN40RhAZTUtR00mhvxtHxEpw== X-Received: by 2002:a17:902:d504:b0:216:4e9f:4ec9 with SMTP id d9443c01a7336-21dd7dcb178mr370336465ad.38.1738552364906; Sun, 02 Feb 2025 19:12:44 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:44 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 06/10] gpio: aggregator: rename 'name' to 'key' in aggr_parse() Date: Mon, 3 Feb 2025 12:12:09 +0900 Message-ID: <20250203031213.399914-7-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Rename the local variable 'name' in aggr_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. Signed-off-by: Koichiro Den Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven --- 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 268b9b580ada..123906c821b1 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1044,7 +1044,7 @@ static struct configfs_subsystem gpio_aggr_subsys =3D= { static int aggr_parse(struct gpio_aggregator *aggr) { char *args =3D skip_spaces(aggr->args); - char *name, *offsets, *p; + char *key, *offsets, *p; unsigned int i, n =3D 0; int error =3D 0; =20 @@ -1053,18 +1053,18 @@ static int aggr_parse(struct gpio_aggregator *aggr) if (!bitmap) return -ENOMEM; =20 - args =3D next_arg(args, &name, &p); + args =3D next_arg(args, &key, &p); while (*args) { args =3D next_arg(args, &offsets, &p); =20 p =3D get_options(offsets, 0, &error); if (error =3D=3D 0 || *p) { /* Named GPIO line */ - error =3D aggr_add_gpio(aggr, name, U16_MAX, &n); + error =3D aggr_add_gpio(aggr, key, U16_MAX, &n); if (error) return error; =20 - name =3D offsets; + key =3D offsets; continue; } =20 @@ -1076,12 +1076,12 @@ static int aggr_parse(struct gpio_aggregator *aggr) } =20 for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { - error =3D aggr_add_gpio(aggr, name, i, &n); + error =3D aggr_add_gpio(aggr, key, i, &n); if (error) return error; } =20 - args =3D next_arg(args, &name, &p); + args =3D next_arg(args, &key, &p); } =20 if (!n) { --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2192B4AEE2 for ; Mon, 3 Feb 2025 03:12:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552372; cv=none; b=fuCQc/rHAhlUwtjVRs7/rGeCVEpWXV4oE3nJ8Sv/6y294bsxPqM2IpY5JeC7rA7QJgWt6mNt4YGUQajyIjxHxrlcZRzMPpeajBPIuzyBcMVpOEdFaMl3/xQC7bHPbP/e62WTZ370zZjIhb1geTol61OpBhTFbQtwhvVAB/VK9ek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552372; c=relaxed/simple; bh=jV+jwZ3dWM5g4zw7mjTrTOxRCXIjes+onPJQRvv+msw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qrcqsyXH5+8Nhj3IfHsJA51uD3NzNAT25Rmqx3xsIuIa1q5wU6Sc9mex5sVtVZh15uVi5vn+clZQShtjTti7QiJNLTljN6TOfdEHei2+CX85SzDCN1iaMFMout22UWZM1QDYqiycjjgRZIuRbwmpkPnWt3aB+K9iYbRgJwp80SQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=e5Uls2tD; arc=none smtp.client-ip=185.125.188.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="e5Uls2tD" 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-1.canonical.com (Postfix) with ESMTPS id 89E733F171 for ; Mon, 3 Feb 2025 03:12:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552369; bh=6DyFq6mV+BC29vN7qARZVdw28cmkBRh6T6+ETTGMoGQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e5Uls2tDkV5lQf1oGGuG4+ntIRW3qyI5x7Z6zGD9WW4Mbppu7O8AOJlOOUmC83ZZi NQXmhW+vSo0P73PjgBhKeD0WyU/tq4JsQju/IbDOfBb1gP1zgy5l0jZlZbDfjC8K1z LHkjmNdJE+psjxgh54ejM5wRdohVQj11x0LaW+tbBX0Z9lBPskbTAc6ZB3bi78IUxn P8dpj13+WBlSq8Jdn9eDoUtjOLaDL1Glvxeq9TzqIMnkCEcmCUwOnqpHuTH/SCOZ9v OF4VaIfSnFLtSePns2oYnplCzDLFGBv38+cHSqHISDcehtiKsZHKbBJ6NFdW30SZDA 5mvpBc3cxEO1w== Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-2ee5616e986so11147291a91.2 for ; Sun, 02 Feb 2025 19:12:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552368; x=1739157168; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6DyFq6mV+BC29vN7qARZVdw28cmkBRh6T6+ETTGMoGQ=; b=gEMllU5l1eIC+UrXviKTVau6DyCEvdYKWnPmxB6ipCXYKNRlGHGh5d6EuB0b9ZEtJu 5gl9qqgRjIrJPqeHHTd+fWowaApeILpmeD9hz/oVc6l6OIjo3++Go1aUmUkAMYneSY1m L3qYxrmF9SYQXKraBaez8WndBNbXDgITP9I9sWaO5LlVLEtRt57tgri9qm1EjPHbUS3A JhbBP+B/VmQH8lWkV21QsUOUwFYyjvNuddXXrvy/B+xHZFlM0cAH1mlb5GwarUkrmFzX j9Dx4TnqllR5ySoe3muW/RfIy39BVrGKLjkGKxM78T998FtAXS9VHP/xzQyVA6ufrDHh Ndlw== X-Forwarded-Encrypted: i=1; AJvYcCVS85gMDHw5WrrxjGFN+JvQxsIcbqjJVXmxSemnbziy54Vca0vlV7pnJsYTfj749IUqlceTljHeGIxBLBo=@vger.kernel.org X-Gm-Message-State: AOJu0YzzjF7TVZa2RqCKpekWL24/MG8kygAjSU91txGmktKdUl4Lhy/T 3KxorDRJecxycIQr90c9Jm/LKYnD2vcCThWDUHZ2Pxbq7JRTAxrLfzYxxzeNtzNr4R7UQpQri2w Ei1MapuC8MV6aWCLTIejdjcIqVupAgZ9e/EOUjZrulOxOarFH0E5sYJnR392m0NTph1OkDnGNgc YwLg== X-Gm-Gg: ASbGncs1Ha60V9j91j87CCnrMiMhSQy0a9cYRKxhDobhEgAeuhzt0QuwRYujacUsdo6 5Q1Y+4T+ZZWOf8yZvrtFgnZrtm8C31XbYl1KtD0xPQLPHdkriXs3HmqG9RUbjxk0vsY+IO8qhp/ 5CefudqNLUtxCOAhnfXmLPWbqoml6VSMXyMv1HvjflS5nPiQc9ARRTf9JKruM93/NKSgrd/kuhE alXhjGI+JATFt4tFk/85n5jK6UufD9Ou91wqYaFjf0mOZKjCS1o8fpS5S8iy0UGYoov/N0RQHS2 NVaw X-Received: by 2002:a17:90a:c88e:b0:2ee:ad18:b309 with SMTP id 98e67ed59e1d1-2f83aba9d18mr28008913a91.3.1738552367978; Sun, 02 Feb 2025 19:12:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IEzG+WvmWiYepWaFCOO88/K5IDS+0Hn9mfJmyS1XrTAE8a8vQnuxwP07j83XMT180bDYT7duA== X-Received: by 2002:a17:90a:c88e:b0:2ee:ad18:b309 with SMTP id 98e67ed59e1d1-2f83aba9d18mr28008897a91.3.1738552367679; Sun, 02 Feb 2025 19:12:47 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:47 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 07/10] gpio: aggregator: clean up gpio_aggregator_free() Date: Mon, 3 Feb 2025 12:12:10 +0900 Message-ID: <20250203031213.399914-8-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" - Rename gpio_aggregator_free() to use the "aggr_" prefix for consistency with other functions that modify struct gpio_aggregator internals. - Replace four lines within the function to invoke aggr_deactivate() - Move it to a more natural location. This is a preparatory change for the next commit. No functional change. Signed-off-by: Koichiro Den Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 123906c821b1..d5fd9fe58164 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1092,6 +1092,12 @@ static int aggr_parse(struct gpio_aggregator *aggr) return 0; } =20 +static void aggr_free(struct gpio_aggregator *aggr) +{ + aggr_deactivate(aggr); + kfree(aggr); +} + static ssize_t new_device_store(struct device_driver *driver, const char *= buf, size_t count) { @@ -1160,15 +1166,6 @@ static ssize_t new_device_store(struct device_driver= *driver, const char *buf, =20 static DRIVER_ATTR_WO(new_device); =20 -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) { @@ -1189,7 +1186,7 @@ static ssize_t delete_device_store(struct device_driv= er *driver, if (!aggr) return -ENOENT; =20 - gpio_aggregator_free(aggr); + aggr_free(aggr); return count; } static DRIVER_ATTR_WO(delete_device); @@ -1261,7 +1258,7 @@ static struct platform_driver gpio_aggregator_driver = =3D { =20 static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) { - gpio_aggregator_free(p); + aggr_free(p); return 0; } =20 --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6BA6F1D86FF for ; Mon, 3 Feb 2025 03:12:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552376; cv=none; b=pqPegxP3/LZCJqiX4q/Afxgp1eqwVR4buOnELDoVltnDNZclMhYfqXqP2uK1PifRphLX6V/wsCUr+p05MQM3i9m4lINf0KW5oT0AWhmk3hc98i7NWu3itfjS/rTaAaKQiJLTkMbxwGNXBLIBHtQWlLB5BiDnHzZ4Qz4mY7uudX8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552376; c=relaxed/simple; bh=U6fEqHsDuUdsVMOe9L1E9vnzvA8Wve4zCELAh2CEfW0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=reZmkawxSfB4HHru5lcFELv7705oVcgcAfO/k2hK1RZy96VKedm0F63bT8G4sFWd7saw2WUOz4IOdvmCUFP/2wLc9OXqmvQrD3cvWPUyiJR7pOafaK/+NCFApk9UcwEPe1b4Z9LVKStrCDaZCkHTXq0+j8OoYOSirm0CYbsolEA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=eblDfehz; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="eblDfehz" 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 E48423FA53 for ; Mon, 3 Feb 2025 03:12:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552373; bh=eQvDT9I6qIi3KEVVJ1wodCSAHDsDnsDQuR6xWwKwDIM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eblDfehz4aaYaoDJ9wUxjarN6Z1q0tkOlOEnW05hRNg/r7Y3/ZdUiRdD1h5ep53K5 LSrwRpf/QHjUGoab/fX475qqQvTWLiUZFBo+3G53fcSxodnHE1h+QS3Mg5BB9u9Fuk tAlcXOgnq7Ea/tNwRIHWP7v/TGQ8O8s+4pZLQ/ghh/T3hso6NguUfPwJsOTlvYYLPx rSgTLc1AQ/l15noKG85ugZtTp2XdMyt2XcYb2iYucpBhyggVVSziXo6WZ2GswmW9ga /8PdgfgBev/SSveze+rabVz8c4zDzM73XgW3B1an8SeOky65aj5w7lteS/6T58vHJZ Uc4yLjAB0t/cw== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2161d5b3eb5so77968575ad.3 for ; Sun, 02 Feb 2025 19:12:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552371; x=1739157171; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eQvDT9I6qIi3KEVVJ1wodCSAHDsDnsDQuR6xWwKwDIM=; b=ZqruPm0eXsLRExdX9rNpv2v+Jno933XNeUZWY9uGjpsyNvAQoMrYgYdgT173Rx7hdg YF5AwnDO4CWE0DloX5ayTOmz1eXxq02qd6+t9Wb9LXmQvVCh6P+ZkCthuM1J2PIHJbw7 GH8VwQCqjqt3FJr/HLFtaG+HV0tvkkrpH2gqLkUIqjfq1Fb9CMcki45N9EAivv9W2gWk PC/hu1B2/doK4MLOwBy0e+dR/3b/+Z9Y4OCaHwFX0oRKdPS/kY+sgsFqc4JHKkkXFi8a lcu1ZKhv89Y678lPYiVSsSu3ZXHLuFnuOeUEbk+zunxXMwPxiKOc3OLXrk9Ztiy+6Can AbJQ== X-Forwarded-Encrypted: i=1; AJvYcCXe04u+XcwGVRwQ5qTY/mkytZuyCymIP5Mql3p9QgMt1mriSQ3Z11/AM2SAkusoFC4tW9lrzDQKYyt3fnY=@vger.kernel.org X-Gm-Message-State: AOJu0YwVcsKXOppYl36DouBNCi5SWO/e9HxMZ4/DPWWWB8YqjV5iBAS1 y636+NfpM1YolM2oQcAOj0P86sJUATEJH3YL7WEHP5FcFCZDylq24r13t0v0Fd+VxsUeuNL7vUN CFhCm+wULNg+loPBZDCzT5Tr9EePLJMku7yJCHpFdDkaGbksChBAAGUbl1EQMQ7C2t+LoZSkzT2 4xBjd3QQ+F+A== X-Gm-Gg: ASbGncv+vDiDoGO2GV5o9UhPU65AgNMZjRyRcmNt9kgOOUWKXHCscgsUKC81WvOa505 SjYnD6en2kWCDDg8Wwz3eRQ/A1QIyNinuIkmBygnKAo7LHIdDhhRjxTEo5RqSGmn2YgMFDeeyqv Qf83ZvXC8dgt5Z2pVp7C5MCACZyrkw4GmhDPSxkOd3ZQj8uWeeimOlOWLPV/5ZoXKWnA4rdpAD6 EdoeU7GJQnzEuRleOsnWz/BvhkjkKp7U3WeGPeaxNbLmhhVV5HFXGjENUfIyj1zso0eUW6yQ+AD k9Jv X-Received: by 2002:a17:902:e84b:b0:215:b087:5d62 with SMTP id d9443c01a7336-21dd7deec73mr329853475ad.36.1738552371115; Sun, 02 Feb 2025 19:12:51 -0800 (PST) X-Google-Smtp-Source: AGHT+IGZwxZJDa9lhc3DtX2c9/0Y/XXsToTPF3wSKg/veEbtxBCWuGSeuvImIo4eqsvLkLd/6lyQiw== X-Received: by 2002:a17:902:e84b:b0:215:b087:5d62 with SMTP id d9443c01a7336-21dd7deec73mr329853145ad.36.1738552370682; Sun, 02 Feb 2025 19:12:50 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:50 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 08/10] gpio: aggregator: expoose aggregator created via legacy sysfs to configfs Date: Mon, 3 Feb 2025 12:12:11 +0900 Message-ID: <20250203031213.399914-9-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Expose settings for aggregators created using the sysfs 'new_device' interface to configfs. Once written to 'new_device', an "_auto." 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 asynchrnous, 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, editting 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 behaviour; users of legacy sysfs interface simply gain additional almost read-only configfs exposure. Still, users can write into '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 Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 174 +++++++++++++++++++++++++++++---- 1 file changed, 157 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index d5fd9fe58164..e101b78ad524 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -32,6 +32,7 @@ #include =20 #define AGGREGATOR_MAX_GPIOS 512 +#define AGGREGATOR_LEGACY_PREFIX "_auto" =20 /* * GPIO Aggregator sysfs interface @@ -52,6 +53,8 @@ struct gpio_aggregator { /* List of gpio_aggregator_line. Always added in order */ struct list_head list_head; =20 + /* used by legacy sysfs interface only */ + bool init_via_sysfs; char args[]; }; =20 @@ -73,6 +76,10 @@ struct gpio_aggregator_line { enum gpio_lookup_flags flags; }; =20 +struct gpio_aggregator_pdev_meta { + bool init_via_sysfs; +}; + static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); =20 @@ -127,6 +134,14 @@ static bool aggr_is_active(struct gpio_aggregator *agg= r) return !!aggr->pdev && platform_get_drvdata(aggr->pdev); } =20 +/* Only aggregators created via legacy sysfs can be "activating". */ +static bool aggr_is_activating(struct gpio_aggregator *aggr) +{ + lockdep_assert_held(&aggr->lock); + + return !!aggr->pdev && !platform_get_drvdata(aggr->pdev); +} + static size_t aggr_count_lines(struct gpio_aggregator *aggr) { lockdep_assert_held(&aggr->lock); @@ -186,6 +201,25 @@ static void aggr_line_del(struct gpio_aggregator *aggr, list_del(&line->entry); } =20 +static void aggr_unregister_lines(struct gpio_aggregator *aggr) +{ + struct gpio_aggregator_line *line; + + list_for_each_entry(line, &aggr->list_head, entry) + configfs_unregister_group(&line->group); +} + +static void aggr_free_lines(struct gpio_aggregator *aggr) +{ + struct gpio_aggregator_line *line, *tmp; + + list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) { + aggr_line_del(aggr, line); + kfree(line->key); + kfree(line); + } +} + =20 /* * GPIO Forwarder @@ -447,6 +481,7 @@ static int gpiochip_fwd_line_names(struct device *dev, = const char **names, int l * This array must contain @ngpios entries, and must not be deallo= cated * before the forwarder has been destroyed again. * @features: Bitwise ORed features as defined with FWD_FEATURE_*. + * @init_via_sysfs: True if the creation is done via legacy sysfs interfac= e. * * This function creates a new gpiochip, which forwards all GPIO operation= s to * the passed GPIO descriptors. @@ -457,7 +492,8 @@ static int gpiochip_fwd_line_names(struct device *dev, = const char **names, int l static struct gpiochip_fwd *gpiochip_fwd_create(struct device *dev, unsigned int ngpios, struct gpio_desc *descs[], - unsigned long features) + unsigned long features, + bool init_via_sysfs) { const char *label =3D dev_name(dev); struct gpiochip_fwd *fwd; @@ -473,7 +509,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct = device *dev, =20 chip =3D &fwd->chip; =20 - if (!dev_of_node(dev)) { + if (!dev_of_node(dev) && !init_via_sysfs) { line_names =3D devm_kcalloc(dev, sizeof(*line_names), ngpios, GFP_KERNEL= ); if (!line_names) return ERR_PTR(-ENOMEM); @@ -516,7 +552,7 @@ static struct gpiochip_fwd *gpiochip_fwd_create(struct = device *dev, chip->ngpio =3D ngpios; fwd->descs =3D descs; =20 - if (!dev_of_node(dev)) + if (!dev_of_node(dev) && !init_via_sysfs) chip->names =3D line_names; =20 if (chip->can_sleep) @@ -734,7 +770,7 @@ gpio_aggr_line_key_store(struct config_item *item, cons= t char *page, =20 guard(mutex)(&aggr->lock); =20 - if (aggr_is_active(aggr)) + if (aggr_is_activating(aggr) || aggr_is_active(aggr)) return -EBUSY; =20 kfree(line->key); @@ -772,7 +808,7 @@ gpio_aggr_line_name_store(struct config_item *item, con= st char *page, =20 guard(mutex)(&aggr->lock); =20 - if (aggr_is_active(aggr)) + if (aggr_is_activating(aggr) || aggr_is_active(aggr)) return -EBUSY; =20 kfree(line->name); @@ -821,7 +857,7 @@ gpio_aggr_line_offset_store(struct config_item *item, c= onst char *page, =20 guard(mutex)(&aggr->lock); =20 - if (aggr_is_active(aggr)) + if (aggr_is_activating(aggr) || aggr_is_active(aggr)) return -EBUSY; =20 line->offset =3D offset; @@ -879,11 +915,12 @@ gpio_aggr_device_live_store(struct config_item *item,= const char *page, if (ret) return ret; =20 - if (live) + if (live && !aggr->init_via_sysfs) aggr_lockup_configfs(aggr, true); =20 scoped_guard(mutex, &aggr->lock) { - if (live =3D=3D aggr_is_active(aggr)) + if (aggr_is_activating(aggr) || + (live =3D=3D aggr_is_active(aggr))) ret =3D -EPERM; else if (live) ret =3D aggr_activate(aggr); @@ -895,7 +932,7 @@ gpio_aggr_device_live_store(struct config_item *item, c= onst char *page, * Undepend is required only if device disablement (live =3D=3D 0) * succeeds or if device enablement (live =3D=3D 1) fails. */ - if (live =3D=3D !!ret) + if (live =3D=3D !!ret && !aggr->init_via_sysfs) aggr_lockup_configfs(aggr, false); =20 return ret ?: count; @@ -963,6 +1000,15 @@ gpio_aggr_device_make_group(struct config_group *grou= p, const char *name) if (ret !=3D 1 || nchar !=3D strlen(name)) return ERR_PTR(-EINVAL); =20 + if (aggr->init_via_sysfs) + /* + * Aggregators created via legacy sysfs interface are exposed as + * default groups, which means rmdir(2) is prohibited for them. + * For simplicity, and to avoid confusion, we also prohibit + * mkdir(2). + */ + return ERR_PTR(-EPERM); + guard(mutex)(&aggr->lock); =20 if (aggr_is_active(aggr)) @@ -1002,6 +1048,14 @@ gpio_aggr_make_group(struct config_group *group, con= st char *name) if (!aggr) return ERR_PTR(-ENOMEM); =20 + /* + * "_auto" 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)) =3D=3D 0) + return ERR_PTR(-EINVAL); + mutex_lock(&gpio_aggregator_lock); aggr->id =3D idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL); mutex_unlock(&gpio_aggregator_lock); @@ -1044,6 +1098,8 @@ static struct configfs_subsystem gpio_aggr_subsys =3D= { static int aggr_parse(struct gpio_aggregator *aggr) { char *args =3D skip_spaces(aggr->args); + struct gpio_aggregator_line *line; + char name[CONFIGFS_ITEM_NAME_LEN]; char *key, *offsets, *p; unsigned int i, n =3D 0; int error =3D 0; @@ -1055,14 +1111,29 @@ static int aggr_parse(struct gpio_aggregator *aggr) =20 args =3D next_arg(args, &key, &p); while (*args) { + scnprintf(name, CONFIGFS_ITEM_NAME_LEN, "line%u", n); + args =3D next_arg(args, &offsets, &p); =20 p =3D get_options(offsets, 0, &error); if (error =3D=3D 0 || *p) { /* Named GPIO line */ + line =3D aggr_line_alloc(aggr, n, key, -1); + if (!line) { + error =3D -ENOMEM; + goto err; + } + config_group_init_type_name(&line->group, name, + &gpio_aggr_line_type); + error =3D configfs_register_group(&aggr->group, + &line->group); + if (error) + goto err; + aggr_line_add(aggr, line); + error =3D aggr_add_gpio(aggr, key, U16_MAX, &n); if (error) - return error; + goto err; =20 key =3D offsets; continue; @@ -1076,9 +1147,22 @@ static int aggr_parse(struct gpio_aggregator *aggr) } =20 for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) { + line =3D aggr_line_alloc(aggr, n, key, i); + if (!line) { + error =3D -ENOMEM; + goto err; + } + config_group_init_type_name(&line->group, name, + &gpio_aggr_line_type); + error =3D configfs_register_group(&aggr->group, + &line->group); + if (error) + goto err; + aggr_line_add(aggr, line); + error =3D aggr_add_gpio(aggr, key, i, &n); if (error) - return error; + goto err; } =20 args =3D next_arg(args, &key, &p); @@ -1086,21 +1170,35 @@ static int aggr_parse(struct gpio_aggregator *aggr) =20 if (!n) { pr_err("No GPIOs specified\n"); - return -EINVAL; + goto err; } =20 return 0; + +err: + aggr_unregister_lines(aggr); + aggr_free_lines(aggr); + return error; } =20 static void aggr_free(struct gpio_aggregator *aggr) { - aggr_deactivate(aggr); + if (aggr_is_active(aggr)) + aggr_deactivate(aggr); + + aggr_unregister_lines(aggr); + aggr_free_lines(aggr); + configfs_unregister_group(&aggr->group); + mutex_destroy(&aggr->lock); + idr_remove(&gpio_aggregator_idr, aggr->id); kfree(aggr); } =20 static ssize_t new_device_store(struct device_driver *driver, const char *= buf, size_t count) { + struct gpio_aggregator_pdev_meta meta; + char name[CONFIGFS_ITEM_NAME_LEN]; struct gpio_aggregator *aggr; struct platform_device *pdev; int res, id; @@ -1112,6 +1210,7 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, =20 memcpy(aggr->args, buf, count + 1); =20 + aggr->init_via_sysfs =3D true; aggr->lookups =3D kzalloc(struct_size(aggr->lookups, table, 1), GFP_KERNEL); if (!aggr->lookups) { @@ -1128,10 +1227,22 @@ static ssize_t new_device_store(struct device_drive= r *driver, const char *buf, goto free_table; } =20 + scnprintf(name, CONFIGFS_ITEM_NAME_LEN, + "%s.%d", AGGREGATOR_LEGACY_PREFIX, id); + INIT_LIST_HEAD(&aggr->list_head); + mutex_init(&aggr->lock); + config_group_init_type_name(&aggr->group, name, &gpio_aggr_device_type); + init_completion(&aggr->probe_completion); + + /* Expose to configfs */ + res =3D configfs_register_group(&gpio_aggr_subsys.su_group, &aggr->group); + if (res) + goto remove_idr; + aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id); if (!aggr->lookups->dev_id) { res =3D -ENOMEM; - goto remove_idr; + goto unregister_group; } =20 res =3D aggr_parse(aggr); @@ -1140,7 +1251,9 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, =20 gpiod_add_lookup_table(aggr->lookups); =20 - pdev =3D platform_device_register_simple(DRV_NAME, id, NULL, 0); + meta.init_via_sysfs =3D true; + + pdev =3D platform_device_register_data(NULL, DRV_NAME, id, &meta, sizeof(= meta)); if (IS_ERR(pdev)) { res =3D PTR_ERR(pdev); goto remove_table; @@ -1153,6 +1266,8 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, gpiod_remove_lookup_table(aggr->lookups); free_dev_id: kfree(aggr->lookups->dev_id); +unregister_group: + configfs_unregister_group(&aggr->group); remove_idr: mutex_lock(&gpio_aggregator_lock); idr_remove(&gpio_aggregator_idr, id); @@ -1205,7 +1320,9 @@ ATTRIBUTE_GROUPS(gpio_aggregator); =20 static int gpio_aggregator_probe(struct platform_device *pdev) { + struct gpio_aggregator_pdev_meta *meta; struct device *dev =3D &pdev->dev; + bool init_via_sysfs =3D false; struct gpio_desc **descs; struct gpiochip_fwd *fwd; unsigned long features; @@ -1219,6 +1336,10 @@ static int gpio_aggregator_probe(struct platform_dev= ice *pdev) if (!descs) return -ENOMEM; =20 + meta =3D dev_get_platdata(&pdev->dev); + if (meta && meta->init_via_sysfs) + init_via_sysfs =3D true; + for (i =3D 0; i < n; i++) { descs[i] =3D devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS); if (IS_ERR(descs[i])) @@ -1226,7 +1347,7 @@ static int gpio_aggregator_probe(struct platform_devi= ce *pdev) } =20 features =3D (uintptr_t)device_get_match_data(dev); - fwd =3D gpiochip_fwd_create(dev, n, descs, features); + fwd =3D gpiochip_fwd_create(dev, n, descs, features, init_via_sysfs); if (IS_ERR(fwd)) return PTR_ERR(fwd); =20 @@ -1258,7 +1379,26 @@ static struct platform_driver gpio_aggregator_driver= =3D { =20 static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) { - aggr_free(p); + /* + * There should be no aggregator created via configfs, as their + * presence would prevent module unloading. + */ + struct gpio_aggregator *aggr =3D (struct gpio_aggregator *)p; + + /* + * For aggregators created via legacy sysfs, some may have been + * deactivated via configfs or may be pending a deferred probe. + * In either case, they need to be deactivated. + */ + if (aggr_is_activating(aggr) || aggr_is_active(aggr)) + aggr_deactivate(aggr); + + /* + * No need to call aggr_unregister_lines() since + * configfs_unregister_subsystem() has already been invoked. + */ + aggr_free_lines(aggr); + kfree(aggr); return 0; } =20 --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03D111D88A6 for ; Mon, 3 Feb 2025 03:12:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552378; cv=none; b=uCiVJRO5FBcnOjnAmtpCX1pAI6MRgn1VEKkEcQMunxqGieBhin1SBHCZraTrXVrGcED8ka2gSrOVAS/GcvKW72hVqQDqPk0FVEzYJT1jrDSEVjL19P2ta0H2PtfhPgntd4N1uXAuj5PybKE7zy0g3p4z3VENi893lNDbLftZRLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552378; c=relaxed/simple; bh=xO8cH1CFMF4UXApKu8/ysA04MUGZtHuGSgRmuumTW8w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T1ygrkMZeO+kdn4uCJbFK5+6KYvDGjLhY7CjWXH3kAche/yD1N2OPDA/U+zn6vXK3LzCBYzJuZnxcx1n/oMXuqYAZDJ/zrU9VNtKaljigGLGkre2JUA9nOinyjoX8/lmEnSi1TqdUEXCZvqJDYO+a7nM+obcPMO9WMi2DirFR2Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=qyrkX7SN; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="qyrkX7SN" Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 720DB3F84C for ; Mon, 3 Feb 2025 03:12:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552375; bh=Q1KkqwEQeDF8kvWjV8IZaCfD/CB9EQIzfOrcms/yLv8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qyrkX7SNiG5+UBZmg2m0u+J4XRBZxR+mhq3gnud1m4LmekLgOR6Wh642RlPrEnc4o 5URDZ3TvcIv7rKZNktJpePqsHmWx0EAP68A96p2Jlfm7+ljulNKaC7UEfZrBR5r4BD hgypIHwnRLCD+m62CuB5SuDJnawGpQFDDplLPGok4FRwIc+2mIuhXUJSSHSUcXNZ/l uJAJie3fPWj3+aIx0imD/n8kFAChurKlKApqddP4SQViL78PP7bPIXnwUCsYY6Byyj nanz2DcuC5RRpU59V+8iiliEmZXZVAeDWpXZ/Jc5uOYnM4u4eHDQO1a76CbrW+vl57 lxQB0a5Zi9xoQ== Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-2166855029eso78515075ad.0 for ; Sun, 02 Feb 2025 19:12:55 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552374; x=1739157174; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q1KkqwEQeDF8kvWjV8IZaCfD/CB9EQIzfOrcms/yLv8=; b=IP5CYkypXkBxqutuIe+IIDO4rZo5NhfPWB32YWZvFRA31WfOTzOszs2RYfPPt5pJVf 1OTBqGPXzcU5GADhO+dUEHzjDDYimkIoYhnD2dXSd9kzWTWAZF6fntUjWO89JUBusuDb XRXNJp+oZPtbKPVWYxHslj7z7QaK3PKkY6l6ZMHeG+uIPxLZcxuXKnheg7vtV01EEJi2 t8x/0z2fCwZcIK80MHbPdm+q9oCs/2lcqh1h5Blch3Z/qVtta7u4uNiKLndS4SAG9Nr0 f8CY75NzTO0mtrMUfq+H9RV0JYpW/N8NvFqnlTZJ9gPPmSB5VIOKaHKlOgZIC8mht+VL pITw== X-Forwarded-Encrypted: i=1; AJvYcCWnLl3nxN2Tqo7iER68u0N9kLyLA0YRFrIbbHrY10W172TsBvqgqj4aonkZp6h+9QaUFkhsXMMlL/TH1fI=@vger.kernel.org X-Gm-Message-State: AOJu0YyWU8ZcDckwG9swo2s4qKOKVbgKIjwaSYj32nyh3rnImsKdAhq2 gbBjTlWT0zWfZGfrElsg2NyEeCFtGXiiry8jS57oxPVkPs2AROKNZeKY2uYoXXhJJFNootMez2m l9K1GMKo6nFYkMxu4iBAUlS5wEvEN8ZDQ/D9xJUm86ZbENintWDuEGSjDu+varlYA77/ZkESMn+ 7Uww== X-Gm-Gg: ASbGnctkEvUXfC8e2RFfaOe8DoTU/IEBSI1ZgsaHefnUoB8ThRfK4oAH6MT2lHmvu7/ h+1xrU1byGY8QV9SikNwhUSCqYTBsWiDkSMW9gehceOF/BpbZRiiZG2QP4fjG252DjHUEitZqWS FEC1Vth7U82wFXJnKPPnFENF/DUn/MowLFNzbvbYdizrKB+2tYOqyTNuEPvp87wStkzpLH+hCVh j57wlsXdI1xOMM9YHOCG6iNq6OpYdvxtuYMQhUJ5NeRmmDPM0rafj8GiW1KfafU4UmbkDZi/Lw1 SxpG X-Received: by 2002:a17:903:2447:b0:216:6901:d588 with SMTP id d9443c01a7336-21dd7c66599mr326364265ad.15.1738552374112; Sun, 02 Feb 2025 19:12:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IFR9MoLCLJxLkNlFxcqA8WCKNHLXRd9lv4QEaLuhYy1EVJ2xo3+n+a0zlf35BvyGIVKprQjxQ== X-Received: by 2002:a17:903:2447:b0:216:6901:d588 with SMTP id d9443c01a7336-21dd7c66599mr326364135ad.15.1738552373836; Sun, 02 Feb 2025 19:12:53 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:53 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 09/10] gpio: aggregator: cancel deferred probe for devices created via configfs Date: Mon, 3 Feb 2025 12:12:12 +0900 Message-ID: <20250203031213.399914-10-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 editting 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 Tested-by: Geert Uytterhoeven --- drivers/gpio/gpio-aggregator.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index e101b78ad524..174078e02287 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -1313,7 +1313,6 @@ static struct attribute *gpio_aggregator_attrs[] =3D { }; ATTRIBUTE_GROUPS(gpio_aggregator); =20 - /* * GPIO Aggregator platform device */ @@ -1342,8 +1341,22 @@ static int gpio_aggregator_probe(struct platform_dev= ice *pdev) =20 for (i =3D 0; i < n; i++) { descs[i] =3D 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 by userspace. 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] =3D=3D ERR_PTR(-EPROBE_DEFER)) { + pr_warn("Deferred probe canceled for creation by userspace.\n"); + return -ENODEV; + } return PTR_ERR(descs[i]); + } } =20 features =3D (uintptr_t)device_get_match_data(dev); --=20 2.45.2 From nobody Mon Feb 9 04:31:42 2026 Received: from smtp-relay-internal-1.canonical.com (smtp-relay-internal-1.canonical.com [185.125.188.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBE4F1DC9B0 for ; Mon, 3 Feb 2025 03:12:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552381; cv=none; b=UwsZJZerAIzSmUx2w0ARmHAXmSZ1PZE+lt4U0rnQXx7gtNuLTgiXH09OLk0sDYm1lK1HkWW6jATHpCMcfNKs/3KPgsdVOTeDooQPs0P9gMFauOESkJSdN7DFdCuPEOr1HOPvSCDHg74wCcob8iNK5QcuiSyoiXsaIm1t8uF7IMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738552381; c=relaxed/simple; bh=Vqk19K2G5OkkvB0lmlmp+qiCv2ThpYOqqX/LCVhB150=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CxnNXe4eOwi1arJlo7UYaejac89BI4o6SPWSve+Ja/5FpU/fQ6tA9AB3fn9n3AqlZG9YrQ4XNDv5ImK+3exHqLpVWZlA4CjrnyDXyUQn1O6ZHTSQ6Dl+vn/y1+rcpZqjpUaD19sgnyuwU9wkWoTF79iXTrwTsBBKOuCtZIzHqzA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b=F5M/t3xL; arc=none smtp.client-ip=185.125.188.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=canonical.com header.i=@canonical.com header.b="F5M/t3xL" Received: from mail-pl1-f199.google.com (mail-pl1-f199.google.com [209.85.214.199]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 352B43F2F0 for ; Mon, 3 Feb 2025 03:12:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1738552378; bh=XeAXiTNaWKC5ny0m9ZhKc05Lq+fQXFbLlYp1VOJLKnk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F5M/t3xLWy+VqRaTGXxrNtjGXsFYvs1jYEiAgNS+fsu+9l8tlf9h+mmuz+D3EJW5b A2BtyP40NxQUjDFnJaURGdpS0F2skIsRgDjT55VrHUjy2gBgdJ1IaijY0MKmRg5VUj txkY4oYX70m+yY/QG5qVyoKq0LxN0GXR+ta/mtHsicmnZBLQ9FeVvIUsT3cAAB/1fm V39YDJeHJjv0phjhCe4/E1Jm6bVUHdL3Sb1uKWrKDPfk0YLq8pg4QHC8+Tj1eqBejt UOwK5f30i6fobwrge4pKWSEHvi1LFurcQgFfvc1cTTGVISFEcvMu/VHPNaDNCcPKG7 LvH88XQgCorDQ== Received: by mail-pl1-f199.google.com with SMTP id d9443c01a7336-216405eea1fso78588655ad.0 for ; Sun, 02 Feb 2025 19:12:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738552377; x=1739157177; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XeAXiTNaWKC5ny0m9ZhKc05Lq+fQXFbLlYp1VOJLKnk=; b=eFYMrFzUUUqtIcmzITazs/F0XebBEmd4MdZ/itVBctN8I8djNoqgYrHQbPIsi8ias/ 5od4Zu0LAR/iKuJZCWysdj+vpdTY+gxRs3D+NGNLi4TUENAvnK+B1X70X6fdgZvHTEJd FAlJ4Jq+bn2qiJos+L8wwdHyR5/oWRQ5We0orzl6f2GuATQzmxgmf2PY+kZhPhHAmM6+ +HMAlleoEcxQhrOlOJ7rg3fyC2/tAhNmjtSRw0Q1Qs+5F+e+LrfNwtG3szfCHHG7WXfP szL8pPaqyxNXrUvI7WbhC6S6K9EhJ1HVtkcZhnSRgPMexOt+sbeEkwgLjMnIkOP/mrdf avcQ== X-Forwarded-Encrypted: i=1; AJvYcCWPROd8o6FH6HR7soh3Yn/g5ILG1BweH9e/HCa0e7is++YZItv8XgzYIlkwKGCfImDj1Dx9/8G3r7qrB3s=@vger.kernel.org X-Gm-Message-State: AOJu0YwXB7q1wACvazMlDchO5Nui4k3qxO31YVvM3Au4Hj4LWesbe/1T bkEIIMAKLTq2aemyYYvkkb8GDgKATPTRbbu2ghVkKd9eOVTVnFUZOC7Obs6m1Ps26mX2ExocWnO lnjzCC14+mgZmyS9UkwEvIUxBs1ZjkSWJHEpbhXRUoRxQqYg0TkD1ujBDWbj7LB6hFHlWFgGv7E 9e3A== X-Gm-Gg: ASbGncu9eUsF8gONKoXpO6QkxQITLJaVtdI7mp2I7pAQj9s4nMCGmdsFTwiqIVr77BK T3k8pPkndumcA14Zg78CQEJX8bgo51+oRqAwMcJ6kEmvCKsjqbLTVuCmedkSANEZ4PQYzipP9Vp 3W+bbHUlFu0jiVrqrBwud9yD16ne/DbPRyX+QFLDvhsYNONnLGyeJpQzi0dEZZuJE2dyAQX7wcp +smKWdDON2wP0mWrs02sU3HfLa0b/sHjNw6q0wXEdycPzAlKZv0FRC5gDrhBwM7Ka9qZa7O3PLB hHqH X-Received: by 2002:a17:903:287:b0:215:cbbf:8926 with SMTP id d9443c01a7336-21dd7dddeabmr350239805ad.35.1738552376678; Sun, 02 Feb 2025 19:12:56 -0800 (PST) X-Google-Smtp-Source: AGHT+IEW85KdLcUDRiEGLjEV+sTd+bF/5MEuJ3Hn6OGahCN/cydQSnjK+aCn0zLmryY81e4Gjuewlw== X-Received: by 2002:a17:903:287:b0:215:cbbf:8926 with SMTP id d9443c01a7336-21dd7dddeabmr350239495ad.35.1738552376297; Sun, 02 Feb 2025 19:12:56 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:33e1:5e62:5b35:92b]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-21de3300253sm65809075ad.162.2025.02.02.19.12.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Feb 2025 19:12:56 -0800 (PST) From: Koichiro Den To: linux-gpio@vger.kernel.org Cc: brgl@bgdev.pl, geert+renesas@glider.be, linus.walleij@linaro.org, maciej.borzecki@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 10/10] Documentation: gpio: document configfs interface for gpio-aggregator Date: Mon, 3 Feb 2025 12:12:13 +0900 Message-ID: <20250203031213.399914-11-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250203031213.399914-1-koichiro.den@canonical.com> References: <20250203031213.399914-1-koichiro.den@canonical.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation for the newly added configfs-based interface for GPIO aggregator. Signed-off-by: Koichiro Den Tested-by: Geert Uytterhoeven --- .../admin-guide/gpio/gpio-aggregator.rst | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/Documentation/admin-guide/gpio/gpio-aggregator.rst b/Documenta= tion/admin-guide/gpio/gpio-aggregator.rst index 5cd1e7221756..e753f3dc4ae6 100644 --- a/Documentation/admin-guide/gpio/gpio-aggregator.rst +++ b/Documentation/admin-guide/gpio/gpio-aggregator.rst @@ -69,6 +69,99 @@ write-only attribute files in sysfs. $ echo gpio-aggregator.0 > delete_device =20 =20 +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 + ``_auto`` 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 de= vice + once it's fully configured. The accepted values are: ``1`` to enable t= he + virtual device and ``0`` to disable and tear it down. + +**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 t= hat 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 >=3D 0) lines. Configure all lines bef= ore +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`` + + If ``offset`` is >=3D 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. + +**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, wr= iting +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/_auto./``. 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 ------------------- =20 --=20 2.45.2