mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 02:32:09 -04:00
PM / OPP: Update OPP users to put reference
This patch updates dev_pm_opp_find_freq_*() routines to get a reference
to the OPPs returned by them.
Also updates the users of dev_pm_opp_find_freq_*() routines to call
dev_pm_opp_put() after they are done using the OPPs.
As it is guaranteed the that OPPs wouldn't get freed while being used,
the RCU read side locking present with the users isn't required anymore.
Drop it as well.
This patch also updates all users of devfreq_recommended_opp() which was
returning an OPP received from the OPP core.
Note that some of the OPP core routines have gained
rcu_read_{lock|unlock}() calls, as those still use RCU specific APIs
within them.
Signed-off-by: Viresh Kumar <[email protected]>
Reviewed-by: Chanwoo Choi <[email protected]> [Devfreq]
Signed-off-by: Rafael J. Wysocki <[email protected]>
This commit is contained in:
parent
7034764a1e
commit
8a31d9d942
15 changed files with 110 additions and 153 deletions
|
|
@ -111,18 +111,16 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
|
|||
return;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0, freq = 0; i < profile->max_state; i++, freq++) {
|
||||
opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq);
|
||||
if (IS_ERR(opp)) {
|
||||
devm_kfree(devfreq->dev.parent, profile->freq_table);
|
||||
profile->max_state = 0;
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
dev_pm_opp_put(opp);
|
||||
profile->freq_table[i] = freq;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1112,17 +1110,16 @@ static ssize_t available_frequencies_show(struct device *d,
|
|||
ssize_t count = 0;
|
||||
unsigned long freq = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
do {
|
||||
opp = dev_pm_opp_find_freq_ceil(dev, &freq);
|
||||
if (IS_ERR(opp))
|
||||
break;
|
||||
|
||||
dev_pm_opp_put(opp);
|
||||
count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
|
||||
"%lu ", freq);
|
||||
freq++;
|
||||
} while (1);
|
||||
rcu_read_unlock();
|
||||
|
||||
/* Truncate the trailing space */
|
||||
if (count)
|
||||
|
|
@ -1224,11 +1221,8 @@ subsys_initcall(devfreq_init);
|
|||
* @freq: The frequency given to target function
|
||||
* @flags: Flags handed from devfreq framework.
|
||||
*
|
||||
* Locking: This function must be called under rcu_read_lock(). opp is a rcu
|
||||
* protected pointer. The reason for the same is that the opp pointer which is
|
||||
* returned will remain valid for use with opp_get_{voltage, freq} only while
|
||||
* under the locked area. The pointer returned must be used prior to unlocking
|
||||
* with rcu_read_unlock() to maintain the integrity of the pointer.
|
||||
* The callers are required to call dev_pm_opp_put() for the returned OPP after
|
||||
* use.
|
||||
*/
|
||||
struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
|
||||
unsigned long *freq,
|
||||
|
|
|
|||
|
|
@ -103,18 +103,17 @@ static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags)
|
|||
int ret = 0;
|
||||
|
||||
/* Get new opp-bus instance according to new bus clock */
|
||||
rcu_read_lock();
|
||||
new_opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
if (IS_ERR(new_opp)) {
|
||||
dev_err(dev, "failed to get recommended opp instance\n");
|
||||
rcu_read_unlock();
|
||||
return PTR_ERR(new_opp);
|
||||
}
|
||||
|
||||
new_freq = dev_pm_opp_get_freq(new_opp);
|
||||
new_volt = dev_pm_opp_get_voltage(new_opp);
|
||||
dev_pm_opp_put(new_opp);
|
||||
|
||||
old_freq = bus->curr_freq;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (old_freq == new_freq)
|
||||
return 0;
|
||||
|
|
@ -214,17 +213,16 @@ static int exynos_bus_passive_target(struct device *dev, unsigned long *freq,
|
|||
int ret = 0;
|
||||
|
||||
/* Get new opp-bus instance according to new bus clock */
|
||||
rcu_read_lock();
|
||||
new_opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
if (IS_ERR(new_opp)) {
|
||||
dev_err(dev, "failed to get recommended opp instance\n");
|
||||
rcu_read_unlock();
|
||||
return PTR_ERR(new_opp);
|
||||
}
|
||||
|
||||
new_freq = dev_pm_opp_get_freq(new_opp);
|
||||
dev_pm_opp_put(new_opp);
|
||||
|
||||
old_freq = bus->curr_freq;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (old_freq == new_freq)
|
||||
return 0;
|
||||
|
|
@ -358,16 +356,14 @@ static int exynos_bus_parse_of(struct device_node *np,
|
|||
|
||||
rate = clk_get_rate(bus->clk);
|
||||
|
||||
rcu_read_lock();
|
||||
opp = devfreq_recommended_opp(dev, &rate, 0);
|
||||
if (IS_ERR(opp)) {
|
||||
dev_err(dev, "failed to find dev_pm_opp\n");
|
||||
rcu_read_unlock();
|
||||
ret = PTR_ERR(opp);
|
||||
goto err_opp;
|
||||
}
|
||||
bus->curr_freq = dev_pm_opp_get_freq(opp);
|
||||
rcu_read_unlock();
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -59,14 +59,14 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq,
|
|||
* list of parent device. Because in this case, *freq is temporary
|
||||
* value which is decided by ondemand governor.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
opp = devfreq_recommended_opp(parent_devfreq->dev.parent, freq, 0);
|
||||
rcu_read_unlock();
|
||||
if (IS_ERR(opp)) {
|
||||
ret = PTR_ERR(opp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
/*
|
||||
* Get the OPP table's index of decided freqeuncy by governor
|
||||
* of parent device.
|
||||
|
|
|
|||
|
|
@ -91,17 +91,13 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
|
|||
unsigned long target_volt, target_rate;
|
||||
int err;
|
||||
|
||||
rcu_read_lock();
|
||||
opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
if (IS_ERR(opp)) {
|
||||
rcu_read_unlock();
|
||||
if (IS_ERR(opp))
|
||||
return PTR_ERR(opp);
|
||||
}
|
||||
|
||||
target_rate = dev_pm_opp_get_freq(opp);
|
||||
target_volt = dev_pm_opp_get_voltage(opp);
|
||||
|
||||
rcu_read_unlock();
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
if (dmcfreq->rate == target_rate)
|
||||
return 0;
|
||||
|
|
@ -422,15 +418,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
|
|||
|
||||
data->rate = clk_get_rate(data->dmc_clk);
|
||||
|
||||
rcu_read_lock();
|
||||
opp = devfreq_recommended_opp(dev, &data->rate, 0);
|
||||
if (IS_ERR(opp)) {
|
||||
rcu_read_unlock();
|
||||
if (IS_ERR(opp))
|
||||
return PTR_ERR(opp);
|
||||
}
|
||||
|
||||
data->rate = dev_pm_opp_get_freq(opp);
|
||||
data->volt = dev_pm_opp_get_voltage(opp);
|
||||
rcu_read_unlock();
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
rk3399_devfreq_dmc_profile.initial_freq = data->rate;
|
||||
|
||||
|
|
|
|||
|
|
@ -487,15 +487,13 @@ static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
|
|||
struct dev_pm_opp *opp;
|
||||
unsigned long rate = *freq * KHZ;
|
||||
|
||||
rcu_read_lock();
|
||||
opp = devfreq_recommended_opp(dev, &rate, flags);
|
||||
if (IS_ERR(opp)) {
|
||||
rcu_read_unlock();
|
||||
dev_err(dev, "Failed to find opp for %lu KHz\n", *freq);
|
||||
return PTR_ERR(opp);
|
||||
}
|
||||
rate = dev_pm_opp_get_freq(opp);
|
||||
rcu_read_unlock();
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
clk_set_min_rate(tegra->emc_clock, rate);
|
||||
clk_set_rate(tegra->emc_clock, 0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue