aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/power/opp/cpu.c45
-rw-r--r--include/linux/pm_opp.h6
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/base/power/opp/cpu.c b/drivers/base/power/opp/cpu.c
index 5469e7730ff2..3428380dfca7 100644
--- a/drivers/base/power/opp/cpu.c
+++ b/drivers/base/power/opp/cpu.c
@@ -330,3 +330,48 @@ unlock:
330 return ret; 330 return ret;
331} 331}
332EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); 332EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);
333
334/**
335 * dev_pm_opp_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with @cpu_dev
336 * @cpu_dev: CPU device for which we do this operation
337 * @cpumask: cpumask to update with information of sharing CPUs
338 *
339 * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
340 *
341 * Returns -ENODEV if OPP table isn't already present.
342 *
343 * Locking: The internal opp_table and opp structures are RCU protected.
344 * Hence this function internally uses RCU updater strategy with mutex locks
345 * to keep the integrity of the internal data structures. Callers should ensure
346 * that this function is *NOT* called under RCU protection or in contexts where
347 * mutex cannot be locked.
348 */
349int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
350{
351 struct opp_device *opp_dev;
352 struct opp_table *opp_table;
353 int ret = 0;
354
355 mutex_lock(&opp_table_lock);
356
357 opp_table = _find_opp_table(cpu_dev);
358 if (IS_ERR(opp_table)) {
359 ret = PTR_ERR(opp_table);
360 goto unlock;
361 }
362
363 cpumask_clear(cpumask);
364
365 if (opp_table->shared_opp) {
366 list_for_each_entry(opp_dev, &opp_table->dev_list, node)
367 cpumask_set_cpu(opp_dev->dev->id, cpumask);
368 } else {
369 cpumask_set_cpu(cpu_dev->id, cpumask);
370 }
371
372unlock:
373 mutex_unlock(&opp_table_lock);
374
375 return ret;
376}
377EXPORT_SYMBOL_GPL(dev_pm_opp_get_sharing_cpus);
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 0c08ed3836b1..15f554443b59 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -66,6 +66,7 @@ int dev_pm_opp_set_regulator(struct device *dev, const char *name);
66void dev_pm_opp_put_regulator(struct device *dev); 66void dev_pm_opp_put_regulator(struct device *dev);
67int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); 67int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
68int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const cpumask_var_t cpumask); 68int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const cpumask_var_t cpumask);
69int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask);
69#else 70#else
70static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) 71static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
71{ 72{
@@ -184,6 +185,11 @@ static inline int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const cpum
184 return -ENOTSUPP; 185 return -ENOTSUPP;
185} 186}
186 187
188static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask)
189{
190 return -EINVAL;
191}
192
187#endif /* CONFIG_PM_OPP */ 193#endif /* CONFIG_PM_OPP */
188 194
189#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) 195#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)