blob: 203411a41898abc83073d21a985e5b96aefd589c [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 Sun73e5d972013-08-21 17:04:34 +080081static inline const char *clock_rate(uint *rate)
Daniel Lezcanoc6718332011-03-23 14:37:39 +010082{
Shaojie Sun73e5d972013-08-21 17:04:34 +080083 uint r;
Daniel Lezcanoc6718332011-03-23 14:37:39 +010084
Daniel Lezcanoafe62252011-06-08 23:30:00 +020085 /* GHZ */
86 r = *rate >> 30;
87 if (r) {
88 *rate = r;
89 return "GHZ";
90 }
Daniel Lezcanoc6718332011-03-23 14:37:39 +010091
Daniel Lezcanoafe62252011-06-08 23:30:00 +020092 /* MHZ */
93 r = *rate >> 20;
94 if (r) {
95 *rate = r;
96 return "MHZ";
97 }
Daniel Lezcanoc6718332011-03-23 14:37:39 +010098
Daniel Lezcanoafe62252011-06-08 23:30:00 +020099 /* KHZ */
100 r = *rate >> 10;
101 if (r) {
102 *rate = r;
103 return "KHZ";
104 }
105
106 return "";
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100107}
108
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200109static int dump_clock_cb(struct tree *t, void *data)
Daniel Lezcanoef323192011-03-26 22:06:20 +0100110{
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200111 struct clock_info *clk = t->private;
112 struct clock_info *pclk;
113 const char *unit;
114 int ret = 0;
Shaojie Sun73e5d972013-08-21 17:04:34 +0800115 uint rate = clk->rate;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100116
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200117 if (!t->parent) {
118 printf("/\n");
119 clk->prefix = "";
120 return 0;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100121 }
122
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200123 pclk = t->parent->private;
124
125 if (!clk->prefix)
126 ret = asprintf(&clk->prefix, "%s%s%s", pclk->prefix,
127 t->depth > 1 ? " ": "", t->next ? "|" : " ");
128 if (ret < 0)
129 return -1;
130
131 unit = clock_rate(&rate);
132
Shaojie Sun73e5d972013-08-21 17:04:34 +0800133 printf("%s%s-- %s (flags:0x%x, usecount:%d, rate: %u %s)\n",
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200134 clk->prefix, !t->next ? "`" : "", t->name, clk->flags,
135 clk->usecount, rate, unit);
136
137 return 0;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100138}
139
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200140int dump_clock_info(void)
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100141{
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200142 return tree_for_each(clock_tree, dump_clock_cb, NULL);
143}
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100144
Daniel Lezcano3e38e0f2011-06-08 23:30:00 +0200145static int dump_all_parents(char *clkarg)
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200146{
147 struct tree *tree;
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100148
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200149 tree = tree_find(clock_tree, clkarg);
150 if (!tree) {
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100151 printf("Clock NOT found!\n");
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200152 return -1;
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100153 }
Daniel Lezcanoafe62252011-06-08 23:30:00 +0200154
155 return tree_for_each_parent(tree, dump_clock_cb, NULL);
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100156}
157
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200158static inline int read_clock_cb(struct tree *t, void *data)
Daniel Lezcanoef323192011-03-26 22:06:20 +0100159{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200160 struct clock_info *clk = t->private;
Daniel Lezcanoef323192011-03-26 22:06:20 +0100161
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530162 if(clock_fw == CCF) {
163 file_read_value(t->path, "clk_flags", "%x", &clk->flags);
Shaojie Sun73e5d972013-08-21 17:04:34 +0800164 file_read_value(t->path, "clk_rate", "%u", &clk->rate);
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530165 file_read_value(t->path, "clk_prepare_count", "%d", &clk->preparecount);
166 file_read_value(t->path, "clk_enable_count", "%d", &clk->enablecount);
167 file_read_value(t->path, "clk_notifier_count", "%d", &clk->notifiercount);
168 }
169 else {
170 file_read_value(t->path, "flags", "%x", &clk->flags);
Shaojie Sun73e5d972013-08-21 17:04:34 +0800171 file_read_value(t->path, "rate", "%u", &clk->rate);
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530172 file_read_value(t->path, "usecount", "%d", &clk->usecount);
173 }
Amit Arora3bc8c922010-11-16 11:27:38 +0530174
175 return 0;
176}
177
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200178static int read_clock_info(struct tree *tree)
Amit Aroraac4e8652010-11-09 11:16:53 +0530179{
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200180 return tree_for_each(tree, read_clock_cb, NULL);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200181}
182
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200183static int fill_clock_cb(struct tree *t, void *data)
184{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200185 struct clock_info *clk;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200186
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200187 clk = clock_alloc();
188 if (!clk)
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200189 return -1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200190 t->private = clk;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200191
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200192 /* we skip the root node but we set it expanded for its children */
193 if (!t->parent) {
194 clk->expanded = true;
195 return 0;
196 }
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200197
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200198 return read_clock_cb(t, data);
199}
200
201static int fill_clock_tree(void)
202{
203 return tree_for_each(clock_tree, fill_clock_cb, NULL);
204}
205
206static int is_collapsed(struct tree *t, void *data)
207{
208 struct clock_info *clk = t->private;
209
210 if (!clk->expanded)
211 return 1;
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200212
213 return 0;
214}
215
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200216static char *clock_line(struct tree *t)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530217{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200218 struct clock_info *clk;
Shaojie Sun73e5d972013-08-21 17:04:34 +0800219 uint rate;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200220 const char *clkunit;
221 char *clkrate, *clkname, *clkline = NULL;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200222
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200223 clk = t->private;
224 rate = clk->rate;
225 clkunit = clock_rate(&rate);
226
227 if (asprintf(&clkname, "%*s%s", (t->depth - 1) * 2, "", t->name) < 0)
228 return NULL;
229
230 if (asprintf(&clkrate, "%d%s", rate, clkunit) < 0)
231 goto free_clkname;
232
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530233 if(clock_fw == CCF) {
234 if (asprintf(&clkline, "%-35s 0x%-8x %-12s %-10d %-11d %-15d %-14d %-10d",
235 clkname, clk->flags, clkrate, clk->usecount, t->nrchild,
236 clk->preparecount, clk->enablecount, clk->notifiercount) < 0)
237 goto free_clkrate;
238 }
239 else {
240 if (asprintf(&clkline, "%-55s 0x%-16x %-12s %-9d %-8d",
241 clkname, clk->flags, clkrate, clk->usecount, t->nrchild) < 0)
242 goto free_clkrate;
243 }
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200244
245free_clkrate:
246 free(clkrate);
247free_clkname:
248 free(clkname);
249
250 return clkline;
251}
252
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200253static int _clock_print_info_cb(struct tree *t, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200254{
255 struct clock_info *clock = t->private;
256 int *line = data;
257 char *buffer;
258
Daniel Lezcano73b40022011-06-21 00:57:08 +0200259 /* we skip the root node of the tree */
260 if (!t->parent)
261 return 0;
262
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200263 buffer = clock_line(t);
264 if (!buffer)
Daniel Lezcano9d5431c2011-06-08 23:30:00 +0200265 return -1;
266
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200267 display_print_line(CLOCK, *line, buffer, clock->usecount, t);
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200268
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200269 (*line)++;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200270
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200271 free(buffer);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200272
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200273 return 0;
274}
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200275
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200276static int clock_print_info_cb(struct tree *t, void *data)
277{
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200278 /* we skip the root node of the tree */
279 if (!t->parent)
280 return 0;
281
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200282 /* show the clock when *all* its parent is expanded */
283 if (tree_for_each_parent(t->parent, is_collapsed, NULL))
284 return 0;
285
286 return _clock_print_info_cb(t, data);
287}
288
Daniel Lezcanofa453332011-06-21 00:57:08 +0200289static int clock_print_header(void)
290{
291 char *buf;
292 int ret;
293
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530294 if(clock_fw == CCF) {
295 if (asprintf(&buf, "%-35s %-10s %-12s %-10s %-11s %-15s %-14s %-14s",
296 "Name", "Flags", "Rate", "Usecount", "Children", "Prepare_Count",
297 "Enable_Count", "Notifier_Count") < 0)
298 return -1;
299 }
300 else {
301 if (asprintf(&buf, "%-55s %-16s %-12s %-9s %-8s",
Daniel Lezcanofa453332011-06-21 00:57:08 +0200302 "Name", "Flags", "Rate", "Usecount", "Children") < 0)
303 return -1;
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530304 }
Daniel Lezcanofa453332011-06-21 00:57:08 +0200305
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200306 ret = display_column_name(buf);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200307
308 free(buf);
309
310 return ret;
311}
312
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200313static int clock_print_info(struct tree *tree)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200314{
315 int ret, line = 0;
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200316
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200317 display_reset_cursor(CLOCK);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200318
Daniel Lezcanofa453332011-06-21 00:57:08 +0200319 clock_print_header();
320
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200321 ret = tree_for_each(tree, clock_print_info_cb, &line);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200322
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200323 display_refresh_pad(CLOCK);
Daniel Lezcanob2565a82011-06-08 23:30:00 +0200324
325 return ret;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200326}
327
Daniel Lezcano73b40022011-06-21 00:57:08 +0200328static int clock_select(void)
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200329{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200330 struct tree *t = display_get_row_data(CLOCK);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200331 struct clock_info *clk = t->private;
332
333 clk->expanded = !clk->expanded;
334
335 return 0;
336}
337
338/*
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200339 * Read the clock information and fill the tree with the information
340 * found in the files. Then print the result to the text based interface
341 * Return 0 on success, < 0 otherwise
342 */
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200343static int clock_display(bool refresh)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200344{
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200345 if (refresh && read_clock_info(clock_tree))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200346 return -1;
347
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200348 return clock_print_info(clock_tree);
349}
350
Daniel Lezcano73b40022011-06-21 00:57:08 +0200351static int clock_find(const char *name)
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200352{
353 struct tree **ptree = NULL;
354 int i, nr, line = 0, ret = 0;
355
356 nr = tree_finds(clock_tree, name, &ptree);
357
358 display_reset_cursor(CLOCK);
359
360 for (i = 0; i < nr; i++) {
361
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200362 ret = _clock_print_info_cb(ptree[i], &line);
363 if (ret)
364 break;
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200365
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200366 }
367
368 display_refresh_pad(CLOCK);
369
370 free(ptree);
371
372 return ret;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200373}
374
Daniel Lezcano73b40022011-06-21 00:57:08 +0200375static int clock_selectf(void)
376{
377 struct tree *t = display_get_row_data(CLOCK);
378 int line = 0;
379
380 display_reset_cursor(CLOCK);
381
382 if (tree_for_each_parent(t, _clock_print_info_cb, &line))
383 return -1;
384
385 return display_refresh_pad(CLOCK);
386}
387
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200388/*
389 * Read the clock information and fill the tree with the information
390 * found in the files. Then dump to stdout a formatted result.
391 * @clk : a name for a specific clock we want to show
392 * Return 0 on success, < 0 otherwise
393 */
Daniel Lezcano597892a2011-06-15 15:45:12 +0200394int clock_dump(char *clk)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200395{
396 int ret;
397
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200398 if (read_clock_info(clock_tree))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200399 return -1;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530400
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200401 if (clk) {
402 printf("\nParents for \"%s\" Clock :\n\n", clk);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200403 ret = dump_all_parents(clk);
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200404 printf("\n\n");
405 } else {
406 printf("\nClock Tree :\n");
407 printf("**********\n");
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200408 ret = dump_clock_info();
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200409 printf("\n\n");
410 }
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200411
412 return ret;
Daniel Lezcano28b53cd2011-06-08 23:30:00 +0200413}
Daniel Lezcanob301b082011-06-15 15:45:12 +0200414
415static struct display_ops clock_ops = {
416 .display = clock_display,
Daniel Lezcano73b40022011-06-21 00:57:08 +0200417 .select = clock_select,
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200418 .find = clock_find,
Daniel Lezcano73b40022011-06-21 00:57:08 +0200419 .selectf = clock_selectf,
Daniel Lezcanob301b082011-06-15 15:45:12 +0200420};
421
422/*
423 * Initialize the clock framework
424 */
425int clock_init(void)
426{
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530427 char clk_dir_path[MAX+1][PATH_MAX];
Daniel Lezcanob301b082011-06-15 15:45:12 +0200428
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530429 if (locate_debugfs(clk_dir_path[CCF]) || locate_debugfs(clk_dir_path[OCF]))
Daniel Lezcanob301b082011-06-15 15:45:12 +0200430 return -1;
431
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530432 sprintf(clk_dir_path[CCF], "%s/clk", clk_dir_path[CCF]);
433 sprintf(clk_dir_path[OCF], "%s/clock", clk_dir_path[OCF]);
434 if (!access(clk_dir_path[CCF], F_OK)) {
435 clock_fw = CCF;
436 strcpy(clk_dir_path[MAX],clk_dir_path[CCF]);
437 }
438 else if(!access(clk_dir_path[OCF], F_OK)) {
439 clock_fw = OCF;
440 strcpy(clk_dir_path[MAX],clk_dir_path[OCF]);
441 }
442 else
Daniel Lezcanob301b082011-06-15 15:45:12 +0200443 return -1;
444
Sanjay Singh Rawat88fdebb2013-01-24 18:13:47 +0530445 clock_tree = tree_load(clk_dir_path[MAX], NULL, false);
Daniel Lezcanob301b082011-06-15 15:45:12 +0200446 if (!clock_tree)
447 return -1;
448
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200449 if (fill_clock_tree())
450 return -1;
451
452 return display_register(CLOCK, &clock_ops);
Daniel Lezcanob301b082011-06-15 15:45:12 +0200453}