dd009fd801f5fb854b612f57e5bfba50f71e81bb
[linux-3.10.git] / arch / arm / mach-tegra / tegra_core_volt_cap.c
1 /*
2  * arch/arm/mach-tegra/tegra_core_volt_cap.c
3  *
4  * Copyright (c), 2013 NVIDIA CORPORATION. All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/clk.h>
21 #include <linux/kobject.h>
22 #include <linux/err.h>
23 #include <linux/pm_qos.h>
24 #include <linux/debugfs.h>
25 #include <linux/seq_file.h>
26
27 #include "clock.h"
28 #include "dvfs.h"
29 #include "tegra_core_sysfs_limits.h"
30
31 /*
32  * sysfs and kernel interfaces to limit tegra core shared bus frequencies based
33  * on the required core voltage (cap level)
34  *
35  * Cap level is specified in millivolts, and rate limits from the respective
36  * dvfs tables are applied to all bus clocks. Note that cap level affects only
37  * scalable bus frequencies (graphics bus, emc, system clock). Core voltage is
38  * not necessarily set at the cap level, since CPU and/or fixed peripheral
39  * clocks outside the buses may require higher voltage level.
40  */
41 static DEFINE_MUTEX(core_cap_lock);
42
43 struct core_cap {
44         int refcnt;
45         int level;
46 };
47
48 static struct core_cap core_buses_cap;
49 static struct core_cap override_core_cap;
50 static struct core_cap vmax_core_cap;
51 static struct core_cap user_core_cap;
52
53 static struct core_dvfs_cap_table *core_cap_table;
54 static int core_cap_table_size;
55
56 static const int *cap_millivolts;
57 static int cap_millivolts_num;
58
59 static int core_cap_level_set(int level, int core_nominal_mv)
60 {
61         int i, j;
62         int ret = 0;
63
64         if (!core_cap_table) {
65                 int mv = tegra_dvfs_rail_get_boot_level(tegra_core_rail);
66                 if (level == mv) {
67                         core_buses_cap.level = level;
68                         return 0;
69                 }
70                 return -ENOENT;
71         }
72
73         for (j = 0; j < cap_millivolts_num; j++) {
74                 int v = cap_millivolts[j];
75                 if ((v == 0) || (level < v))
76                         break;
77         }
78         j = (j == 0) ? 0 : j - 1;
79         level = cap_millivolts[j];
80
81         if (level < core_buses_cap.level) {
82                 for (i = 0; i < core_cap_table_size; i++)
83                         if (core_cap_table[i].cap_clk)
84                                 ret |= clk_set_rate(core_cap_table[i].cap_clk,
85                                              core_cap_table[i].freqs[j]);
86         } else if (level > core_buses_cap.level) {
87                 for (i = core_cap_table_size - 1; i >= 0; i--)
88                         if (core_cap_table[i].cap_clk)
89                                 ret |= clk_set_rate(core_cap_table[i].cap_clk,
90                                              core_cap_table[i].freqs[j]);
91         }
92         core_buses_cap.level = level;
93         if (ret)
94                 ret = -EAGAIN;
95         return ret;
96 }
97
98 static int core_cap_update(void)
99 {
100         int new_level;
101         int core_nominal_mv =
102                 tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail);
103         if (core_nominal_mv <= 0)
104                 return -ENOENT;
105
106         new_level = core_nominal_mv;
107         if (override_core_cap.refcnt)
108                 new_level = min(new_level, override_core_cap.level);
109         if (vmax_core_cap.refcnt)
110                 new_level = min(new_level, vmax_core_cap.level);
111         if (user_core_cap.refcnt)
112                 new_level = min(new_level, user_core_cap.level);
113
114         if (core_buses_cap.level != new_level)
115                 return core_cap_level_set(new_level, core_nominal_mv);
116         return 0;
117 }
118
119 static int core_cap_enable(bool enable)
120 {
121         if (enable)
122                 core_buses_cap.refcnt++;
123         else if (core_buses_cap.refcnt)
124                 core_buses_cap.refcnt--;
125
126         return core_cap_update();
127 }
128
129 static ssize_t
130 core_cap_state_show(struct kobject *kobj, struct kobj_attribute *attr,
131                     char *buf)
132 {
133         return sprintf(buf, "%d (%d)\n", core_buses_cap.refcnt ? 1 : 0,
134                         user_core_cap.refcnt ? 1 : 0);
135 }
136 static ssize_t
137 core_cap_state_store(struct kobject *kobj, struct kobj_attribute *attr,
138                      const char *buf, size_t count)
139 {
140         int state;
141
142         if (sscanf(buf, "%d", &state) != 1)
143                 return -1;
144
145         mutex_lock(&core_cap_lock);
146
147         if (state) {
148                 user_core_cap.refcnt++;
149                 if (user_core_cap.refcnt == 1)
150                         core_cap_enable(true);
151         } else if (user_core_cap.refcnt) {
152                 user_core_cap.refcnt--;
153                 if (user_core_cap.refcnt == 0)
154                         core_cap_enable(false);
155         }
156
157         mutex_unlock(&core_cap_lock);
158         return count;
159 }
160
161 static ssize_t
162 core_cap_level_show(struct kobject *kobj, struct kobj_attribute *attr,
163                     char *buf)
164 {
165         return sprintf(buf, "%d (%d)\n", core_buses_cap.level,
166                         user_core_cap.level);
167 }
168 static ssize_t
169 core_cap_level_store(struct kobject *kobj, struct kobj_attribute *attr,
170                      const char *buf, size_t count)
171 {
172         int level;
173
174         if (sscanf(buf, "%d", &level) != 1)
175                 return -1;
176
177         mutex_lock(&core_cap_lock);
178         user_core_cap.level = level;
179         core_cap_update();
180         mutex_unlock(&core_cap_lock);
181         return count;
182 }
183
184 static struct kobj_attribute cap_state_attribute =
185         __ATTR(core_cap_state, 0644, core_cap_state_show, core_cap_state_store);
186 static struct kobj_attribute cap_level_attribute =
187         __ATTR(core_cap_level, 0644, core_cap_level_show, core_cap_level_store);
188
189 const struct attribute *cap_attributes[] = {
190         &cap_state_attribute.attr,
191         &cap_level_attribute.attr,
192         NULL,
193 };
194
195 int tegra_dvfs_override_core_cap_apply(int level)
196 {
197         int ret = 0;
198
199         mutex_lock(&core_cap_lock);
200
201         if (level) {
202                 if (override_core_cap.refcnt) {
203                         pr_err("%s: core cap is already set\n", __func__);
204                         ret = -EPERM;
205                 } else {
206                         override_core_cap.level = level;
207                         override_core_cap.refcnt = 1;
208                         ret = core_cap_enable(true);
209                         if (ret) {
210                                 override_core_cap.refcnt = 0;
211                                 core_cap_enable(false);
212                         }
213                 }
214         } else if (override_core_cap.refcnt) {
215                 override_core_cap.refcnt = 0;
216                 core_cap_enable(false);
217         }
218
219         mutex_unlock(&core_cap_lock);
220         return ret;
221 }
222
223 int tegra_dvfs_therm_vmax_core_cap_apply(int *cap_idx, int new_idx, int level)
224 {
225         int ret = 0;
226
227         mutex_lock(&core_cap_lock);
228         if (*cap_idx == new_idx)
229                 goto _out;
230
231         *cap_idx = new_idx;
232
233         if (level) {
234                 if (!vmax_core_cap.refcnt) {
235                         vmax_core_cap.level = level;
236                         vmax_core_cap.refcnt = 1;
237                         /* just report error (cannot revert temperature) */
238                         ret = core_cap_enable(true);
239                 } else if (vmax_core_cap.level != level) {
240                         vmax_core_cap.level = level;
241                         /* just report error (cannot revert temperature) */
242                         ret = core_cap_update();
243                 }
244         } else if (vmax_core_cap.refcnt) {
245                 vmax_core_cap.refcnt = 0;
246                 core_cap_enable(false);
247         }
248 _out:
249         mutex_unlock(&core_cap_lock);
250         return ret;
251 }
252
253 static int __init init_core_cap_one(struct clk *c, unsigned long *freqs)
254 {
255         int i, v, next_v = 0;
256         unsigned long rate, next_rate = 0;
257
258         for (i = 0; i < cap_millivolts_num; i++) {
259                 v = cap_millivolts[i];
260                 if (v == 0)
261                         break;
262
263                 for (;;) {
264                         rate = next_rate;
265                         next_rate = clk_round_rate(c->parent, rate + 1000);
266                         if (IS_ERR_VALUE(next_rate)) {
267                                 pr_debug("%s: failed to round %s rate %lu\n",
268                                          __func__, c->parent->name, rate);
269                                 return -EINVAL;
270                         }
271                         if (rate == next_rate)
272                                 break;
273
274                         next_v = tegra_dvfs_predict_peak_millivolts(
275                                 c->parent, next_rate);
276                         if (IS_ERR_VALUE(next_v)) {
277                                 pr_debug("%s: failed to predict %s mV for rate %lu\n",
278                                          __func__, c->parent->name, next_rate);
279                                 return -EINVAL;
280                         }
281                         if (next_v > v)
282                                 break;
283                 }
284
285                 if (rate == 0) {
286                         rate = next_rate;
287                         pr_info("%s: %s V=%dmV @ min F=%luHz above Vmin=%dmV\n",
288                                 __func__, c->parent->name, next_v, rate, v);
289                 }
290                 freqs[i] = rate;
291                 next_rate = rate;
292         }
293         return 0;
294 }
295
296 int __init tegra_init_core_cap(
297         struct core_dvfs_cap_table *table, int table_size,
298         const int *millivolts, int millivolts_num,
299         struct kobject *cap_kobj)
300 {
301         int i;
302         struct clk *c = NULL;
303
304         if (!table || !table_size || !millivolts || !millivolts_num)
305                 return -EINVAL;
306
307         user_core_cap.level =
308                 tegra_dvfs_rail_get_nominal_millivolts(tegra_core_rail);
309         if (user_core_cap.level <= 0)
310                 return -ENOENT;
311
312         cap_millivolts = millivolts;
313         cap_millivolts_num = millivolts_num;
314
315         for (i = 0; i < table_size; i++) {
316                 c = tegra_get_clock_by_name(table[i].cap_name);
317                 if (!c || !c->parent ||
318                     init_core_cap_one(c, table[i].freqs)) {
319                         pr_err("%s: failed to initialize %s table\n",
320                                __func__, table[i].cap_name);
321                         continue;
322                 }
323                 table[i].cap_clk = c;
324         }
325
326         if (!cap_kobj || sysfs_create_files(cap_kobj, cap_attributes))
327                 return -ENOMEM;
328
329         core_cap_table = table;
330         core_cap_table_size = table_size;
331         return 0;
332 }
333
334
335 /*
336  * sysfs interfaces to profile tegra core shared bus frequencies by directly
337  * specifying limit level in Hz for each bus independently
338  */
339
340 #define refcnt_to_bus(attr) \
341         container_of(attr, struct core_bus_limit_table, refcnt_attr)
342 #define level_to_bus(attr) \
343         container_of(attr, struct core_bus_limit_table, level_attr)
344 #define nb_to_bus(nb) \
345         container_of(nb, struct core_bus_limit_table, qos_nb)
346
347 #define MAX_BUS_NUM     8
348
349 static DEFINE_MUTEX(bus_limit_lock);
350 static const struct attribute *bus_attributes[2 * MAX_BUS_NUM + 1];
351
352 static int _floor_update(struct core_bus_limit_table *bus_limit,
353                          unsigned long qos_limit_level)
354 {
355         int ret = 0;
356         unsigned long level, max_level;
357         struct clk *c = bus_limit->limit_clk;
358
359         BUG_ON(!c);
360         max_level = clk_get_max_rate(c);
361
362         if (!bus_limit->refcnt && !qos_limit_level) {
363                 if (bus_limit->applied) {
364                         tegra_clk_disable_unprepare(c);
365                         bus_limit->applied = false;
366                 }
367                 return 0;
368         }
369
370         level = bus_limit->refcnt ? bus_limit->level : 0;
371
372         /* qos level is in kHz, bus floor level is in Hz */
373         if (qos_limit_level < max_level / 1000)
374                 qos_limit_level *= 1000;
375         else
376                 qos_limit_level = max_level;
377
378         level = max(level, qos_limit_level);
379
380
381         ret = clk_set_rate(c, level);
382         if (!bus_limit->applied)
383                 ret = tegra_clk_prepare_enable(c);
384
385         if (ret) {
386                 pr_err("%s: Failed to floor %s at level %lu\n",
387                        __func__, bus_limit->limit_clk_name, level);
388                 return ret;
389         }
390         bus_limit->applied = true;
391
392         return 0;
393 }
394
395 static int _cap_update(struct core_bus_limit_table *bus_limit,
396                        unsigned long qos_limit_level)
397 {
398         int ret = 0;
399         unsigned long level, max_level;
400         struct clk *c = bus_limit->limit_clk;
401
402         BUG_ON(!c);
403         max_level = clk_get_max_rate(c);
404         level = bus_limit->refcnt ? bus_limit->level : max_level;
405
406         /* qos level is in kHz, bus cap level is in Hz */
407         if (qos_limit_level < max_level / 1000)
408                 qos_limit_level *= 1000;
409         else
410                 qos_limit_level = max_level;
411
412         level = min(level, qos_limit_level);
413
414         ret = clk_set_rate(c, level);
415         if (ret)
416                 pr_err("%s: Failed to cap %s at level %lu\n",
417                        __func__, bus_limit->limit_clk_name, level);
418         return ret;
419 }
420
421 static int bus_limit_update(struct core_bus_limit_table *bus_limit)
422 {
423         unsigned long qos_limit_level;
424
425         if (bus_limit->pm_qos_class)
426                 qos_limit_level = pm_qos_request(bus_limit->pm_qos_class);
427         else
428                 qos_limit_level = bus_limit->update == _cap_update ?
429                                                         ULONG_MAX : 0;
430         return bus_limit->update(bus_limit, qos_limit_level);
431 }
432
433 static ssize_t
434 bus_limit_state_show(struct kobject *kobj, struct kobj_attribute *attr,
435                     char *buf)
436 {
437         struct core_bus_limit_table *bus_limit = refcnt_to_bus(attr);
438         return sprintf(buf, "%d\n", bus_limit->refcnt ? 1 : 0);
439 }
440 static ssize_t
441 bus_limit_state_store(struct kobject *kobj, struct kobj_attribute *attr,
442                      const char *buf, size_t count)
443 {
444         int state;
445         struct core_bus_limit_table *bus_limit = refcnt_to_bus(attr);
446
447         if (sscanf(buf, "%d", &state) != 1)
448                 return -1;
449
450         mutex_lock(&bus_limit_lock);
451
452         if (state) {
453                 bus_limit->refcnt++;
454                 if (bus_limit->refcnt == 1)
455                         bus_limit_update(bus_limit);
456         } else if (bus_limit->refcnt) {
457                 bus_limit->refcnt--;
458                 if (bus_limit->refcnt == 0)
459                         bus_limit_update(bus_limit);
460         }
461
462         mutex_unlock(&bus_limit_lock);
463         return count;
464 }
465
466 static ssize_t
467 bus_limit_level_show(struct kobject *kobj, struct kobj_attribute *attr,
468                     char *buf)
469 {
470         struct core_bus_limit_table *bus_limit = level_to_bus(attr);
471         return sprintf(buf, "%lu\n", bus_limit->level);
472 }
473 static ssize_t
474 bus_limit_level_store(struct kobject *kobj, struct kobj_attribute *attr,
475                      const char *buf, size_t count)
476 {
477         int level;
478         struct core_bus_limit_table *bus_limit = level_to_bus(attr);
479
480         if (sscanf(buf, "%d", &level) != 1)
481                 return -1;
482
483         mutex_lock(&bus_limit_lock);
484         if (bus_limit->level != level) {
485                 bus_limit->level = level;
486                 bus_limit_update(bus_limit);
487         }
488         mutex_unlock(&bus_limit_lock);
489         return count;
490 }
491
492 static int qos_limit_notify(struct notifier_block *nb,
493                           unsigned long qos_limit_level, void *p)
494 {
495         struct core_bus_limit_table *bus_limit = nb_to_bus(nb);
496
497         mutex_lock(&bus_limit_lock);
498         bus_limit->update(bus_limit, qos_limit_level);
499         mutex_unlock(&bus_limit_lock);
500         return NOTIFY_OK;
501 }
502
503 int __init tegra_init_shared_bus_cap(
504         struct core_bus_limit_table *table, int table_size,
505         struct kobject *cap_kobj)
506 {
507         int i, j;
508         struct clk *c = NULL;
509
510         if (!table || !table_size || (table_size > MAX_BUS_NUM))
511                 return -EINVAL;
512
513         for (i = 0, j = 0; i < table_size; i++) {
514                 c = tegra_get_clock_by_name(table[i].limit_clk_name);
515                 if (!c) {
516                         pr_err("%s: failed to initialize %s table\n",
517                                __func__, table[i].limit_clk_name);
518                         continue;
519                 }
520                 table[i].limit_clk = c;
521                 table[i].level = clk_get_max_rate(c);
522                 table[i].refcnt = 0;
523                 table[i].refcnt_attr.show = bus_limit_state_show;
524                 table[i].refcnt_attr.store = bus_limit_state_store;
525                 table[i].level_attr.show = bus_limit_level_show;
526                 table[i].level_attr.store = bus_limit_level_store;
527                 table[i].update = _cap_update;
528                 bus_attributes[j++] = &table[i].refcnt_attr.attr;
529                 bus_attributes[j++] = &table[i].level_attr.attr;
530                 if (table[i].pm_qos_class) {
531                         table[i].qos_nb.notifier_call = qos_limit_notify;
532                         if (pm_qos_add_notifier(
533                                 table[i].pm_qos_class, &table[i].qos_nb)) {
534                                 pr_err("%s: Failed register %s with PM QoS\n",
535                                         __func__, table[i].limit_clk_name);
536                                 table[i].pm_qos_class = 0;
537                         }
538                 }
539         }
540         bus_attributes[j] = NULL;
541
542         if (!cap_kobj || sysfs_create_files(cap_kobj, bus_attributes))
543                 return -ENOMEM;
544         return 0;
545 }
546
547 int __init tegra_init_shared_bus_floor(
548         struct core_bus_limit_table *table, int table_size,
549         struct kobject *floor_kobj)
550 {
551         int i, j;
552         struct clk *c = NULL;
553
554         if (!table || !table_size || (table_size > MAX_BUS_NUM))
555                 return -EINVAL;
556
557         for (i = 0, j = 0; i < table_size; i++) {
558                 c = tegra_get_clock_by_name(table[i].limit_clk_name);
559                 if (!c) {
560                         pr_err("%s: failed to initialize %s table\n",
561                                __func__, table[i].limit_clk_name);
562                         continue;
563                 }
564                 table[i].limit_clk = c;
565                 table[i].level = clk_get_max_rate(c);
566                 table[i].refcnt_attr.show = bus_limit_state_show;
567                 table[i].refcnt_attr.store = bus_limit_state_store;
568                 table[i].level_attr.show = bus_limit_level_show;
569                 table[i].level_attr.store = bus_limit_level_store;
570                 table[i].update = _floor_update;
571                 bus_attributes[j++] = &table[i].refcnt_attr.attr;
572                 bus_attributes[j++] = &table[i].level_attr.attr;
573                 if (table[i].pm_qos_class) {
574                         table[i].qos_nb.notifier_call = qos_limit_notify;
575                         if (pm_qos_add_notifier(
576                                 table[i].pm_qos_class, &table[i].qos_nb)) {
577                                 pr_err("%s: Failed register %s with PM QoS\n",
578                                         __func__, table[i].limit_clk_name);
579                                 table[i].pm_qos_class = 0;
580                         }
581                 }
582         }
583         bus_attributes[j] = NULL;
584
585         if (!floor_kobj || sysfs_create_files(floor_kobj, bus_attributes))
586                 return -ENOMEM;
587         return 0;
588 }
589
590 /* sysfs interfaces to read tegra core shared bus current / available rates */
591 #define rate_to_bus(attr) \
592         container_of(attr, struct core_bus_rates_table, rate_attr)
593 #define available_rates_to_bus(attr) \
594         container_of(attr, struct core_bus_rates_table, available_rates_attr)
595
596
597 static ssize_t
598 bus_rate_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
599 {
600         struct core_bus_rates_table *bus = rate_to_bus(attr);
601         struct clk *c = bus->bus_clk;
602         return sprintf(buf, "%lu\n", clk_get_rate(c));
603 }
604
605 static ssize_t
606 bus_available_rates_show(struct kobject *kobj, struct kobj_attribute *attr,
607                          char *buf)
608 {
609         int i;
610         ssize_t n = 0;
611         struct core_bus_rates_table *bus = available_rates_to_bus(attr);
612
613         for (i = 0; i < MAX_DVFS_FREQS; i++) {
614                 unsigned long rate = bus->available_rates[i];
615                 if (!rate || ((n + 10) > PAGE_SIZE))
616                         break;
617
618                 n += sprintf(&buf[n], "%lu ", rate);
619         }
620         n = n ? n-1 : 0;
621         n += sprintf(&buf[n], "\n");
622         return n;
623 }
624
625 static int get_available_rates(struct clk *c, struct core_bus_rates_table *t)
626 {
627         int i = 0;
628         unsigned long rate = 0;
629         unsigned long max_rate = clk_get_max_rate(c);
630
631         /* available rates search below applied to shared bus only */
632         if (!c->ops || !c->ops->round_rate || !c->ops->shared_bus_update) {
633                 pr_err("%s: cannot find %s rates ladder\n", __func__, c->name);
634                 return -ENOSYS;
635         }
636
637         /* shared bus clock must round up, unless top of range reached */
638         while ((rate <= max_rate) && (i <= MAX_DVFS_FREQS)) {
639                 unsigned long rounded_rate = clk_round_rate(c, rate);
640                 if (IS_ERR_VALUE(rounded_rate) || (rounded_rate <= rate))
641                         break;
642
643                 rate = rounded_rate + 2000;     /* 2kHz resolution */
644                 t->available_rates[i++] = rounded_rate;
645         }
646         return 0;
647 }
648
649 int __init tegra_init_sysfs_shared_bus_rate(
650         struct core_bus_rates_table *table, int table_size,
651         struct kobject *floor_kobj)
652 {
653         int i, j;
654         struct clk *c = NULL;
655
656         if (!table || !table_size || (table_size > MAX_BUS_NUM))
657                 return -EINVAL;
658
659         for (i = 0, j = 0; i < table_size; i++) {
660                 c = tegra_get_clock_by_name(table[i].bus_clk_name);
661                 if (!c || get_available_rates(c, &table[i])) {
662                         pr_err("%s: failed to initialize %s table\n",
663                                __func__, table[i].bus_clk_name);
664                         continue;
665                 }
666                 table[i].bus_clk = c;
667                 table[i].rate_attr.show = bus_rate_show;
668                 table[i].available_rates_attr.show = bus_available_rates_show;
669                 bus_attributes[j++] = &table[i].rate_attr.attr;
670                 bus_attributes[j++] = &table[i].available_rates_attr.attr;
671         }
672         bus_attributes[j] = NULL;
673
674         if (!floor_kobj || sysfs_create_files(floor_kobj, bus_attributes))
675                 return -ENOMEM;
676         return 0;
677 }
678
679 #ifdef CONFIG_DEBUG_FS
680
681 static int vcore_cap_table_show(struct seq_file *s, void *data)
682 {
683         int i, j, n, therm_cap, therm_trip;
684
685         seq_printf(s, "%-20s", "bus/vcore");
686         for (j = 0; j < cap_millivolts_num; j++) {
687                 int v = cap_millivolts[j];
688                 if (!v)
689                         break;
690                 seq_printf(s, "%7d", v);
691         }
692         n = j;
693         seq_puts(s, " mV\n");
694
695         for (i = 0; i < core_cap_table_size; i++) {
696                 struct core_dvfs_cap_table *table = &core_cap_table[i];
697                 seq_printf(s, "%-20s", table->cap_name);
698                 for (j = 0; j < n; j++)
699                         seq_printf(s, "%7lu", table->freqs[j] / 1000);
700                 seq_puts(s, " kHz\n");
701         }
702
703         return 0;
704 }
705
706 static int vcore_cap_table_open(struct inode *inode, struct file *file)
707 {
708         return single_open(file, vcore_cap_table_show, inode->i_private);
709 }
710
711 static const struct file_operations vcore_cap_table_fops = {
712         .open           = vcore_cap_table_open,
713         .read           = seq_read,
714         .llseek         = seq_lseek,
715         .release        = single_release,
716 };
717
718 int __init tegra_core_cap_debug_init(void)
719 {
720         struct dentry *core_cap_debugfs_dir;
721
722         if (!core_cap_table)
723                 return 0;
724
725         core_cap_debugfs_dir = debugfs_create_dir("tegra_core_cap", NULL);
726         if (!core_cap_debugfs_dir)
727                 return -ENOMEM;
728
729         if (!debugfs_create_file("vcore_cap_table", S_IRUGO,
730                 core_cap_debugfs_dir, NULL, &vcore_cap_table_fops))
731                 goto err_out;
732
733         return 0;
734
735 err_out:
736         debugfs_remove_recursive(core_cap_debugfs_dir);
737         return -ENOMEM;
738 }
739 #endif