diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2016-04-26 23:22:23 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-04-28 09:18:18 -0400 |
commit | 6f707daa3833761110a03478cba5cc4b708ec77d (patch) | |
tree | c01c90b01dd8a481283586b2738ac79a95322b27 | |
parent | dde370b23c1787a9c723ac049d56a3014937f889 (diff) |
PM / OPP: Add dev_pm_opp_get_sharing_cpus()
OPP core allows a platform to mark OPP table as shared, when the
platform isn't using operating-points-v2 bindings.
And, so there should be a non DT way of finding out if the OPP table is
shared or not.
This patch adds dev_pm_opp_get_sharing_cpus(), which first tries to get
OPP sharing information from the opp-table (in case it is already marked
as shared), otherwise it uses the existing DT way of finding sharing
information.
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/base/power/opp/cpu.c | 45 | ||||
-rw-r--r-- | include/linux/pm_opp.h | 6 |
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 | } |
332 | EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); | 332 | EXPORT_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 | */ | ||
349 | int 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 | |||
372 | unlock: | ||
373 | mutex_unlock(&opp_table_lock); | ||
374 | |||
375 | return ret; | ||
376 | } | ||
377 | EXPORT_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); | |||
66 | void dev_pm_opp_put_regulator(struct device *dev); | 66 | void dev_pm_opp_put_regulator(struct device *dev); |
67 | int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); | 67 | int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); |
68 | int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const cpumask_var_t cpumask); | 68 | int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const cpumask_var_t cpumask); |
69 | int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, cpumask_var_t cpumask); | ||
69 | #else | 70 | #else |
70 | static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) | 71 | static 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 | ||
188 | static 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) |