From nobody Fri Dec 19 06:07:40 2025 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 A9EEF192B75 for ; Sun, 16 Feb 2025 12:58:40 +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=1739710722; cv=none; b=i7Q0+WEPQLfN08/G4+LYggF7GRd9bg0Kah/R7C8dqvTLDiHCeCbbuMm4+2aN4OGlDb7L1Zpif+twxw+svP9vPa4L5olMGvq1LlJtMduFGLgcZ+ppvfD/ot6JQBG4qGhyV8SsgyG/6T6zG+W0zHMGsWmCljIojkgPXhbwKlN8wkc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710722; c=relaxed/simple; bh=ON0ehqNkL/xvxuSncxnJd1gtNg+6gWPXLCaJXpCE84w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b6AwkjaUdWB5QM3p7fJdw9r0TwYJMbndpqhGiY+wmJ0tJWyvvOqzV7Zn46x4QRRwQ+2Ls+uQyL3sXrI8uuphfewHBubAR9BEK6zFJ5KkQMKQB14He1Tb2PbKRsPbeXw1QO5USzh/0Q9nN4/xnIaWMAYJHAwujdW95kB51T6zl9U= 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=pE0FEtNV; 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="pE0FEtNV" 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-0.canonical.com (Postfix) with ESMTPS id 07C5A3F87A for ; Sun, 16 Feb 2025 12:58:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710713; bh=/dv1clno4vwekIxpQT8JlY6+oBRlXDyt/p4pqtLh8l4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pE0FEtNVVAIOwUSlri8XNQXUAZjteXxuWkbOAdEhW6rgy1wF45OetBKud5otbKPtJ xU7PAsqiVhBYVdVz+oDzHxGxp2E1gywb0nqlWYB369SJBxM+WDVtxCdARmrzDXedJr DGohQYhIIoIeJEHhkTeEHQ+SI2ZAX4v6evoKTG6haqdQkx4WiNtKYe0u/qd95knkE0 Md2g2n/h0HkTN0b42z7TdjOJvDEtPPIVSbCnDul8q2uoeY0BDbg5HhMisoUlYQmTer 1Rg053qTKcyhpIbsf8jQzt1LgwUSssresKl3vsc0En731QolLMbsHkwy7j3ye+wmwk wlCnB+ZrN63fQ== Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-2fbfa786a1aso11007616a91.3 for ; Sun, 16 Feb 2025 04:58:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710709; x=1740315509; 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=K4jCzUYNjZLQEU519nSVmzK7bGNMEbdMIu2l5LaeIj+Tb2oIwAg2U4gIozre3qm9kN KRmnvXtJ1r394+wDqNHLExClUoq07oTdB716j7axyOVL/vC8iwKEQhowoWevtVI8zZoP nCXDfJ/uASsR/XitEvGZLX+5evfMeijIL17Bmo2jXhkzXRDHfCBrBJufV3ITy8f9kRqH dQ16izCYuikkSwHALsknXsXjtC1/YxV9Mro6jrkag0soFarDDHR9FQHD88KtkSG0HHpD B4R7jkdt6UHKEYUnWxK9dYrvU/xDgWZig611Ijlf/3xlauv7Jv3vWkvEQpAMQQebKpn6 D5FQ== X-Forwarded-Encrypted: i=1; AJvYcCWhY/fFJ0DXf+rDw8v9+2h1z0fFyDKRnaajKwlbrw1MCzJhXrABhVIHrAltffzSLVqKk9E0avlrO7cm7Z0=@vger.kernel.org X-Gm-Message-State: AOJu0YyQ0shzBF1SdLD8kFPb7qsmjgClHXgsdO7XiFdpCNIRziWkfruX uNffzPTsJ0l1dUHF3071OznVsszrc4dQiNxvUW9ls2HzynqgwpreeW7LMfqbjLQGxw6kgrIimQ4 tljh04qhQ2PZRqAzsmn1qJXZ0J4Hj5bEEj+/3EI8c3HuSU/3YzmXYNUN8k5SwBVtcgyYMM27EQr RBTw== X-Gm-Gg: ASbGnct4JNWsP4+rjOsozSan2SQPrHpQf5AwemuS0kVnpKl/VVSEQN3d0ylDj2gAKGN sgllhX0RhRuGDTq6OQBk0Gve/MJE+gpzx9d43nZ2JuW+xob1IM6il5dHmzr4s9Ii0L5GS3y0HIB KlLFVez38i6Qq8huPbru45XIjHAWE5iHkI95Spcfac/JbvLRaw1Up5CVeRo6dKEReG1bwKejLzy RzHAUxl2wk8vbRr+GxzUYm8fttGkbPHh4WTqcTb23KYMdq9iM3RNpThWmINSEA9sO1C88ERPUgD Sxu4JA== X-Received: by 2002:a05:6a00:1488:b0:731:771:38f2 with SMTP id d2e1a72fcca58-732617999fdmr11611742b3a.8.1739710709445; Sun, 16 Feb 2025 04:58:29 -0800 (PST) X-Google-Smtp-Source: AGHT+IHr0sSHEuxQ/iRTDuywgcXZzEo/SyHTpbRxRCvFg9+hwaoEIdP0tYG9nBhVnyE+pI/KYmPfFg== X-Received: by 2002:a05:6a00:1488:b0:731:771:38f2 with SMTP id d2e1a72fcca58-732617999fdmr11611706b3a.8.1739710709068; Sun, 16 Feb 2025 04:58:29 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:28 -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 v3 01/13] gpio: aggregator: reorder functions to prepare for configfs introduction Date: Sun, 16 Feb 2025 21:58:04 +0900 Message-ID: <20250216125816.14430-2-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 --- 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 Fri Dec 19 06:07:40 2025 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 7D5D118FC7B for ; Sun, 16 Feb 2025 12:58:36 +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=1739710719; cv=none; b=Icw/VDEmrEgF5Dz9Bgww1NCpQcD499kaX8cXChMaMHAa6B/2HF7luw4YSwSDBseEd1VhCtPZ/sKSONsGLzr0z5OfcN9XEvPG1Zf2LSaXeVkKWTYWNG5SD8+Ee3732l5DFsaw0gVYwkgQPLwLjz2xllqZH+P4Uua5VV72dQAooe0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710719; c=relaxed/simple; bh=SKtk5LGExLk6bdAki5p/BEUv1i+8IBo24wWDS1BWA5Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NBcdEERhBxTpHIojzFpx7cJg6XEY9o0tl1yNRJ+GPMnKGWYHOss3w4+7WSB902b5C20dd0CLPB8N2bHOf1+Gxr8Vp3/6KGl86yuRCC5+Ig0fng5AlZ0Ie6K4T/8PZ8gn8irNSIZATSfneJK1yNTqkYosXl0d3fbNk+gyEdPp3/4= 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=L08MBtwB; 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="L08MBtwB" 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 7FFF83F31E for ; Sun, 16 Feb 2025 12:58:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710714; bh=9/5pkxra7VYfBLz3YJTkR4kouC63TcrGmJ2E28pjOC0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L08MBtwBcUL3xaLBOyN8182ozxsWUPBr338mZ/wJWdgDbgetbpkMdzx6OzyOVxY1E c/6cqrAy+DBUNOrCjBuEVrJ8gju2Iu43DOnQuleiI87TtBjXkNEQj5LwlhDvucrhjB xqTR1DVO6cfwLaxwmh4Db4HSMxSPwruqld064KnbOhaEVpr4MHamVWsINxSy7h3cbe O8c/D31vu8n6VIHuXt/TaQPHXBQYKRLXGOkrsCpYXm27P35QEtKWVLFQ4h1WTLRjmQ RyiuLEwVlNMPvWBUult560/nRgDPHoBW7eR+8Vt1qYI64Muo39rwZ6WWgCQY9wn4Zj mbD3+nGp1F6Wg== Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-2210305535bso47789685ad.1 for ; Sun, 16 Feb 2025 04:58:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710712; x=1740315512; 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=9/5pkxra7VYfBLz3YJTkR4kouC63TcrGmJ2E28pjOC0=; b=CqEINBipqMs74f7tBvx26XQgAmJ7uR0ayoipPb7rJOJ/5pJpk3FAS0IlV80FslqM/f UjGJQ67Vah0g7XUhXH7wW4NG7a4VM1DNF1jqLBOmh1Tzb0He/1uY2FVXudJjD/poBo4b lwX623gXm7hmCUzEgWk/YiREF3ULLxUnmilFUqivSxUkYH2hA8bdGu6m3JT32CQhBrNR SKUSM3kA6usIrJfyKOwySJti0M7qqtfK62DvBoVRp6rgIdp9uTyF8ABpgoITYkQO9sTq WqvHqF1516/RyGAPXR70B3/3bY2zTHKL5WYgu+V1b3qIkKN1Up+g83r8pV7OS9dwtCBm gZIw== X-Forwarded-Encrypted: i=1; AJvYcCXaICV9x8+tIUe0AgaB3aib6ZOz9BoQoje2kMiH/HD/n4IN9SGeSywMTPoHYBOp22JQHVfUerdyF8jPKuk=@vger.kernel.org X-Gm-Message-State: AOJu0YwpGdfmn2oh+/aTFCHE+fXKCFVMK5g5QdWGah2fr4JCv9T3BLK4 sQirGitqIlNPHUPi5a8E7jAgt8319s6emHrWmwR5e4zuR594Glpvn7BaXcnK+Qvi4rWBUE/jEBA Rl7CLoVfSAYbq9agR9lc5BntVEoAtdyCNW6MMXBKSmehVwjBV90l8YSRGSyhqFB8T9oTY52hd34 fJxA== X-Gm-Gg: ASbGncsIN4UESObDMlMzIJpp7KpgBRRIf7EPwcO1JwmfHX2R31N6b9XrH+GdvG6jAwq Gvhh1dqEvfOz7GXr4Gypj6wlFWeefOl5hquSrjFxB05RxOXYszHuBlPtTHiCTg6QxCMV7CGy9XB EWCHRf+2y481xYkdOlE+5tRlD/ZY6Y3z+ZxZY9N0gqmJ4d8/1Z8tYv04i4kDraiwrAtNVA0Kh3T FW45haIMT4IZudM4lAa8Kl7j+3SQU/O404KKgS/axMPwVdia+EjwZP+Pibmj0TteZYFgJomYLLL BuQw4Q== X-Received: by 2002:a05:6a20:258b:b0:1ee:668f:4232 with SMTP id adf61e73a8af0-1ee8cbe8181mr9301437637.29.1739710712633; Sun, 16 Feb 2025 04:58:32 -0800 (PST) X-Google-Smtp-Source: AGHT+IEpMqivvwPm0hDtcmUrV8dkJTDpemIr76dzIdEexUvHzP0VmV3hCHaiULKqPm03NeL8sl5Ygw== X-Received: by 2002:a05:6a20:258b:b0:1ee:668f:4232 with SMTP id adf61e73a8af0-1ee8cbe8181mr9301416637.29.1739710712225; Sun, 16 Feb 2025 04:58:32 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:31 -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 v3 02/13] gpio: aggregator: protect driver attr handlers against module unload Date: Sun, 16 Feb 2025 21:58:05 +0900 Message-ID: <20250216125816.14430-3-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Both new_device_store and delete_device_store touch module global resources (e.g. gpio_aggregator_lock). To prevent race conditions with module unload, a reference needs to be held. Add try_module_get() in these handlers. For new_device_store, this eliminates what appears to be the most dangerous scenario: if an id is allocated from gpio_aggregator_idr but platform_device_register has not yet been called or completed, a concurrent module unload could fail to unregister/delete the device, leaving behind a dangling platform device/GPIO forwarder. This can result in various issues. The following simple reproducer demonstrates these problems: #!/bin/bash while :; do # note: whether 'gpiochip0 0' exists or not does not matter. echo 'gpiochip0 0' > /sys/bus/platform/drivers/gpio-aggregator/new_devi= ce done & while :; do modprobe gpio-aggregator modprobe -r gpio-aggregator done & wait Starting with the following warning, several kinds of warnings will appear and the system may become unstable: ------------[ cut here ]------------ list_del corruption, ffff888103e2e980->next is LIST_POISON1 (dead00000000= 0100) WARNING: CPU: 1 PID: 1327 at lib/list_debug.c:56 __list_del_entry_valid_o= r_report+0xa3/0x120 [...] RIP: 0010:__list_del_entry_valid_or_report+0xa3/0x120 [...] Call Trace: ? __list_del_entry_valid_or_report+0xa3/0x120 ? __warn.cold+0x93/0xf2 ? __list_del_entry_valid_or_report+0xa3/0x120 ? report_bug+0xe6/0x170 ? __irq_work_queue_local+0x39/0xe0 ? handle_bug+0x58/0x90 ? exc_invalid_op+0x13/0x60 ? asm_exc_invalid_op+0x16/0x20 ? __list_del_entry_valid_or_report+0xa3/0x120 gpiod_remove_lookup_table+0x22/0x60 new_device_store+0x315/0x350 [gpio_aggregator] kernfs_fop_write_iter+0x137/0x1f0 vfs_write+0x262/0x430 ksys_write+0x60/0xd0 do_syscall_64+0x6c/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e [...] ---[ end trace 0000000000000000 ]--- Fixes: 828546e24280 ("gpio: Add GPIO Aggregator") Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 570cd1ff8cc2..893cd56de867 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -446,10 +446,15 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, struct platform_device *pdev; int res, id; =20 + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + /* kernfs guarantees string termination, so count + 1 is safe */ aggr =3D kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) - return -ENOMEM; + if (!aggr) { + res =3D -ENOMEM; + goto put_module; + } =20 memcpy(aggr->args, buf, count + 1); =20 @@ -488,6 +493,7 @@ static ssize_t new_device_store(struct device_driver *d= river, const char *buf, } =20 aggr->pdev =3D pdev; + module_put(THIS_MODULE); return count; =20 remove_table: @@ -502,6 +508,8 @@ static ssize_t new_device_store(struct device_driver *d= river, const char *buf, kfree(aggr->lookups); free_ga: kfree(aggr); +put_module: + module_put(THIS_MODULE); return res; } =20 @@ -530,13 +538,19 @@ static ssize_t delete_device_store(struct device_driv= er *driver, if (error) return error; =20 + if (!try_module_get(THIS_MODULE)) + return -ENOENT; + mutex_lock(&gpio_aggregator_lock); aggr =3D idr_remove(&gpio_aggregator_idr, id); mutex_unlock(&gpio_aggregator_lock); - if (!aggr) + if (!aggr) { + module_put(THIS_MODULE); return -ENOENT; + } =20 gpio_aggregator_free(aggr); + module_put(THIS_MODULE); return count; } static DRIVER_ATTR_WO(delete_device); --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 7041A192590 for ; Sun, 16 Feb 2025 12:58: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=1739710722; cv=none; b=DnsOkFPA9z+pq/3mGNrgbKlUHrrTrmGloqRpbax4y0iPqv3SwvWJ/0p4GALslGjYWuDZF7/xQHYbr7vhqk3nmGlDFNFb0p9cswy/4eux1rcGky7t1G/Bz44kRVLAj19maIdqDIteHQJZ4G26feFRYGKsQWIYWK9kjxQ0bBMcd9A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710722; c=relaxed/simple; bh=rEnR6g5dONAt30j589RxgJPlKFdaeKR/MdU4AsEK4Sg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h+DlvBCK+QVtfBFB5hl2rju4ps0GeuemUIP+ca6ZD2nlJrv4odDw1HO6mMKeM+1Kwy6KIx6GCm6+5H+duBBYZeFFFdSU7dKhgnTqkI+/NO1sc4H3lH5G39NXbo3NMCMHmTlMEv0fVtJ+M6xRK7Rze7ceRe24UcN55ay9++pZMFk= 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=FjmU+VmG; 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="FjmU+VmG" Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id BD3DA3F2BC for ; Sun, 16 Feb 2025 12:58:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710716; bh=YWbOsm+CZ0rP8EEsqBCFAU6ijhi7ERtYl/4TbSEKuvk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FjmU+VmG3XpGk8sOLsid9aMPn+kAU/cjp4u2KxpyZZOxGm5h4UTxVixjrpZuuFbDD Wuz5Eoi0761f2wDojMMtJkX6r4mdtA0yJ8UHniXnZS4JcNGF/f5fxHH9DDdBbGp54B tLgDy/kDlYzycaY9UQcz2Oi9vzFViBNgpkLjFxYur7ZopswgRTpAsL7eJWb0MSzvMi vtDw8hsqi2EzaEqcP2vuQ8VD0lbyR/iDujrkigPDEXKrAQCnGRd7oABZ8+YbxVU1Xv uWpZFZvtiR3iWEKWke4qjrnujsvNy6O1ny0Lsa2o5n9FMCQF26NIgWjRUJ/Nm9VWP2 W2L8T+tLv0Etg== Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-2fc1cb0c2cbso9395665a91.1 for ; Sun, 16 Feb 2025 04:58:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710715; x=1740315515; 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=YWbOsm+CZ0rP8EEsqBCFAU6ijhi7ERtYl/4TbSEKuvk=; b=UbImcP+yWxIj5CShjcKJyy6wrTDF20lMHKzCCTkVvbtvCjgdPaIwXr2PO1NW1DWQE/ y7Kimx2FcNTurMD3F486DGReO1++g97eTJVvPLHdV5Q3qX1LFGvsNzqPdyzqIEvQ64G/ dgULHx6ufwQDJdm7OQaMvdtDdc13eeSR2KGWprZggyc4QQ/VDJJhiM0EKjbWG+NhBT5O IaPq2fdWm35bpK7R+nVR1oc9h0TSt1qHdiQzFh1gXhamMemR/2gcUJuU2hrwogQo9BqU 0Y2KFa4aFsu5pej9mP4OAxH4mtvq26VAf2mmnhb9io6kcpe4YnEhGLxbCRfX96pDdJBx ldsA== X-Forwarded-Encrypted: i=1; AJvYcCWE0nyoX1cHviE7dTZ1dsDS2FKuEvxt4U/SRgLYcwx2CGCNVfZrqW4GopnWHosvSY5zzwdWVjjuW6VkBws=@vger.kernel.org X-Gm-Message-State: AOJu0YyWueyZZcXdp4cE0pNQK5h3WCFJJHtjWsv09Lx3ZEexqPqFABY9 MSA5GCHaIPmS+7W5w8BHovdCLS4+wLg3yYgQLrg62Un5YLJxS+ulW2EZ3K5AP0wZclW9DXNVBWr Dwfmis7tJbmffAnGEaa6YIoLOOgInOxk/YphQd34vYcdaFo2kfPeEs81Meq1vOOsTKdwlgH9kJ7 Ea0g== X-Gm-Gg: ASbGncss4hLuViDzxbFbsJzjmN+9LgKM42ltGHQ2nHtmJEJVJOB0AuIH/hTjYcpRJAC kfRE/OJdq7LYhbhtur/OBQbLaqgJykzLku8pcfeq7/upYAOlC/kJbcV4/308HVHVpIXmGGbghUJ RGQ7jKr2NdY461QDoADHOW1U3txXdZunCbCOZaqJHCr8/rSpvk3sNXo+VMdeE/XYTH3khj4BrTR yK3qu14Bg1K0MNLqJQyC+6hekxxuDnH8VhQt23ttdB7kiSQO0+BlQSdQ1nj8PY0JYWY6cmwVeMR EQk/Ng== X-Received: by 2002:a05:6a20:918e:b0:1e4:80a9:3fb8 with SMTP id adf61e73a8af0-1ee8cb5d194mr9500718637.16.1739710715284; Sun, 16 Feb 2025 04:58:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IFm+gOGp9YBo5KHi2FrSJg3FynLc/Gzo+d49GTcLDk3uRw/FcP0OrcjD42Gx4gpZ8lwU2fMEg== X-Received: by 2002:a05:6a20:918e:b0:1e4:80a9:3fb8 with SMTP id adf61e73a8af0-1ee8cb5d194mr9500690637.16.1739710715005; Sun, 16 Feb 2025 04:58:35 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:34 -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 v3 03/13] gpio: pseudo: common helper functions for pseudo gpio devices Date: Sun, 16 Feb 2025 21:58:06 +0900 Message-ID: <20250216125816.14430-4-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Both gpio-sim and gpio-virtuser share a mechanism to instantiate a platform device and wait synchronously for probe completion. With gpio-aggregator adopting the same approach in a later commit for its configfs interface, it's time to factor out the common code. Add gpio-pseudo.[ch] to house helper functions used by all the pseudo GPIO device implementations. No functional change. Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 4 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-pseudo.c | 86 ++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpio-pseudo.h | 24 +++++++++++ 4 files changed, 115 insertions(+) create mode 100644 drivers/gpio/gpio-pseudo.c create mode 100644 drivers/gpio/gpio-pseudo.h diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 56c1f30ac195..1e2c95e03a95 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1863,6 +1863,10 @@ config GPIO_MPSSE =20 endmenu =20 +# This symbol is selected by some pseudo gpio device implementations +config GPIO_PSEUDO + bool + menu "Virtual GPIO drivers" =20 config GPIO_AGGREGATOR diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index af3ba4d81b58..5eb54147a1ab 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -136,6 +136,7 @@ obj-$(CONFIG_GPIO_PISOSR) +=3D gpio-pisosr.o obj-$(CONFIG_GPIO_PL061) +=3D gpio-pl061.o obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) +=3D gpio-pmic-eic-sprd.o obj-$(CONFIG_GPIO_POLARFIRE_SOC) +=3D gpio-mpfs.o +obj-$(CONFIG_GPIO_PSEUDO) +=3D gpio-pseudo.o obj-$(CONFIG_GPIO_PXA) +=3D gpio-pxa.o obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) +=3D gpio-raspberrypi-exp.o obj-$(CONFIG_GPIO_RC5T583) +=3D gpio-rc5t583.o diff --git a/drivers/gpio/gpio-pseudo.c b/drivers/gpio/gpio-pseudo.c new file mode 100644 index 000000000000..6e3da05440d8 --- /dev/null +++ b/drivers/gpio/gpio-pseudo.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Helper functions for Pseudo GPIOs + * + * Copyright 2025 Canonical Ltd. + */ + +#include "gpio-pseudo.h" + +static int pseudo_gpio_notifier_call(struct notifier_block *nb, + unsigned long action, + void *data) +{ + struct pseudo_gpio_common *common; + struct device *dev =3D data; + + common =3D container_of(nb, struct pseudo_gpio_common, bus_notifier); + if (!device_match_name(dev, common->name)) + return NOTIFY_DONE; + + switch (action) { + case BUS_NOTIFY_BOUND_DRIVER: + common->driver_bound =3D true; + break; + case BUS_NOTIFY_DRIVER_NOT_BOUND: + common->driver_bound =3D false; + break; + default: + return NOTIFY_DONE; + } + + complete(&common->probe_completion); + return NOTIFY_OK; +} + +void pseudo_gpio_init(struct pseudo_gpio_common *common) +{ + memset(common, 0, sizeof(*common)); + init_completion(&common->probe_completion); + common->bus_notifier.notifier_call =3D pseudo_gpio_notifier_call; +} +EXPORT_SYMBOL_GPL(pseudo_gpio_init); + +int pseudo_gpio_register(struct pseudo_gpio_common *common, + struct platform_device_info *pdevinfo) +{ + struct platform_device *pdev; + char *name; + + name =3D kasprintf(GFP_KERNEL, "%s.%u", pdevinfo->name, pdevinfo->id); + if (!name) + return -ENOMEM; + + common->driver_bound =3D false; + common->name =3D name; + reinit_completion(&common->probe_completion); + bus_register_notifier(&platform_bus_type, &common->bus_notifier); + + pdev =3D platform_device_register_full(pdevinfo); + if (IS_ERR(pdev)) { + bus_unregister_notifier(&platform_bus_type, &common->bus_notifier); + kfree(common->name); + return PTR_ERR(pdev); + } + + wait_for_completion(&common->probe_completion); + bus_unregister_notifier(&platform_bus_type, &common->bus_notifier); + + if (!common->driver_bound) { + platform_device_unregister(pdev); + kfree(common->name); + return -ENXIO; + } + + common->pdev =3D pdev; + return 0; +} +EXPORT_SYMBOL_GPL(pseudo_gpio_register); + +void pseudo_gpio_unregister(struct pseudo_gpio_common *common) +{ + platform_device_unregister(common->pdev); + kfree(common->name); + common->pdev =3D NULL; +} +EXPORT_SYMBOL_GPL(pseudo_gpio_unregister); diff --git a/drivers/gpio/gpio-pseudo.h b/drivers/gpio/gpio-pseudo.h new file mode 100644 index 000000000000..093112b6cce5 --- /dev/null +++ b/drivers/gpio/gpio-pseudo.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef GPIO_PSEUDO_H +#define GPIO_PSEUDO_H + +#include +#include + +struct pseudo_gpio_common { + struct platform_device *pdev; + const char *name; + + /* Synchronize with probe */ + struct notifier_block bus_notifier; + struct completion probe_completion; + bool driver_bound; +}; + +void pseudo_gpio_init(struct pseudo_gpio_common *common); +int pseudo_gpio_register(struct pseudo_gpio_common *common, + struct platform_device_info *pdevinfo); +void pseudo_gpio_unregister(struct pseudo_gpio_common *common); + +#endif /* GPIO_PSEUDO_H */ --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 F327B1917D9 for ; Sun, 16 Feb 2025 12:58:42 +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=1739710724; cv=none; b=rkTW8Y22YCcXTdLa79gur5EdT4e1hjNv2xQLf4SQDJtSsE+CbVgBSdDqbzUS0f8w0mBGfrexMzj7YMFqYHx/G9ZL4JIIy4ZB/rAVuTUKIeNKFfThMIFQbYVA64i6BQD/+8G/dwSwRZ6FufWbPnhaP6VtA1bMB8VmTQPS8xuZqzo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710724; c=relaxed/simple; bh=QAOA908gNel3y1R7ETsRu2jzdhf2WxIWOfoFCHcP9qo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YucJ9mNuPNgWWC2Xp/+S9gTgH3e6nOfq4WKKC6pn/V8ZxGLVjjrB/ynZuAYgM3mQyMylTGfiWABBKgbTir2AnN88PbNNnlgKCYMCp+MlPFVk3/ucNe8oPGLQkGLlW/wOdtLnlrRfhZhAM4xWvoGP5YlvFR6x+k66w3iJsuFSYyE= 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=K/rEkbm7; 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="K/rEkbm7" 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-0.canonical.com (Postfix) with ESMTPS id 93A733F2A0 for ; Sun, 16 Feb 2025 12:58:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710720; bh=N0Kj1d8MdTe6Cku6k8Y4hSRN1wAEicDaX3HkzkoJuyo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=K/rEkbm7ThcQ5Dl97ITLHjXADsoQ1zziXuk8U6tMGS3BfCK9MwThgAw2Jngnp7uqo xblJ74gCYLq2L5RNc2inH80pIi1riuKLCWEFQ0tsPITRuxlhbRG6WaruKSE9x9XspG 81BWo/xIqTUx3ZfyaaUK2uyZlh9LTvJDDUqP9JvHAfMRq0P1lC/L9j8tz1wAkZ33R1 8ELWeQwkyvxJS2l8ANeCPFGY8se2eGemm+X6t1XAPqQHBR32owc6CJkkdo2LHccnkE 1DM1UjZrR09s/SP2tz5A0qNDV86SwAc/EXHY84mCsrkA8S8sqwqHJHX4SesE+lGlTd hFCur173etkaQ== Received: by mail-pj1-f71.google.com with SMTP id 98e67ed59e1d1-2fc2e648da3so4025986a91.3 for ; Sun, 16 Feb 2025 04:58:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710719; x=1740315519; 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=N0Kj1d8MdTe6Cku6k8Y4hSRN1wAEicDaX3HkzkoJuyo=; b=cLcVZr8HdysxybHnuPq/9HUol+59eSh9xGO+7R8//rkBUA+nnUYeOFb8x2XKa33NaY pxXXtIQo2bMz7pLwkitJsdYuISbVkaneaUohdpV5Gtm86s8Np7AS9nGt2pSyUy7jREXo l1a6YzFDZW8Ny78UvRZ8XV8JIeTXlV5GS/Mqx67HTgxsvxKy7eZsQ2LmtWptuH1YLkgB b3ompcVrM7Y2yyql/+xaNJmGtKKiK6mh0BRn21tQoWPQZqjNyur6GIpfDCkt5r+Knnsb BYtmIQvs0EU0GKsgxYqC8F3YuDV/jta0Y5c74Nz6U7T5D9VCvsF/xj9YvoH/UQrHzr4s LSsg== X-Forwarded-Encrypted: i=1; AJvYcCX3rgDzXGrIQ/UPLD798F/xSEHoBLvvlaCMnU/y6fx76item+jQIqTVgwx8Hg5e9K/kqtHGPbg28wSZJIg=@vger.kernel.org X-Gm-Message-State: AOJu0YxfcX8Dm8S2pblcbz9KEWphxAeGBXjE9r3kT2uKGGDojwBsT/7p FuI6IX/WqoBCvVEMhvtqnSNExImN3l6sVMUcEZfShuseBlqqFCABgc7x1jatlo2Ul1/rM3D5K5R 5QldS+bPTaKvCNmlGYrtVeNIbAuq22ASPZ7grR9Iu7syVGx9ZiWv7cuDygzcuD+7oRJ4A/EwSe1 o13w== X-Gm-Gg: ASbGncvFgQVFqEr5W+7+0dYT/gt+WhsbQeqgkRR2JDvpe3MfcFn4YdwB0N9KVefdrcC KUu7FyYjoSIZnCajjgbybYfeVRZQMs185gEzTD6J61n/BeTloPpo+5W8TJe5jkWJU5ZTrQCcsTl 0hxLFTdVkM28sLfwZXI7PWJCMlri1YF+AWQ5sOLpXZOpHQ/2m85Fzelg7tCdDuIWeC9ms22ThZW 19t9BPTtRzJtJww1pKex30eSfOuW5HYqAtQ4eeEHMrMkc2tBjzTP+dbN0vgXwcC623Y9iy4WG0m W2bWIg== X-Received: by 2002:a05:6a00:198c:b0:730:7885:d902 with SMTP id d2e1a72fcca58-7326144b262mr10956755b3a.0.1739710718760; Sun, 16 Feb 2025 04:58:38 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNx31ACnol66ZluTW2jPSBmJYZlDsj5AI975Vm2nDmoYYTRm8RaHhWXg3ML7mJhrQFbFiFIA== X-Received: by 2002:a05:6a00:198c:b0:730:7885:d902 with SMTP id d2e1a72fcca58-7326144b262mr10956735b3a.0.1739710718404; Sun, 16 Feb 2025 04:58:38 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:37 -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 v3 04/13] gpio: sim: convert to use gpio-pseudo utilities Date: Sun, 16 Feb 2025 21:58:07 +0900 Message-ID: <20250216125816.14430-5-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Update gpio-sim to use the new gpio-pseudo helper functions for synchronized platform device creation, reducing code duplication. No functional change. Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-sim.c | 84 ++++++----------------------------------- 2 files changed, 13 insertions(+), 72 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 1e2c95e03a95..c482e3494bac 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1913,6 +1913,7 @@ config GPIO_SIM tristate "GPIO Simulator Module" select IRQ_SIM select CONFIGFS_FS + select GPIO_PSEUDO help This enables the GPIO simulator - a configfs-based GPIO testing driver. diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index a086087ada17..45dbf16bee12 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include =20 +#include "gpio-pseudo.h" + #define GPIO_SIM_NGPIO_MAX 1024 #define GPIO_SIM_PROP_MAX 4 /* Max 3 properties + sentinel. */ #define GPIO_SIM_NUM_ATTRS 3 /* value, pull and sentinel */ @@ -541,14 +542,9 @@ static struct platform_driver gpio_sim_driver =3D { }; =20 struct gpio_sim_device { + struct pseudo_gpio_common common; struct config_group group; =20 - /* - * If pdev is NULL, the device is 'pending' (waiting for configuration). - * Once the pointer is assigned, the device has been created and the - * item is 'live'. - */ - struct platform_device *pdev; int id; =20 /* @@ -562,46 +558,11 @@ struct gpio_sim_device { */ struct mutex lock; =20 - /* - * This is used to synchronously wait for the driver's probe to complete - * and notify the user-space about any errors. - */ - struct notifier_block bus_notifier; - struct completion probe_completion; - bool driver_bound; - struct gpiod_hog *hogs; =20 struct list_head bank_list; }; =20 -/* This is called with dev->lock already taken. */ -static int gpio_sim_bus_notifier_call(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct gpio_sim_device *simdev =3D container_of(nb, - struct gpio_sim_device, - bus_notifier); - struct device *dev =3D data; - char devname[32]; - - snprintf(devname, sizeof(devname), "gpio-sim.%u", simdev->id); - - if (!device_match_name(dev, devname)) - return NOTIFY_DONE; - - if (action =3D=3D BUS_NOTIFY_BOUND_DRIVER) - simdev->driver_bound =3D true; - else if (action =3D=3D BUS_NOTIFY_DRIVER_NOT_BOUND) - simdev->driver_bound =3D false; - else - return NOTIFY_DONE; - - complete(&simdev->probe_completion); - - return NOTIFY_OK; -} - static struct gpio_sim_device *to_gpio_sim_device(struct config_item *item) { struct config_group *group =3D to_config_group(item); @@ -708,7 +669,7 @@ static bool gpio_sim_device_is_live(struct gpio_sim_dev= ice *dev) { lockdep_assert_held(&dev->lock); =20 - return !!dev->pdev; + return !!dev->common.pdev; } =20 static char *gpio_sim_strdup_trimmed(const char *str, size_t count) @@ -730,7 +691,7 @@ static ssize_t gpio_sim_device_config_dev_name_show(str= uct config_item *item, =20 guard(mutex)(&dev->lock); =20 - pdev =3D dev->pdev; + pdev =3D dev->common.pdev; if (pdev) return sprintf(page, "%s\n", dev_name(&pdev->dev)); =20 @@ -939,7 +900,6 @@ static int gpio_sim_device_activate(struct gpio_sim_dev= ice *dev) { struct platform_device_info pdevinfo; struct fwnode_handle *swnode; - struct platform_device *pdev; struct gpio_sim_bank *bank; int ret; =20 @@ -981,31 +941,13 @@ static int gpio_sim_device_activate(struct gpio_sim_d= evice *dev) pdevinfo.fwnode =3D swnode; pdevinfo.id =3D dev->id; =20 - reinit_completion(&dev->probe_completion); - dev->driver_bound =3D false; - bus_register_notifier(&platform_bus_type, &dev->bus_notifier); - - pdev =3D platform_device_register_full(&pdevinfo); - if (IS_ERR(pdev)) { - bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); - gpio_sim_remove_hogs(dev); - gpio_sim_remove_swnode_recursive(swnode); - return PTR_ERR(pdev); - } - - wait_for_completion(&dev->probe_completion); - bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); - - if (!dev->driver_bound) { - /* Probe failed, check kernel log. */ - platform_device_unregister(pdev); + ret =3D pseudo_gpio_register(&dev->common, &pdevinfo); + if (ret) { gpio_sim_remove_hogs(dev); gpio_sim_remove_swnode_recursive(swnode); - return -ENXIO; + return ret; } =20 - dev->pdev =3D pdev; - return 0; } =20 @@ -1015,11 +957,10 @@ static void gpio_sim_device_deactivate(struct gpio_s= im_device *dev) =20 lockdep_assert_held(&dev->lock); =20 - swnode =3D dev_fwnode(&dev->pdev->dev); - platform_device_unregister(dev->pdev); + swnode =3D dev_fwnode(&dev->common.pdev->dev); + pseudo_gpio_unregister(&dev->common); gpio_sim_remove_hogs(dev); gpio_sim_remove_swnode_recursive(swnode); - dev->pdev =3D NULL; } =20 static void @@ -1117,7 +1058,7 @@ static ssize_t gpio_sim_bank_config_chip_name_show(st= ruct config_item *item, guard(mutex)(&dev->lock); =20 if (gpio_sim_device_is_live(dev)) - return device_for_each_child(&dev->pdev->dev, &ctx, + return device_for_each_child(&dev->common.pdev->dev, &ctx, gpio_sim_emit_chip_name); =20 return sprintf(page, "none\n"); @@ -1558,8 +1499,7 @@ gpio_sim_config_make_device_group(struct config_group= *group, const char *name) mutex_init(&dev->lock); INIT_LIST_HEAD(&dev->bank_list); =20 - dev->bus_notifier.notifier_call =3D gpio_sim_bus_notifier_call; - init_completion(&dev->probe_completion); + pseudo_gpio_init(&dev->common); =20 return &no_free_ptr(dev)->group; } --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 6B155198E92 for ; Sun, 16 Feb 2025 12:58: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=1739710727; cv=none; b=DC2KOKIi8rP7ibT+IpMwgr0lWRH+g+vV0yNd5jpdLBMA1w6yVpIOBr9NzbxLZv+42pc64mj+EsUFL0YnWuuAL3JEE1C8dBZqVoizpcxbVO+0ykugZ+FddzG0i3ZFZDpsNjr/s38lnC/w2LDLDnrP3MB62RkxCxlhnFfCq8dXJAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710727; c=relaxed/simple; bh=kgTHhR4YUfUQvLTcLHSzDC9nY3pfgiRlMVx62VhpKuU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HG/OJC0Gt9OaOCB16RDz+SKPznv4QvoUOFv/Aqg6M7LrtlB17Ro/wzUM55rxZE8ACdYH7mxZFqL1bDGJf5VmG2eLavhCOpAKH3MS+gnqDxJG24qPlYHdLONEybKPEwDBWcdDJ37Rnl3AxqyHwn0KpCfYHz2301Dzgvq5+WxoTZE= 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=mUTwenus; 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="mUTwenus" Received: from mail-pj1-f70.google.com (mail-pj1-f70.google.com [209.85.216.70]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 602F83F175 for ; Sun, 16 Feb 2025 12:58:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710723; bh=ejmbjvPRmedRPsWRD+UddjAoJvDsol1360tkb/DZqGw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mUTwenush0rt1O7IRL/b5nkNDRczKkHhRh/K5eJRwcQshl+cdJutg5TL0t56joOGv K+MInoWTWkuXYpfZIFDoSpw/ZMekyV1XrDTnEFAtLlR1aru8IUp+xN7AJ17VllzUhK tLaLGg+h9YWzXGOhthhOQ55VZGX6CJEOQ4J4xZqOZ71xr2OFV0wjHyaT6QjWs62WuC zus/u5BdnwDKEpybYptKbXxcQRNkmtDG0CrECaoITHXmKOEYAd3DXN+qlBF+ruKE6l JyGomns0/k4ygB6mCsGR6oRJYdZ+sO2OvNTUkjIgihApmx/wLDV/ilhio/SFHvngBt ANH0UgPL1PPjw== Received: by mail-pj1-f70.google.com with SMTP id 98e67ed59e1d1-2fc1a4c150bso6936984a91.2 for ; Sun, 16 Feb 2025 04:58:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710721; x=1740315521; 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=ejmbjvPRmedRPsWRD+UddjAoJvDsol1360tkb/DZqGw=; b=e9iBWZBFmttWVwSc4PBhOLg6qHwHAvZznjG4lEg0XP69RkFB82bIC7al5GB1+FdG4t J/ENwMIMugMd9XDXvkJqwbcD99LLimaAJ5tBPb1B4hKM/r/omk/O0nZy4E1lTTFdCncw izaa5OJs3vEUpz8xYlsGCAQfADnnp6ZVpEynVJNDKVSJ9qmUPPIrhW5OpATUwCkztrBI hfSgxGth45N27W9/9UnGHyofjhOihTlpJQGMBQD3hC2HXw6neCZ5okpoOI90fubEPOat 3Zw5Mp27zMSLsVd5Ph4EAA8yggEPkd7jsNThqVgou95jI1uGfWZE87Fw0Y01c5LJKSkS 5Juw== X-Forwarded-Encrypted: i=1; AJvYcCVAUlTDUQKY1iyGKCJGac4m0QwNO82sObyZv/whUUdogN8ahJo6/tHUQedxRRMFKvTSwN5Ab/cugEOzFh8=@vger.kernel.org X-Gm-Message-State: AOJu0Ywht6uBj+nIwtk2QXgiIuD9cR+Zc9+/jgiAOP72uWmuJH2oDBS4 hw1MTpMOrJoM+pPRknvXUWky0Ba+iILDGP/BGUnHUuyjKHpVATAHYra5fIo8SURIfBAg5PPiI+1 OBZNOkfbEBZVgWlDgteYgFfYE+RQCpZH2W4unoHOMqKieJfChCq8jZFRqwrT2VZ3bJmrn8AX9wY D/JA== X-Gm-Gg: ASbGnctOBQXv09WkStmAgClEaRgQQywIs+YWVaWPslG24NKBoSAb3XtxhGFMB+X5PYZ kTXAoMLELKDUdTbKbOSyJcJQ+WmQ9kmkR5f3B6I8vjJE6704pnmwDISgT9lKDUUzHndA2uRDlAh pJg5m9ZV8euFM2wbofhl3rc3tArg4AX7p1YtLqryoDLt9c1m+uuzsVylFGDjMaMCp3Z6Y38AhUP Ne39mKsV4JLYljleBd1gdyNnUOQDjXK/8acYfBi7bb7VmlAaeXR811qQ3kFxTzKTGLKUcR7zjm5 toUTxw== X-Received: by 2002:a05:6a00:18a4:b0:730:9446:4d75 with SMTP id d2e1a72fcca58-732618e4f34mr8670819b3a.17.1739710721514; Sun, 16 Feb 2025 04:58:41 -0800 (PST) X-Google-Smtp-Source: AGHT+IFPHBclEt084DH4Oi8DjKq91nsAuXScOqPf/+0apG77WS62OuJWd3yoxzJOWqYY3EEppdkZRQ== X-Received: by 2002:a05:6a00:18a4:b0:730:9446:4d75 with SMTP id d2e1a72fcca58-732618e4f34mr8670797b3a.17.1739710721224; Sun, 16 Feb 2025 04:58:41 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:40 -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 v3 05/13] gpio: virtuser: convert to use gpio-pseudo utilities Date: Sun, 16 Feb 2025 21:58:08 +0900 Message-ID: <20250216125816.14430-6-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Update gpio-virtuser to use the new gpio-pseudo helper functions for synchronized platform device creation, reducing code duplication. No functional change. Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-virtuser.c | 73 +++++------------------------------- 2 files changed, 11 insertions(+), 63 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c482e3494bac..d8fede07149f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1942,6 +1942,7 @@ config GPIO_VIRTUSER select DEBUG_FS select CONFIGFS_FS select IRQ_WORK + select GPIO_PSEUDO help Say Y here to enable the configurable, configfs-based virtual GPIO consumer testing driver. diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c index e89f299f2140..a825edc6fbc5 100644 --- a/drivers/gpio/gpio-virtuser.c +++ b/drivers/gpio/gpio-virtuser.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include =20 +#include "gpio-pseudo.h" + #define GPIO_VIRTUSER_NAME_BUF_LEN 32 =20 static DEFINE_IDA(gpio_virtuser_ida); @@ -973,49 +974,17 @@ static struct platform_driver gpio_virtuser_driver = =3D { }; =20 struct gpio_virtuser_device { + struct pseudo_gpio_common common; struct config_group group; =20 - struct platform_device *pdev; int id; struct mutex lock; =20 - struct notifier_block bus_notifier; - struct completion probe_completion; - bool driver_bound; - struct gpiod_lookup_table *lookup_table; =20 struct list_head lookup_list; }; =20 -static int gpio_virtuser_bus_notifier_call(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct gpio_virtuser_device *vdev; - struct device *dev =3D data; - char devname[32]; - - vdev =3D container_of(nb, struct gpio_virtuser_device, bus_notifier); - snprintf(devname, sizeof(devname), "gpio-virtuser.%d", vdev->id); - - if (!device_match_name(dev, devname)) - return NOTIFY_DONE; - - switch (action) { - case BUS_NOTIFY_BOUND_DRIVER: - vdev->driver_bound =3D true; - break; - case BUS_NOTIFY_DRIVER_NOT_BOUND: - vdev->driver_bound =3D false; - break; - default: - return NOTIFY_DONE; - } - - complete(&vdev->probe_completion); - return NOTIFY_OK; -} - static struct gpio_virtuser_device * to_gpio_virtuser_device(struct config_item *item) { @@ -1029,7 +998,7 @@ gpio_virtuser_device_is_live(struct gpio_virtuser_devi= ce *dev) { lockdep_assert_held(&dev->lock); =20 - return !!dev->pdev; + return !!dev->common.pdev; } =20 struct gpio_virtuser_lookup { @@ -1369,7 +1338,7 @@ gpio_virtuser_device_config_dev_name_show(struct conf= ig_item *item, =20 guard(mutex)(&dev->lock); =20 - pdev =3D dev->pdev; + pdev =3D dev->common.pdev; if (pdev) return sprintf(page, "%s\n", dev_name(&pdev->dev)); =20 @@ -1478,7 +1447,6 @@ gpio_virtuser_device_activate(struct gpio_virtuser_de= vice *dev) { struct platform_device_info pdevinfo; struct fwnode_handle *swnode; - struct platform_device *pdev; int ret; =20 lockdep_assert_held(&dev->lock); @@ -1499,31 +1467,12 @@ gpio_virtuser_device_activate(struct gpio_virtuser_= device *dev) if (ret) goto err_remove_swnode; =20 - reinit_completion(&dev->probe_completion); - dev->driver_bound =3D false; - bus_register_notifier(&platform_bus_type, &dev->bus_notifier); - - pdev =3D platform_device_register_full(&pdevinfo); - if (IS_ERR(pdev)) { - ret =3D PTR_ERR(pdev); - bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); + ret =3D pseudo_gpio_register(&dev->common, &pdevinfo); + if (ret) goto err_remove_lookup_table; - } - - wait_for_completion(&dev->probe_completion); - bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); - - if (!dev->driver_bound) { - ret =3D -ENXIO; - goto err_unregister_pdev; - } - - dev->pdev =3D pdev; =20 return 0; =20 -err_unregister_pdev: - platform_device_unregister(pdev); err_remove_lookup_table: gpio_virtuser_remove_lookup_table(dev); err_remove_swnode: @@ -1539,11 +1488,10 @@ gpio_virtuser_device_deactivate(struct gpio_virtuse= r_device *dev) =20 lockdep_assert_held(&dev->lock); =20 - swnode =3D dev_fwnode(&dev->pdev->dev); - platform_device_unregister(dev->pdev); + swnode =3D dev_fwnode(&dev->common.pdev->dev); + pseudo_gpio_unregister(&dev->common); gpio_virtuser_remove_lookup_table(dev); fwnode_remove_software_node(swnode); - dev->pdev =3D NULL; } =20 static void @@ -1772,8 +1720,7 @@ gpio_virtuser_config_make_device_group(struct config_= group *group, &gpio_virtuser_device_config_group_type); mutex_init(&dev->lock); INIT_LIST_HEAD(&dev->lookup_list); - dev->bus_notifier.notifier_call =3D gpio_virtuser_bus_notifier_call; - init_completion(&dev->probe_completion); + pseudo_gpio_init(&dev->common); =20 return &no_free_ptr(dev)->group; } --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 98DFE1922FD for ; Sun, 16 Feb 2025 12:58:47 +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=1739710729; cv=none; b=BCdKhLfgIOFGlSo3yCya8TlwEGQ8ublFN9oKoXJC7ppKWm1Np1HO3KfB5mk8znS2Buqj93ZpIqfxU8mimAmnYFPT3mtzdvhfWlv/UzkiXcdPSIN7FEqXnIMqdtLeUA8uVOu0tBDhsofGq2y5iJQca1E3ZXUwEmrstZUBpsosXo0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710729; c=relaxed/simple; bh=gaGxbWoVq59TTDiq4cJd0eCsgnEJQWKB3/3FfvlvZ5M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hlHD7rwbI7msu2Y/oFRbrX5R9IdBQvECqoEN4QCFIbqalZ+xkCFT/VJHz2fnWSTeslg5E1SQPo0kvOnbWjGwgsKtn+L8Cfr5wPTzHoRsCSqP7kcdik16WnR80HMT8hR3pR/x2tgNOl3g6XG3MrPSZ0vcjbNG4hMPIf6fAMYnHj4= 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=lHiS89xy; 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="lHiS89xy" 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 BE1CF3F2A0 for ; Sun, 16 Feb 2025 12:58:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710725; bh=iZPn8FzJi1wBDhT5MKcLY0VoABjKA3JgOf2KFRB4x/o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lHiS89xyiIXGuTMfAXkvnZGJEjt0GCRZGubgqjQzIooz9qDJ1f6UbKh6aDt7/JUYZ o+kMPvntcodBAUPKIo/sUSvp2u2glTAugiCsmDb80l+Yxel6F7ZGT7fcgIMcfiyrE0 GwC/Cjnij2njDyT3qtpJy7cDqH+Aeepa77E5NlkruwQgRCDjRrcR71voVY8a5ThRN/ pkA+dF9EYPk3vZU4A/CxCKh1gWgvzBNntRPH/Pk+LwBBPieCYzF56kCAgEz64H1vTa aaXU99VMiwDJbhvIramhx2jXdLC4HMsVYTP7RUwihVm8KkmLWxr/mDuxs1giTejrpR 0PTYVbuzEaetA== Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-2fc404aaed5so3995071a91.3 for ; Sun, 16 Feb 2025 04:58:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710724; x=1740315524; 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=iZPn8FzJi1wBDhT5MKcLY0VoABjKA3JgOf2KFRB4x/o=; b=QTxHl3z+Rqx4ynlI3JGbLVyLb2OwQXLMKXWjfD5Ovn/eNTX3loGAJz+loskbvu9tUk M8f+JuFVL4Pgbu9mtusiO5BWdHYWqxtuXNN0iSPYGmJyXCHUyYhLioFmN8xkdbGFZRfA vf6Nit7K1nOvRze0I5fzEMWjo2SGW5MS6etErww2bR+Bu4WUdDldBZFiXwqXvRBkVpT7 efVQ7AiKBih6/L0NtiMflNLjcjtRghCzl4TBhoEMEn8uV54hMPJE65JGAFzYTj24XH9T iaFye9qgFn/2hgcH/t+yLoPQ/BR8n/ddEN57SQ7Xvs+dHFAvl3nbQ209BXthcL2mFkc1 +RTg== X-Forwarded-Encrypted: i=1; AJvYcCVristO/+QHHKoIwa5WXvpGTMYMDCLaNJc8YXj2Q/TPlnoAc+J/rMGvxN3j8lQ/hMF26bLyDrfxJNF4njQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzSw60JPquuQoeK019Rx1nXrw1wf1dDDw/35zy0burYHmYEIa9D xClbeDXTMjqHqgCxk5IlwdRoi22KISBYRxhwOfce4OeyWP7NCIQ7B5c7RnlbM3JfCcYykpfWMJu 1bfATcRS10trU/uHDtFd/Vwdm4f5adQKmN7M9EER6dgc6cHce4WvmPNO8nEjkg14cUKmsmqH/0u tO1A== X-Gm-Gg: ASbGncsbqpc4Tj9OzcezhrKRNMkTJETkoq5V3U6wjwlSYtJS/3A5DzarYNxDhyNE87c vPJTZHvnLS27OhH4a/dmAjMopCmePTwffLUw7qUgAPemSoiPeLPYJT8x4JslRl3mDwkpoU50ZIJ eKD2+YyVhmyWvhFcD8VtOlZQgutQE7XM3pc7/L1Sre2BRfKmlUeZ2tM2oGe/L5crrCSG1dXBptn VAgwiQx5E+nUfmuGJJINF9iH1L7xsiq4fMH5K7ScCLkz2/GUACTFv6l0k+DqkNNPnTX/KMJbz63 xcioLA== X-Received: by 2002:a05:6a21:4014:b0:1e4:8fdd:8c77 with SMTP id adf61e73a8af0-1ee8caab5bcmr12234116637.8.1739710724260; Sun, 16 Feb 2025 04:58:44 -0800 (PST) X-Google-Smtp-Source: AGHT+IHfRPYv58J7W+79MK/Q30Fi4lENg4yHxG8EDlpAXCIOHoz6Soxw8W0XJQto3mMp1Ii5Vz+npw== X-Received: by 2002:a05:6a21:4014:b0:1e4:8fdd:8c77 with SMTP id adf61e73a8af0-1ee8caab5bcmr12234095637.8.1739710724000; Sun, 16 Feb 2025 04:58:44 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:43 -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 v3 06/13] gpio: aggregator: convert to use gpio-pseudo utilities Date: Sun, 16 Feb 2025 21:58:09 +0900 Message-ID: <20250216125816.14430-7-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Update gpio-aggregator to use the new gpio-pseudo helper functions. Note that the current sysfs interface for gpio-aggregator does not wait for probe completion when creating a platform device. This change brings no immediate benefit but prepares for a later commit introducing configfs that shares this mechanism. No functional change. Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-aggregator.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d8fede07149f..8b9ffe17426e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1871,6 +1871,7 @@ menu "Virtual GPIO drivers" =20 config GPIO_AGGREGATOR tristate "GPIO Aggregator" + select GPIO_PSEUDO help Say yes here to enable the GPIO Aggregator, which provides a way to aggregate existing GPIO lines into a new virtual GPIO chip. diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 893cd56de867..b24ed963cd9a 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -27,6 +27,8 @@ #include #include =20 +#include "gpio-pseudo.h" + #define AGGREGATOR_MAX_GPIOS 512 =20 /* @@ -34,8 +36,8 @@ */ =20 struct gpio_aggregator { + struct pseudo_gpio_common common; struct gpiod_lookup_table *lookups; - struct platform_device *pdev; char args[]; }; =20 @@ -492,7 +494,7 @@ static ssize_t new_device_store(struct device_driver *d= river, const char *buf, goto remove_table; } =20 - aggr->pdev =3D pdev; + aggr->common.pdev =3D pdev; module_put(THIS_MODULE); return count; =20 @@ -517,7 +519,7 @@ static DRIVER_ATTR_WO(new_device); =20 static void gpio_aggregator_free(struct gpio_aggregator *aggr) { - platform_device_unregister(aggr->pdev); + platform_device_unregister(aggr->common.pdev); gpiod_remove_lookup_table(aggr->lookups); kfree(aggr->lookups->dev_id); kfree(aggr->lookups); --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 2AE5119A298 for ; Sun, 16 Feb 2025 12:58:50 +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=1739710731; cv=none; b=RRHvzPZlNyH5tMnHA9UV2gcjh4kVsxSTqMkVJMXp/xzwdxAe+8rvuFNu3XrGb2qnNUqWLe7xV+BydrfNtFRS/KCLE7pkix8n05RJcJcJR7oT3lYOgXD1iF8HaYBoUEh6z4gveTLvy2JA+2minUdj0hOABdHRqC+vKaBAOGRsmgQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710731; c=relaxed/simple; bh=qqnT84gn7S+HraZ5CVJDXcqJXkGyam0Bt8hN1MkY3TE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bY25j++5+M5ejITWWLahdT623LHG4uYM6v9aB/iesAWoKyGc2/cLPPmhClbRzKf2muNQ3jRSDRprm07o94wWz29ULdpPp0yO8DP/g3j+5R70p3vxmnAUfC5ROsXA5pOIrfBFzsrt7FU6j12ij2Juj7I7YwqKn013RNNQb8dIo40= 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=cFsAa7hx; 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="cFsAa7hx" Received: from mail-pl1-f198.google.com (mail-pl1-f198.google.com [209.85.214.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id B58DD3F29B for ; Sun, 16 Feb 2025 12:58:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710728; bh=WH64JcRz8MPBFf1546ogFJ11akD0QnrE8MTXmnLnDMk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cFsAa7hxudFEts3UjyjJpQIYgu71hJ7PN0B9VuK3W02o1i9Wajair6N3Cm1u1VVCC gU3ZnlUvt7Au3I7zl0VbYi5F7R1cgcV3TgyoQhRfZHUBwrULGZiPtC5QcYlWnnoOZW HHXujmfHXr3v5yoABwuEt2h14M08oF6B5WkLvY0uGkwPM+uJKSEYG2V3mXDkOua0Dx XKFQHt+IDHZqRPWGdhdZfz1odWoNdmIKo5BRCvy3jXTLOC20L3ggZBXzCB3rf52Pri faPrm5dDjOTuZPdYtbCBGR25QGyKijxFGyZhnE28nAJYube9mhPqL/a/G2mSEZdSVI jgquRIsnb4NCA== Received: by mail-pl1-f198.google.com with SMTP id d9443c01a7336-220e04e67e2so93338955ad.2 for ; Sun, 16 Feb 2025 04:58:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710727; x=1740315527; 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=WH64JcRz8MPBFf1546ogFJ11akD0QnrE8MTXmnLnDMk=; b=nXSNQtRn41GqaHbohDWDv96dQyvMQrM5rsQQy5vfEZi1x2kK9i6kMp41Ca361FysRY m+9rBw90IucfHIRdbT0COLcDShEHc/vpPCLE/OePdGrn6WM4UBTBQ3dbCOs9a0AyDQmU dwPh8mas6MCdx0HOF0oEw4eLGnFdna8xumS4wtXGhxjh5fEn+GPnHIf+O/AQMF2ptkR5 OomQBkYPPeEdTPtlaIy/+Yy2y3KdjhRIaf9n2N4Byxh80vdwqMJEcFeQiaq/wZTzPh2w 8UvRs2cid6YalJQAq4I5tqO476ZSwPBAtZxVb8ToLILik7UU13R2aZ9/nIlVN+woj3c/ 3T3A== X-Forwarded-Encrypted: i=1; AJvYcCWZTVMOd3jYHHSRheb084BZLg94K0RilORmu0PAg3DOxTQmI9+WtN3WzDqHeXPgBkeEnwZ7ggaDmZ42xAk=@vger.kernel.org X-Gm-Message-State: AOJu0YyWLhY9ByrycBBxcNnxFq3toaN6EqgdonoTfhMMyajKs52TaEFl 24GsQl8DSvXn7lbtZzfBWfTUbOpgoclLgrfvhk4Eyr+u5RC6Rs9EeUw+UkXU1ChPdWiImh3p7Ln S7Tl5rNfwnbYmjilWF6AFSWjTV0TofAyMMmSb8SOdwG2rmsAQhLa6e3QLRikWPxQxIXNfuSK0HW M26A== X-Gm-Gg: ASbGncuKLHM0D5P5DDp6Pc0O2ds9BMsG+mAdW1K3x0XVibpEA3lL++mU9TyXUaW9aDj pAvsTofM+dR4ROrxfHeBmf8O/T01rCzcb0Vn+EQWOZ3fzQsszdM6fy7Ht1I8FMJAFWoXSeW1JF4 U3N85nok9nM5FiltCZm972FECBokwB8GWq0ZtLR1osyJFWEKxrpMXTTVgirbjnQTI3DMNYrwGgD m3F01H+7pfETvQ3gB3cKaBt09HVbncPs1WNTskUa+BciUkwXnA0k94O+QgMuAS7J3LyWPuAdpJ7 hqr4Tw== X-Received: by 2002:a05:6a21:71c5:b0:1ee:ab1f:41a2 with SMTP id adf61e73a8af0-1eeab1f7a48mr1052490637.28.1739710727130; Sun, 16 Feb 2025 04:58:47 -0800 (PST) X-Google-Smtp-Source: AGHT+IH854gcVlirPEulSVV/z9Wux6mWAG4+D9ei/MpzFkeEIpH39xQJcWJETrmq7a4gCv6UvLpCwQ== X-Received: by 2002:a05:6a21:71c5:b0:1ee:ab1f:41a2 with SMTP id adf61e73a8af0-1eeab1f7a48mr1052478637.28.1739710726858; Sun, 16 Feb 2025 04:58:46 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:46 -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 v3 07/13] gpio: aggregator: add aggr_alloc()/aggr_free() Date: Sun, 16 Feb 2025 21:58:10 +0900 Message-ID: <20250216125816.14430-8-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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" Prepare for the upcoming configfs interface. These functions will be used by both the existing sysfs interface and the new configfs interface, reducing code duplication. No functional change. Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 58 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index b24ed963cd9a..6252a686f805 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -38,12 +38,41 @@ struct gpio_aggregator { struct pseudo_gpio_common common; struct gpiod_lookup_table *lookups; + int id; char args[]; }; =20 static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); =20 +static int aggr_alloc(struct gpio_aggregator **aggr, size_t arg_size) +{ + struct gpio_aggregator *new __free(kfree) =3D NULL; + int ret; + + new =3D kzalloc(sizeof(*new) + arg_size, GFP_KERNEL); + if (!new) + return -ENOMEM; + + mutex_lock(&gpio_aggregator_lock); + ret =3D idr_alloc(&gpio_aggregator_idr, new, 0, 0, GFP_KERNEL); + mutex_unlock(&gpio_aggregator_lock); + if (ret < 0) + return ret; + + new->id =3D ret; + *aggr =3D no_free_ptr(new); + return 0; +} + +static void aggr_free(struct gpio_aggregator *aggr) +{ + mutex_lock(&gpio_aggregator_lock); + idr_remove(&gpio_aggregator_idr, aggr->id); + mutex_unlock(&gpio_aggregator_lock); + kfree(aggr); +} + static int aggr_add_gpio(struct gpio_aggregator *aggr, const char *key, int hwnum, unsigned int *n) { @@ -446,17 +475,15 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, { struct gpio_aggregator *aggr; struct platform_device *pdev; - int res, id; + int res; =20 if (!try_module_get(THIS_MODULE)) return -ENOENT; =20 /* kernfs guarantees string termination, so count + 1 is safe */ - aggr =3D kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL); - if (!aggr) { - res =3D -ENOMEM; + res =3D aggr_alloc(&aggr, count + 1); + if (res) goto put_module; - } =20 memcpy(aggr->args, buf, count + 1); =20 @@ -467,19 +494,10 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, goto free_ga; } =20 - 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); + aggr->lookups->dev_id =3D kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->= id); if (!aggr->lookups->dev_id) { res =3D -ENOMEM; - goto remove_idr; + goto free_table; } =20 res =3D aggr_parse(aggr); @@ -488,7 +506,7 @@ static ssize_t new_device_store(struct device_driver *d= river, const char *buf, =20 gpiod_add_lookup_table(aggr->lookups); =20 - pdev =3D platform_device_register_simple(DRV_NAME, id, NULL, 0); + pdev =3D platform_device_register_simple(DRV_NAME, aggr->id, NULL, 0); if (IS_ERR(pdev)) { res =3D PTR_ERR(pdev); goto remove_table; @@ -502,14 +520,10 @@ 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); -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); + aggr_free(aggr); put_module: module_put(THIS_MODULE); return res; --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 AC69319C578 for ; Sun, 16 Feb 2025 12:58:53 +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=1739710735; cv=none; b=GvwzYRDaQeCRoQ1HzsLExMeclaNgMqxsms4o3sj24swRcfHoXfmgaRjwf/jFbhGaQkaaWJx6de7n2uLtA4fHr5J41CE1i8jo8SRsD3h7ToOyoft7ES4mLJWKCQalqnlW7Gg8bSfyvlz9FvhBcrWrZ2vM42wy289jXMRJpzOqkBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710735; c=relaxed/simple; bh=iunzfnwXFZMiOJcVkULwj7dzepJGOPG5VVJaaTzqHOc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gG2mv1BafqrKH/GBTahHzvmUh9ATYQFsMmWK4Uiw7hI38hzfmeE2y2j1oU+LjK/3zfkQRjCNTLq6tGrRSu+AMa2Fc68NmwovaNL57cOPpjA/fyn3WTtoBX0BWmOH/0gZX4fGn/Pr+UgqzP3enJQBARn7uCWqZX93UoWuMm4Ba0w= 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=HQt1mVWQ; 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="HQt1mVWQ" 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 D49313F516 for ; Sun, 16 Feb 2025 12:58:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710732; bh=Gk/La4hkh91qCBNBtRkn7mQ3+1B82nsIS3HpG8PL1f4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HQt1mVWQ95vA5oXZ1mUecvSv/6VBuG+8/Pgu/faFfef+khQ9t56mrzbm5r/Wljfiz qxoYQ6jcpFlG6MNnz2tcYbiHISefP7hSbD9Bt89xWswRvAl0utVLUfxPSJCVpp4fSY KVVehmTCBxX+MnWAw0KgdNxdj04Pr8OtpCOozQ6FE2OkVYIlVbWWpBqqiinaG1DFv8 2aWjFpSxBHZ6V6ZH/sniWNLqcUfJ5aMgpIpptkKO+AydLoCaDYFnTLaiNeN8YKcJ43 U4f8rdgkCB87dTyf8nLiR25ykk/0UBVWjZThoYEHtL4me+tBvsFxKu0AuJKgWGG6US jvCkeJ6AQBmqw== Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-2fc518f0564so1367337a91.2 for ; Sun, 16 Feb 2025 04:58:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710730; x=1740315530; 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=Gk/La4hkh91qCBNBtRkn7mQ3+1B82nsIS3HpG8PL1f4=; b=HG8fgxasHpha+Gh2+bZ8HAxXgHcHCm7vsdw7ie2adXC/zQArQMHruKqifhxF3vFvJh XJHxJvzVFSgUkLcuiAw9jyy+AEsQq5366R2EAZDs9UYJZrCPfmJsARMcA3+aAUE1mDkf lMHivL54aaeaeK1ZKAMpv72TINFUrpEl2OISq0FLcEAVWlRpASMm3o5/cGnlAI1bmv+2 zt6cFx4JgtwIoNcocSWEznbb7N2s27kETqAFNo0cyUixJT3rCpKGjwFUGBGr/EYqVWqO ZJIQ4VIznniLdeIt/Bll0L7vZ8P7GzobLJldKLDh2f1XbXQkJRduycBST2UAvDmk7nWG qxLg== X-Forwarded-Encrypted: i=1; AJvYcCWEeoQFGBWSCF5lfMyGEmsyIl2dbM9EIHbKNypa6B90KKwI7bLi4iVPzz+EePRpx0GPZWW2UjfhrBI/6p4=@vger.kernel.org X-Gm-Message-State: AOJu0YwU0Hw3txHkp3naKZuCPL4zz+t1WUFSLYhGdtkUVL/vs+XpG/9G FZ16+9Gi0tD8i1WMLeXgzBYxBzmj3evHObe31AF5Grn1wYNCXr8NnwEN6VyhxpdfhV03RFDyDqR 89nl0BvReBE1+Qsvcys1wHkT83IilFTh3af7flVfEnKbBZLP83JBpzFV+pUJD/A2CwAK7y3lCsA vZ8w== X-Gm-Gg: ASbGnctB/GDTa96ZPrbRaX0QJjfrvNCs4tUwL2FD7jSqzz6GR8urQRV2I2LAzc4spXq 4NywVBgmNHqDuvAGcGKFXNlu2R2xmk8JHLOGxGpHEgcj5fLq2J2RBJaiJP4HRuVbW0EHHGqjkUT BFpPwpQMUgeJaSpBwUagO5RHhFqUPGMmEHlXJ3wxb46lE503x5TPKOoTJRHvomPdFQ2XHHthlnH YYaztmv2OZ8mg6GThsjDq2hEkE01N1/6guTQH4jY3ldKntj1JTsveu07NBmQa2+tFjmfYGmtpCI hZ7Www== X-Received: by 2002:aa7:88c1:0:b0:730:91fc:f9c4 with SMTP id d2e1a72fcca58-7326190a122mr9417875b3a.24.1739710730122; Sun, 16 Feb 2025 04:58:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IFXkL97gmZRuswV2wo/Hb4xAoccXkZA0zPnnNOfSFswbTD//6qwI9Ditkpzitl+ERgixr4HWw== X-Received: by 2002:aa7:88c1:0:b0:730:91fc:f9c4 with SMTP id d2e1a72fcca58-7326190a122mr9417844b3a.24.1739710729660; Sun, 16 Feb 2025 04:58:49 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:49 -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 v3 08/13] gpio: aggregator: introduce basic configfs interface Date: Sun, 16 Feb 2025 21:58:11 +0900 Message-ID: <20250216125816.14430-9-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 behavior is retained for now. This commit implements basic functionalities: /config/gpio-aggregator// /config/gpio-aggregator//live /config/gpio-aggregator//dev_name /config/gpio-aggregator/// /config/gpio-aggregator///key /config/gpio-aggregator///offset 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 The corresponding gpio_device id can be identified as follows: cd /sys/kernel/config/gpio-aggregator/ ls -d /sys/devices/platform/`cat dev_name`/gpiochip* Signed-off-by: Koichiro Den --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-aggregator.c | 540 ++++++++++++++++++++++++++++++++- 2 files changed, 533 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8b9ffe17426e..591244e6cd4e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1871,6 +1871,7 @@ menu "Virtual GPIO drivers" =20 config GPIO_AGGREGATOR tristate "GPIO Aggregator" + select CONFIGFS_FS select GPIO_PSEUDO help Say yes here to enable the GPIO Aggregator, which provides a way to diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 6252a686f805..ec102453817b 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -9,10 +9,13 @@ =20 #include #include +#include #include #include #include #include +#include +#include #include #include #include @@ -37,11 +40,35 @@ =20 struct gpio_aggregator { struct pseudo_gpio_common common; + struct config_group group; struct gpiod_lookup_table *lookups; + struct mutex lock; int id; + + /* List of gpio_aggregator_line. Always added in order */ + struct list_head list_head; + + /* used by legacy sysfs interface only */ + bool init_via_sysfs; char args[]; }; =20 +struct gpio_aggregator_line { + struct config_group group; + struct gpio_aggregator *parent; + struct list_head entry; + + /* Line index within the aggregator device */ + unsigned int idx; + + /* GPIO chip label or line name */ + const char *key; + /* Can be negative to indicate lookup by line name */ + int offset; + + enum gpio_lookup_flags flags; +}; + static DEFINE_MUTEX(gpio_aggregator_lock); /* protects idr */ static DEFINE_IDR(gpio_aggregator_idr); =20 @@ -61,6 +88,8 @@ static int aggr_alloc(struct gpio_aggregator **aggr, size= _t arg_size) return ret; =20 new->id =3D ret; + INIT_LIST_HEAD(&new->list_head); + mutex_init(&new->lock); *aggr =3D no_free_ptr(new); return 0; } @@ -70,6 +99,7 @@ static void aggr_free(struct gpio_aggregator *aggr) mutex_lock(&gpio_aggregator_lock); idr_remove(&gpio_aggregator_idr, aggr->id); mutex_unlock(&gpio_aggregator_lock); + mutex_destroy(&aggr->lock); kfree(aggr); } =20 @@ -92,6 +122,70 @@ static int aggr_add_gpio(struct gpio_aggregator *aggr, = const char *key, return 0; } =20 +static bool aggr_is_active(struct gpio_aggregator *aggr) +{ + lockdep_assert_held(&aggr->lock); + + return aggr->common.pdev && platform_get_drvdata(aggr->common.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, unsigned 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 (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 @@ -416,6 +510,400 @@ 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; + 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); + + ret =3D pseudo_gpio_register(&aggr->common, &pdevinfo); + if (ret) + goto err_remove_lookup_table; + + return 0; + +err_remove_lookup_table: + kfree(aggr->lookups->dev_id); + gpiod_remove_lookup_table(aggr->lookups); +err_remove_lookups: + kfree(aggr->lookups); + + return ret; +} + +static void aggr_deactivate(struct gpio_aggregator *aggr) +{ + pseudo_gpio_unregister(&aggr->common); + gpiod_remove_lookup_table(aggr->lookups); + kfree(aggr->lookups->dev_id); + kfree(aggr->lookups); +} + +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) + 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 sysfs_emit(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 sysfs_emit(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; + + /* + * When offset =3D=3D -1, 'key' represents a line name to lookup. + * When 0 <=3D offset < 65535, 'key' represents the label of the chip with + * the 'offset' value representing the line within that chip. + * + * GPIOLIB uses the U16_MAX value to indicate lookup by line name so + * the greatest offset we can accept is (U16_MAX - 1). + */ + if (offset > (U16_MAX - 1) || offset < -1) + return -EINVAL; + + guard(mutex)(&aggr->lock); + + if (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_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->common.pdev; + if (pdev) + return sysfs_emit(page, "%s\n", dev_name(&pdev->dev)); + + return sysfs_emit(page, "%s.%d\n", DRV_NAME, aggr->id); +} +CONFIGFS_ATTR_RO(gpio_aggr_device_, dev_name); + +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 sysfs_emit(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 (!try_module_get(THIS_MODULE)) + return -ENOENT; + + 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); + + module_put(THIS_MODULE); + + return ret ?: count; +} +CONFIGFS_ATTR(gpio_aggr_device_, live); + +static struct configfs_attribute *gpio_aggr_device_attrs[] =3D { + &gpio_aggr_device_attr_dev_name, + &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 the aggregator is active, this code wouldn't be reached, + * so calling aggr_deactivate() is always unnecessary. + */ + aggr_free(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) +{ + struct gpio_aggregator *aggr; + int ret; + + /* arg space is unneeded */ + ret =3D aggr_alloc(&aggr, 0); + if (ret) + return ERR_PTR(ret); + + config_group_init_type_name(&aggr->group, name, &gpio_aggr_device_type); + pseudo_gpio_init(&aggr->common); + + 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 */ @@ -487,6 +975,7 @@ static ssize_t new_device_store(struct device_driver *d= river, 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) { @@ -533,10 +1022,7 @@ static DRIVER_ATTR_WO(new_device); =20 static void gpio_aggregator_free(struct gpio_aggregator *aggr) { - platform_device_unregister(aggr->common.pdev); - gpiod_remove_lookup_table(aggr->lookups); - kfree(aggr->lookups->dev_id); - kfree(aggr->lookups); + aggr_deactivate(aggr); kfree(aggr); } =20 @@ -558,12 +1044,19 @@ static ssize_t delete_device_store(struct device_dri= ver *driver, return -ENOENT; =20 mutex_lock(&gpio_aggregator_lock); - aggr =3D idr_remove(&gpio_aggregator_idr, id); - mutex_unlock(&gpio_aggregator_lock); - if (!aggr) { + aggr =3D idr_find(&gpio_aggregator_idr, id); + /* + * For simplicity, devices created via configfs cannot be deleted + * via sysfs. + */ + if (aggr && aggr->init_via_sysfs) + idr_remove(&gpio_aggregator_idr, id); + else { + mutex_unlock(&gpio_aggregator_lock); module_put(THIS_MODULE); return -ENOENT; } + mutex_unlock(&gpio_aggregator_lock); =20 gpio_aggregator_free(aggr); module_put(THIS_MODULE); @@ -638,6 +1131,10 @@ static struct platform_driver gpio_aggregator_driver = =3D { =20 static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data) { + /* + * There should be no aggregator created via configfs, as their + * presence would prevent module unloading. + */ gpio_aggregator_free(p); return 0; } @@ -652,7 +1149,33 @@ 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; + + 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); + return ret; + } + + /* + * CAVEAT: This must occur after configfs registration. Otherwise, + * a race condition could arise: driver attribute groups might be + * exposed and accessed by users before configfs registration + * completes. new_device_store() does not expect a partially + * initialized configfs state. + */ + ret =3D platform_driver_register(&gpio_aggregator_driver); + if (ret) { + pr_err("Failed to register the platform driver: %d\n", ret); + mutex_destroy(&gpio_aggr_subsys.su_mutex); + configfs_unregister_subsystem(&gpio_aggr_subsys); + } + + return ret; } module_init(gpio_aggregator_init); =20 @@ -660,6 +1183,7 @@ static void __exit gpio_aggregator_exit(void) { gpio_aggregator_remove_all(); platform_driver_unregister(&gpio_aggregator_driver); + configfs_unregister_subsystem(&gpio_aggr_subsys); } module_exit(gpio_aggregator_exit); =20 --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 5AEA219CC37 for ; Sun, 16 Feb 2025 12:58:56 +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=1739710738; cv=none; b=j3YtHlw6OfcnqrPoL2pz63pjl+Z1pMEwp1yrUAPzD1AuAGkuMv/85WDMNWn0zEn2PuRiAX1qkKKG5YWzZ24QwRI2xH2ESRPiELyy/RUVV38rScOmw+TRcIj1n0kBRh/kSdeAZTyOJE6t4HNGvXeJ4XHm5MYXCBmhiqpXyGeXq6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710738; c=relaxed/simple; bh=uxdDc8NwSSoU/KhYSVoLNE3SLLqdDtG3WoHdkVTCuPk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X7xHlvn20qhoElsQ1TNquxX5LXoDk/qSCjLmBfULy/8Z2bCx/+wxPksqH0ujrHqWZb7rDF5+0LJJp2h65eXZGL4e9k8l+4eLhrIHLLFQKFjC9WT/USKX07WF0qE3DWrr14jEt5jFS+g7cwDoY56Ke6uj9IzmyK8Ou80ZcSr9ff8= 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=mr5ZnzxU; 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="mr5ZnzxU" Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 14A833F2BC for ; Sun, 16 Feb 2025 12:58:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710734; bh=v4sbOHRoeQS1MOSALsPLtSJ65COLeoaPvTmtbuEu58k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mr5ZnzxU+GxcELfh4cg+MAKjOHcpaoD8lYrtXjB4Yw9AXSywbyEry3ihuoQMD3u4B fo+4pMKTiVcu3mIFX0/vrcJ4XOsI6Qt6Mb87hfXgYNmfVShWnrieBzu1Qg+pzBdoPT yWnw58sB0oC4SDAfr2YqurBqGyek80AyCH7YGtI8j7IU/KmzuraL2DD2juRJHXXsLo 2CZOk1C1ruoP4vgDoRHp+l4roAK8L+bfSyYeUwtS2GO9p5oL77IeXbJ7m3ATLdqRpJ CJW0ppzkD8+eNqi0eTghXetjSEsGfXbkByuzVl0k43NYkkdQy7qOHNKpyuTdOAhxfx HYOWe3OfoEqTg== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-21f6cb3097bso97046515ad.3 for ; Sun, 16 Feb 2025 04:58:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710732; x=1740315532; 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=v4sbOHRoeQS1MOSALsPLtSJ65COLeoaPvTmtbuEu58k=; b=UrEXKUS6H0ujFlXUZpxJuRTh4KpQNPlg/B8PYGJNgfruzmfEZ5NCo1Gj7lugc1X+aE JDOE3EJiI97/5oM1TFGvzWk3v340XUxPIPlebUNCVPrcisVakAZftSTBQ1irOwfMGVLt 4idzCax6R49zkoD0wuVLFw/nNR9F873FCgEk3KYW7zYJkaWbuIyfP2VikUv4/W01Beli +jYEHc2VFR5gS2CGI+fMcvOt0mDHOBayWKCNSSMddzfofgH5rPWchHCiiciLDSk/j84k aGZrrGGmewant47N5tlMtEJqsMQrn8FHGQfE7pwObnLlH+WdLoMNLVpUikcYQhMyqFlP T0eA== X-Forwarded-Encrypted: i=1; AJvYcCWgt6JhxQA2OSckkGRJ5R31cL9pkMzhVrBJrhvFqld649PBPpShlv9SAcy5AcR10uMIaMMVEoFNmwR5gPY=@vger.kernel.org X-Gm-Message-State: AOJu0Yyjmvxn2FXaLh8mYf6UbsHD14BEgBj7/Hymn4wlpYh38O+WVq13 jo3AYzNxrCUViQyInTqx+PS5Rhq9zJn5Dnq/qcgbsuP3c3zd7nJsBvvaJfPINdbsqD5UIfWnq25 D2N7zbpbsv31BcXppwx4Ya+DEIZf48Qb/TvE4t4xUH8U3gBUSyx43QW6aUD/SLh0pGGuplOvGzI IdlQ== X-Gm-Gg: ASbGncv6qr3/MZ342jetcv8ez92+YePZDfN18unpGEordA8WZOcz+X+i8EgQPaJ+pCQ Fmyqha5fq49WXwxY+tD+LW3pkizsuCTgWF8mv5o7jCGFCXw4aPqV2kNWGuJuQ2dkRyrORRj4e5G 7GPJRioD6qVySBbmhoW50M1qU9FYDZSdplXhxQilEhcH6blbw/V8PnRnen5boMLGTnNUmZ71yQD X8EQv6qMhf4EoVA50GINmpZ8lVdjYa3K43XEekKCMChGqxUrRl5ksbGoyvR3+5elDpxgUy8+9q1 hCyogA== X-Received: by 2002:a05:6a21:6182:b0:1ee:7714:50 with SMTP id adf61e73a8af0-1ee8cb0e872mr8693878637.5.1739710732663; Sun, 16 Feb 2025 04:58:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IETzXxsVanjAhXHVIrho5GeRODi5T05ultUcs3mcWlJEertTezQ6W5MIqTT3OooQDM45eE3tQ== X-Received: by 2002:a05:6a21:6182:b0:1ee:7714:50 with SMTP id adf61e73a8af0-1ee8cb0e872mr8693857637.5.1739710732350; Sun, 16 Feb 2025 04:58:52 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:52 -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 v3 09/13] gpio: aggregator: add 'name' attribute for custom GPIO line names Date: Sun, 16 Feb 2025 21:58:12 +0900 Message-ID: <20250216125816.14430-10-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 was no way to assign names to GPIO lines exported through the aggregator when the device was created via sysfs. Allow users to set custom line names via a 'name' attribute and expose them using swnode. Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 84 ++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index ec102453817b..692d90246674 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -61,6 +61,8 @@ struct gpio_aggregator_line { /* Line index within the aggregator device */ unsigned int idx; =20 + /* Custom name for the virtual line */ + const char *name; /* GPIO chip label or line name */ const char *key; /* Can be negative to indicate lookup by line name */ @@ -530,10 +532,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) +{ + const 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; unsigned int n =3D 0; int ret =3D 0; =20 @@ -545,9 +577,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) { @@ -559,7 +596,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) @@ -567,13 +604,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); @@ -587,6 +624,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 @@ -658,6 +697,43 @@ gpio_aggr_line_key_store(struct config_item *item, con= st char *page, } 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 sysfs_emit(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) { @@ -707,6 +783,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 }; @@ -795,6 +872,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 Fri Dec 19 06:07:40 2025 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 145B419D89B for ; Sun, 16 Feb 2025 12:58:58 +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=1739710739; cv=none; b=rQ6VD7ypwl2vemipkj8/wqnyd4wyCg1PM5Of+FZVUs4O56ylEOPJRNRmB1pWL3Vn5f+2MoIyRb96zW2eEPEMnRcz5l0awJXtPyUQAgotQGQ8FkzAuHO7aDdhaUUDhy75TRFi3Vx+v3hZl1eONcf7pLHmukoyxweaXiZn6D9KxTI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710739; c=relaxed/simple; bh=M027Wka85YHpOsFpEaAyOcm3fQNZIgSRcuqEQ7ncvt8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AYVPMAC6lIeINSsVCXSraHAnUo7A6Ne23qqBqtQZ6xB+BPzdCnFrefdtxT5b5AETossKo1dV/fqqtraUkGv8JXFBp9RfoytlVlfzTAmyp80MsuY+lq4/t9grMhLw6EMoxZXneh8X+p+gossJxNnRdY04zM1AYCgvDs4EhLIXA2o= 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=Zee3AAfF; 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="Zee3AAfF" 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 CBE8E3F175 for ; Sun, 16 Feb 2025 12:58:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710736; bh=zhY6qp/Hv2zLsONt663fjITCkgKIh4r/C82D6wubct4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Zee3AAfFtX2bUD4y8q0RnGqvVeKcsn/2Jyckah1iZ7BHbFVuRRAJNJpn642JS3vjp rYTSHqmtB8mXj6lD+8jTAENMk2ysM4fjXEToFpmxmoDSccMFMBwrytxqNTD2for5HX sf7qW4+6LqapyysqjLeWVwdNkyPMAZaQdBGXrPY722grhQx0K/7kfa0zy9AkjrF2tu Z1xlMdJWUExehQ70yt8SIYFGp570PNkLNLmFOljrcl4Ej+1+jW5QIGhDS8MbXJrxz1 oA0RsKp/7/qDiv0HUq6jSCIVuOzLXcj7DlMq52dHHljoa7SNNlDIru+CUIQhUNIM+a +V9eouTau6BFg== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-220f0382404so44830915ad.1 for ; Sun, 16 Feb 2025 04:58:56 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710735; x=1740315535; 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=zhY6qp/Hv2zLsONt663fjITCkgKIh4r/C82D6wubct4=; b=sN/lZaPmPUVr6hbIOWn+C9mOaiN6yMmc82eieGAFJPjBM6aFmAblgRLaHzER3olyFQ jf2itGCV9JxMd52Jmc8KPc2sJEMG6tOPYRKqRXAHtuNsjydLo+nSXq5kgUhj6MME9ppB YM8JA4aiFUrt2bdKS867mnel0NSyRY0KUTr43eWCUGVt8nfiEpFHbkq4XyXMCHcJD4MY r5XGWOeQl48RG3TlqW29ryB6Cht3yhu8QNCQPN0FAhS/7gLo6s6VUMs8ETTHq9cVAHJv JX3yInCzJvG69ww2mdb7NM/pNCGl0WyGPppS5PPPzUy+Syzv9IhI20KdMduNGy8t5AK7 m1tQ== X-Forwarded-Encrypted: i=1; AJvYcCWph70u8z6j6tCx/PRqLCVO9jPfECFlEFtMsmaGFTQQtG0WmpMMkZ2geVbs6ZwXOyicuobgXfNhzt5T9EY=@vger.kernel.org X-Gm-Message-State: AOJu0YzVUCgGSyLA/P1i79OGtu0PZyLiGrNwJ8iKYD3CzrfSCkG29Cbl TxTfuOwHc0xP3icu0HIwKsKFV1eFuV+KK1fIAHkWiBdHcZlMTmLldCEAbR1oC+SZfy/L4VKtGnt Qvf895vCJ9Tf7X29I/hkzz2DzcxeNM4xVu2QMxFCLVVSO8IhX1uQr4mXeiZRtl6jZOdWumu8JOE Tytg== X-Gm-Gg: ASbGncuLP2rMpEij+zN6VMbRtLJkSBuCMOharX1Q5kYT4H92l/vBVepXN5hNHbWiebz QD6F9yUm3dyOl4n081WjHX/KIJeOEeJlOC8dKc+56RhVHx1XnTQE7z1Zr8kfiN2jnVEgXI8EK9t WtYsrIendDnc+ieq3vo1ad4YDe6DfPNN8+8Rx4jJDfpy+PiG7pCu8wPzbzvEy2f/zTOGaCBRoI+ QasHTq+9lm0Lpp96U7OVqnA3HpuYHKnU/X/NfEpFtW3ZH/MoVATm3sTATNxnV32lcu6i+WR2r4b vOqweA== X-Received: by 2002:a05:6a21:e8d:b0:1e1:aef4:9ce8 with SMTP id adf61e73a8af0-1ee8cba0fc4mr11535562637.28.1739710735444; Sun, 16 Feb 2025 04:58:55 -0800 (PST) X-Google-Smtp-Source: AGHT+IHuPqNVXjgq1Wr/qoPHQT9LJIyj39hUcdGoEPe0WRrviyP2A3rvxb9A/MoT8qL0lIxtuEIFPA== X-Received: by 2002:a05:6a21:e8d:b0:1e1:aef4:9ce8 with SMTP id adf61e73a8af0-1ee8cba0fc4mr11535543637.28.1739710735131; Sun, 16 Feb 2025 04:58:55 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:54 -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 v3 10/13] gpio: aggregator: rename 'name' to 'key' in aggr_parse() Date: Sun, 16 Feb 2025 21:58:13 +0900 Message-ID: <20250216125816.14430-11-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 --- 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 692d90246674..2e993c9a7ce5 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -988,7 +988,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 @@ -997,18 +997,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 @@ -1020,12 +1020,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 Fri Dec 19 06:07:40 2025 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 4B5F7194A59 for ; Sun, 16 Feb 2025 12:59:01 +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=1739710743; cv=none; b=MB4Oz6KVNmMFk2+W1MCF6DdcxEWCS3s597GXLGSo8ANkVUFoOMmzs9dm0YuxVpq/MPHIojTmGlT4OIpn8yUB9qO7DPl8qaop1/10emijMV9eBwoEumXV1X0x7jZbX8JSUHynYp1NpQdgn1M0UiFLHLnksa5+sDjsyahpbjFhx3U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710743; c=relaxed/simple; bh=lWi8cSb8BfWbLOPOp2GNgU6ysUye4CsGO9grvCFpPc8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u2Ac7m25FtJst0IabAlGjk0DzWgjppKRpkYbp4sDVAM1enDJBUEz+T9SPJpQLV2FsH1LR3qDwnR556Ba5/FbwEX0NTjKSOsikvLn27wuWAaOehLnpMe8bA4UYu++CfInFzc05Wh2+c7S8H4dAePMtO+dyrDCeGZqHXipI2PdSls= 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=mA/ta2PS; 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="mA/ta2PS" 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 A91443F2A0 for ; Sun, 16 Feb 2025 12:58:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710739; bh=xsxLQ8/cIyaXlfRbTYcIHh/jf9fjXDEfeDZdjuEqzxg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mA/ta2PSRlwWyq1ft9QqJSaBgE1zsXxnRDBycmyfkZKa4IEQlzoF144iz0J5z7AnM xsZfWAR+U4Iwdu91prAlwpsnIOKxIbHq6iXF0UJMfnRB2Y8cKQJpk8pcRVvQlzu6eQ OPxKmdRIriBGiTAUpuP3zmI8U/AH+O36+3lRrOty9uoK8zjmMdqazTUaheiUYiRV9f kH7sg1Y6qzSp3FR/YzNz0sLPiFGU37+4jTPgzfl1JCIpjWu/Q0yEp0HxIM1F2oqDFi Kw1IwlvNVDyQYH5oxz18bxXihI709RNmyYNSStmVM2DEkAP7cxcgVx3uYLjlNz82ef PrBG4yIuLDdjw== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-220cd43c75aso123892115ad.3 for ; Sun, 16 Feb 2025 04:58:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710738; x=1740315538; 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=xsxLQ8/cIyaXlfRbTYcIHh/jf9fjXDEfeDZdjuEqzxg=; b=pfP6OJMUimET2lcrE3vGrPYrz1Wqa7GOAi0BabiWgi0O+eq3qKYQeBuGuNfXeh+UFz 4WfnzqYmbFL52k3N9UXuN/38miIn/vTAE5PyW76RMCjaL29YyCNIuAp1WFF9GICFfxg4 rBq0mw2DpSGbwBW8etzZj1LEpCqLxYu7UH8ge+RRllx09HJS1J+TUe75B0yovUOC0dUH xEB+xYbjlvKYpbQtFVjjSjawp2NvnxMNNdXnZyy/1ypopTKlM8wsifOqUUar/jafFKet lGR0r+9kxxA90tb+Df8D3NDIK+Oz3fDwbMG5Oi1zOiLmwgnLseyCFv9SsFeL1Bsn/JE9 tFwQ== X-Forwarded-Encrypted: i=1; AJvYcCVUGFApTsWBsWurorx3zzpU/O58gm+IIAjkellj1sT42c21fuI2JjYThPpdSyTCtakxUYSX4JzVRG/EEyM=@vger.kernel.org X-Gm-Message-State: AOJu0YznC+P8FzEguqAPGbMskHnRhugJKjgs4v4hgvcFvDQHEGZUPFFh MNQxPH0QwuQyFCpRMQz9Rfvk+eBEs4NwHxeLTy2EKHwdIfv009FBCFyNgAeoY0c0ae8AwKlfdSR yvzgqz0CfWYm8XRjrCjMMk4CAY3vBxpZ3w8DWVEb6WsoJIpHQayeYbm5nZ9yxdFXn5RtqzIXDLI r0bw== X-Gm-Gg: ASbGnct3jV4fmk4Rclvbt9G0nO0nkLr7qUJrbBt0We0SBfq6tHKJx0Z1LRTwI+pY8J8 gGAGJ5zrzFFTsbTNyTdf4Dvmjxrm5Z5L5HY06a5jnDBh2mNO/EzuBarqoEzugLPuvsZNSwonuaP ujiG8bxubfkyAUadLLRrO9FJNW5PhOFCGztXVzaWyJieUaf1t4WruyhW+n0QVOqP/x5MB7rUFl5 BoFQeHv3mgHA6w/kxO21kCuVVnPdiPQRvX1vfTbSTzjhiM4ea4aRVaZhbt9pqQ4u2tJME7YNgbf 3Z9Hwg== X-Received: by 2002:a05:6a20:734c:b0:1d8:a9c0:8853 with SMTP id adf61e73a8af0-1ee8cb1738fmr10303060637.23.1739710738244; Sun, 16 Feb 2025 04:58:58 -0800 (PST) X-Google-Smtp-Source: AGHT+IGX3reIldeUK0by88Q0O41ffSGW5Iq7r2xShkOSx8hGvz+DJc6z8RJ94YczGts59TaJt2Tb7w== X-Received: by 2002:a05:6a20:734c:b0:1d8:a9c0:8853 with SMTP id adf61e73a8af0-1ee8cb1738fmr10303033637.23.1739710737827; Sun, 16 Feb 2025 04:58:57 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:58:57 -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 v3 11/13] gpio: aggregator: expose aggregator created via legacy sysfs to configfs Date: Sun, 16 Feb 2025 21:58:14 +0900 Message-ID: <20250216125816.14430-12-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 "_sysfs." path appears in the configfs regardless of whether the probe succeeds. Consequently, users can no longer use that prefix for custom GPIO aggregator names. The 'live' attribute changes to 1 when the probe succeeds and the GPIO forwarder is instantiated. Note that the aggregator device created via sysfs is asynchronous, i.e. writing into 'new_device' returns without waiting for probe completion, and the probe may succeed, fail, or eventually succeed via deferred probe. Thus, the 'live' attribute may change from 0 to 1 asynchronously without notice. So, editing key/offset/name while it's waiting for deferred probe is prohibited. The configfs auto-generation relies on create_default_group(), which inherently prohibits rmdir(2). To align with the limitation, this commit also prohibits mkdir(2) for them. When users want to change the number of lines for an aggregator initialized via 'new_device', they need to tear down the device using 'delete_device' and reconfigure it from scratch. This does not break previous behavior; users of legacy sysfs interface simply gain additional almost read-only configfs exposure. Still, users can write to the 'live' attribute to toggle the device unless it's waiting for deferred probe. So once probe succeeds, they can deactivate it in the same manner as the devices initialized via configfs. Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 117 +++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 2e993c9a7ce5..8f8793f27211 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -33,6 +33,7 @@ #include "gpio-pseudo.h" =20 #define AGGREGATOR_MAX_GPIOS 512 +#define AGGREGATOR_LEGACY_PREFIX "_sysfs" =20 /* * GPIO Aggregator sysfs interface @@ -131,6 +132,14 @@ static bool aggr_is_active(struct gpio_aggregator *agg= r) return aggr->common.pdev && platform_get_drvdata(aggr->common.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->common.pdev && !platform_get_drvdata(aggr->common.pdev); +} + static size_t aggr_count_lines(struct gpio_aggregator *aggr) { lockdep_assert_held(&aggr->lock); @@ -188,6 +197,18 @@ static void aggr_line_del(struct gpio_aggregator *aggr, list_del(&line->entry); } =20 +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) { + configfs_unregister_group(&line->group); + aggr_line_del(aggr, line); + kfree(line->key); + kfree(line); + } +} + =20 /* * GPIO Forwarder @@ -687,7 +708,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); @@ -724,7 +745,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); @@ -772,7 +793,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; @@ -831,11 +852,12 @@ gpio_aggr_device_live_store(struct config_item *item,= const char *page, if (!try_module_get(THIS_MODULE)) return -ENOENT; =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); @@ -847,7 +869,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 module_put(THIS_MODULE); @@ -893,7 +915,7 @@ static void gpio_aggr_device_release(struct config_item= *item) guard(mutex)(&aggr->lock); =20 /* - * If the aggregator is active, this code wouldn't be reached, + * At this point, aggr is neither active nor activating, * so calling aggr_deactivate() is always unnecessary. */ aggr_free(aggr); @@ -915,6 +937,15 @@ gpio_aggr_device_make_group(struct config_group *group= , 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)) @@ -952,6 +983,14 @@ gpio_aggr_make_group(struct config_group *group, const= char *name) struct gpio_aggregator *aggr; int ret; =20 + /* + * "_sysfs" prefix is reserved for auto-generated config group + * for devices create via legacy sysfs interface. + */ + if (strncmp(name, AGGREGATOR_LEGACY_PREFIX, + sizeof(AGGREGATOR_LEGACY_PREFIX)) =3D=3D 0) + return ERR_PTR(-EINVAL); + /* arg space is unneeded */ ret =3D aggr_alloc(&aggr, 0); if (ret) @@ -988,6 +1027,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; @@ -999,14 +1040,29 @@ static int aggr_parse(struct gpio_aggregator *aggr) =20 args =3D next_arg(args, &key, &p); while (*args) { + scnprintf(name, sizeof(name), "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; @@ -1020,9 +1076,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); @@ -1030,15 +1099,20 @@ 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_free_lines(aggr); + return error; } =20 static ssize_t new_device_store(struct device_driver *driver, const char *= buf, size_t count) { + char name[CONFIGFS_ITEM_NAME_LEN]; struct gpio_aggregator *aggr; struct platform_device *pdev; int res; @@ -1067,10 +1141,24 @@ static ssize_t new_device_store(struct device_drive= r *driver, const char *buf, goto free_table; } =20 - res =3D aggr_parse(aggr); + scnprintf(name, sizeof(name), "%s.%d", AGGREGATOR_LEGACY_PREFIX, aggr->id= ); + config_group_init_type_name(&aggr->group, name, &gpio_aggr_device_type); + + /* + * Since the device created by sysfs might be toggled via configfs + * 'live' attribute later, this initialization is needed. + */ + pseudo_gpio_init(&aggr->common); + + /* Expose to configfs */ + res =3D configfs_register_group(&gpio_aggr_subsys.su_group, &aggr->group); if (res) goto free_dev_id; =20 + res =3D aggr_parse(aggr); + if (res) + goto unregister_group; + gpiod_add_lookup_table(aggr->lookups); =20 pdev =3D platform_device_register_simple(DRV_NAME, aggr->id, NULL, 0); @@ -1085,6 +1173,8 @@ static ssize_t new_device_store(struct device_driver = *driver, const char *buf, =20 remove_table: gpiod_remove_lookup_table(aggr->lookups); +unregister_group: + configfs_unregister_group(&aggr->group); free_dev_id: kfree(aggr->lookups->dev_id); free_table: @@ -1100,7 +1190,10 @@ static DRIVER_ATTR_WO(new_device); =20 static void gpio_aggregator_free(struct gpio_aggregator *aggr) { - aggr_deactivate(aggr); + if (aggr_is_activating(aggr) || aggr_is_active(aggr)) + aggr_deactivate(aggr); + aggr_free_lines(aggr); + configfs_unregister_group(&aggr->group); kfree(aggr); } =20 --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 4A5A019F116 for ; Sun, 16 Feb 2025 12:59:04 +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=1739710745; cv=none; b=OcfiyXspDUQRqrVXwn15oYycCjPUsuLJfY5/D9ICSnMEwMkNTKuowl46OgWucuB0Svcw593DnmDO6CZnXQ30bBiEeS8mCZJdrXvhBFGSGGH004xj4gd86mJbNwIvNFT3q2A8oD4fDUzX4BLAYMe3gjbuaigOSAy8NLigs2UKj/A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710745; c=relaxed/simple; bh=uvDPPe/zh18N6hlSUI3RGzfNlPtrpvVYWv/tx+FGhgY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rcPuwxfNPuplFBfBepMJ8w2RspaTy6G0DemR6Hw/ZwPxuw01yvlXYfgjlGKNuxP5xMfLLC6fyU+1b47R67eByNBM16Wp0qk9Uo9NWM0iSaw8gHAc9VlHSkZ1hkqBOUN9BVUgcA56ebruyy2yHmGC+J+XWO35nVrUDMf8Jslqkgg= 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=VUi3ECL5; 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="VUi3ECL5" Received: from mail-pl1-f200.google.com (mail-pl1-f200.google.com [209.85.214.200]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id A052D3F516 for ; Sun, 16 Feb 2025 12:59:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710742; bh=dSs/jDBsvmuiaXfkwHoPbsWqaGsAOzbJ2wNat8FrzKA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VUi3ECL5RJL2iHSdHSL/9moVCCZh3flOun25gV+qalvZITCWO3vU36hWJOIBuSN6n PWOqc3ByP7cjdZhPPdUW2KDDdNnhrywyPDNHmJeO7TETlMs+PBGBO7TMz8C8/xeaAv GXYAW/qJS7uLQos1pHVOhMAv70VizHyJ8tYiqFl8e8VeLWMlPBQo/SQtLqCptalc6T fP60t8R/qsQ+NZmuXHJLW4kAbCnRHtoOewQaNdzyszKBsxKJtgUQNe0u6g0svZ22GB t6C57Fq5egcAKOiBLC/yK6hsckHlRvkg8nTS71f82ekcigusQwTgFIzOtXRt+bBN6u cdYrU7u8EpgkQ== Received: by mail-pl1-f200.google.com with SMTP id d9443c01a7336-220fff23644so39218515ad.0 for ; Sun, 16 Feb 2025 04:59:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710741; x=1740315541; 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=dSs/jDBsvmuiaXfkwHoPbsWqaGsAOzbJ2wNat8FrzKA=; b=UKj0tdAu1hTXhx/eH9osOSZRljkghOLTZ8a0J35agHbuZoFsOlXljqUOza8cZssa7V JM6PHoWndqlpjywWmkY+hJMfiAWu4ESollgea5kQod05iS+0NGvhsaoRivMs8A+dWOjK 7/SzkmpB5u4/y4yRfP4Xb1Tb6UoAPiat2mVTYHqWn04MaY5RQbpLJWzCKwOEtw6j8rUx OEA1b58DpjH8uG0G7OKsTxq0y0ug+P1L70j1z1YKLUi+BVaYmYRV0pCZDiYjUhN4Tauw CfcU2BnqS+bzI+u0GCYhzdtNh0etO3SZKwLquF69nD/W7qSTRj022oA5uASz//kFvd+U 66og== X-Forwarded-Encrypted: i=1; AJvYcCVBqx1Sdqf4mP2B5u2ZPmy84a7wI0WqwBfP3j++23o43n8OMnIl686+pOyR9sgIgBDqmgNjnhtuXFhHyH0=@vger.kernel.org X-Gm-Message-State: AOJu0YwGV2T0/P3TBrfp0jDy6/W2rfab+fJAqd0shKqZ5L507ClsJDuh A0yS4A2tFgggF1qZhi/3ysrQ7P5WTVqLTnDnFyVFyRE+RKNWa9iDQ9Ua90xlPDkQBYDRLWmY5dI d6F4JUau8g9zIweNrOhxDPhW9AnB8p+zpIfJj6pr42AI2zNdIDuDcgTEo0B+CCIHVrB7bsWIWq4 Lq9Q== X-Gm-Gg: ASbGncsGzI18E1ofzeLfPLGWAs+2BBP1GhzcCzmlTAAdm/pE/OOWTCsGA79p8P9nkZ1 I7W9k+GzKT5pXIyG9ed6NcGJt4NLDxDGTkyAZVAh8RFy6VHV5LcGZ1r+TSb2n5N7J/Kn7l2M2Gb Peg10EeZLaLrcfHqzq314NbbWLWeUUTt/aYhi1A09bXRBE9ibyryae6Pag/KExqNUuemIllFfkv 1P6QqCFmsKjxNwt4bt8IZLap6P4IW7GiOqcL60OMXhix504IMmVL1qFZLerKpJOg+IkxGSmhiau CQiahQ== X-Received: by 2002:a05:6a21:483:b0:1db:ff9d:1560 with SMTP id adf61e73a8af0-1ee8cb83e07mr11012680637.18.1739710740990; Sun, 16 Feb 2025 04:59:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IEX2DoXZH2gdxB4GWkakyck9S/MVDzRPWAT4rIheXRziUt7feS9YZINV7LVPXBklwt62cw7UA== X-Received: by 2002:a05:6a21:483:b0:1db:ff9d:1560 with SMTP id adf61e73a8af0-1ee8cb83e07mr11012654637.18.1739710740669; Sun, 16 Feb 2025 04:59:00 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.58.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:59:00 -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 v3 12/13] gpio: aggregator: cancel deferred probe for devices created via configfs Date: Sun, 16 Feb 2025 21:58:15 +0900 Message-ID: <20250216125816.14430-13-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 editing configurations while 'live' is 0, deferred probing is both unnatural and unsafe. Cancel deferred probe for purely configfs-based aggregators when probe fails. Signed-off-by: Koichiro Den --- drivers/gpio/gpio-aggregator.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index 8f8793f27211..f6beb9f41b9a 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -72,6 +72,10 @@ struct gpio_aggregator_line { enum gpio_lookup_flags flags; }; =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 @@ -1112,6 +1116,7 @@ static int aggr_parse(struct gpio_aggregator *aggr) static ssize_t new_device_store(struct device_driver *driver, const char *= buf, size_t count) { + struct gpio_aggregator_pdev_meta meta =3D { .init_via_sysfs =3D true }; char name[CONFIGFS_ITEM_NAME_LEN]; struct gpio_aggregator *aggr; struct platform_device *pdev; @@ -1161,7 +1166,7 @@ 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, aggr->id, NULL, 0); + pdev =3D platform_device_register_data(NULL, DRV_NAME, aggr->id, &meta, s= izeof(meta)); if (IS_ERR(pdev)) { res =3D PTR_ERR(pdev); goto remove_table; @@ -1242,14 +1247,15 @@ static struct attribute *gpio_aggregator_attrs[] = =3D { }; ATTRIBUTE_GROUPS(gpio_aggregator); =20 - /* * GPIO Aggregator platform device */ =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; @@ -1263,10 +1269,28 @@ static int gpio_aggregator_probe(struct platform_de= vice *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])) + if (IS_ERR(descs[i])) { + /* + * Deferred probing is not suitable when the aggregator + * is created via configfs. They should just retry later + * whenever they like. For device creation via sysfs, + * error is propagated without overriding for backward + * compatibility. .prevent_deferred_probe is kept unset + * for other cases. + */ + if (!init_via_sysfs && !dev_of_node(dev) && + descs[i] =3D=3D ERR_PTR(-EPROBE_DEFER)) { + pr_warn("Deferred probe canceled for creation via configfs.\n"); + return -ENODEV; + } return PTR_ERR(descs[i]); + } } =20 features =3D (uintptr_t)device_get_match_data(dev); --=20 2.45.2 From nobody Fri Dec 19 06:07:40 2025 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 68FF61A0BDB for ; Sun, 16 Feb 2025 12:59:07 +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=1739710749; cv=none; b=UuwxL7e+0esQD45v4pXJ580TafbmCwtbotAgJA04phX0/zVmM1xJCxvFnWxYcWbxApvsaXAnMxs5yM/pVHEXKn0DR9AxqanfYD0Uxro7vi22qBVF0anLfbUx9j8E7Ian7ySjBe8HmUu6JhdJ4OvfFLAUYU8rFcW5Jh/2aqtLhAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739710749; c=relaxed/simple; bh=5z75klJulPBK3euVFo5jCw9QXY35/qZ4NCunDCR/9Jo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NhPmBOZ3woPKoOa/jp9GEHuOKI5jocJveeoPn0IrPDYkeveTx1bn7Ln69YVFOAwGBBixJ/541rqMc6MVWSNiWsNAEGVPd1sCmbuc7AHjWIXEcbs7l4nUum/aEfRuom3OUMECSA7s+6ck5+QSbJKf5UKFpwWWUt7qfzE2keyRahU= 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=FBqhXcA7; 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="FBqhXcA7" Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 2B9E13F2BC for ; Sun, 16 Feb 2025 12:59:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1739710745; bh=VbN0B6Oenuw6+py3+N6wdefqtqSm9CuUWAW6b8DJ97M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FBqhXcA7ki76jeo2zoKrLcuptSNJKEfvrWc9cxO4tKBfRPUbbRxEik3WwPKHZJ0Gt PGT/CKgQvyYfDrarAhGrhu2T1IllCveSfCd7YjJhZ32hzB5MzUxSR2a1hQU/LFIVSg gcrqQZP/lDiKvYHcJY4Khzv/P78PKkACozRTJG48i5+A4o/vTvFjH8dSarWJ3W4xE4 Ddg3vcfqUVOWelAzpodcFEnJ6j0XcBMAJ3iBcoUW2tSqeJe7Augl+k1rOKG07VOf2n RAHC37F+pwGWFCI/mCg7R9OgowjJzm+AQXDeHV5t3NGJGwenATm2fHL5mg0/pG4VIv mdNKlNGcicssw== Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-220d6c10a17so60262815ad.0 for ; Sun, 16 Feb 2025 04:59:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739710744; x=1740315544; 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=VbN0B6Oenuw6+py3+N6wdefqtqSm9CuUWAW6b8DJ97M=; b=YXfwXX9hTKfJzc5oq7EuR5jGrHZb/6gd6zdOliwA4NoMiLOJAPTsijJKXiOzp08yBB rf8fU0MWl7uvFOF+o2mowY+Hz1HVnMOBdYQY93b9IM5IMq1oZUubUe0c1QohIYEKoFS1 nlsQYw62b3HZdGazKTFtSSnfU2wjpVOjgjCnzLny8tL0agu2nd8KmwigCLBz5sBeRLrG TK7DwgCPJ0cXJmsu+ebeZdRJmOs0FnzNTKf8sCaK3AOoaoPrDuOcbY2eJNAv0ODFcbLT PqBXgEfn1v+TVxq0qqzUAkEUtbPz2442TUDwUHzIB72O94wkrBBgclARXo7TM7gASKTz rEKg== X-Forwarded-Encrypted: i=1; AJvYcCWxwwJL55jjXnI/5PB5gTUEbmqwJjTw0av/bPqe9y0ImAs/QLUPkgStUv4bO3gvoNMQvDU0IXIJ1XSJ95w=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+KalFkqeVG8cKEkR4KsAh3aNc8xWiIrXas/9KUc3uGuBkGZeQ JKQp78VAELUXO/vqke0mZP3d1RmhBgJSzj9BKiN1H8ZG9nxsCiL/h4FNP1T1TNRNqAWZ4Lg5Ku2 nVMkjE1lcCvddvMdQq8G0L8+eoLCrGMRwGlMgLs7jTNfXg0h9FJRPn8/db9+FgRPVDDRGAg+qbw 5zUw== X-Gm-Gg: ASbGncvACOmCRBxMdFl4KpVzOLtTG2BSZ4gvRaURxZY5Vn+CCY6+DuIOBmvgmXQs3d6 UfWw5Mclk3b4esdR9bQDLaZHUKLatnS6lCwdzYzkvH/+VUv9UDAqT0b0W6WR/ItKRj4939TvP5V Ew5k2KJBspheNhPvG9vrJOVsk/3sVxtUkCvhDO+csZpEMRFPyayjR/66pa690yaWx/MJPyJeLxF +VF62c+jxUNgXawkacOvYgrkJWdDDhndnghVh27xIUXZkYJp47M6EY61Nwp6E3srGdL7YX/AeCU CueEUg== X-Received: by 2002:aa7:9912:0:b0:732:5875:eb95 with SMTP id d2e1a72fcca58-7325875ee4fmr11310405b3a.4.1739710743634; Sun, 16 Feb 2025 04:59:03 -0800 (PST) X-Google-Smtp-Source: AGHT+IHo/tLeo1FafwhPWL09gZg/Vg+JGHNlMxvFuz7WLwpyGUOorkDmHNR4ArvfJ6p5/jd7rf5PvA== X-Received: by 2002:aa7:9912:0:b0:732:5875:eb95 with SMTP id d2e1a72fcca58-7325875ee4fmr11310374b3a.4.1739710743132; Sun, 16 Feb 2025 04:59:03 -0800 (PST) Received: from z790sl.. ([240f:74:7be:1:eaa9:d394:f21d:ee9f]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73256fb09e1sm4316545b3a.65.2025.02.16.04.59.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Feb 2025 04:59:02 -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 v3 13/13] Documentation: gpio: document configfs interface for gpio-aggregator Date: Sun, 16 Feb 2025 21:58:16 +0900 Message-ID: <20250216125816.14430-14-koichiro.den@canonical.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250216125816.14430-1-koichiro.den@canonical.com> References: <20250216125816.14430-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 --- .../admin-guide/gpio/gpio-aggregator.rst | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/Documentation/admin-guide/gpio/gpio-aggregator.rst b/Documenta= tion/admin-guide/gpio/gpio-aggregator.rst index 5cd1e7221756..8374a9df9105 100644 --- a/Documentation/admin-guide/gpio/gpio-aggregator.rst +++ b/Documentation/admin-guide/gpio/gpio-aggregator.rst @@ -69,6 +69,113 @@ write-only attribute files in sysfs. $ echo gpio-aggregator.0 > delete_device =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 + ``_sysfs`` prefix, which are reserved for auto-generated configfs + entries corresponding to devices created via Sysfs. + +**Attribute:** ``/config/gpio-aggregator//live`` + + The ``live`` attribute allows to trigger the actual creation of the de= vice + once it's fully configured. Accepted values are: + + * ``1``, ``yes``, ``true`` : enable the virtual device + * ``0``, ``no``, ``false`` : disable the virtual device + +**Attribute:** ``/config/gpio-aggregator//dev_name`` + + The read-only ``dev_name`` attribute exposes the name of the device as= it + will appear in the system on the platform bus (e.g. ``gpio-aggregator.= 0``). + This is useful for identifying a character device for the newly created + aggregator. If it's ``gpio-aggregator.0``, + ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you 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`` + + The default values after creating the ```` directory are: + + * ``key`` : + * ``offset`` : -1 + + ``key`` must always be explicitly configured, while ``offset`` depends. + Two configuration patterns exist for each ````: + + (a). For lookup by GPIO line name: + + * Set ``key`` to the line name. + * Ensure ``offset`` remains -1 (the default). + + (b). For lookup by GPIO chip name and the line offset within the chip: + + * Set ``key`` to the chip name. + * Set ``offset`` to the line offset (0 <=3D ``offset`` < 65535). + +**Attribute:** ``/config/gpio-aggregator///name`` + + The ``name`` attribute sets a custom name for lineY. If left unset, the + line will remain unnamed. + +Once the configuration is done, the ``'live'`` attribute must be set to 1 +in order to instantiate the aggregator device. It can be set back to 0 to +destroy the virtual device. The module will synchronously wait for the new +aggregator device to be successfully probed and if this doesn't happen, 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/_sysfs./``. Y= ou + 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