[PATCH v2] fsi: aspeed: publish cfam_reset through driver groups

Pengpeng Hou <[email protected]>
Newsgroups org.ozlabs.lists.linux-aspeed,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The cfam_reset attribute currently gets created manually while probe is
still initializing the master. Its store callback expects device drvdata
and the master's mutex to be ready, and manual publication also requires
matching cleanup on every later failure and remove path.

Expose the attribute through the driver's default groups instead. The
driver core publishes those groups only after probe succeeds. Hide the
attribute when the optional reset GPIO is unavailable, while retaining
probe deferral and other GPIO acquisition errors.

Fixes: 4a851d714eade ("fsi: aspeed: Support CFAM reset GPIO")
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <[email protected]>
---
Changes since v1: https://lore.kernel.org/all/[email protected]/
- replace manual sysfs publication with driver-core groups and is_visible()
- preserve optional-GPIO and probe-deferral error semantics
- remove manual sysfs unwind paths

The probe/publication ordering was reviewed statically; no Aspeed FSI
hardware test was performed.

 drivers/fsi/fsi-master-aspeed.c | 38 ++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index aa1380cdff33..ac05e1a263ac 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -464,26 +464,42 @@ static ssize_t cfam_reset_store(struct device *dev, struct device_attribute *att
 
 static DEVICE_ATTR(cfam_reset, 0200, NULL, cfam_reset_store);
 
+static umode_t fsi_master_aspeed_attr_is_visible(struct kobject *kobj,
+						 struct attribute *attr, int n)
+{
+	struct fsi_master_aspeed *aspeed = dev_get_drvdata(kobj_to_dev(kobj));
+
+	if (!aspeed || !aspeed->cfam_reset_gpio)
+		return 0;
+
+	return attr->mode;
+}
+
+static struct attribute *fsi_master_aspeed_attrs[] = {
+	&dev_attr_cfam_reset.attr,
+	NULL,
+};
+
+static const struct attribute_group fsi_master_aspeed_group = {
+	.attrs = fsi_master_aspeed_attrs,
+	.is_visible = fsi_master_aspeed_attr_is_visible,
+};
+
+static const struct attribute_group *fsi_master_aspeed_groups[] = {
+	&fsi_master_aspeed_group,
+	NULL,
+};
+
 static int setup_cfam_reset(struct fsi_master_aspeed *aspeed)
 {
 	struct device *dev = aspeed->dev;
 	struct gpio_desc *gpio;
-	int rc;
 
 	gpio = devm_gpiod_get_optional(dev, "cfam-reset", GPIOD_OUT_LOW);
 	if (IS_ERR(gpio))
 		return PTR_ERR(gpio);
-	if (!gpio)
-		return 0;
 
 	aspeed->cfam_reset_gpio = gpio;
-
-	rc = device_create_file(dev, &dev_attr_cfam_reset);
-	if (rc) {
-		devm_gpiod_put(dev, gpio);
-		return rc;
-	}
-
 	return 0;
 }
 
@@ -573,6 +589,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 	rc = setup_cfam_reset(aspeed);
 	if (rc) {
 		dev_err(&pdev->dev, "CFAM reset GPIO setup failed\n");
+		goto err_release;
 	}
 
 	writel(0x1, aspeed->base + OPB_CLK_SYNC);
@@ -664,6 +681,7 @@ static struct platform_driver fsi_master_aspeed_driver = {
 	.driver = {
 		.name		= "fsi-master-aspeed",
 		.of_match_table	= fsi_master_aspeed_match,
+		.dev_groups	= fsi_master_aspeed_groups,
 	},
 	.probe	= fsi_master_aspeed_probe,
 	.remove = fsi_master_aspeed_remove,
-- 
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.