]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cpufreq: Add an interface to mark inefficient frequencies
authorVincent Donnefort <vincent.donnefort@arm.com>
Wed, 8 Sep 2021 14:05:27 +0000 (15:05 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 5 Oct 2021 14:33:05 +0000 (16:33 +0200)
Some SoCs such as the sd855 have OPPs within the same policy whose cost is
higher than others with a higher frequency. Those OPPs are inefficients
and it might be interesting for a governor to not use them.

cpufreq_table_set_inefficient() allows the caller to identify a specified
frequency as being inefficient. Inefficient frequencies are only supported
on sorted tables.

Signed-off-by: Vincent Donnefort <vincent.donnefort@arm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
include/linux/cpufreq.h

index ff88bb3e44fca1ba7bb58137ca9aea1971a62c9b..16997e1ff3fe55f93fafefba813ed7a649f6b332 100644 (file)
@@ -660,10 +660,11 @@ struct governor_attr {
  *********************************************************************/
 
 /* Special Values of .frequency field */
-#define CPUFREQ_ENTRY_INVALID  ~0u
-#define CPUFREQ_TABLE_END      ~1u
+#define CPUFREQ_ENTRY_INVALID          ~0u
+#define CPUFREQ_TABLE_END              ~1u
 /* Special Values of .flags field */
-#define CPUFREQ_BOOST_FREQ     (1 << 0)
+#define CPUFREQ_BOOST_FREQ             (1 << 0)
+#define CPUFREQ_INEFFICIENT_FREQ       (1 << 1)
 
 struct cpufreq_frequency_table {
        unsigned int    flags;
@@ -1003,6 +1004,36 @@ static inline int cpufreq_table_count_valid_entries(const struct cpufreq_policy
        return count;
 }
 
+/**
+ * cpufreq_table_set_inefficient() - Mark a frequency as inefficient
+ * @policy:    the &struct cpufreq_policy containing the inefficient frequency
+ * @frequency: the inefficient frequency
+ *
+ * The &struct cpufreq_policy must use a sorted frequency table
+ *
+ * Return:     %0 on success or a negative errno code
+ */
+
+static inline int
+cpufreq_table_set_inefficient(struct cpufreq_policy *policy,
+                             unsigned int frequency)
+{
+       struct cpufreq_frequency_table *pos;
+
+       /* Not supported */
+       if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED)
+               return -EINVAL;
+
+       cpufreq_for_each_valid_entry(pos, policy->freq_table) {
+               if (pos->frequency == frequency) {
+                       pos->flags |= CPUFREQ_INEFFICIENT_FREQ;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
 static inline int parse_perf_domain(int cpu, const char *list_name,
                                    const char *cell_name)
 {
@@ -1071,6 +1102,13 @@ static inline bool policy_has_boost_freq(struct cpufreq_policy *policy)
        return false;
 }
 
+static inline int
+cpufreq_table_set_inefficient(struct cpufreq_policy *policy,
+                             unsigned int frequency)
+{
+       return -EINVAL;
+}
+
 static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_name,
                                                     const char *cell_name, struct cpumask *cpumask)
 {