[PATCH 2/3] soc/tegra: pmc: Remove reset sysfs entries on error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info")
added sysfs entries for Tegra reset source and level. However, these
sysfs are not removed on error and so if the registering of PMC device
is probe deferred, then the next time we attempt to probe the PMC device
warnings such as the following will be displayed on boot ...

 sysfs: cannot create duplicate filename '/devices/platform/7000e400.pmc/reset_reason'

Fix this by ...

1. Splitting the function tegra_pmc_reset_sysfs_init() into two separate
   functions for initialising the reset reason sysfs entry and the reset
   level sysfs entry. Given that not all devices support both this
   simplifies the cleanup in the error path.
2. If either of the sysfs entries fail to be created, then instead of
   just printing a warning message, print an error message and return
   the error to prevent the probe from succeeding and cleanup as
   necessary. Previously the intention was to avoid the failure of
   creating the sysfs entries to causing the PMC probe to fail, this
   should never happen and so it is better to just return the error.

Fixes: 5f84bb1a4099 ("soc/tegra: pmc: Add sysfs entries for reset info")
Signed-off-by: Jon Hunter <jonathanh@xxxxxxxxxx>
---
 drivers/soc/tegra/pmc.c | 68 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 50 insertions(+), 18 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 61c61994f17d..8d769e3ba668 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1771,26 +1771,48 @@ static ssize_t reset_level_show(struct device *dev,
 
 static DEVICE_ATTR_RO(reset_level);
 
-static void tegra_pmc_reset_sysfs_init(struct tegra_pmc *pmc)
+static int tegra_pmc_reset_reason_init(struct tegra_pmc *pmc)
 {
 	struct device *dev = pmc->dev;
-	int err = 0;
+	int err;
 
-	if (pmc->soc->reset_sources) {
-		err = device_create_file(dev, &dev_attr_reset_reason);
-		if (err < 0)
-			dev_warn(dev,
-				 "failed to create attr \"reset_reason\": %d\n",
-				 err);
-	}
+	if (!pmc->soc->reset_sources)
+		return 0;
 
-	if (pmc->soc->reset_levels) {
-		err = device_create_file(dev, &dev_attr_reset_level);
-		if (err < 0)
-			dev_warn(dev,
-				 "failed to create attr \"reset_level\": %d\n",
-				 err);
-	}
+	err = device_create_file(dev, &dev_attr_reset_reason);
+	if (err < 0)
+		dev_err(dev, "failed to create attr \"reset_reason\": %d\n",
+			err);
+
+	return err;
+}
+
+static void tegra_pmc_reset_reason_remove(struct tegra_pmc *pmc)
+{
+	if (pmc->soc->reset_sources)
+		device_remove_file(pmc->dev, &dev_attr_reset_reason);
+}
+
+static int tegra_pmc_reset_level_init(struct tegra_pmc *pmc)
+{
+	struct device *dev = pmc->dev;
+	int err;
+
+	if (!pmc->soc->reset_levels)
+		return 0;
+
+	err = device_create_file(dev, &dev_attr_reset_level);
+	if (err < 0)
+		dev_err(dev, "failed to create attr \"reset_level\": %d\n",
+			err);
+
+	return err;
+}
+
+static void tegra_pmc_reset_level_remove(struct tegra_pmc *pmc)
+{
+	if (pmc->soc->reset_levels)
+		device_remove_file(pmc->dev, &dev_attr_reset_level);
 }
 
 static int tegra_pmc_irq_translate(struct irq_domain *domain,
@@ -2031,12 +2053,18 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 
 	tegra_pmc_init_tsense_reset(pmc);
 
-	tegra_pmc_reset_sysfs_init(pmc);
+	err = tegra_pmc_reset_reason_init(pmc);
+	if (err < 0)
+		return err;
+
+	err = tegra_pmc_reset_level_init(pmc);
+	if (err < 0)
+		goto cleanup_reset_reason;
 
 	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
 		err = tegra_powergate_debugfs_init();
 		if (err < 0)
-			return err;
+			goto cleanup_reset_level;
 	}
 
 	err = register_restart_handler(&tegra_pmc_restart_handler);
@@ -2067,6 +2095,10 @@ static int tegra_pmc_probe(struct platform_device *pdev)
 	unregister_restart_handler(&tegra_pmc_restart_handler);
 cleanup_debugfs:
 	debugfs_remove(pmc->debugfs);
+cleanup_reset_level:
+	tegra_pmc_reset_level_remove(pmc);
+cleanup_reset_reason:
+	tegra_pmc_reset_reason_remove(pmc);
 	return err;
 }
 
-- 
2.7.4




[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux