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:
Rafael J. Wysocki 2021-04-12 14:49:31 +02:00
commit eed7a17508
13 changed files with 217 additions and 165 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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 */