diff options
Diffstat (limited to 'arch/arm/mach-ux500/clock.c')
-rw-r--r-- | arch/arm/mach-ux500/clock.c | 365 |
1 files changed, 264 insertions, 101 deletions
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index 1675047daf20..912d1cc18c57 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -20,6 +20,12 @@ | |||
20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
21 | #include "clock.h" | 21 | #include "clock.h" |
22 | 22 | ||
23 | #ifdef CONFIG_DEBUG_FS | ||
24 | #include <linux/debugfs.h> | ||
25 | #include <linux/uaccess.h> /* for copy_from_user */ | ||
26 | static LIST_HEAD(clk_list); | ||
27 | #endif | ||
28 | |||
23 | #define PRCC_PCKEN 0x00 | 29 | #define PRCC_PCKEN 0x00 |
24 | #define PRCC_PCKDIS 0x04 | 30 | #define PRCC_PCKDIS 0x04 |
25 | #define PRCC_KCKEN 0x08 | 31 | #define PRCC_KCKEN 0x08 |
@@ -133,7 +139,7 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
133 | { | 139 | { |
134 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) | 140 | void __iomem *addr = __io_address(UX500_PRCMU_BASE) |
135 | + PRCM_TCR; | 141 | + PRCM_TCR; |
136 | u32 tcr = readl(addr); | 142 | u32 tcr; |
137 | int mtu = (int) clk->data; | 143 | int mtu = (int) clk->data; |
138 | /* | 144 | /* |
139 | * One of these is selected eventually | 145 | * One of these is selected eventually |
@@ -144,6 +150,14 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
144 | unsigned long mturate; | 150 | unsigned long mturate; |
145 | unsigned long retclk; | 151 | unsigned long retclk; |
146 | 152 | ||
153 | /* | ||
154 | * On a startup, always conifgure the TCR to the doze mode; | ||
155 | * bootloaders do it for us. Do this in the kernel too. | ||
156 | */ | ||
157 | writel(PRCM_TCR_DOZE_MODE, addr); | ||
158 | |||
159 | tcr = readl(addr); | ||
160 | |||
147 | /* Get the rate from the parent as a default */ | 161 | /* Get the rate from the parent as a default */ |
148 | if (clk->parent_periph) | 162 | if (clk->parent_periph) |
149 | mturate = clk_get_rate(clk->parent_periph); | 163 | mturate = clk_get_rate(clk->parent_periph); |
@@ -153,45 +167,6 @@ static unsigned long clk_mtu_get_rate(struct clk *clk) | |||
153 | /* We need to be connected SOMEWHERE */ | 167 | /* We need to be connected SOMEWHERE */ |
154 | BUG(); | 168 | BUG(); |
155 | 169 | ||
156 | /* | ||
157 | * Are we in doze mode? | ||
158 | * In this mode the parent peripheral or the fixed 32768 Hz | ||
159 | * clock is fed into the block. | ||
160 | */ | ||
161 | if (!(tcr & PRCM_TCR_DOZE_MODE)) { | ||
162 | /* | ||
163 | * Here we're using the clock input from the APE ULP | ||
164 | * clock domain. But first: are the timers stopped? | ||
165 | */ | ||
166 | if (tcr & PRCM_TCR_STOPPED) { | ||
167 | clk32k = 0; | ||
168 | mturate = 0; | ||
169 | } else { | ||
170 | /* Else default mode: 0 and 2.4 MHz */ | ||
171 | clk32k = 0; | ||
172 | if (cpu_is_u5500()) | ||
173 | /* DB5500 divides by 8 */ | ||
174 | mturate /= 8; | ||
175 | else if (cpu_is_u8500ed()) { | ||
176 | /* | ||
177 | * This clocking setting must not be used | ||
178 | * in the ED chip, it is simply not | ||
179 | * connected anywhere! | ||
180 | */ | ||
181 | mturate = 0; | ||
182 | BUG(); | ||
183 | } else | ||
184 | /* | ||
185 | * In this mode the ulp38m4 clock is divided | ||
186 | * by a factor 16, on the DB8500 typically | ||
187 | * 38400000 / 16 ~ 2.4 MHz. | ||
188 | * TODO: Replace the constant with a reference | ||
189 | * to the ULP source once this is modeled. | ||
190 | */ | ||
191 | mturate = 38400000 / 16; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /* Return the clock selected for this MTU */ | 170 | /* Return the clock selected for this MTU */ |
196 | if (tcr & (1 << mtu)) | 171 | if (tcr & (1 << mtu)) |
197 | retclk = clk32k; | 172 | retclk = clk32k; |
@@ -317,6 +292,7 @@ static struct clkops clk_prcc_ops = { | |||
317 | }; | 292 | }; |
318 | 293 | ||
319 | static struct clk clk_32khz = { | 294 | static struct clk clk_32khz = { |
295 | .name = "clk_32khz", | ||
320 | .rate = 32000, | 296 | .rate = 32000, |
321 | }; | 297 | }; |
322 | 298 | ||
@@ -366,94 +342,96 @@ static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */ | |||
366 | */ | 342 | */ |
367 | 343 | ||
368 | /* Peripheral Cluster #1 */ | 344 | /* Peripheral Cluster #1 */ |
369 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); | 345 | static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk); |
370 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); | 346 | static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL); |
371 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); | 347 | static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk); |
372 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); | 348 | static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL); |
373 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); | 349 | static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL); |
374 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); | 350 | static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk); |
375 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); | 351 | static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk); |
376 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); | 352 | static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk); |
377 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); | 353 | static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk); |
378 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); | 354 | static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk); |
379 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); | 355 | static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk); |
380 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); | 356 | static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk); |
381 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); | 357 | static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk); |
382 | 358 | ||
383 | /* Peripheral Cluster #2 */ | 359 | /* Peripheral Cluster #2 */ |
384 | 360 | ||
385 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); | 361 | static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL); |
386 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); | 362 | static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL); |
387 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); | 363 | static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL); |
388 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); | 364 | static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL); |
389 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); | 365 | static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk); |
390 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); | 366 | static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk); |
391 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); | 367 | static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk); |
392 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); | 368 | static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk); |
393 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); | 369 | static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL); |
394 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); | 370 | static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL); |
395 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); | 371 | static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL); |
396 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); | 372 | static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk); |
397 | 373 | ||
398 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); | 374 | static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL); |
399 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); | 375 | static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL); |
400 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); | 376 | static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL); |
401 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); | 377 | static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL); |
402 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); | 378 | static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk); |
403 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); | 379 | static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk); |
404 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); | 380 | static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk); |
405 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); | 381 | static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk); |
406 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); | 382 | static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL); |
407 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); | 383 | static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL); |
408 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); | 384 | static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL); |
409 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); | 385 | static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk); |
410 | 386 | ||
411 | /* Peripheral Cluster #3 */ | 387 | /* Peripheral Cluster #3 */ |
412 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); | 388 | static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL); |
413 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); | 389 | static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk); |
414 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); | 390 | static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk); |
415 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); | 391 | static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz); |
416 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); | 392 | static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk); |
417 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); | 393 | static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk); |
418 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); | 394 | static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk); |
419 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); | 395 | static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk); |
420 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); | 396 | static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk); |
421 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); | 397 | static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk); |
422 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); | 398 | static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL); |
423 | 399 | ||
424 | /* Peripheral Cluster #4 is in the always on domain */ | 400 | /* Peripheral Cluster #4 is in the always on domain */ |
425 | 401 | ||
426 | /* Peripheral Cluster #5 */ | 402 | /* Peripheral Cluster #5 */ |
427 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); | 403 | static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL); |
428 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); | 404 | static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk); |
429 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); | 405 | static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL); |
430 | 406 | ||
431 | /* Peripheral Cluster #6 */ | 407 | /* Peripheral Cluster #6 */ |
432 | 408 | ||
433 | /* MTU ID in data */ | 409 | /* MTU ID in data */ |
434 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); | 410 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1); |
435 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); | 411 | static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0); |
436 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); | 412 | static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL); |
437 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); | 413 | static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL); |
438 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); | 414 | static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL); |
439 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); | 415 | static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk); |
440 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); | 416 | static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL); |
441 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); | 417 | static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL); |
442 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); | 418 | static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL); |
443 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); | 419 | static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL); |
444 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); | 420 | static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk); |
445 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); | 421 | static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk); |
446 | 422 | ||
447 | /* Peripheral Cluster #7 */ | 423 | /* Peripheral Cluster #7 */ |
448 | 424 | ||
449 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); | 425 | static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL); |
450 | /* MTU ID in data */ | 426 | /* MTU ID in data */ |
451 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); | 427 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1); |
452 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); | 428 | static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0); |
453 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); | 429 | static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL); |
454 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); | 430 | static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL); |
455 | 431 | ||
456 | static struct clk clk_dummy_apb_pclk; | 432 | static struct clk clk_dummy_apb_pclk = { |
433 | .name = "apb_pclk", | ||
434 | }; | ||
457 | 435 | ||
458 | static struct clk_lookup u8500_common_clks[] = { | 436 | static struct clk_lookup u8500_common_clks[] = { |
459 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), | 437 | CLK(dummy_apb_pclk, NULL, "apb_pclk"), |
@@ -554,7 +532,7 @@ static struct clk_lookup u8500_ed_clks[] = { | |||
554 | 532 | ||
555 | static struct clk_lookup u8500_v1_clks[] = { | 533 | static struct clk_lookup u8500_v1_clks[] = { |
556 | /* Peripheral Cluster #1 */ | 534 | /* Peripheral Cluster #1 */ |
557 | CLK(i2c4, "nmk-i2c.4", NULL), | 535 | CLK(i2c4, "nmk-i2c.4", NULL), |
558 | CLK(spi3_v1, "spi3", NULL), | 536 | CLK(spi3_v1, "spi3", NULL), |
559 | CLK(msp1_v1, "msp1", NULL), | 537 | CLK(msp1_v1, "msp1", NULL), |
560 | 538 | ||
@@ -599,6 +577,183 @@ static struct clk_lookup u8500_v1_clks[] = { | |||
599 | CLK(uiccclk, "uicc", NULL), | 577 | CLK(uiccclk, "uicc", NULL), |
600 | }; | 578 | }; |
601 | 579 | ||
580 | #ifdef CONFIG_DEBUG_FS | ||
581 | /* | ||
582 | * debugfs support to trace clock tree hierarchy and attributes with | ||
583 | * powerdebug | ||
584 | */ | ||
585 | static struct dentry *clk_debugfs_root; | ||
586 | |||
587 | void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num) | ||
588 | { | ||
589 | while (num--) { | ||
590 | /* Check that the clock has not been already registered */ | ||
591 | if (!(cl->clk->list.prev != cl->clk->list.next)) | ||
592 | list_add_tail(&cl->clk->list, &clk_list); | ||
593 | |||
594 | cl++; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | static ssize_t usecount_dbg_read(struct file *file, char __user *buf, | ||
599 | size_t size, loff_t *off) | ||
600 | { | ||
601 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
602 | char cusecount[128]; | ||
603 | unsigned int len; | ||
604 | |||
605 | len = sprintf(cusecount, "%u\n", clk->enabled); | ||
606 | return simple_read_from_buffer(buf, size, off, cusecount, len); | ||
607 | } | ||
608 | |||
609 | static ssize_t rate_dbg_read(struct file *file, char __user *buf, | ||
610 | size_t size, loff_t *off) | ||
611 | { | ||
612 | struct clk *clk = file->f_dentry->d_inode->i_private; | ||
613 | char crate[128]; | ||
614 | unsigned int rate; | ||
615 | unsigned int len; | ||
616 | |||
617 | rate = clk_get_rate(clk); | ||
618 | len = sprintf(crate, "%u\n", rate); | ||
619 | return simple_read_from_buffer(buf, size, off, crate, len); | ||
620 | } | ||
621 | |||
622 | static const struct file_operations usecount_fops = { | ||
623 | .read = usecount_dbg_read, | ||
624 | }; | ||
625 | |||
626 | static const struct file_operations set_rate_fops = { | ||
627 | .read = rate_dbg_read, | ||
628 | }; | ||
629 | |||
630 | static struct dentry *clk_debugfs_register_dir(struct clk *c, | ||
631 | struct dentry *p_dentry) | ||
632 | { | ||
633 | struct dentry *d, *clk_d, *child, *child_tmp; | ||
634 | char s[255]; | ||
635 | char *p = s; | ||
636 | |||
637 | if (c->name == NULL) | ||
638 | p += sprintf(p, "BUG"); | ||
639 | else | ||
640 | p += sprintf(p, "%s", c->name); | ||
641 | |||
642 | clk_d = debugfs_create_dir(s, p_dentry); | ||
643 | if (!clk_d) | ||
644 | return NULL; | ||
645 | |||
646 | d = debugfs_create_file("usecount", S_IRUGO, | ||
647 | clk_d, c, &usecount_fops); | ||
648 | if (!d) | ||
649 | goto err_out; | ||
650 | d = debugfs_create_file("rate", S_IRUGO, | ||
651 | clk_d, c, &set_rate_fops); | ||
652 | if (!d) | ||
653 | goto err_out; | ||
654 | /* | ||
655 | * TODO : not currently available in ux500 | ||
656 | * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags); | ||
657 | * if (!d) | ||
658 | * goto err_out; | ||
659 | */ | ||
660 | |||
661 | return clk_d; | ||
662 | |||
663 | err_out: | ||
664 | d = clk_d; | ||
665 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
666 | debugfs_remove(child); | ||
667 | debugfs_remove(clk_d); | ||
668 | return NULL; | ||
669 | } | ||
670 | |||
671 | static void clk_debugfs_remove_dir(struct dentry *cdentry) | ||
672 | { | ||
673 | struct dentry *d, *child, *child_tmp; | ||
674 | |||
675 | d = cdentry; | ||
676 | list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) | ||
677 | debugfs_remove(child); | ||
678 | debugfs_remove(cdentry); | ||
679 | return ; | ||
680 | } | ||
681 | |||
682 | static int clk_debugfs_register_one(struct clk *c) | ||
683 | { | ||
684 | struct clk *pa = c->parent_periph; | ||
685 | struct clk *bpa = c->parent_cluster; | ||
686 | |||
687 | if (!(bpa && !pa)) { | ||
688 | c->dent = clk_debugfs_register_dir(c, | ||
689 | pa ? pa->dent : clk_debugfs_root); | ||
690 | if (!c->dent) | ||
691 | return -ENOMEM; | ||
692 | } | ||
693 | |||
694 | if (bpa) { | ||
695 | c->dent_bus = clk_debugfs_register_dir(c, | ||
696 | bpa->dent_bus ? bpa->dent_bus : bpa->dent); | ||
697 | if ((!c->dent_bus) && (c->dent)) { | ||
698 | clk_debugfs_remove_dir(c->dent); | ||
699 | c->dent = NULL; | ||
700 | return -ENOMEM; | ||
701 | } | ||
702 | } | ||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int clk_debugfs_register(struct clk *c) | ||
707 | { | ||
708 | int err; | ||
709 | struct clk *pa = c->parent_periph; | ||
710 | struct clk *bpa = c->parent_cluster; | ||
711 | |||
712 | if (pa && (!pa->dent && !pa->dent_bus)) { | ||
713 | err = clk_debugfs_register(pa); | ||
714 | if (err) | ||
715 | return err; | ||
716 | } | ||
717 | |||
718 | if (bpa && (!bpa->dent && !bpa->dent_bus)) { | ||
719 | err = clk_debugfs_register(bpa); | ||
720 | if (err) | ||
721 | return err; | ||
722 | } | ||
723 | |||
724 | if ((!c->dent) && (!c->dent_bus)) { | ||
725 | err = clk_debugfs_register_one(c); | ||
726 | if (err) | ||
727 | return err; | ||
728 | } | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static int __init clk_debugfs_init(void) | ||
733 | { | ||
734 | struct clk *c; | ||
735 | struct dentry *d; | ||
736 | int err; | ||
737 | |||
738 | d = debugfs_create_dir("clock", NULL); | ||
739 | if (!d) | ||
740 | return -ENOMEM; | ||
741 | clk_debugfs_root = d; | ||
742 | |||
743 | list_for_each_entry(c, &clk_list, list) { | ||
744 | err = clk_debugfs_register(c); | ||
745 | if (err) | ||
746 | goto err_out; | ||
747 | } | ||
748 | return 0; | ||
749 | err_out: | ||
750 | debugfs_remove_recursive(clk_debugfs_root); | ||
751 | return err; | ||
752 | } | ||
753 | |||
754 | late_initcall(clk_debugfs_init); | ||
755 | #endif /* defined(CONFIG_DEBUG_FS) */ | ||
756 | |||
602 | int __init clk_init(void) | 757 | int __init clk_init(void) |
603 | { | 758 | { |
604 | if (cpu_is_u8500ed()) { | 759 | if (cpu_is_u8500ed()) { |
@@ -609,7 +764,8 @@ int __init clk_init(void) | |||
609 | /* Clock tree for U5500 not implemented yet */ | 764 | /* Clock tree for U5500 not implemented yet */ |
610 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; | 765 | clk_prcc_ops.enable = clk_prcc_ops.disable = NULL; |
611 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; | 766 | clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL; |
612 | clk_per6clk.rate = 26000000; | 767 | clk_uartclk.rate = 36360000; |
768 | clk_sdmmcclk.rate = 99900000; | ||
613 | } | 769 | } |
614 | 770 | ||
615 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | 771 | clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); |
@@ -618,5 +774,12 @@ int __init clk_init(void) | |||
618 | else | 774 | else |
619 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | 775 | clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); |
620 | 776 | ||
777 | #ifdef CONFIG_DEBUG_FS | ||
778 | clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks)); | ||
779 | if (cpu_is_u8500ed()) | ||
780 | clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks)); | ||
781 | else | ||
782 | clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks)); | ||
783 | #endif | ||
621 | return 0; | 784 | return 0; |
622 | } | 785 | } |