aboutsummaryrefslogtreecommitdiffstats
path: root/extras/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch
blob: 576cd08f567db092a55c6d71d84060fff89bc1e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
From 8726f3a7218b72a1003904a24bb000b3e4f9b4d1 Mon Sep 17 00:00:00 2001
From: Mike Turquette <mturquette@ti.com>
Date: Tue, 17 May 2011 09:35:54 -0500
Subject: [PATCH 1/2] cpufreq: helpers for walking the frequency table

Two new functions for getting the next higher and next lower frequencies
in the cpufreq table, based upon a frequency supplied in kHz.

This is useful for cpufreq governors that do not target frequencies
based upon a percentage or a pre-determined value, but instead access
the cpufreq table directly.

Signed-off-by: Mike Turquette <mturquette@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
---
 drivers/cpufreq/freq_table.c |   73 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/cpufreq.h      |    9 +++++
 2 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 0543221..11a307b 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/err.h>
 
 #define dprintk(msg...) \
 	cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
@@ -174,6 +175,78 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 
+int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
+		struct cpufreq_frequency_table *table, int *index)
+{
+	unsigned int cur_freq;
+	unsigned int next_lowest_freq;
+	int optimal_index = -1;
+	int i = 0;
+
+	if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
+			!index || IS_ERR(index))
+		return -ENOMEM;
+
+	cur_freq = policy->cur;
+	next_lowest_freq = policy->min;
+
+	/* we're at the lowest frequency in the table already, bail out */
+	if (cur_freq == policy->min)
+		return -EINVAL;
+
+	/* walk the list, find closest freq to cur_freq that is below it */
+	while(table[i].frequency != CPUFREQ_TABLE_END) {
+		if (table[i].frequency < cur_freq &&
+				table[i].frequency >= next_lowest_freq) {
+			next_lowest_freq = table[i].frequency;
+			optimal_index = table[i].index;
+		}
+
+		i++;
+	}
+
+	*index = optimal_index;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_lowest);
+
+int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
+		struct cpufreq_frequency_table *table, int *index)
+{
+	unsigned int cur_freq;
+	unsigned int next_higher_freq;
+	int optimal_index = -1;
+	int i = 0;
+
+	if (!policy || IS_ERR(policy) || !table || IS_ERR(table) ||
+			!index || IS_ERR(index))
+		return -ENOMEM;
+
+	cur_freq = policy->cur;
+	next_higher_freq = policy->max;
+
+	/* we're at the highest frequency in the table already, bail out */
+	if (cur_freq == policy->max)
+		return -EINVAL;
+
+	/* walk the list, find closest freq to cur_freq that is above it */
+	while(table[i].frequency != CPUFREQ_TABLE_END) {
+		if (table[i].frequency > cur_freq &&
+				table[i].frequency <= next_higher_freq) {
+			next_higher_freq = table[i].frequency;
+			optimal_index = table[i].index;
+		}
+
+		i++;
+	}
+
+	*index = optimal_index;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_highest);
+
 static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
 /**
  * show_available_freqs - show available frequencies for the specified CPU
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 9343dd3..a38fca8 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -396,6 +396,15 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu);
 
+/* the following are for use in governors, or anywhere else */
+extern int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy,
+					struct cpufreq_frequency_table *table,
+					int *index);
+
+extern int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy,
+					struct cpufreq_frequency_table *table,
+					int *index);
+
 
 /*********************************************************************
  *                     UNIFIED DEBUG HELPERS                         *
-- 
1.6.6.1