aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/cpufreq_stats.c')
-rw-r--r--drivers/cpufreq/cpufreq_stats.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index e1fe0a945639..5d7bf9b1dfc5 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -164,12 +164,13 @@ static void cpufreq_stats_free_table(unsigned int cpu)
164 164
165static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) 165static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
166{ 166{
167 unsigned int i, count = 0, ret = 0; 167 unsigned int i = 0, count = 0, ret = -ENOMEM;
168 struct cpufreq_stats *stats; 168 struct cpufreq_stats *stats;
169 unsigned int alloc_size; 169 unsigned int alloc_size;
170 unsigned int cpu = policy->cpu; 170 unsigned int cpu = policy->cpu;
171 struct cpufreq_frequency_table *pos, *table; 171 struct cpufreq_frequency_table *pos, *table;
172 172
173 /* We need cpufreq table for creating stats table */
173 table = cpufreq_frequency_get_table(cpu); 174 table = cpufreq_frequency_get_table(cpu);
174 if (unlikely(!table)) 175 if (unlikely(!table))
175 return 0; 176 return 0;
@@ -179,15 +180,10 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
179 return -EEXIST; 180 return -EEXIST;
180 181
181 stats = kzalloc(sizeof(*stats), GFP_KERNEL); 182 stats = kzalloc(sizeof(*stats), GFP_KERNEL);
182 if ((stats) == NULL) 183 if (!stats)
183 return -ENOMEM; 184 return -ENOMEM;
184 185
185 ret = sysfs_create_group(&policy->kobj, &stats_attr_group); 186 /* Find total allocation size */
186 if (ret)
187 goto error_out;
188
189 policy->stats = stats;
190
191 cpufreq_for_each_valid_entry(pos, table) 187 cpufreq_for_each_valid_entry(pos, table)
192 count++; 188 count++;
193 189
@@ -196,32 +192,42 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
196#ifdef CONFIG_CPU_FREQ_STAT_DETAILS 192#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
197 alloc_size += count * count * sizeof(int); 193 alloc_size += count * count * sizeof(int);
198#endif 194#endif
199 stats->max_state = count; 195
196 /* Allocate memory for time_in_state/freq_table/trans_table in one go */
200 stats->time_in_state = kzalloc(alloc_size, GFP_KERNEL); 197 stats->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
201 if (!stats->time_in_state) { 198 if (!stats->time_in_state)
202 ret = -ENOMEM; 199 goto free_stat;
203 goto error_alloc; 200
204 }
205 stats->freq_table = (unsigned int *)(stats->time_in_state + count); 201 stats->freq_table = (unsigned int *)(stats->time_in_state + count);
206 202
207#ifdef CONFIG_CPU_FREQ_STAT_DETAILS 203#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
208 stats->trans_table = stats->freq_table + count; 204 stats->trans_table = stats->freq_table + count;
209#endif 205#endif
210 i = 0; 206
207 stats->max_state = count;
208
209 /* Find valid-unique entries */
211 cpufreq_for_each_valid_entry(pos, table) 210 cpufreq_for_each_valid_entry(pos, table)
212 if (freq_table_get_index(stats, pos->frequency) == -1) 211 if (freq_table_get_index(stats, pos->frequency) == -1)
213 stats->freq_table[i++] = pos->frequency; 212 stats->freq_table[i++] = pos->frequency;
214 stats->state_num = i; 213 stats->state_num = i;
214
215 spin_lock(&cpufreq_stats_lock); 215 spin_lock(&cpufreq_stats_lock);
216 stats->last_time = get_jiffies_64(); 216 stats->last_time = get_jiffies_64();
217 stats->last_index = freq_table_get_index(stats, policy->cur); 217 stats->last_index = freq_table_get_index(stats, policy->cur);
218 spin_unlock(&cpufreq_stats_lock); 218 spin_unlock(&cpufreq_stats_lock);
219 return 0; 219
220error_alloc: 220 policy->stats = stats;
221 sysfs_remove_group(&policy->kobj, &stats_attr_group); 221 ret = sysfs_create_group(&policy->kobj, &stats_attr_group);
222error_out: 222 if (!ret)
223 kfree(stats); 223 return 0;
224
225 /* We failed, release resources */
224 policy->stats = NULL; 226 policy->stats = NULL;
227 kfree(stats->time_in_state);
228free_stat:
229 kfree(stats);
230
225 return ret; 231 return ret;
226} 232}
227 233