blob: b069547dbdf21738b3a7494e60673b8b25627be1 [file] [log] [blame]
Amit Arora728e0c92010-09-14 12:06:09 +05301/*******************************************************************************
Amit Kucheriac0e17fc2011-01-17 09:35:52 +02002 * Copyright (C) 2010, Linaro Limited.
Amit Arora728e0c92010-09-14 12:06:09 +05303 *
4 * This file is part of PowerDebug.
5 *
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors:
12 * Amit Arora <amit.arora@linaro.org> (IBM Corporation)
13 * - initial API and implementation
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020014 *
15 * Daniel Lezcano <daniel.lezcano@linaro.org> (IBM Corporation)
16 * - Rewrote code and API
17 *
Amit Arora728e0c92010-09-14 12:06:09 +053018 *******************************************************************************/
19
Daniel Lezcano141c0482011-06-08 23:30:00 +020020#ifndef _GNU_SOURCE
21#define _GNU_SOURCE
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010022#include <stdio.h>
Daniel Lezcano141c0482011-06-08 23:30:00 +020023#undef _GNU_SOURCE
24#endif
Daniel Lezcano15627482011-06-15 15:45:12 +020025#include <string.h>
26#include <stdbool.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <sys/param.h>
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010030#include <mntent.h>
Daniel Lezcanoef323192011-03-26 22:06:20 +010031#include <sys/stat.h>
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010032
Amit Arora728e0c92010-09-14 12:06:09 +053033#include "powerdebug.h"
Daniel Lezcanob301b082011-06-15 15:45:12 +020034#include "display.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053035#include "clocks.h"
Daniel Lezcanoc193b602011-06-08 23:30:00 +020036#include "tree.h"
Daniel Lezcano88b38e32011-06-15 15:45:12 +020037#include "utils.h"
Amit Arora24ed7d12010-09-14 12:12:58 +053038
Shaojie Sun73e5d972013-08-21 17:04:34 +080039#ifndef uint
40#define uint unsigned int
41#endif
42
43
Daniel Lezcanoc45662b2011-06-08 23:30:00 +020044struct clock_info {
Daniel Lezcanoc45662b2011-06-08 23:30:00 +020045 int flags;
Shaojie Sun73e5d972013-08-21 17:04:34 +080046 uint rate;
Daniel Lezcanoc45662b2011-06-08 23:30:00 +020047 int usecount;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020048 bool expanded;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +020049 char *prefix;
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +053050 int preparecount;
51 int enablecount;
52 int notifiercount;
Daniel Lezcanoc45662b2011-06-08 23:30:00 +020053} *clocks_info;
54
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +053055enum clock_fw_type{
56 CCF, /* common clock framework */
57 OCF, /* old clock framework */
58 MAX,
59};
60
Daniel Lezcano9d5431c2011-06-08 23:30:00 +020061static struct tree *clock_tree = NULL;
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +053062static int clock_fw;
Daniel Lezcanoc193b602011-06-08 23:30:00 +020063
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010064static int locate_debugfs(char *clk_path)
65{
Nishanth Menona14971b2011-09-20 11:31:17 +020066 strcpy(clk_path, "/sys/kernel/debug");
67 return 0;
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010068}
69
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020070static struct clock_info *clock_alloc(void)
Amit Arora24ed7d12010-09-14 12:12:58 +053071{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020072 struct clock_info *ci;
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010073
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020074 ci = malloc(sizeof(*ci));
75 if (ci)
76 memset(ci, 0, sizeof(*ci));
Daniel Lezcanoc5a65bf2011-03-26 22:06:11 +010077
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020078 return ci;
Amit Arora24ed7d12010-09-14 12:12:58 +053079}
Amit Arora728e0c92010-09-14 12:06:09 +053080
Shaojie Sun2489bc72013-08-21 17:27:33 +080081static inline bool is_hex_clock(uint rate)
82{
83 return rate%10;
84}
85
Shaojie Sun73e5d972013-08-21 17:04:34 +080086static inline const char *clock_rate(uint *rate)
Daniel Lezcanoc6718332011-03-23 14:37:39 +010087{
Shaojie Sun2489bc72013-08-21 17:27:33 +080088 uint r, mod;
89 bool is_hex = is_hex_clock(*rate);
Daniel Lezcanoc6718332011-03-23 14:37:39 +010090
Daniel Lezcanoafe62252011-06-08 23:30:00 +020091 /* GHZ */
Shaojie Sun2489bc72013-08-21 17:27:33 +080092 if (is_hex) {
93 r = *rate >> 30;
94 mod = *rate&((1<<30)-1);
95 } else {
96 r = *rate / 1000000000;
97 mod = *rate % 1000000000;
98 }
99 if (r && !mod) {
100 *rate = r;
101 return "GHZ";
102 }
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100103
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200104 /* MHZ */
Shaojie Sun2489bc72013-08-21 17:27:33 +0800105 if (is_hex) {
106 r = *rate >> 20;
107 mod = *rate&((1<<20)-1);
108 } else {
109 r = *rate / 1000000;
110 mod = *rate % 1000000;
111 }
112 if (r && !mod) {
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200113 *rate = r;
114 return "MHZ";
115 }
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100116
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200117 /* KHZ */
Shaojie Sun2489bc72013-08-21 17:27:33 +0800118 if (is_hex) {
119 r = *rate >> 10;
120 mod = *rate&((1<<10)-1);
121 } else {
122 r = *rate / 1000;
123 mod = *rate % 1000;
124 }
125 if (r && !mod) {
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200126 *rate = r;
127 return "KHZ";
128 }
129
130 return "";
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100131}
132
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200133static int dump_clock_cb(struct tree *t, void *data)
Daniel Lezcanoef323192011-03-26 22:06:20 +0100134{
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200135 struct clock_info *clk = t->private;
136 struct clock_info *pclk;
137 const char *unit;
138 int ret = 0;
Shaojie Sun73e5d972013-08-21 17:04:34 +0800139 uint rate = clk->rate;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100140
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200141 if (!t->parent) {
142 printf("/\n");
143 clk->prefix = "";
144 return 0;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100145 }
146
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200147 pclk = t->parent->private;
148
149 if (!clk->prefix)
150 ret = asprintf(&clk->prefix, "%s%s%s", pclk->prefix,
151 t->depth > 1 ? " ": "", t->next ? "|" : " ");
152 if (ret < 0)
153 return -1;
154
155 unit = clock_rate(&rate);
156
Shaojie Sun73e5d972013-08-21 17:04:34 +0800157 printf("%s%s-- %s (flags:0x%x, usecount:%d, rate: %u %s)\n",
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200158 clk->prefix, !t->next ? "`" : "", t->name, clk->flags,
159 clk->usecount, rate, unit);
160
161 return 0;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100162}
163
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200164int dump_clock_info(void)
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100165{
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200166 return tree_for_each(clock_tree, dump_clock_cb, NULL);
167}
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100168
Daniel Lezcano3e38e0f2011-06-08 23:30:00 +0200169static int dump_all_parents(char *clkarg)
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200170{
171 struct tree *tree;
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100172
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200173 tree = tree_find(clock_tree, clkarg);
174 if (!tree) {
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100175 printf("Clock NOT found!\n");
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200176 return -1;
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100177 }
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200178
179 return tree_for_each_parent(tree, dump_clock_cb, NULL);
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100180}
181
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200182static inline int read_clock_cb(struct tree *t, void *data)
Daniel Lezcanoef323192011-03-26 22:06:20 +0100183{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200184 struct clock_info *clk = t->private;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100185
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530186 if(clock_fw == CCF) {
187 file_read_value(t->path, "clk_flags", "%x", &clk->flags);
Shaojie Sun73e5d972013-08-21 17:04:34 +0800188 file_read_value(t->path, "clk_rate", "%u", &clk->rate);
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530189 file_read_value(t->path, "clk_prepare_count", "%d", &clk->preparecount);
190 file_read_value(t->path, "clk_enable_count", "%d", &clk->enablecount);
191 file_read_value(t->path, "clk_notifier_count", "%d", &clk->notifiercount);
192 }
193 else {
194 file_read_value(t->path, "flags", "%x", &clk->flags);
Shaojie Sun73e5d972013-08-21 17:04:34 +0800195 file_read_value(t->path, "rate", "%u", &clk->rate);
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530196 file_read_value(t->path, "usecount", "%d", &clk->usecount);
197 }
Amit Arora3bc8c922010-11-16 11:27:38 +0530198
199 return 0;
200}
201
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200202static int read_clock_info(struct tree *tree)
Amit Aroraac4e8652010-11-09 11:16:53 +0530203{
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200204 return tree_for_each(tree, read_clock_cb, NULL);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200205}
206
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200207static int fill_clock_cb(struct tree *t, void *data)
208{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200209 struct clock_info *clk;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200210
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200211 clk = clock_alloc();
212 if (!clk)
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200213 return -1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200214 t->private = clk;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200215
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200216 /* we skip the root node but we set it expanded for its children */
217 if (!t->parent) {
218 clk->expanded = true;
219 return 0;
220 }
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200221
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200222 return read_clock_cb(t, data);
223}
224
225static int fill_clock_tree(void)
226{
227 return tree_for_each(clock_tree, fill_clock_cb, NULL);
228}
229
230static int is_collapsed(struct tree *t, void *data)
231{
232 struct clock_info *clk = t->private;
233
234 if (!clk->expanded)
235 return 1;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200236
237 return 0;
238}
239
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200240static char *clock_line(struct tree *t)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530241{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200242 struct clock_info *clk;
Shaojie Sun73e5d972013-08-21 17:04:34 +0800243 uint rate;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200244 const char *clkunit;
245 char *clkrate, *clkname, *clkline = NULL;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200246
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200247 clk = t->private;
248 rate = clk->rate;
249 clkunit = clock_rate(&rate);
250
251 if (asprintf(&clkname, "%*s%s", (t->depth - 1) * 2, "", t->name) < 0)
252 return NULL;
253
254 if (asprintf(&clkrate, "%d%s", rate, clkunit) < 0)
255 goto free_clkname;
256
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530257 if(clock_fw == CCF) {
258 if (asprintf(&clkline, "%-35s 0x%-8x %-12s %-10d %-11d %-15d %-14d %-10d",
259 clkname, clk->flags, clkrate, clk->usecount, t->nrchild,
260 clk->preparecount, clk->enablecount, clk->notifiercount) < 0)
261 goto free_clkrate;
262 }
263 else {
264 if (asprintf(&clkline, "%-55s 0x%-16x %-12s %-9d %-8d",
265 clkname, clk->flags, clkrate, clk->usecount, t->nrchild) < 0)
266 goto free_clkrate;
267 }
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200268
269free_clkrate:
270 free(clkrate);
271free_clkname:
272 free(clkname);
273
274 return clkline;
275}
276
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200277static int _clock_print_info_cb(struct tree *t, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200278{
279 struct clock_info *clock = t->private;
280 int *line = data;
281 char *buffer;
282
Daniel Lezcano73b40022011-06-21 00:57:08 +0200283 /* we skip the root node of the tree */
284 if (!t->parent)
285 return 0;
286
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200287 buffer = clock_line(t);
288 if (!buffer)
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200289 return -1;
290
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200291 display_print_line(CLOCK, *line, buffer, clock->usecount, t);
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200292
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200293 (*line)++;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200294
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200295 free(buffer);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200296
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200297 return 0;
298}
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200299
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200300static int clock_print_info_cb(struct tree *t, void *data)
301{
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200302 /* we skip the root node of the tree */
303 if (!t->parent)
304 return 0;
305
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200306 /* show the clock when *all* its parent is expanded */
307 if (tree_for_each_parent(t->parent, is_collapsed, NULL))
308 return 0;
309
310 return _clock_print_info_cb(t, data);
311}
312
Daniel Lezcanofa453332011-06-21 00:57:08 +0200313static int clock_print_header(void)
314{
315 char *buf;
316 int ret;
317
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530318 if(clock_fw == CCF) {
319 if (asprintf(&buf, "%-35s %-10s %-12s %-10s %-11s %-15s %-14s %-14s",
320 "Name", "Flags", "Rate", "Usecount", "Children", "Prepare_Count",
321 "Enable_Count", "Notifier_Count") < 0)
322 return -1;
323 }
324 else {
325 if (asprintf(&buf, "%-55s %-16s %-12s %-9s %-8s",
Daniel Lezcanofa453332011-06-21 00:57:08 +0200326 "Name", "Flags", "Rate", "Usecount", "Children") < 0)
327 return -1;
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530328 }
Daniel Lezcanofa453332011-06-21 00:57:08 +0200329
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200330 ret = display_column_name(buf);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200331
332 free(buf);
333
334 return ret;
335}
336
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200337static int clock_print_info(struct tree *tree)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200338{
339 int ret, line = 0;
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200340
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200341 display_reset_cursor(CLOCK);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200342
Daniel Lezcanofa453332011-06-21 00:57:08 +0200343 clock_print_header();
344
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200345 ret = tree_for_each(tree, clock_print_info_cb, &line);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200346
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200347 display_refresh_pad(CLOCK);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200348
349 return ret;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200350}
351
Daniel Lezcano73b40022011-06-21 00:57:08 +0200352static int clock_select(void)
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200353{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200354 struct tree *t = display_get_row_data(CLOCK);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200355 struct clock_info *clk = t->private;
356
357 clk->expanded = !clk->expanded;
358
359 return 0;
360}
361
362/*
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200363 * Read the clock information and fill the tree with the information
364 * found in the files. Then print the result to the text based interface
365 * Return 0 on success, < 0 otherwise
366 */
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200367static int clock_display(bool refresh)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200368{
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200369 if (refresh && read_clock_info(clock_tree))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200370 return -1;
371
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200372 return clock_print_info(clock_tree);
373}
374
Daniel Lezcano73b40022011-06-21 00:57:08 +0200375static int clock_find(const char *name)
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200376{
377 struct tree **ptree = NULL;
378 int i, nr, line = 0, ret = 0;
379
380 nr = tree_finds(clock_tree, name, &ptree);
381
382 display_reset_cursor(CLOCK);
383
384 for (i = 0; i < nr; i++) {
385
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200386 ret = _clock_print_info_cb(ptree[i], &line);
387 if (ret)
388 break;
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200389
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200390 }
391
392 display_refresh_pad(CLOCK);
393
394 free(ptree);
395
396 return ret;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200397}
398
Daniel Lezcano73b40022011-06-21 00:57:08 +0200399static int clock_selectf(void)
400{
401 struct tree *t = display_get_row_data(CLOCK);
402 int line = 0;
403
404 display_reset_cursor(CLOCK);
405
406 if (tree_for_each_parent(t, _clock_print_info_cb, &line))
407 return -1;
408
409 return display_refresh_pad(CLOCK);
410}
411
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200412/*
413 * Read the clock information and fill the tree with the information
414 * found in the files. Then dump to stdout a formatted result.
415 * @clk : a name for a specific clock we want to show
416 * Return 0 on success, < 0 otherwise
417 */
Daniel Lezcano597892a2011-06-15 15:45:12 +0200418int clock_dump(char *clk)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200419{
420 int ret;
421
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200422 if (read_clock_info(clock_tree))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200423 return -1;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530424
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200425 if (clk) {
426 printf("\nParents for \"%s\" Clock :\n\n", clk);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200427 ret = dump_all_parents(clk);
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200428 printf("\n\n");
429 } else {
430 printf("\nClock Tree :\n");
431 printf("**********\n");
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200432 ret = dump_clock_info();
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200433 printf("\n\n");
434 }
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200435
436 return ret;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200437}
Daniel Lezcanob301b082011-06-15 15:45:12 +0200438
439static struct display_ops clock_ops = {
440 .display = clock_display,
Daniel Lezcano73b40022011-06-21 00:57:08 +0200441 .select = clock_select,
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200442 .find = clock_find,
Daniel Lezcano73b40022011-06-21 00:57:08 +0200443 .selectf = clock_selectf,
Daniel Lezcanob301b082011-06-15 15:45:12 +0200444};
445
446/*
447 * Initialize the clock framework
448 */
449int clock_init(void)
450{
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530451 char clk_dir_path[MAX+1][PATH_MAX];
Daniel Lezcanob301b082011-06-15 15:45:12 +0200452
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530453 if (locate_debugfs(clk_dir_path[CCF]) || locate_debugfs(clk_dir_path[OCF]))
Daniel Lezcanob301b082011-06-15 15:45:12 +0200454 return -1;
455
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530456 sprintf(clk_dir_path[CCF], "%s/clk", clk_dir_path[CCF]);
457 sprintf(clk_dir_path[OCF], "%s/clock", clk_dir_path[OCF]);
458 if (!access(clk_dir_path[CCF], F_OK)) {
459 clock_fw = CCF;
460 strcpy(clk_dir_path[MAX],clk_dir_path[CCF]);
461 }
462 else if(!access(clk_dir_path[OCF], F_OK)) {
463 clock_fw = OCF;
464 strcpy(clk_dir_path[MAX],clk_dir_path[OCF]);
465 }
466 else
Daniel Lezcanob301b082011-06-15 15:45:12 +0200467 return -1;
468
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530469 clock_tree = tree_load(clk_dir_path[MAX], NULL, false);
Daniel Lezcanob301b082011-06-15 15:45:12 +0200470 if (!clock_tree)
471 return -1;
472
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200473 if (fill_clock_tree())
474 return -1;
475
476 return display_register(CLOCK, &clock_ops);
Daniel Lezcanob301b082011-06-15 15:45:12 +0200477}