Skip to content

Commit

Permalink
Merge branches 'pm-cpuidle', 'pm-cpufreq' and 'pm-sleep'
Browse files Browse the repository at this point in the history
* pm-cpuidle:
  doc: trace: fix reference to cpuidle documentation file
  cpuidle / Documentation: Update cpuidle MAINTAINERS entry

* pm-cpufreq:
  cpufreq: scmi: Fix frequency invariance in slow path
  cpufreq: check if policy is inactive early in __cpufreq_get()
  cpufreq: scpi/scmi: Fix freeing of dynamic OPPs
  cpufreq / Documentation: Update cpufreq MAINTAINERS entry

* pm-sleep:
  PM: sleep: call devfreq suspend/resume
  • Loading branch information
rafaeljw committed Jan 11, 2019
4 parents ca27e4c + 7604bf0 + 0e141d1 + 6e86384 commit 343e60e
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Documentation/trace/coresight-cpu-debug.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ Do some work...
The same can also be done from an application program.

Disable specific CPU's specific idle state from cpuidle sysfs (see
Documentation/cpuidle/sysfs.txt):
Documentation/admin-guide/pm/cpuidle.rst):
# echo 1 > /sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable


Expand Down
7 changes: 5 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3951,14 +3951,16 @@ L: [email protected]
S: Maintained
F: drivers/net/ethernet/ti/cpmac.c

CPU FREQUENCY DRIVERS
CPU FREQUENCY SCALING FRAMEWORK
M: "Rafael J. Wysocki" <[email protected]>
M: Viresh Kumar <[email protected]>
L: [email protected]
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
T: git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
B: https://bugzilla.kernel.org
F: Documentation/admin-guide/pm/cpufreq.rst
F: Documentation/admin-guide/pm/intel_pstate.rst
F: Documentation/cpu-freq/
F: Documentation/devicetree/bindings/cpufreq/
F: drivers/cpufreq/
Expand Down Expand Up @@ -4006,13 +4008,14 @@ S: Supported
F: drivers/cpuidle/cpuidle-exynos.c
F: arch/arm/mach-exynos/pm.c

CPUIDLE DRIVERS
CPU IDLE TIME MANAGEMENT FRAMEWORK
M: "Rafael J. Wysocki" <[email protected]>
M: Daniel Lezcano <[email protected]>
L: [email protected]
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
B: https://bugzilla.kernel.org
F: Documentation/admin-guide/pm/cpuidle.rst
F: drivers/cpuidle/*
F: include/linux/cpuidle.h

Expand Down
3 changes: 3 additions & 0 deletions drivers/base/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <trace/events/power.h>
#include <linux/cpufreq.h>
#include <linux/cpuidle.h>
#include <linux/devfreq.h>
#include <linux/timer.h>

#include "../base.h"
Expand Down Expand Up @@ -1078,6 +1079,7 @@ void dpm_resume(pm_message_t state)
dpm_show_time(starttime, state, 0, NULL);

cpufreq_resume();
devfreq_resume();
trace_suspend_resume(TPS("dpm_resume"), state.event, false);
}

Expand Down Expand Up @@ -1852,6 +1854,7 @@ int dpm_suspend(pm_message_t state)
trace_suspend_resume(TPS("dpm_suspend"), state.event, true);
might_sleep();

devfreq_suspend();
cpufreq_suspend();

mutex_lock(&dpm_list_mtx);
Expand Down
12 changes: 4 additions & 8 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1530,17 +1530,16 @@ static unsigned int __cpufreq_get(struct cpufreq_policy *policy)
{
unsigned int ret_freq = 0;

if (!cpufreq_driver->get)
if (unlikely(policy_is_inactive(policy)) || !cpufreq_driver->get)
return ret_freq;

ret_freq = cpufreq_driver->get(policy->cpu);

/*
* Updating inactive policies is invalid, so avoid doing that. Also
* if fast frequency switching is used with the given policy, the check
* If fast frequency switching is used with the given policy, the check
* against policy->cur is pointless, so skip it in that case too.
*/
if (unlikely(policy_is_inactive(policy)) || policy->fast_switch_enabled)
if (policy->fast_switch_enabled)
return ret_freq;

if (ret_freq && policy->cur &&
Expand Down Expand Up @@ -1569,10 +1568,7 @@ unsigned int cpufreq_get(unsigned int cpu)

if (policy) {
down_read(&policy->rwsem);

if (!policy_is_inactive(policy))
ret_freq = __cpufreq_get(policy);

ret_freq = __cpufreq_get(policy);
up_read(&policy->rwsem);

cpufreq_cpu_put(policy);
Expand Down
8 changes: 4 additions & 4 deletions drivers/cpufreq/scmi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ scmi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index)
int ret;
struct scmi_data *priv = policy->driver_data;
struct scmi_perf_ops *perf_ops = handle->perf_ops;
u64 freq = policy->freq_table[index].frequency * 1000;
u64 freq = policy->freq_table[index].frequency;

ret = perf_ops->freq_set(handle, priv->domain_id, freq, false);
ret = perf_ops->freq_set(handle, priv->domain_id, freq * 1000, false);
if (!ret)
arch_set_freq_scale(policy->related_cpus, freq,
policy->cpuinfo.max_freq);
Expand Down Expand Up @@ -176,7 +176,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
out_free_priv:
kfree(priv);
out_free_opp:
dev_pm_opp_cpumask_remove_table(policy->cpus);
dev_pm_opp_remove_all_dynamic(cpu_dev);

return ret;
}
Expand All @@ -188,7 +188,7 @@ static int scmi_cpufreq_exit(struct cpufreq_policy *policy)
cpufreq_cooling_unregister(priv->cdev);
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
kfree(priv);
dev_pm_opp_cpumask_remove_table(policy->related_cpus);
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);

return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/cpufreq/scpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy)
out_free_priv:
kfree(priv);
out_free_opp:
dev_pm_opp_cpumask_remove_table(policy->cpus);
dev_pm_opp_remove_all_dynamic(cpu_dev);

return ret;
}
Expand All @@ -190,7 +190,7 @@ static int scpi_cpufreq_exit(struct cpufreq_policy *policy)
clk_put(priv->clk);
dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
kfree(priv);
dev_pm_opp_cpumask_remove_table(policy->related_cpus);
dev_pm_opp_remove_all_dynamic(priv->cpu_dev);

return 0;
}
Expand Down
63 changes: 58 additions & 5 deletions drivers/opp/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -988,11 +988,9 @@ void _opp_free(struct dev_pm_opp *opp)
kfree(opp);
}

static void _opp_kref_release(struct kref *kref)
static void _opp_kref_release(struct dev_pm_opp *opp,
struct opp_table *opp_table)
{
struct dev_pm_opp *opp = container_of(kref, struct dev_pm_opp, kref);
struct opp_table *opp_table = opp->opp_table;

/*
* Notify the changes in the availability of the operable
* frequency/voltage list.
Expand All @@ -1002,7 +1000,22 @@ static void _opp_kref_release(struct kref *kref)
opp_debug_remove_one(opp);
list_del(&opp->node);
kfree(opp);
}

static void _opp_kref_release_unlocked(struct kref *kref)
{
struct dev_pm_opp *opp = container_of(kref, struct dev_pm_opp, kref);
struct opp_table *opp_table = opp->opp_table;

_opp_kref_release(opp, opp_table);
}

static void _opp_kref_release_locked(struct kref *kref)
{
struct dev_pm_opp *opp = container_of(kref, struct dev_pm_opp, kref);
struct opp_table *opp_table = opp->opp_table;

_opp_kref_release(opp, opp_table);
mutex_unlock(&opp_table->lock);
}

Expand All @@ -1013,10 +1026,16 @@ void dev_pm_opp_get(struct dev_pm_opp *opp)

void dev_pm_opp_put(struct dev_pm_opp *opp)
{
kref_put_mutex(&opp->kref, _opp_kref_release, &opp->opp_table->lock);
kref_put_mutex(&opp->kref, _opp_kref_release_locked,
&opp->opp_table->lock);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_put);

static void dev_pm_opp_put_unlocked(struct dev_pm_opp *opp)
{
kref_put(&opp->kref, _opp_kref_release_unlocked);
}

/**
* dev_pm_opp_remove() - Remove an OPP from OPP table
* @dev: device for which we do this operation
Expand Down Expand Up @@ -1060,6 +1079,40 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq)
}
EXPORT_SYMBOL_GPL(dev_pm_opp_remove);

/**
* dev_pm_opp_remove_all_dynamic() - Remove all dynamically created OPPs
* @dev: device for which we do this operation
*
* This function removes all dynamically created OPPs from the opp table.
*/
void dev_pm_opp_remove_all_dynamic(struct device *dev)
{
struct opp_table *opp_table;
struct dev_pm_opp *opp, *temp;
int count = 0;

opp_table = _find_opp_table(dev);
if (IS_ERR(opp_table))
return;

mutex_lock(&opp_table->lock);
list_for_each_entry_safe(opp, temp, &opp_table->opp_list, node) {
if (opp->dynamic) {
dev_pm_opp_put_unlocked(opp);
count++;
}
}
mutex_unlock(&opp_table->lock);

/* Drop the references taken by dev_pm_opp_add() */
while (count--)
dev_pm_opp_put_opp_table(opp_table);

/* Drop the reference taken by _find_opp_table() */
dev_pm_opp_put_opp_table(opp_table);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_remove_all_dynamic);

struct dev_pm_opp *_opp_allocate(struct opp_table *table)
{
struct dev_pm_opp *opp;
Expand Down
5 changes: 5 additions & 0 deletions include/linux/pm_opp.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ void dev_pm_opp_put(struct dev_pm_opp *opp);
int dev_pm_opp_add(struct device *dev, unsigned long freq,
unsigned long u_volt);
void dev_pm_opp_remove(struct device *dev, unsigned long freq);
void dev_pm_opp_remove_all_dynamic(struct device *dev);

int dev_pm_opp_enable(struct device *dev, unsigned long freq);

Expand Down Expand Up @@ -217,6 +218,10 @@ static inline void dev_pm_opp_remove(struct device *dev, unsigned long freq)
{
}

static inline void dev_pm_opp_remove_all_dynamic(struct device *dev)
{
}

static inline int dev_pm_opp_enable(struct device *dev, unsigned long freq)
{
return 0;
Expand Down

0 comments on commit 343e60e

Please sign in to comment.