Skip to content

Commit

Permalink
PM / EM: update callback structure and add device pointer
Browse files Browse the repository at this point in the history
The Energy Model framework is going to support devices other that CPUs. In
order to make this happen change the callback function and add pointer to
a device as an argument.

Update the related users to use new function and new callback from the
Energy Model.

Acked-by: Quentin Perret <qperret@google.com>
Signed-off-by: Lukasz Luba <lukasz.luba@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Lukasz Luba authored and Rafael J. Wysocki committed Jun 24, 2020
1 parent 7d9895c commit d0351cc
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 26 deletions.
11 changes: 3 additions & 8 deletions drivers/cpufreq/scmi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,12 @@ scmi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
}

static int __maybe_unused
scmi_get_cpu_power(unsigned long *power, unsigned long *KHz, int cpu)
scmi_get_cpu_power(unsigned long *power, unsigned long *KHz,
struct device *cpu_dev)
{
struct device *cpu_dev = get_cpu_device(cpu);
unsigned long Hz;
int ret, domain;

if (!cpu_dev) {
pr_err("failed to get cpu%d device\n", cpu);
return -ENODEV;
}

domain = handle->perf_ops->device_domain_id(cpu_dev);
if (domain < 0)
return domain;
Expand Down Expand Up @@ -200,7 +195,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)

policy->fast_switch_possible = true;

em_register_perf_domain(policy->cpus, nr_opp, &em_cb);
em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, policy->cpus);

return 0;

Expand Down
9 changes: 2 additions & 7 deletions drivers/opp/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -1216,20 +1216,15 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);
* calculation failed because of missing parameters, 0 otherwise.
*/
static int __maybe_unused _get_cpu_power(unsigned long *mW, unsigned long *kHz,
int cpu)
struct device *cpu_dev)
{
struct device *cpu_dev;
struct dev_pm_opp *opp;
struct device_node *np;
unsigned long mV, Hz;
u32 cap;
u64 tmp;
int ret;

cpu_dev = get_cpu_device(cpu);
if (!cpu_dev)
return -ENODEV;

np = of_node_get(cpu_dev->of_node);
if (!np)
return -EINVAL;
Expand Down Expand Up @@ -1297,6 +1292,6 @@ void dev_pm_opp_of_register_em(struct cpumask *cpus)
if (ret || !cap)
return;

em_register_perf_domain(cpus, nr_opp, &em_cb);
em_dev_register_perf_domain(cpu_dev, nr_opp, &em_cb, cpus);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_register_em);
15 changes: 8 additions & 7 deletions include/linux/energy_model.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,25 @@ struct em_perf_domain {
struct em_data_callback {
/**
* active_power() - Provide power at the next performance state of
* a CPU
* a device
* @power : Active power at the performance state in mW
* (modified)
* @freq : Frequency at the performance state in kHz
* (modified)
* @cpu : CPU for which we do this operation
* @dev : Device for which we do this operation (can be a CPU)
*
* active_power() must find the lowest performance state of 'cpu' above
* active_power() must find the lowest performance state of 'dev' above
* 'freq' and update 'power' and 'freq' to the matching active power
* and frequency.
*
* The power is the one of a single CPU in the domain, expressed in
* milli-watts. It is expected to fit in the [0, EM_MAX_POWER]
* range.
* In case of CPUs, the power is the one of a single CPU in the domain,
* expressed in milli-watts. It is expected to fit in the
* [0, EM_MAX_POWER] range.
*
* Return 0 on success.
*/
int (*active_power)(unsigned long *power, unsigned long *freq, int cpu);
int (*active_power)(unsigned long *power, unsigned long *freq,
struct device *dev);
};
#define EM_DATA_CB(_active_power_cb) { .active_power = &_active_power_cb }

Expand Down
9 changes: 5 additions & 4 deletions kernel/power/energy_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ core_initcall(em_debug_init);
#else /* CONFIG_DEBUG_FS */
static void em_debug_create_pd(struct em_perf_domain *pd, int cpu) {}
#endif
static struct em_perf_domain *em_create_pd(cpumask_t *span, int nr_states,
struct em_data_callback *cb)
static struct em_perf_domain *
em_create_pd(struct device *dev, int nr_states, struct em_data_callback *cb,
cpumask_t *span)
{
unsigned long opp_eff, prev_opp_eff = ULONG_MAX;
unsigned long power, freq, prev_freq = 0;
Expand All @@ -106,7 +107,7 @@ static struct em_perf_domain *em_create_pd(cpumask_t *span, int nr_states,
* lowest performance state of 'cpu' above 'freq' and updates
* 'power' and 'freq' accordingly.
*/
ret = cb->active_power(&power, &freq, cpu);
ret = cb->active_power(&power, &freq, dev);
if (ret) {
pr_err("pd%d: invalid perf. state: %d\n", cpu, ret);
goto free_ps_table;
Expand Down Expand Up @@ -237,7 +238,7 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states,
}

/* Create the performance domain and add it to the Energy Model. */
pd = em_create_pd(span, nr_states, cb);
pd = em_create_pd(dev, nr_states, cb, span);
if (!pd) {
ret = -EINVAL;
goto unlock;
Expand Down

0 comments on commit d0351cc

Please sign in to comment.