summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2021-04-12 14:49:31 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2021-04-12 14:49:31 +0200
commiteed7a175089bb615af8c47ea5e07574062298187 (patch)
tree320e2b0e90a742c8c39eb022f405538ee5b5eb76
parente49d033bddf5b565044e2abe4241353959bc9120 (diff)
parenta8bb0e872bfb962de4653ce8f8723c0e1f712ce3 (diff)
Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
Pull OPP (Operating Performance Points) framework updates for v5.13 from Viresh Kumar: "This adds devm variants for OPP APIs and updates few of the users as well (Yangtao Li and Dmitry Osipenko)." * 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm: memory: samsung: exynos5422-dmc: Convert to use resource-managed OPP API drm/panfrost: Convert to use resource-managed OPP API drm/lima: Convert to use resource-managed OPP API mmc: sdhci-msm: Convert to use resource-managed OPP API spi: spi-qcom-qspi: Convert to use resource-managed OPP API spi: spi-geni-qcom: Convert to use resource-managed OPP API serial: qcom_geni_serial: Convert to use resource-managed OPP API opp: Change return type of devm_pm_opp_attach_genpd() opp: Change return type of devm_pm_opp_register_set_opp_helper() opp: Add devres wrapper for dev_pm_opp_of_add_table opp: Add devres wrapper for dev_pm_opp_set_supported_hw opp: Add devres wrapper for dev_pm_opp_set_regulators opp: Add devres wrapper for dev_pm_opp_set_clkname
-rw-r--r--drivers/gpu/drm/lima/lima_devfreq.c47
-rw-r--r--drivers/gpu/drm/lima/lima_devfreq.h3
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_devfreq.c37
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_devfreq.h2
-rw-r--r--drivers/memory/samsung/exynos5422-dmc.c13
-rw-r--r--drivers/mmc/host/sdhci-msm.c19
-rw-r--r--drivers/opp/core.c122
-rw-r--r--drivers/opp/of.c36
-rw-r--r--drivers/spi/spi-geni-qcom.c16
-rw-r--r--drivers/spi/spi-qcom-qspi.c18
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c23
-rw-r--r--include/linux/pm_opp.h44
-rw-r--r--include/linux/qcom-geni-se.h2
13 files changed, 217 insertions, 165 deletions
diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c
index 5686ad4aaf7c..dbc1d1eb9543 100644
--- a/drivers/gpu/drm/lima/lima_devfreq.c
+++ b/drivers/gpu/drm/lima/lima_devfreq.c
@@ -99,20 +99,12 @@ void lima_devfreq_fini(struct lima_device *ldev)
devm_devfreq_remove_device(ldev->dev, devfreq->devfreq);
devfreq->devfreq = NULL;
}
-
- dev_pm_opp_of_remove_table(ldev->dev);
-
- dev_pm_opp_put_regulators(devfreq->regulators_opp_table);
- dev_pm_opp_put_clkname(devfreq->clkname_opp_table);
- devfreq->regulators_opp_table = NULL;
- devfreq->clkname_opp_table = NULL;
}
int lima_devfreq_init(struct lima_device *ldev)
{
struct thermal_cooling_device *cooling;
struct device *dev = ldev->dev;
- struct opp_table *opp_table;
struct devfreq *devfreq;
struct lima_devfreq *ldevfreq = &ldev->devfreq;
struct dev_pm_opp *opp;
@@ -125,40 +117,28 @@ int lima_devfreq_init(struct lima_device *ldev)
spin_lock_init(&ldevfreq->lock);
- opp_table = dev_pm_opp_set_clkname(dev, "core");
- if (IS_ERR(opp_table)) {
- ret = PTR_ERR(opp_table);
- goto err_fini;
- }
-
- ldevfreq->clkname_opp_table = opp_table;
-
- opp_table = dev_pm_opp_set_regulators(dev,
- (const char *[]){ "mali" },
- 1);
- if (IS_ERR(opp_table)) {
- ret = PTR_ERR(opp_table);
+ ret = devm_pm_opp_set_clkname(dev, "core");
+ if (ret)
+ return ret;
+ ret = devm_pm_opp_set_regulators(dev, (const char *[]){ "mali" }, 1);
+ if (ret) {
/* Continue if the optional regulator is missing */
if (ret != -ENODEV)
- goto err_fini;
- } else {
- ldevfreq->regulators_opp_table = opp_table;
+ return ret;
}
- ret = dev_pm_opp_of_add_table(dev);
+ ret = devm_pm_opp_of_add_table(dev);
if (ret)
- goto err_fini;
+ return ret;
lima_devfreq_reset(ldevfreq);
cur_freq = clk_get_rate(ldev->clk_gpu);
opp = devfreq_recommended_opp(dev, &cur_freq, 0);
- if (IS_ERR(opp)) {
- ret = PTR_ERR(opp);
- goto err_fini;
- }
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
lima_devfreq_profile.initial_freq = cur_freq;
dev_pm_opp_put(opp);
@@ -167,8 +147,7 @@ int lima_devfreq_init(struct lima_device *ldev)
DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
if (IS_ERR(devfreq)) {
dev_err(dev, "Couldn't initialize GPU devfreq\n");
- ret = PTR_ERR(devfreq);
- goto err_fini;
+ return PTR_ERR(devfreq);
}
ldevfreq->devfreq = devfreq;
@@ -180,10 +159,6 @@ int lima_devfreq_init(struct lima_device *ldev)
ldevfreq->cooling = cooling;
return 0;
-
-err_fini:
- lima_devfreq_fini(ldev);
- return ret;
}
void lima_devfreq_record_busy(struct lima_devfreq *devfreq)
diff --git a/drivers/gpu/drm/lima/lima_devfreq.h b/drivers/gpu/drm/lima/lima_devfreq.h
index 2d9b3008ce77..688ee71e263a 100644
--- a/drivers/gpu/drm/lima/lima_devfreq.h
+++ b/drivers/gpu/drm/lima/lima_devfreq.h
@@ -8,15 +8,12 @@
#include <linux/ktime.h>
struct devfreq;
-struct opp_table;
struct thermal_cooling_device;
struct lima_device;
struct lima_devfreq {
struct devfreq *devfreq;
- struct opp_table *clkname_opp_table;
- struct opp_table *regulators_opp_table;
struct thermal_cooling_device *cooling;
ktime_t busy_time;
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 56b3f5935703..c878391f3e8c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -89,29 +89,25 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
unsigned long cur_freq;
struct device *dev = &pfdev->pdev->dev;
struct devfreq *devfreq;
- struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
- opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
- pfdev->comp->num_supplies);
- if (IS_ERR(opp_table)) {
- ret = PTR_ERR(opp_table);
+ ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
+ pfdev->comp->num_supplies);
+ if (ret) {
/* Continue if the optional regulator is missing */
if (ret != -ENODEV) {
DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
- goto err_fini;
+ return ret;
}
- } else {
- pfdevfreq->regulators_opp_table = opp_table;
}
- ret = dev_pm_opp_of_add_table(dev);
+ ret = devm_pm_opp_of_add_table(dev);
if (ret) {
/* Optional, continue without devfreq */
if (ret == -ENODEV)
ret = 0;
- goto err_fini;
+ return ret;
}
pfdevfreq->opp_of_table_added = true;
@@ -122,10 +118,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
cur_freq = clk_get_rate(pfdev->clock);
opp = devfreq_recommended_opp(dev, &cur_freq, 0);
- if (IS_ERR(opp)) {
- ret = PTR_ERR(opp);
- goto err_fini;
- }
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
panfrost_devfreq_profile.initial_freq = cur_freq;
dev_pm_opp_put(opp);
@@ -134,8 +128,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
if (IS_ERR(devfreq)) {
DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
- ret = PTR_ERR(devfreq);
- goto err_fini;
+ return PTR_ERR(devfreq);
}
pfdevfreq->devfreq = devfreq;
@@ -146,10 +139,6 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
pfdevfreq->cooling = cooling;
return 0;
-
-err_fini:
- panfrost_devfreq_fini(pfdev);
- return ret;
}
void panfrost_devfreq_fini(struct panfrost_device *pfdev)
@@ -160,14 +149,6 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
devfreq_cooling_unregister(pfdevfreq->cooling);
pfdevfreq->cooling = NULL;
}
-
- if (pfdevfreq->opp_of_table_added) {
- dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
- pfdevfreq->opp_of_table_added = false;
- }
-
- dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table);
- pfdevfreq->regulators_opp_table = NULL;
}
void panfrost_devfreq_resume(struct panfrost_device *pfdev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index db6ea48e21f9..210269944687 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -8,14 +8,12 @@
#include <linux/ktime.h>
struct devfreq;
-struct opp_table;
struct thermal_cooling_device;
struct panfrost_device;
struct panfrost_devfreq {
struct devfreq *devfreq;
- struct opp_table *regulators_opp_table;
struct thermal_cooling_device *cooling;
bool opp_of_table_added;
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c
index 1dabb509dec3..56f6e65d40cd 100644
--- a/drivers/memory/samsung/exynos5422-dmc.c
+++ b/drivers/memory/samsung/exynos5422-dmc.c
@@ -343,7 +343,7 @@ static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
int idx;
unsigned long freq;
- ret = dev_pm_opp_of_add_table(dmc->dev);
+ ret = devm_pm_opp_of_add_table(dmc->dev);
if (ret < 0) {
dev_err(dmc->dev, "Failed to get OPP table\n");
return ret;
@@ -354,7 +354,7 @@ static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
dmc->opp = devm_kmalloc_array(dmc->dev, dmc->opp_count,
sizeof(struct dmc_opp_table), GFP_KERNEL);
if (!dmc->opp)
- goto err_opp;
+ return -ENOMEM;
idx = dmc->opp_count - 1;
for (i = 0, freq = ULONG_MAX; i < dmc->opp_count; i++, freq--) {
@@ -362,7 +362,7 @@ static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
opp = dev_pm_opp_find_freq_floor(dmc->dev, &freq);
if (IS_ERR(opp))
- goto err_opp;
+ return PTR_ERR(opp);
dmc->opp[idx - i].freq_hz = freq;
dmc->opp[idx - i].volt_uv = dev_pm_opp_get_voltage(opp);
@@ -371,11 +371,6 @@ static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
}
return 0;
-
-err_opp:
- dev_pm_opp_of_remove_table(dmc->dev);
-
- return -EINVAL;
}
/**
@@ -1567,8 +1562,6 @@ static int exynos5_dmc_remove(struct platform_device *pdev)
clk_disable_unprepare(dmc->mout_bpll);
clk_disable_unprepare(dmc->fout_bpll);
- dev_pm_opp_remove_table(dmc->dev);
-
return 0;
}
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 5e1da4df096f..d170c919e6e4 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -264,7 +264,6 @@ struct sdhci_msm_host {
struct clk_bulk_data bulk_clks[5];
unsigned long clk_rate;
struct mmc_host *mmc;
- struct opp_table *opp_table;
bool use_14lpp_dll_reset;
bool tuning_done;
bool calibration_done;
@@ -2551,17 +2550,15 @@ static int sdhci_msm_probe(struct platform_device *pdev)
if (ret)
goto bus_clk_disable;
- msm_host->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "core");
- if (IS_ERR(msm_host->opp_table)) {
- ret = PTR_ERR(msm_host->opp_table);
+ ret = devm_pm_opp_set_clkname(&pdev->dev, "core");
+ if (ret)
goto bus_clk_disable;
- }
/* OPP table is optional */
- ret = dev_pm_opp_of_add_table(&pdev->dev);
+ ret = devm_pm_opp_of_add_table(&pdev->dev);
if (ret && ret != -ENODEV) {
dev_err(&pdev->dev, "Invalid OPP table in Device tree\n");
- goto opp_put_clkname;
+ goto bus_clk_disable;
}
/* Vote for maximum clock rate for maximum performance */
@@ -2587,7 +2584,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
ret = clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks),
msm_host->bulk_clks);
if (ret)
- goto opp_cleanup;
+ goto bus_clk_disable;
/*
* xo clock is needed for FLL feature of cm_dll.
@@ -2732,10 +2729,6 @@ pm_runtime_disable:
clk_disable:
clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks),
msm_host->bulk_clks);
-opp_cleanup:
- dev_pm_opp_of_remove_table(&pdev->dev);
-opp_put_clkname:
- dev_pm_opp_put_clkname(msm_host->opp_table);
bus_clk_disable:
if (!IS_ERR(msm_host->bus_clk))
clk_disable_unprepare(msm_host->bus_clk);
@@ -2754,8 +2747,6 @@ static int sdhci_msm_remove(struct platform_device *pdev)
sdhci_remove_host(host, dead);
- dev_pm_opp_of_remove_table(&pdev->dev);
- dev_pm_opp_put_clkname(msm_host->opp_table);
pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 1556998425d5..e366218d6736 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1857,6 +1857,35 @@ void dev_pm_opp_put_supported_hw(struct opp_table *opp_table)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
+static void devm_pm_opp_supported_hw_release(void *data)
+{
+ dev_pm_opp_put_supported_hw(data);
+}
+
+/**
+ * devm_pm_opp_set_supported_hw() - Set supported platforms
+ * @dev: Device for which supported-hw has to be set.
+ * @versions: Array of hierarchy of versions to match.
+ * @count: Number of elements in the array.
+ *
+ * This is a resource-managed variant of dev_pm_opp_set_supported_hw().
+ *
+ * Return: 0 on success and errorno otherwise.
+ */
+int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
+ unsigned int count)
+{
+ struct opp_table *opp_table;
+
+ opp_table = dev_pm_opp_set_supported_hw(dev, versions, count);
+ if (IS_ERR(opp_table))
+ return PTR_ERR(opp_table);
+
+ return devm_add_action_or_reset(dev, devm_pm_opp_supported_hw_release,
+ opp_table);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_set_supported_hw);
+
/**
* dev_pm_opp_set_prop_name() - Set prop-extn name
* @dev: Device for which the prop-name has to be set.
@@ -2047,6 +2076,36 @@ put_opp_table:
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators);
+static void devm_pm_opp_regulators_release(void *data)
+{
+ dev_pm_opp_put_regulators(data);
+}
+
+/**
+ * devm_pm_opp_set_regulators() - Set regulator names for the device
+ * @dev: Device for which regulator name is being set.
+ * @names: Array of pointers to the names of the regulator.
+ * @count: Number of regulators.
+ *
+ * This is a resource-managed variant of dev_pm_opp_set_regulators().
+ *
+ * Return: 0 on success and errorno otherwise.
+ */
+int devm_pm_opp_set_regulators(struct device *dev,
+ const char * const names[],
+ unsigned int count)
+{
+ struct opp_table *opp_table;
+
+ opp_table = dev_pm_opp_set_regulators(dev, names, count);
+ if (IS_ERR(opp_table))
+ return PTR_ERR(opp_table);
+
+ return devm_add_action_or_reset(dev, devm_pm_opp_regulators_release,
+ opp_table);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_set_regulators);
+
/**
* dev_pm_opp_set_clkname() - Set clk name for the device
* @dev: Device for which clk name is being set.
@@ -2119,6 +2178,33 @@ void dev_pm_opp_put_clkname(struct opp_table *opp_table)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put_clkname);
+static void devm_pm_opp_clkname_release(void *data)
+{
+ dev_pm_opp_put_clkname(data);
+}
+
+/**
+ * devm_pm_opp_set_clkname() - Set clk name for the device
+ * @dev: Device for which clk name is being set.
+ * @name: Clk name.
+ *
+ * This is a resource-managed variant of dev_pm_opp_set_clkname().
+ *
+ * Return: 0 on success and errorno otherwise.
+ */
+int devm_pm_opp_set_clkname(struct device *dev, const char *name)
+{
+ struct opp_table *opp_table;
+
+ opp_table = dev_pm_opp_set_clkname(dev, name);
+ if (IS_ERR(opp_table))
+ return PTR_ERR(opp_table);
+
+ return devm_add_action_or_reset(dev, devm_pm_opp_clkname_release,
+ opp_table);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_set_clkname);
+
/**
* dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper
* @dev: Device for which the helper is getting registered.
@@ -2209,25 +2295,19 @@ static void devm_pm_opp_unregister_set_opp_helper(void *data)
*
* This is a resource-managed version of dev_pm_opp_register_set_opp_helper().
*
- * Return: pointer to 'struct opp_table' on success and errorno otherwise.
+ * Return: 0 on success and errorno otherwise.
*/
-struct opp_table *
-devm_pm_opp_register_set_opp_helper(struct device *dev,
- int (*set_opp)(struct dev_pm_set_opp_data *data))
+int devm_pm_opp_register_set_opp_helper(struct device *dev,
+ int (*set_opp)(struct dev_pm_set_opp_data *data))
{
struct opp_table *opp_table;
- int err;
opp_table = dev_pm_opp_register_set_opp_helper(dev, set_opp);
if (IS_ERR(opp_table))
- return opp_table;
-
- err = devm_add_action_or_reset(dev, devm_pm_opp_unregister_set_opp_helper,
- opp_table);
- if (err)
- return ERR_PTR(err);
+ return PTR_ERR(opp_table);
- return opp_table;
+ return devm_add_action_or_reset(dev, devm_pm_opp_unregister_set_opp_helper,
+ opp_table);
}
EXPORT_SYMBOL_GPL(devm_pm_opp_register_set_opp_helper);
@@ -2380,25 +2460,19 @@ static void devm_pm_opp_detach_genpd(void *data)
*
* This is a resource-managed version of dev_pm_opp_attach_genpd().
*
- * Return: pointer to 'struct opp_table' on success and errorno otherwise.
+ * Return: 0 on success and errorno otherwise.
*/
-struct opp_table *
-devm_pm_opp_attach_genpd(struct device *dev, const char **names,
- struct device ***virt_devs)
+int devm_pm_opp_attach_genpd(struct device *dev, const char **names,
+ struct device ***virt_devs)
{
struct opp_table *opp_table;
- int err;
opp_table = dev_pm_opp_attach_genpd(dev, names, virt_devs);
if (IS_ERR(opp_table))
- return opp_table;
-
- err = devm_add_action_or_reset(dev, devm_pm_opp_detach_genpd,
- opp_table);
- if (err)
- return ERR_PTR(err);
+ return PTR_ERR(opp_table);
- return opp_table;
+ return devm_add_action_or_reset(dev, devm_pm_opp_detach_genpd,
+ opp_table);
}
EXPORT_SYMBOL_GPL(devm_pm_opp_attach_genpd);
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index f480c10e6314..c582a9ca397b 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -1104,6 +1104,42 @@ static int _of_add_table_indexed(struct device *dev, int index, bool getclk)
return ret;
}
+static void devm_pm_opp_of_table_release(void *data)
+{
+ dev_pm_opp_of_remove_table(data);
+}
+
+/**
+ * devm_pm_opp_of_add_table() - Initialize opp table from device tree
+ * @dev: device pointer used to lookup OPP table.
+ *
+ * Register the initial OPP table with the OPP library for given device.
+ *
+ * The opp_table structure will be freed after the device is destroyed.
+ *
+ * Return:
+ * 0 On success OR
+ * Duplicate OPPs (both freq and volt are same) and opp->available
+ * -EEXIST Freq are same and volt are different OR
+ * Duplicate OPPs (both freq and volt are same) and !opp->available
+ * -ENOMEM Memory allocation failure
+ * -ENODEV when 'operating-points' property is not found or is invalid data
+ * in device node.
+ * -ENODATA when empty 'operating-points' property is found
+ * -EINVAL when invalid entries are found in opp-v2 table
+ */
+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);
+}
+EXPORT_SYMBOL_GPL(devm_pm_opp_of_add_table);
+
/**
* dev_pm_opp_of_add_table() - Initialize opp table from device tree
* @dev: device pointer used to lookup OPP table.
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 881f645661cc..3d0d8ddd5772 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -691,14 +691,15 @@ static int spi_geni_probe(struct platform_device *pdev)
mas->se.wrapper = dev_get_drvdata(dev->parent);
mas->se.base = base;
mas->se.clk = clk;
- mas->se.opp_table = dev_pm_opp_set_clkname(&pdev->dev, "se");
- if (IS_ERR(mas->se.opp_table))
- return PTR_ERR(mas->se.opp_table);
+
+ ret = devm_pm_opp_set_clkname(&pdev->dev, "se");
+ if (ret)
+ return ret;
/* OPP table is optional */
- ret = dev_pm_opp_of_add_table(&pdev->dev);
+ ret = devm_pm_opp_of_add_table(&pdev->dev);
if (ret && ret != -ENODEV) {
dev_err(&pdev->dev, "invalid OPP table in device tree\n");
- goto put_clkname;
+ return ret;
}
spi->bus_num = -1;
@@ -750,9 +751,6 @@ spi_geni_probe_free_irq:
free_irq(mas->irq, spi);
spi_geni_probe_runtime_disable:
pm_runtime_disable(dev);
- dev_pm_opp_of_remove_table(&pdev->dev);
-put_clkname:
- dev_pm_opp_put_clkname(mas->se.opp_table);
return ret;
}
@@ -766,8 +764,6 @@ static int spi_geni_remove(struct platform_device *pdev)
free_irq(mas->irq, spi);
pm_runtime_disable(&pdev->dev);
- dev_pm_opp_of_remove_table(&pdev->dev);
- dev_pm_opp_put_clkname(mas->se.opp_table);
return 0;
}
diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c
index 1dbcc410cd35..c334dfec4117 100644
--- a/drivers/spi/spi-qcom-qspi.c
+++ b/drivers/spi/spi-qcom-qspi.c
@@ -142,7 +142,6 @@ struct qcom_qspi {
struct clk_bulk_data *clks;
struct qspi_xfer xfer;
struct icc_path *icc_path_cpu_to_qspi;
- struct opp_table *opp_table;
unsigned long last_speed;
/* Lock to protect data accessed by IRQs */
spinlock_t lock;
@@ -530,14 +529,14 @@ static int qcom_qspi_probe(struct platform_device *pdev)
master->handle_err = qcom_qspi_handle_err;
master->auto_runtime_pm = true;
- ctrl->opp_table = dev_pm_opp_set_clkname(&pdev->dev, "core");
- if (IS_ERR(ctrl->opp_table))
- return PTR_ERR(ctrl->opp_table);
+ ret = devm_pm_opp_set_clkname(&pdev->dev, "core");
+ if (ret)
+ return ret;
/* OPP table is optional */
- ret = dev_pm_opp_of_add_table(&pdev->dev);
+ ret = devm_pm_opp_of_add_table(&pdev->dev);
if (ret && ret != -ENODEV) {
dev_err(&pdev->dev, "invalid OPP table in device tree\n");
- goto exit_probe_put_clkname;
+ return ret;
}
pm_runtime_use_autosuspend(dev);
@@ -549,10 +548,6 @@ static int qcom_qspi_probe(struct platform_device *pdev)
return 0;
pm_runtime_disable(dev);
- dev_pm_opp_of_remove_table(&pdev->dev);
-
-exit_probe_put_clkname:
- dev_pm_opp_put_clkname(ctrl->opp_table);
return ret;
}
@@ -560,14 +555,11 @@ exit_probe_put_clkname:
static int qcom_qspi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
- struct qcom_qspi *ctrl = spi_master_get_devdata(master);
/* Unregister _before_ disabling pm_runtime() so we stop transfers */
spi_unregister_master(master);
pm_runtime_disable(&pdev->dev);
- dev_pm_opp_of_remove_table(&pdev->dev);
- dev_pm_opp_put_clkname(ctrl->opp_table);
return 0;
}
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 0d85b55ea823..99375d99f6fa 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1426,14 +1426,14 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (of_property_read_bool(pdev->dev.of_node, "cts-rts-swap"))
port->cts_rts_swap = true;
- port->se.opp_table = dev_pm_opp_set_clkname(&pdev->dev, "se");
- if (IS_ERR(port->se.opp_table))
- return PTR_ERR(port->se.opp_table);
+ ret = devm_pm_opp_set_clkname(&pdev->dev, "se");
+ if (ret)
+ return ret;
/* OPP table is optional */
- ret = dev_pm_opp_of_add_table(&pdev->dev);
+ ret = devm_pm_opp_of_add_table(&pdev->dev);
if (ret && ret != -ENODEV) {
dev_err(&pdev->dev, "invalid OPP table in device tree\n");
- goto put_clkname;
+ return ret;
}
port->private_data.drv = drv;
@@ -1443,7 +1443,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
ret = uart_add_one_port(drv, uport);
if (ret)
- goto err;
+ return ret;
irq_set_status_flags(uport->irq, IRQ_NOAUTOEN);
ret = devm_request_irq(uport->dev, uport->irq, qcom_geni_serial_isr,
@@ -1451,7 +1451,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
uart_remove_one_port(drv, uport);
- goto err;
+ return ret;
}
/*
@@ -1468,16 +1468,11 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
if (ret) {
device_init_wakeup(&pdev->dev, false);
uart_remove_one_port(drv, uport);
- goto err;
+ return ret;
}
}
return 0;
-err:
- dev_pm_opp_of_remove_table(&pdev->dev);
-put_clkname:
- dev_pm_opp_put_clkname(port->se.opp_table);
- return ret;
}
static int qcom_geni_serial_remove(struct platform_device *pdev)
@@ -1485,8 +1480,6 @@ static int qcom_geni_serial_remove(struct platform_device *pdev)
struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
struct uart_driver *drv = port->private_data.drv;
- dev_pm_opp_of_remove_table(&pdev->dev);
- dev_pm_opp_put_clkname(port->se.opp_table);
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
uart_remove_one_port(drv, &port->uport);
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index c0371efa4a0f..84150a22fd7c 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -144,18 +144,21 @@ int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb
struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
void dev_pm_opp_put_supported_hw(struct opp_table *opp_table);
+int devm_pm_opp_set_supported_hw(struct device *dev, const u32 *versions, unsigned int count);
struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name);
void dev_pm_opp_put_prop_name(struct opp_table *opp_table);
struct opp_table *dev_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
void dev_pm_opp_put_regulators(struct opp_table *opp_table);
+int devm_pm_opp_set_regulators(struct device *dev, const char * const names[], unsigned int count);
struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name);
void dev_pm_opp_put_clkname(struct opp_table *opp_table);
+int devm_pm_opp_set_clkname(struct device *dev, const char *name);
struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
-struct opp_table *devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
+int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
-struct opp_table *devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
+int devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp);
int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
@@ -319,6 +322,13 @@ static inline struct opp_table *dev_pm_opp_set_supported_hw(struct device *dev,
static inline void dev_pm_opp_put_supported_hw(struct opp_table *opp_table) {}
+static inline int devm_pm_opp_set_supported_hw(struct device *dev,
+ const u32 *versions,
+ unsigned int count)
+{
+ return -EOPNOTSUPP;
+}
+
static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev,
int (*set_opp)(struct dev_pm_set_opp_data *data))
{
@@ -327,11 +337,10 @@ static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device
static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
-static inline struct opp_table *
-devm_pm_opp_register_set_opp_helper(struct device *dev,
+static inline int devm_pm_opp_register_set_opp_helper(struct device *dev,
int (*set_opp)(struct dev_pm_set_opp_data *data))
{
- return ERR_PTR(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
}
static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
@@ -348,6 +357,13 @@ static inline struct opp_table *dev_pm_opp_set_regulators(struct device *dev, co
static inline void dev_pm_opp_put_regulators(struct opp_table *opp_table) {}
+static inline int devm_pm_opp_set_regulators(struct device *dev,
+ const char * const names[],
+ unsigned int count)
+{
+ return -EOPNOTSUPP;
+}
+
static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name)
{
return ERR_PTR(-EOPNOTSUPP);
@@ -355,6 +371,11 @@ static inline struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const
static inline void dev_pm_opp_put_clkname(struct opp_table *opp_table) {}
+static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name)
+{
+ return -EOPNOTSUPP;
+}
+
static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs)
{
return ERR_PTR(-EOPNOTSUPP);
@@ -362,10 +383,11 @@ static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, cons
static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
-static inline struct opp_table *devm_pm_opp_attach_genpd(struct device *dev,
- const char **names, struct device ***virt_devs)
+static inline int devm_pm_opp_attach_genpd(struct device *dev,
+ const char **names,
+ struct device ***virt_devs)
{
- return ERR_PTR(-EOPNOTSUPP);
+ return -EOPNOTSUPP;
}
static inline struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table,
@@ -419,6 +441,7 @@ int dev_pm_opp_of_add_table(struct device *dev);
int dev_pm_opp_of_add_table_indexed(struct device *dev, int index);
int dev_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);
void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask);
int dev_pm_opp_of_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
@@ -451,6 +474,11 @@ static inline void dev_pm_opp_of_remove_table(struct device *dev)
{
}
+static inline int devm_pm_opp_of_add_table(struct device *dev)
+{
+ return -EOPNOTSUPP;
+}
+
static inline int dev_pm_opp_of_cpumask_add_table(const struct cpumask *cpumask)
{
return -EOPNOTSUPP;
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index c4fdb4463f7d..7c811eebcaab 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -47,7 +47,6 @@ struct geni_icc_path {
* @num_clk_levels: Number of valid clock levels in clk_perf_tbl
* @clk_perf_tbl: Table of clock frequency input to serial engine clock
* @icc_paths: Array of ICC paths for SE
- * @opp_table: Pointer to the OPP table
*/
struct geni_se {
void __iomem *base;
@@ -57,7 +56,6 @@ struct geni_se {
unsigned int num_clk_levels;
unsigned long *clk_perf_tbl;
struct geni_icc_path icc_paths[3];
- struct opp_table *opp_table;
};
/* Common SE registers */