aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-10-20 11:07:19 -0400
committerDavid Vrabel <david.vrabel@csr.com>2008-10-20 11:07:19 -0400
commit61e0e79ee3c609eb34edf2fe023708cba6a79b1f (patch)
tree663deacffd4071120dc9badb70428fe5f124c7b9 /arch/arm/mach-omap2/clock.c
parentc15895ef30c2c03e99802951787183039a349d32 (diff)
parent0cfd81031a26717fe14380d18275f8e217571615 (diff)
Merge branch 'master' into for-upstream
Conflicts: Documentation/ABI/testing/sysfs-bus-usb drivers/Makefile
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c69
1 files changed, 53 insertions, 16 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 1d891e4a6933..ad721e0cbf7a 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -21,11 +21,11 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <asm/bitops.h> 24#include <linux/io.h>
25 25#include <linux/bitops.h>
26#include <asm/io.h>
27 26
28#include <mach/clock.h> 27#include <mach/clock.h>
28#include <mach/clockdomain.h>
29#include <mach/sram.h> 29#include <mach/sram.h>
30#include <mach/cpu.h> 30#include <mach/cpu.h>
31#include <asm/div64.h> 31#include <asm/div64.h>
@@ -62,10 +62,36 @@
62u8 cpu_mask; 62u8 cpu_mask;
63 63
64/*------------------------------------------------------------------------- 64/*-------------------------------------------------------------------------
65 * Omap2 specific clock functions 65 * OMAP2/3 specific clock functions
66 *-------------------------------------------------------------------------*/ 66 *-------------------------------------------------------------------------*/
67 67
68/** 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/**
69 * 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
70 * @clk: OMAP clock struct ptr to use 96 * @clk: OMAP clock struct ptr to use
71 * 97 *
@@ -251,7 +277,7 @@ int _omap2_clk_enable(struct clk *clk)
251 if (clk->enable) 277 if (clk->enable)
252 return clk->enable(clk); 278 return clk->enable(clk);
253 279
254 if (unlikely(clk->enable_reg == 0)) { 280 if (unlikely(clk->enable_reg == NULL)) {
255 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",
256 clk->name); 282 clk->name);
257 return 0; /* REVISIT: -EINVAL */ 283 return 0; /* REVISIT: -EINVAL */
@@ -283,7 +309,7 @@ void _omap2_clk_disable(struct clk *clk)
283 return; 309 return;
284 } 310 }
285 311
286 if (clk->enable_reg == 0) { 312 if (clk->enable_reg == NULL) {
287 /* 313 /*
288 * 'Independent' here refers to a clock which is not 314 * 'Independent' here refers to a clock which is not
289 * controlled by its parent. 315 * controlled by its parent.
@@ -308,6 +334,9 @@ void omap2_clk_disable(struct clk *clk)
308 _omap2_clk_disable(clk); 334 _omap2_clk_disable(clk);
309 if (likely((u32)clk->parent)) 335 if (likely((u32)clk->parent))
310 omap2_clk_disable(clk->parent); 336 omap2_clk_disable(clk->parent);
337 if (clk->clkdm)
338 omap2_clkdm_clk_disable(clk->clkdm, clk);
339
311 } 340 }
312} 341}
313 342
@@ -324,11 +353,19 @@ int omap2_clk_enable(struct clk *clk)
324 return ret; 353 return ret;
325 } 354 }
326 355
356 if (clk->clkdm)
357 omap2_clkdm_clk_enable(clk->clkdm, clk);
358
327 ret = _omap2_clk_enable(clk); 359 ret = _omap2_clk_enable(clk);
328 360
329 if (unlikely(ret != 0) && clk->parent) { 361 if (unlikely(ret != 0)) {
330 omap2_clk_disable(clk->parent); 362 if (clk->clkdm)
331 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 }
332 } 369 }
333 } 370 }
334 371
@@ -477,7 +514,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
477/* 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 */
478long omap2_clk_round_rate(struct clk *clk, unsigned long rate) 515long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
479{ 516{
480 if (clk->round_rate != 0) 517 if (clk->round_rate != NULL)
481 return clk->round_rate(clk, rate); 518 return clk->round_rate(clk, rate);
482 519
483 if (clk->flags & RATE_FIXED) 520 if (clk->flags & RATE_FIXED)
@@ -566,7 +603,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
566 */ 603 */
567void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask) 604void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
568{ 605{
569 if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0))) 606 if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
570 return NULL; 607 return NULL;
571 608
572 *field_mask = clk->clksel_mask; 609 *field_mask = clk->clksel_mask;
@@ -586,7 +623,7 @@ u32 omap2_clksel_get_divisor(struct clk *clk)
586 void __iomem *div_addr; 623 void __iomem *div_addr;
587 624
588 div_addr = omap2_get_clksel(clk, &field_mask); 625 div_addr = omap2_get_clksel(clk, &field_mask);
589 if (div_addr == 0) 626 if (div_addr == NULL)
590 return 0; 627 return 0;
591 628
592 field_val = __raw_readl(div_addr) & field_mask; 629 field_val = __raw_readl(div_addr) & field_mask;
@@ -605,7 +642,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
605 return -EINVAL; 642 return -EINVAL;
606 643
607 div_addr = omap2_get_clksel(clk, &field_mask); 644 div_addr = omap2_get_clksel(clk, &field_mask);
608 if (div_addr == 0) 645 if (div_addr == NULL)
609 return -EINVAL; 646 return -EINVAL;
610 647
611 field_val = omap2_divisor_to_clksel(clk, new_div); 648 field_val = omap2_divisor_to_clksel(clk, new_div);
@@ -643,7 +680,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
643 return -EINVAL; 680 return -EINVAL;
644 681
645 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ 682 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
646 if (clk->set_rate != 0) 683 if (clk->set_rate != NULL)
647 ret = clk->set_rate(clk, rate); 684 ret = clk->set_rate(clk, rate);
648 685
649 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES))) 686 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
@@ -664,7 +701,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
664 const struct clksel_rate *clkr; 701 const struct clksel_rate *clkr;
665 702
666 *parent_div = 0; 703 *parent_div = 0;
667 *src_addr = 0; 704 *src_addr = NULL;
668 705
669 clks = omap2_get_clksel_by_parent(clk, src_clk); 706 clks = omap2_get_clksel_by_parent(clk, src_clk);
670 if (clks == NULL) 707 if (clks == NULL)
@@ -705,7 +742,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
705 742
706 field_val = omap2_clksel_get_src_field(&src_addr, new_parent, 743 field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
707 &field_mask, clk, &parent_div); 744 &field_mask, clk, &parent_div);
708 if (src_addr == 0) 745 if (src_addr == NULL)
709 return -EINVAL; 746 return -EINVAL;
710 747
711 if (clk->usecount > 0) 748 if (clk->usecount > 0)