Skip to contentSkip to conversation

Make probe() of Tegra devfreq driver completely resource-managed

PATCH Applied Dmitry Osipenko 3 participants 10 messages Sep 20, 2021 – Oct 5, 2021

Subsystems (5)
lore
Share & tools
lore

Dmitry Osipenko

author maintainer
#0 lore raw

v2 cover Make probe() of Tegra devfreq driver completely resource-managed

This series adds new resource-managed helpers and makes Tegra devfreq driver to use them, improving the driver's error-handling code.

Changelog:

v2: - Added WARN_ON() to devm_devfreq_remove_governor() and moved
devm_devfreq_add_governor() as was requested by Chanwoo Choi.

- Added ack from Chanwoo Choi to the "Check whether clk_round_rate() returns zero rate" patch.

Dmitry Osipenko (4):
opp: Add more resource-managed variants of dev_pm_opp_of_add_table() PM / devfreq: Add devm_devfreq_add_governor()
PM / devfreq: tegra30: Use resource-managed helpers
PM / devfreq: tegra30: Check whether clk_round_rate() returns zero
rate

 drivers/devfreq/devfreq.c         |  26 +++++++
 drivers/devfreq/governor.h        |   3 +
 drivers/devfreq/tegra30-devfreq.c | 109 +++++++++++++-----------------
 drivers/opp/of.c                  |  46 +++++++++++--
 include/linux/pm_opp.h            |  12 ++++
 5 files changed, 127 insertions(+), 69 deletions(-)
Signature · 1 line
2.32.0
author maintainer
#1 lore raw

PATCH v2 1/4 opp: Add more resource-managed variants of dev_pm_opp_of_add_table()

Add resource-managed variants of dev_pm_opp_of_add_table_indexed() and dev_pm_opp_of_add_table_noclk(), allowing drivers to remove boilerplate code.

---
 drivers/opp/of.c       | 46 +++++++++++++++++++++++++++++++++++-------
 include/linux/pm_opp.h | 12 +++++++++++
 2 files changed, 51 insertions(+), 7 deletions(-)
drivers/opp/of.c +39 -7
index 2a97c6535c4c..bd01ecb1d85c 100644
@@ -1081,6 +1081,17 @@ static void devm_pm_opp_of_table_release(void *data)
 	dev_pm_opp_of_remove_table(data);
 }
 
+static int devm_of_add_table_indexed(struct device *dev, int index, bool getclk)
+{
+	int ret;
+
+	ret = _of_add_table_indexed(dev, index, getclk);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, devm_pm_opp_of_table_release, dev);
+}
+
 /**
  * devm_pm_opp_of_add_table() - Initialize opp table from device tree
  * @dev:	device pointer used to lookup OPP table.
@@ -1102,13 +1113,7 @@ static void devm_pm_opp_of_table_release(void *data)
  */
 int devm_pm_opp_of_add_table(struct device *dev)
 {
-	int ret;
-
-	ret = dev_pm_opp_of_add_table(dev);
-	if (ret)
-		return ret;
-
-	return devm_add_action_or_reset(dev, devm_pm_opp_of_table_release, dev);
+	return devm_of_add_table_indexed(dev, 0, true);
 }
 EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table);
 
@@ -1151,6 +1156,19 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_indexed);
 
+/**
+ * devm_pm_opp_of_add_table_indexed() - Initialize indexed opp table from device tree
+ * @dev:	device pointer used to lookup OPP table.
+ * @index:	Index number.
+ *
+ * This is a resource-managed variant of dev_pm_opp_of_add_table_indexed().
+ */
+int devm_pm_opp_of_add_table_indexed(struct device *dev, int index)
+{
+	return devm_of_add_table_indexed(dev, index, true);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_indexed);
+
 /**
  * dev_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device
  *		tree without getting clk for device.
@@ -1169,6 +1187,20 @@ int dev_pm_opp_of_add_table_noclk(struct device *dev, int index)
 }
 EXPORT_SYMBOL_GPL(dev_pm_opp_of_add_table_noclk);
 
+/**
+ * devm_pm_opp_of_add_table_noclk() - Initialize indexed opp table from device
+ *		tree without getting clk for device.
+ * @dev:	device pointer used to lookup OPP table.
+ * @index:	Index number.
+ *
+ * This is a resource-managed variant of dev_pm_opp_of_add_table_noclk().
+ */
+int devm_pm_opp_of_add_table_noclk(struct device *dev, int index)
+{
+	return devm_of_add_table_indexed(dev, index, false);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table_noclk);
+
 /* CPU device specific helpers */
 
 /**
include/linux/pm_opp.h +12 -0
index 84150a22fd7c..a95d6fdd20b6 100644
@@ -439,7 +439,9 @@ static inline int dev_pm_opp_sync_regulators(struct device *dev)
 #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
 int dev_pm_opp_of_add_table(struct device *dev);
 int dev_pm_opp_of_add_table_indexed(struct device *dev, int index);
+int devm_pm_opp_of_add_table_indexed(struct device *dev, int index);
 int dev_pm_opp_of_add_table_noclk(struct device *dev, int index);
+int devm_pm_opp_of_add_table_noclk(struct device *dev, int index);
 void dev_pm_opp_of_remove_table(struct device *dev);
 int devm_pm_opp_of_add_table(struct device *dev);
 int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask);
@@ -465,11 +467,21 @@ static inline int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
 	return -EOPNOTSUPP;
 }
 
+static inline int devm_pm_opp_of_add_table_indexed(struct device *dev, int index)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int dev_pm_opp_of_add_table_noclk(struct device *dev, int index)
 {
 	return -EOPNOTSUPP;
 }
 
+static inline int devm_pm_opp_of_add_table_noclk(struct device *dev, int index)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline void dev_pm_opp_of_remove_table(struct device *dev)
 {
 }
Signature · 1 line
2.32.0
#2 lore raw

Re: [PATCH v2 1/4] opp: Add more resource-managed variants of dev_pm_opp_of_add_table()

Quoted 15 lines · Dmitry Osipenko

Add resource-managed variants of dev_pm_opp_of_add_table_indexed() and dev_pm_opp_of_add_table_noclk(), allowing drivers to remove boilerplate code.

---
 drivers/opp/of.c       | 46 +++++++++++++++++++++++++++++++++++-------
 include/linux/pm_opp.h | 12 +++++++++++
 2 files changed, 51 insertions(+), 7 deletions(-)
drivers/opp/of.c +0 -0
index 2a97c6535c4c..bd01ecb1d85c 100644

drivers/opp/of.c static void devm_pm_opp_of_table_release(void *data) · line 1084

Quoted 4 lines
drivers/opp/of.c +1 -0
@@ -1081,6 +1081,17 @@ static void devm_pm_opp_of_table_release(void *data)
 	dev_pm_opp_of_remove_table(data);
 }
 
+static int devm_of_add_table_indexed(struct device *dev, int index, bool getclk)

Made this _devm_of_add_table_indexed() and applied this patch. Thanks.

What about rest of the series ?

Signature · 1 line
viresh
author maintainer
#3 lore raw

Re: [PATCH v2 1/4] opp: Add more resource-managed variants of dev_pm_opp_of_add_table()

04.10.2021 14:04, Viresh Kumar пишет:

Quoted 19 lines · Dmitry Osipenko
Quoted 18 lines

Add resource-managed variants of dev_pm_opp_of_add_table_indexed() and dev_pm_opp_of_add_table_noclk(), allowing drivers to remove boilerplate code.

---
 drivers/opp/of.c       | 46 +++++++++++++++++++++++++++++++++++-------
 include/linux/pm_opp.h | 12 +++++++++++
 2 files changed, 51 insertions(+), 7 deletions(-)
drivers/opp/of.c +0 -0
index 2a97c6535c4c..bd01ecb1d85c 100644
@@ -1081,6 +1081,17 @@ static void devm_pm_opp_of_table_release(void *data)
 	dev_pm_opp_of_remove_table(data);
 }
 
Quoted 6 lines

drivers/opp/of.c static void devm_pm_opp_of_table_release(void *data) · line 1084

Quoted 1 line
drivers/opp/of.c +1 -0
+static int devm_of_add_table_indexed(struct device *dev, int index, bool getclk)

Made this _devm_of_add_table_indexed() and applied this patch. Thanks.

What about rest of the series ?

I assume you should take it all via the OPP tree since Chanwoo gave the acks, otherwise immutable branch is needed from you.

author maintainer
#4 lore raw

PATCH v2 2/4 PM / devfreq: Add devm_devfreq_add_governor()

In reply to Dmitry Osipenko

Add resource-managed variant of devfreq_add_governor().

---
 drivers/devfreq/devfreq.c  | 26 ++++++++++++++++++++++++++
 drivers/devfreq/governor.h |  3 +++
 2 files changed, 29 insertions(+)
drivers/devfreq/devfreq.c +26 -0
index 85faa7a5c7d1..4579eefb8fe7 100644
@@ -1301,6 +1301,32 @@ int devfreq_add_governor(struct devfreq_governor *governor)
 }
 EXPORT_SYMBOL(devfreq_add_governor);
 
+static void devm_devfreq_remove_governor(void *governor)
+{
+	WARN_ON(devfreq_remove_governor(governor));
+}
+
+/**
+ * devm_devfreq_add_governor() - Add devfreq governor
+ * @dev:	device which adds devfreq governor
+ * @governor:	the devfreq governor to be added
+ *
+ * This is a resource-managed variant of devfreq_add_governor().
+ */
+int devm_devfreq_add_governor(struct device *dev,
+			      struct devfreq_governor *governor)
+{
+	int err;
+
+	err = devfreq_add_governor(governor);
+	if (err)
+		return err;
+
+	return devm_add_action_or_reset(dev, devm_devfreq_remove_governor,
+					governor);
+}
+EXPORT_SYMBOL(devm_devfreq_add_governor);
+
 /**
  * devfreq_remove_governor() - Remove devfreq feature from a device.
  * @governor:	the devfreq governor to be removed
drivers/devfreq/governor.h +3 -0
index 2d69a0ce6291..002a7d67e39d 100644
@@ -84,6 +84,9 @@ void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay);
 int devfreq_add_governor(struct devfreq_governor *governor);
 int devfreq_remove_governor(struct devfreq_governor *governor);
 
+int devm_devfreq_add_governor(struct device *dev,
+			      struct devfreq_governor *governor);
+
 int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
 int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);
 
Signature · 1 line
2.32.0
Acked-by on v2 2/4
#5 lore raw

Re: [PATCH v2 2/4] PM / devfreq: Add devm_devfreq_add_governor()

Quoted 51 lines · Dmitry Osipenko

Add resource-managed variant of devfreq_add_governor().

---
  drivers/devfreq/devfreq.c  | 26 ++++++++++++++++++++++++++
  drivers/devfreq/governor.h |  3 +++
  2 files changed, 29 insertions(+)
drivers/devfreq/devfreq.c +26 -0
index 85faa7a5c7d1..4579eefb8fe7 100644
@@ -1301,6 +1301,32 @@ int devfreq_add_governor(struct devfreq_governor *governor)
  }
  EXPORT_SYMBOL(devfreq_add_governor);
 
+static void devm_devfreq_remove_governor(void *governor)
+{
+	WARN_ON(devfreq_remove_governor(governor));
+}
+
+/**
+ * devm_devfreq_add_governor() - Add devfreq governor
+ * @dev:	device which adds devfreq governor
+ * @governor:	the devfreq governor to be added
+ *
+ * This is a resource-managed variant of devfreq_add_governor().
+ */
+int devm_devfreq_add_governor(struct device *dev,
+			      struct devfreq_governor *governor)
+{
+	int err;
+
+	err = devfreq_add_governor(governor);
+	if (err)
+		return err;
+
+	return devm_add_action_or_reset(dev, devm_devfreq_remove_governor,
+					governor);
+}
+EXPORT_SYMBOL(devm_devfreq_add_governor);
+
  /**
   * devfreq_remove_governor() - Remove devfreq feature from a device.
   * @governor:	the devfreq governor to be removed
drivers/devfreq/governor.h +0 -0
index 2d69a0ce6291..002a7d67e39d 100644

drivers/devfreq/governor.h void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay); · line 92

Quoted 9 lines
drivers/devfreq/governor.h +3 -0
@@ -84,6 +84,9 @@ void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay);
  int devfreq_add_governor(struct devfreq_governor *governor);
  int devfreq_remove_governor(struct devfreq_governor *governor);
 
+int devm_devfreq_add_governor(struct device *dev,
+			      struct devfreq_governor *governor);
+
  int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
  int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);
 
Signature · 3 lines
Best Regards,
Samsung Electronics
Chanwoo Choi
author maintainer
#6 lore raw

PATCH v2 3/4 PM / devfreq: tegra30: Use resource-managed helpers

In reply to Dmitry Osipenko

Use resource-managed API helpers to simplify driver's probe() function, making code cleaner.

---
 drivers/devfreq/tegra30-devfreq.c | 107 +++++++++++++-----------------
 1 file changed, 46 insertions(+), 61 deletions(-)
drivers/devfreq/tegra30-devfreq.c +46 -61
index 10661eb2aed8..d83fdc2713ed 100644
@@ -178,7 +178,6 @@ struct tegra_devfreq_soc_data {
 
 struct tegra_devfreq {
 	struct devfreq		*devfreq;
-	struct opp_table	*opp_table;
 
 	struct reset_control	*reset;
 	struct clk		*clock;
@@ -789,6 +788,39 @@ static struct devfreq_governor tegra_devfreq_governor = {
 	.event_handler = tegra_governor_event_handler,
 };
 
+static void devm_tegra_devfreq_deinit_hw(void *data)
+{
+	struct tegra_devfreq *tegra = data;
+
+	reset_control_reset(tegra->reset);
+	clk_disable_unprepare(tegra->clock);
+}
+
+static int devm_tegra_devfreq_init_hw(struct device *dev,
+				      struct tegra_devfreq *tegra)
+{
+	int err;
+
+	err = clk_prepare_enable(tegra->clock);
+	if (err) {
+		dev_err(dev, "Failed to prepare and enable ACTMON clock\n");
+		return err;
+	}
+
+	err = devm_add_action_or_reset(dev, devm_tegra_devfreq_deinit_hw,
+				       tegra);
+	if (err)
+		return err;
+
+	err = reset_control_reset(tegra->reset);
+	if (err) {
+		dev_err(dev, "Failed to reset hardware: %d\n", err);
+		return err;
+	}
+
+	return err;
+}
+
 static int tegra_devfreq_probe(struct platform_device *pdev)
 {
 	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
@@ -842,38 +874,26 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev,
-						       &hw_version, 1);
-	err = PTR_ERR_OR_ZERO(tegra->opp_table);
+	err = devm_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
 		return err;
 	}
 
-	err = dev_pm_opp_of_add_table_noclk(&pdev->dev, 0);
+	err = devm_pm_opp_of_add_table_noclk(&pdev->dev, 0);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
-		goto put_hw;
-	}
-
-	err = clk_prepare_enable(tegra->clock);
-	if (err) {
-		dev_err(&pdev->dev,
-			"Failed to prepare and enable ACTMON clock\n");
-		goto remove_table;
+		return err;
 	}
 
-	err = reset_control_reset(tegra->reset);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to reset hardware: %d\n", err);
-		goto disable_clk;
-	}
+	err = devm_tegra_devfreq_init_hw(&pdev->dev, tegra);
+	if (err)
+		return err;
 
 	rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
 	if (rate < 0) {
 		dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate);
-		err = rate;
-		goto disable_clk;
+		return rate;
 	}
 
 	tegra->max_freq = rate / KHZ;
@@ -892,52 +912,18 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	INIT_DELAYED_WORK(&tegra->cpufreq_update_work,
 			  tegra_actmon_delayed_update);
 
-	err = devfreq_add_governor(&tegra_devfreq_governor);
+	err = devm_devfreq_add_governor(&pdev->dev, &tegra_devfreq_governor);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add governor: %d\n", err);
-		goto remove_opps;
+		return err;
 	}
 
 	tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
 
-	devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
-				     "tegra_actmon", NULL);
-	if (IS_ERR(devfreq)) {
-		err = PTR_ERR(devfreq);
-		goto remove_governor;
-	}
-
-	return 0;
-
-remove_governor:
-	devfreq_remove_governor(&tegra_devfreq_governor);
-
-remove_opps:
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
-
-	reset_control_reset(tegra->reset);
-disable_clk:
-	clk_disable_unprepare(tegra->clock);
-remove_table:
-	dev_pm_opp_of_remove_table(&pdev->dev);
-put_hw:
-	dev_pm_opp_put_supported_hw(tegra->opp_table);
-
-	return err;
-}
-
-static int tegra_devfreq_remove(struct platform_device *pdev)
-{
-	struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
-
-	devfreq_remove_device(tegra->devfreq);
-	devfreq_remove_governor(&tegra_devfreq_governor);
-
-	reset_control_reset(tegra->reset);
-	clk_disable_unprepare(tegra->clock);
-
-	dev_pm_opp_of_remove_table(&pdev->dev);
-	dev_pm_opp_put_supported_hw(tegra->opp_table);
+	devfreq = devm_devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
+					  "tegra_actmon", NULL);
+	if (IS_ERR(devfreq))
+		return PTR_ERR(devfreq);
 
 	return 0;
 }
@@ -967,7 +953,6 @@ MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match);
 
 static struct platform_driver tegra_devfreq_driver = {
 	.probe	= tegra_devfreq_probe,
-	.remove	= tegra_devfreq_remove,
 	.driver = {
 		.name = "tegra-devfreq",
 		.of_match_table = tegra_devfreq_of_match,
Signature · 1 line
2.32.0
Acked-by on v2 3/4
#7 lore raw

Re: [PATCH v2 3/4] PM / devfreq: tegra30: Use resource-managed helpers

Quoted 167 lines · Dmitry Osipenko

Use resource-managed API helpers to simplify driver's probe() function, making code cleaner.

---
  drivers/devfreq/tegra30-devfreq.c | 107 +++++++++++++-----------------
  1 file changed, 46 insertions(+), 61 deletions(-)
drivers/devfreq/tegra30-devfreq.c +46 -60
index 10661eb2aed8..d83fdc2713ed 100644
@@ -178,7 +178,6 @@ struct tegra_devfreq_soc_data {
 
  struct tegra_devfreq {
  	struct devfreq		*devfreq;
-	struct opp_table	*opp_table;
 
  	struct reset_control	*reset;
  	struct clk		*clock;
@@ -789,6 +788,39 @@ static struct devfreq_governor tegra_devfreq_governor = {
  	.event_handler = tegra_governor_event_handler,
  };
 
+static void devm_tegra_devfreq_deinit_hw(void *data)
+{
+	struct tegra_devfreq *tegra = data;
+
+	reset_control_reset(tegra->reset);
+	clk_disable_unprepare(tegra->clock);
+}
+
+static int devm_tegra_devfreq_init_hw(struct device *dev,
+				      struct tegra_devfreq *tegra)
+{
+	int err;
+
+	err = clk_prepare_enable(tegra->clock);
+	if (err) {
+		dev_err(dev, "Failed to prepare and enable ACTMON clock\n");
+		return err;
+	}
+
+	err = devm_add_action_or_reset(dev, devm_tegra_devfreq_deinit_hw,
+				       tegra);
+	if (err)
+		return err;
+
+	err = reset_control_reset(tegra->reset);
+	if (err) {
+		dev_err(dev, "Failed to reset hardware: %d\n", err);
+		return err;
+	}
+
+	return err;
+}
+
  static int tegra_devfreq_probe(struct platform_device *pdev)
  {
  	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
@@ -842,38 +874,26 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
  		return err;
  	}
 
-	tegra->opp_table = dev_pm_opp_set_supported_hw(&pdev->dev,
-						       &hw_version, 1);
-	err = PTR_ERR_OR_ZERO(tegra->opp_table);
+	err = devm_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
  	if (err) {
  		dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
  		return err;
  	}
 
-	err = dev_pm_opp_of_add_table_noclk(&pdev->dev, 0);
+	err = devm_pm_opp_of_add_table_noclk(&pdev->dev, 0);
  	if (err) {
  		dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
-		goto put_hw;
-	}
-
-	err = clk_prepare_enable(tegra->clock);
-	if (err) {
-		dev_err(&pdev->dev,
-			"Failed to prepare and enable ACTMON clock\n");
-		goto remove_table;
+		return err;
  	}
 
-	err = reset_control_reset(tegra->reset);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to reset hardware: %d\n", err);
-		goto disable_clk;
-	}
+	err = devm_tegra_devfreq_init_hw(&pdev->dev, tegra);
+	if (err)
+		return err;
 
  	rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
  	if (rate < 0) {
  		dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate);
-		err = rate;
-		goto disable_clk;
+		return rate;
  	}
 
  	tegra->max_freq = rate / KHZ;
@@ -892,52 +912,18 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
  	INIT_DELAYED_WORK(&tegra->cpufreq_update_work,
  			  tegra_actmon_delayed_update);
 
-	err = devfreq_add_governor(&tegra_devfreq_governor);
+	err = devm_devfreq_add_governor(&pdev->dev, &tegra_devfreq_governor);
  	if (err) {
  		dev_err(&pdev->dev, "Failed to add governor: %d\n", err);
-		goto remove_opps;
+		return err;
  	}
 
  	tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
 
-	devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
-				     "tegra_actmon", NULL);
-	if (IS_ERR(devfreq)) {
-		err = PTR_ERR(devfreq);
-		goto remove_governor;
-	}
-
-	return 0;
-
-remove_governor:
-	devfreq_remove_governor(&tegra_devfreq_governor);
-
-remove_opps:
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
-
-	reset_control_reset(tegra->reset);
-disable_clk:
-	clk_disable_unprepare(tegra->clock);
-remove_table:
-	dev_pm_opp_of_remove_table(&pdev->dev);
-put_hw:
-	dev_pm_opp_put_supported_hw(tegra->opp_table);
-
-	return err;
-}
-
-static int tegra_devfreq_remove(struct platform_device *pdev)
-{
-	struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
-
-	devfreq_remove_device(tegra->devfreq);
-	devfreq_remove_governor(&tegra_devfreq_governor);
-
-	reset_control_reset(tegra->reset);
-	clk_disable_unprepare(tegra->clock);
-
-	dev_pm_opp_of_remove_table(&pdev->dev);
-	dev_pm_opp_put_supported_hw(tegra->opp_table);
+	devfreq = devm_devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
+					  "tegra_actmon", NULL);
+	if (IS_ERR(devfreq))
+		return PTR_ERR(devfreq);
 
  	return 0;
  }

drivers/devfreq/tegra30-devfreq.c MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match); · line 958

Quoted 7 lines
drivers/devfreq/tegra30-devfreq.c +0 -1
@@ -967,7 +953,6 @@ MODULE_DEVICE_TABLE(of, tegra_devfreq_of_match);
 
  static struct platform_driver tegra_devfreq_driver = {
  	.probe	= tegra_devfreq_probe,
-	.remove	= tegra_devfreq_remove,
  	.driver = {
  		.name = "tegra-devfreq",
  		.of_match_table = tegra_devfreq_of_match,

It is more readable than before. Thanks.

Signature · 3 lines
Best Regards,
Samsung Electronics
Chanwoo Choi
author maintainer
#8 lore raw

PATCH v2 4/4 PM / devfreq: tegra30: Check whether clk_round_rate() returns zero rate

In reply to Dmitry Osipenko

EMC clock is always-on and can't be zero. Check whether clk_round_rate() returns zero rate and error out if it does. It can return zero if clock tree isn't initialized properly.

---
 drivers/devfreq/tegra30-devfreq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/devfreq/tegra30-devfreq.c +2 -2
index d83fdc2713ed..65ecf17a36f4 100644
@@ -891,9 +891,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		return err;
 
 	rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
-	if (rate < 0) {
+	if (rate <= 0) {
 		dev_err(&pdev->dev, "Failed to round clock rate: %ld\n", rate);
-		return rate;
+		return rate ?: -EINVAL;
 	}
 
 	tegra->max_freq = rate / KHZ;
Signature · 1 line
2.32.0
Applied
#9 lore raw
In reply to Dmitry Osipenko
Quoted 11 lines · Dmitry Osipenko

This series adds new resource-managed helpers and makes Tegra devfreq driver to use them, improving the driver's error-handling code.

Changelog:

v2: - Added WARN_ON() to devm_devfreq_remove_governor() and moved
devm_devfreq_add_governor() as was requested by Chanwoo Choi.

- Added ack from Chanwoo Choi to the "Check whether clk_round_rate() returns zero rate" patch.

Quoted 6 lines

Dmitry Osipenko (4):
opp: Add more resource-managed variants of dev_pm_opp_of_add_table() PM / devfreq: Add devm_devfreq_add_governor()
PM / devfreq: tegra30: Use resource-managed helpers
PM / devfreq: tegra30: Check whether clk_round_rate() returns zero
rate

Applied. Thanks.

Signature · 1 line
viresh