mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 07:01:32 +00:00
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
This commit is contained in:
commit
eed7a17508
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
return PTR_ERR(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 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;
|
||||
return PTR_ERR(opp_table);
|
||||
|
||||
err = devm_add_action_or_reset(dev, devm_pm_opp_detach_genpd,
|
||||
opp_table);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user