Hi,

On 06/27/2016 06:29 AM, Viresh Kumar wrote:
cpufreq drivers aren't required to provide a sorted frequency table
today, and even the ones which provide a sorted table aren't handled
efficiently by cpufreq core.

This patch adds infrastructure to verify if the freq-table provided by
the drivers is sorted or not, and use efficient helpers if they are
sorted.
<snip>
@@ -610,6 +617,227 @@ int cpufreq_boost_trigger_state(int state);
  int cpufreq_boost_enabled(void);
  int cpufreq_enable_boost_support(void);
  bool policy_has_boost_freq(struct cpufreq_policy *policy);
+
+/* Find lowest freq at or above target in a table in ascending order */
+static inline int cpufreq_table_find_index_al(struct cpufreq_policy *policy,
+                                             unsigned int target_freq)
+{
+       struct cpufreq_frequency_table *table = policy->freq_table;
+       unsigned int freq;
+       int i, best = -1;
+
+       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               freq = table[i].frequency;
+
+               if (freq >= target_freq)
+                       return i;
+
+               best = i;
+       }
+
+       return best;
+}
+
+/* Find lowest freq at or above target in a table in descending order */
+static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy,
+                                             unsigned int target_freq)
+{
+       struct cpufreq_frequency_table *table = policy->freq_table;
+       unsigned int freq;
+       int i, best = -1;
+
+       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               freq = table[i].frequency;
+
+               if (freq == target_freq)
+                       return i;
+
+               if (freq > target_freq) {
+                       best = i;
+                       continue;
+               }
+
+               /* No freq found below target_freq */

"below" should be "above"

+/* Find closest freq to target in a table in ascending order */
+static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy,
+                                             unsigned int target_freq)
+{
+       struct cpufreq_frequency_table *table = policy->freq_table;
+       unsigned int freq;
+       int i, best = -1;
+
+       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               freq = table[i].frequency;
+
+               if (freq == target_freq)
+                       return i;
+
+               if (freq < target_freq) {
+                       best = i;
+                       continue;
+               }
+
+               /* No freq found below target_freq */
+               if (best == -1)
+                       return i;
+
+               /* Choose the closest freq */
+               if (target_freq - table[best].frequency > freq - target_freq)
+                       return i;
+
+               return best;
+       }
+
+       return best;
+}
+
+/* Find closest freq to target in a table in descending order */
+static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy,
+                                             unsigned int target_freq)
+{
+       struct cpufreq_frequency_table *table = policy->freq_table;
+       unsigned int freq;
+       int i, best = -1;
+
+       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               freq = table[i].frequency;
+
+               if (freq == target_freq)
+                       return i;
+
+               if (freq > target_freq) {
+                       best = i;
+                       continue;
+               }
+
+               /* No freq found below target_freq */

"below" should be "above"

+               if (best == -1)
+                       return i;
+
+               /* Choose the closest freq */
+               if (target_freq - table[best].frequency > freq - target_freq)

Here, table[best].frequency > target_freq, and freq < and target_freq, so you should reverse the sign of both sides of the inequation:

        if (table[best].frequency - target_freq > target_freq - freq)

+                       return i;
+
+               return best;
+       }
+
+       return best;
+}

Regards,
Francesco

Reply via email to