diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-14 17:24:42 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-14 17:24:42 -0400 |
commit | b6825d2df55aa7d7341c715b577b73a6a03dc944 (patch) | |
tree | ae4f0f52f4c2ad4e501dd323318486ccdd7fcd93 /arch/arm/mach-omap2/clock.c | |
parent | 6defd90433729c2d795865165cb34d938d8ff07c (diff) | |
parent | aa59e19d05114f9fb7718d6bc8398255476fb4f5 (diff) |
Merge branch 'omap-all' into devel
Conflicts:
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/irq.c
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 97cde3d3611d..ad721e0cbf7a 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
26 | 26 | ||
27 | #include <mach/clock.h> | 27 | #include <mach/clock.h> |
28 | #include <mach/clockdomain.h> | ||
28 | #include <mach/sram.h> | 29 | #include <mach/sram.h> |
29 | #include <mach/cpu.h> | 30 | #include <mach/cpu.h> |
30 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
@@ -61,10 +62,36 @@ | |||
61 | u8 cpu_mask; | 62 | u8 cpu_mask; |
62 | 63 | ||
63 | /*------------------------------------------------------------------------- | 64 | /*------------------------------------------------------------------------- |
64 | * Omap2 specific clock functions | 65 | * OMAP2/3 specific clock functions |
65 | *-------------------------------------------------------------------------*/ | 66 | *-------------------------------------------------------------------------*/ |
66 | 67 | ||
67 | /** | 68 | /** |
69 | * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk | ||
70 | * @clk: OMAP clock struct ptr to use | ||
71 | * | ||
72 | * Convert a clockdomain name stored in a struct clk 'clk' into a | ||
73 | * clockdomain pointer, and save it into the struct clk. Intended to be | ||
74 | * called during clk_register(). No return value. | ||
75 | */ | ||
76 | void omap2_init_clk_clkdm(struct clk *clk) | ||
77 | { | ||
78 | struct clockdomain *clkdm; | ||
79 | |||
80 | if (!clk->clkdm_name) | ||
81 | return; | ||
82 | |||
83 | clkdm = clkdm_lookup(clk->clkdm_name); | ||
84 | if (clkdm) { | ||
85 | pr_debug("clock: associated clk %s to clkdm %s\n", | ||
86 | clk->name, clk->clkdm_name); | ||
87 | clk->clkdm = clkdm; | ||
88 | } else { | ||
89 | pr_debug("clock: could not associate clk %s to " | ||
90 | "clkdm %s\n", clk->name, clk->clkdm_name); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | /** | ||
68 | * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware | 95 | * omap2_init_clksel_parent - set a clksel clk's parent field from the hardware |
69 | * @clk: OMAP clock struct ptr to use | 96 | * @clk: OMAP clock struct ptr to use |
70 | * | 97 | * |
@@ -250,7 +277,7 @@ int _omap2_clk_enable(struct clk *clk) | |||
250 | if (clk->enable) | 277 | if (clk->enable) |
251 | return clk->enable(clk); | 278 | return clk->enable(clk); |
252 | 279 | ||
253 | if (unlikely(clk->enable_reg == 0)) { | 280 | if (unlikely(clk->enable_reg == NULL)) { |
254 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | 281 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", |
255 | clk->name); | 282 | clk->name); |
256 | return 0; /* REVISIT: -EINVAL */ | 283 | return 0; /* REVISIT: -EINVAL */ |
@@ -282,7 +309,7 @@ void _omap2_clk_disable(struct clk *clk) | |||
282 | return; | 309 | return; |
283 | } | 310 | } |
284 | 311 | ||
285 | if (clk->enable_reg == 0) { | 312 | if (clk->enable_reg == NULL) { |
286 | /* | 313 | /* |
287 | * 'Independent' here refers to a clock which is not | 314 | * 'Independent' here refers to a clock which is not |
288 | * controlled by its parent. | 315 | * controlled by its parent. |
@@ -307,6 +334,9 @@ void omap2_clk_disable(struct clk *clk) | |||
307 | _omap2_clk_disable(clk); | 334 | _omap2_clk_disable(clk); |
308 | if (likely((u32)clk->parent)) | 335 | if (likely((u32)clk->parent)) |
309 | omap2_clk_disable(clk->parent); | 336 | omap2_clk_disable(clk->parent); |
337 | if (clk->clkdm) | ||
338 | omap2_clkdm_clk_disable(clk->clkdm, clk); | ||
339 | |||
310 | } | 340 | } |
311 | } | 341 | } |
312 | 342 | ||
@@ -323,11 +353,19 @@ int omap2_clk_enable(struct clk *clk) | |||
323 | return ret; | 353 | return ret; |
324 | } | 354 | } |
325 | 355 | ||
356 | if (clk->clkdm) | ||
357 | omap2_clkdm_clk_enable(clk->clkdm, clk); | ||
358 | |||
326 | ret = _omap2_clk_enable(clk); | 359 | ret = _omap2_clk_enable(clk); |
327 | 360 | ||
328 | if (unlikely(ret != 0) && clk->parent) { | 361 | if (unlikely(ret != 0)) { |
329 | omap2_clk_disable(clk->parent); | 362 | if (clk->clkdm) |
330 | clk->usecount--; | 363 | omap2_clkdm_clk_disable(clk->clkdm, clk); |
364 | |||
365 | if (clk->parent) { | ||
366 | omap2_clk_disable(clk->parent); | ||
367 | clk->usecount--; | ||
368 | } | ||
331 | } | 369 | } |
332 | } | 370 | } |
333 | 371 | ||
@@ -476,7 +514,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate) | |||
476 | /* Given a clock and a rate apply a clock specific rounding function */ | 514 | /* Given a clock and a rate apply a clock specific rounding function */ |
477 | long omap2_clk_round_rate(struct clk *clk, unsigned long rate) | 515 | long omap2_clk_round_rate(struct clk *clk, unsigned long rate) |
478 | { | 516 | { |
479 | if (clk->round_rate != 0) | 517 | if (clk->round_rate != NULL) |
480 | return clk->round_rate(clk, rate); | 518 | return clk->round_rate(clk, rate); |
481 | 519 | ||
482 | if (clk->flags & RATE_FIXED) | 520 | if (clk->flags & RATE_FIXED) |
@@ -565,7 +603,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div) | |||
565 | */ | 603 | */ |
566 | void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) | 604 | void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) |
567 | { | 605 | { |
568 | if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0))) | 606 | if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL))) |
569 | return NULL; | 607 | return NULL; |
570 | 608 | ||
571 | *field_mask = clk->clksel_mask; | 609 | *field_mask = clk->clksel_mask; |
@@ -585,7 +623,7 @@ u32 omap2_clksel_get_divisor(struct clk *clk) | |||
585 | void __iomem *div_addr; | 623 | void __iomem *div_addr; |
586 | 624 | ||
587 | div_addr = omap2_get_clksel(clk, &field_mask); | 625 | div_addr = omap2_get_clksel(clk, &field_mask); |
588 | if (div_addr == 0) | 626 | if (div_addr == NULL) |
589 | return 0; | 627 | return 0; |
590 | 628 | ||
591 | field_val = __raw_readl(div_addr) & field_mask; | 629 | field_val = __raw_readl(div_addr) & field_mask; |
@@ -604,7 +642,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) | |||
604 | return -EINVAL; | 642 | return -EINVAL; |
605 | 643 | ||
606 | div_addr = omap2_get_clksel(clk, &field_mask); | 644 | div_addr = omap2_get_clksel(clk, &field_mask); |
607 | if (div_addr == 0) | 645 | if (div_addr == NULL) |
608 | return -EINVAL; | 646 | return -EINVAL; |
609 | 647 | ||
610 | field_val = omap2_divisor_to_clksel(clk, new_div); | 648 | field_val = omap2_divisor_to_clksel(clk, new_div); |
@@ -642,7 +680,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate) | |||
642 | return -EINVAL; | 680 | return -EINVAL; |
643 | 681 | ||
644 | /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ | 682 | /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ |
645 | if (clk->set_rate != 0) | 683 | if (clk->set_rate != NULL) |
646 | ret = clk->set_rate(clk, rate); | 684 | ret = clk->set_rate(clk, rate); |
647 | 685 | ||
648 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) | 686 | if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) |
@@ -663,7 +701,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr, | |||
663 | const struct clksel_rate *clkr; | 701 | const struct clksel_rate *clkr; |
664 | 702 | ||
665 | *parent_div = 0; | 703 | *parent_div = 0; |
666 | *src_addr = 0; | 704 | *src_addr = NULL; |
667 | 705 | ||
668 | clks = omap2_get_clksel_by_parent(clk, src_clk); | 706 | clks = omap2_get_clksel_by_parent(clk, src_clk); |
669 | if (clks == NULL) | 707 | if (clks == NULL) |
@@ -704,7 +742,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) | |||
704 | 742 | ||
705 | field_val = omap2_clksel_get_src_field(&src_addr, new_parent, | 743 | field_val = omap2_clksel_get_src_field(&src_addr, new_parent, |
706 | &field_mask, clk, &parent_div); | 744 | &field_mask, clk, &parent_div); |
707 | if (src_addr == 0) | 745 | if (src_addr == NULL) |
708 | return -EINVAL; | 746 | return -EINVAL; |
709 | 747 | ||
710 | if (clk->usecount > 0) | 748 | if (clk->usecount > 0) |