d2912cb15bdda drivers/opp/cpu.c (Thomas Gleixner 2019-06-04 10:11:33 +0200 1) // SPDX-License-Identifier: GPL-2.0-only
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 2) /*
33692dc381f9b drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:25 +0530 3) * Generic OPP helper interface for CPU device
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 4) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 5) * Copyright (C) 2009-2014 Texas Instruments Incorporated.
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 6) * Nishanth Menon
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 7) * Romit Dasgupta
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 8) * Kevin Hilman
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 9) */
d6d2a5289a530 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-10-17 09:45:18 +0530 10)
d6d2a5289a530 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-10-17 09:45:18 +0530 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
d6d2a5289a530 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-10-17 09:45:18 +0530 12)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 13) #include <linux/cpu.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 14) #include <linux/cpufreq.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 15) #include <linux/err.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 16) #include <linux/errno.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 17) #include <linux/export.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 18) #include <linux/slab.h>
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 19)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 20) #include "opp.h"
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 21)
33692dc381f9b drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:25 +0530 22) #ifdef CONFIG_CPU_FREQ
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 23)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 24) /**
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 25) * dev_pm_opp_init_cpufreq_table() - create a cpufreq table for a device
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 26) * @dev: device for which we do this operation
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 27) * @table: Cpufreq table returned back to caller
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 28) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 29) * Generate a cpufreq table for a provided device- this assumes that the
2c2709dc6921c drivers/base/power/opp/cpu.c (Viresh Kumar 2016-02-16 14:17:53 +0530 30) * opp table is already initialized and ready for usage.
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 31) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 32) * This function allocates required memory for the cpufreq table. It is
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 33) * expected that the caller does the required maintenance such as freeing
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 34) * the table as required.
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 35) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 36) * Returns -EINVAL for bad pointers, -ENODEV if the device is not found, -ENOMEM
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 37) * if no memory available for the operation (table is not populated), returns 0
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 38) * if successful and table is populated.
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 39) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 40) * WARNING: It is important for the callers to ensure refreshing their copy of
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 41) * the table if any of the mentioned functions have been invoked in the interim.
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 42) */
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 43) int dev_pm_opp_init_cpufreq_table(struct device *dev,
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 44) struct cpufreq_frequency_table **table)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 45) {
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 46) struct dev_pm_opp *opp;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 47) struct cpufreq_frequency_table *freq_table = NULL;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 48) int i, max_opps, ret = 0;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 49) unsigned long rate;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 50)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 51) max_opps = dev_pm_opp_get_opp_count(dev);
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 52) if (max_opps <= 0)
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 53) return max_opps ? max_opps : -ENODATA;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 54)
4a823c0be80fa drivers/opp/cpu.c (Jia-Ju Bai 2018-01-26 16:48:49 +0800 55) freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_KERNEL);
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 56) if (!freq_table)
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 57) return -ENOMEM;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 58)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 59) for (i = 0, rate = 0; i < max_opps; i++, rate++) {
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 60) /* find next rate */
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 61) opp = dev_pm_opp_find_freq_ceil(dev, &rate);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 62) if (IS_ERR(opp)) {
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 63) ret = PTR_ERR(opp);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 64) goto out;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 65) }
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 66) freq_table[i].driver_data = i;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 67) freq_table[i].frequency = rate / 1000;
79eea44a5d7b9 drivers/cpufreq/cpufreq_opp.c (Bartlomiej Zolnierkiewicz 2015-07-29 16:23:08 +0530 68)
79eea44a5d7b9 drivers/cpufreq/cpufreq_opp.c (Bartlomiej Zolnierkiewicz 2015-07-29 16:23:08 +0530 69) /* Is Boost/turbo opp ? */
79eea44a5d7b9 drivers/cpufreq/cpufreq_opp.c (Bartlomiej Zolnierkiewicz 2015-07-29 16:23:08 +0530 70) if (dev_pm_opp_is_turbo(opp))
79eea44a5d7b9 drivers/cpufreq/cpufreq_opp.c (Bartlomiej Zolnierkiewicz 2015-07-29 16:23:08 +0530 71) freq_table[i].flags = CPUFREQ_BOOST_FREQ;
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 72)
8a31d9d94297b drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:47 +0530 73) dev_pm_opp_put(opp);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 74) }
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 75)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 76) freq_table[i].driver_data = i;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 77) freq_table[i].frequency = CPUFREQ_TABLE_END;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 78)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 79) *table = &freq_table[0];
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 80)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 81) out:
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 82) if (ret)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 83) kfree(freq_table);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 84)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 85) return ret;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 86) }
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 87) EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 88)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 89) /**
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 90) * dev_pm_opp_free_cpufreq_table() - free the cpufreq table
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 91) * @dev: device for which we do this operation
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 92) * @table: table to free
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 93) *
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 94) * Free up the table allocated by dev_pm_opp_init_cpufreq_table
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 95) */
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 96) void dev_pm_opp_free_cpufreq_table(struct device *dev,
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 97) struct cpufreq_frequency_table **table)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 98) {
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 99) if (!table)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 100) return;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 101)
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 102) kfree(*table);
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 103) *table = NULL;
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 104) }
a0dd7b79657bd drivers/cpufreq/cpufreq_opp.c (Nishanth Menon 2014-05-05 08:33:50 -0500 105) EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
33692dc381f9b drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:25 +0530 106) #endif /* CONFIG_CPU_FREQ */
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 107)
2a4eb7358aba6 drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:14:36 +0530 108) void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask,
404b1369ea26f drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:09:27 +0530 109) int last_cpu)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 110) {
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 111) struct device *cpu_dev;
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 112) int cpu;
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 113)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 114) WARN_ON(cpumask_empty(cpumask));
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 115)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 116) for_each_cpu(cpu, cpumask) {
404b1369ea26f drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:09:27 +0530 117) if (cpu == last_cpu)
404b1369ea26f drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:09:27 +0530 118) break;
404b1369ea26f drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:09:27 +0530 119)
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 120) cpu_dev = get_cpu_device(cpu);
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 121) if (!cpu_dev) {
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 122) pr_err("%s: failed to get cpu%d device\n", __func__,
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 123) cpu);
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 124) continue;
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 125) }
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 126)
8aaf6264fc7fd drivers/opp/cpu.c (Viresh Kumar 2020-08-20 13:18:23 +0530 127) dev_pm_opp_remove_table(cpu_dev);
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 128) }
f59d3ee8480d3 drivers/base/power/opp/cpu.c (Viresh Kumar 2015-09-04 13:47:26 +0530 129) }
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 130)
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 131) /**
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 132) * dev_pm_opp_cpumask_remove_table() - Removes OPP table for @cpumask
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 133) * @cpumask: cpumask for which OPP table needs to be removed
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 134) *
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 135) * This removes the OPP tables for CPUs present in the @cpumask.
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 136) * This should be used to remove all the OPPs entries associated with
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 137) * the cpus in @cpumask.
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 138) */
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 139) void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 140) {
2a4eb7358aba6 drivers/opp/cpu.c (Viresh Kumar 2018-09-13 13:14:36 +0530 141) _dev_pm_opp_cpumask_remove_table(cpumask, -1);
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 142) }
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 143) EXPORT_SYMBOL_GPL(dev_pm_opp_cpumask_remove_table);
411466c5081d2 drivers/base/power/opp/cpu.c (Sudeep Holla 2016-05-03 15:05:04 +0100 144)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 145) /**
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 146) * dev_pm_opp_set_sharing_cpus() - Mark OPP table as shared by few CPUs
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 147) * @cpu_dev: CPU device for which we do this operation
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 148) * @cpumask: cpumask of the CPUs which share the OPP table with @cpu_dev
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 149) *
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 150) * This marks OPP table of the @cpu_dev as shared by the CPUs present in
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 151) * @cpumask.
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 152) *
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 153) * Returns -ENODEV if OPP table isn't already present.
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 154) */
dde370b23c178 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:22 +0530 155) int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev,
ddbb74bc70c0d drivers/base/power/opp/cpu.c (Arnd Bergmann 2016-04-30 13:33:29 +0200 156) const struct cpumask *cpumask)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 157) {
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 158) struct opp_device *opp_dev;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 159) struct opp_table *opp_table;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 160) struct device *dev;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 161) int cpu, ret = 0;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 162)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 163) opp_table = _find_opp_table(cpu_dev);
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 164) if (IS_ERR(opp_table))
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 165) return PTR_ERR(opp_table);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 166)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 167) for_each_cpu(cpu, cpumask) {
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 168) if (cpu == cpu_dev->id)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 169) continue;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 170)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 171) dev = get_cpu_device(cpu);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 172) if (!dev) {
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 173) dev_err(cpu_dev, "%s: failed to get cpu%d device\n",
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 174) __func__, cpu);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 175) continue;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 176) }
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 177)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 178) opp_dev = _add_opp_dev(dev, opp_table);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 179) if (!opp_dev) {
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 180) dev_err(dev, "%s: failed to add opp-dev for cpu%d device\n",
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 181) __func__, cpu);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 182) continue;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 183) }
46e7a4e183976 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:57 +0530 184)
46e7a4e183976 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:57 +0530 185) /* Mark opp-table as multiple CPUs are sharing it now */
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 186) opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 187) }
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 188)
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 189) dev_pm_opp_put_opp_table(opp_table);
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 190)
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 191) return ret;
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 192) }
2c93104ff2d67 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-21 14:28:56 +0530 193) EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 194)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 195) /**
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 196) * dev_pm_opp_get_sharing_cpus() - Get cpumask of CPUs sharing OPPs with @cpu_dev
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 197) * @cpu_dev: CPU device for which we do this operation
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 198) * @cpumask: cpumask to update with information of sharing CPUs
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 199) *
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 200) * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev.
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 201) *
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 202) * Returns -ENODEV if OPP table isn't already present and -EINVAL if the OPP
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 203) * table's status is access-unknown.
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 204) */
ddbb74bc70c0d drivers/base/power/opp/cpu.c (Arnd Bergmann 2016-04-30 13:33:29 +0200 205) int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 206) {
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 207) struct opp_device *opp_dev;
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 208) struct opp_table *opp_table;
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 209) int ret = 0;
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 210)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 211) opp_table = _find_opp_table(cpu_dev);
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 212) if (IS_ERR(opp_table))
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 213) return PTR_ERR(opp_table);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 214)
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 215) if (opp_table->shared_opp == OPP_TABLE_ACCESS_UNKNOWN) {
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 216) ret = -EINVAL;
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 217) goto put_opp_table;
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 218) }
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 219)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 220) cpumask_clear(cpumask);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 221)
79ee2e8f73041 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-06-16 19:03:11 +0530 222) if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) {
3d2556992a878 drivers/opp/cpu.c (Viresh Kumar 2018-08-03 07:05:21 +0530 223) mutex_lock(&opp_table->lock);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 224) list_for_each_entry(opp_dev, &opp_table->dev_list, node)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 225) cpumask_set_cpu(opp_dev->dev->id, cpumask);
3d2556992a878 drivers/opp/cpu.c (Viresh Kumar 2018-08-03 07:05:21 +0530 226) mutex_unlock(&opp_table->lock);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 227) } else {
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 228) cpumask_set_cpu(cpu_dev->id, cpumask);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 229) }
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 230)
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 231) put_opp_table:
5b650b388844f drivers/base/power/opp/cpu.c (Viresh Kumar 2017-01-23 10:11:48 +0530 232) dev_pm_opp_put_opp_table(opp_table);
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 233)
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 234) return ret;
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 235) }
6f707daa38337 drivers/base/power/opp/cpu.c (Viresh Kumar 2016-04-27 08:52:23 +0530 236) EXPORT_SYMBOL_GPL(dev_pm_opp_get_sharing_cpus);