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