aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-14 17:24:42 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-14 17:24:42 -0400
commitb6825d2df55aa7d7341c715b577b73a6a03dc944 (patch)
treeae4f0f52f4c2ad4e501dd323318486ccdd7fcd93 /arch/arm/mach-omap2/clock.c
parent6defd90433729c2d795865165cb34d938d8ff07c (diff)
parentaa59e19d05114f9fb7718d6bc8398255476fb4f5 (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.c64
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 @@
61u8 cpu_mask; 62u8 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 */
76void 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 */
477long omap2_clk_round_rate(struct clk *clk, unsigned long rate) 515long 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 */
566void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) 604void __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)