aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRajendra Nayak <rnayak@ti.com>2012-09-22 04:24:16 -0400
committerPaul Walmsley <paul@pwsan.com>2012-09-22 12:50:01 -0400
commit4d7cb45ee823541632a3d50f57031ce9fd60e13f (patch)
tree8d5dbefa5d4140a26fa830b4985ae5e2d3d4d4db /arch
parenta04bcc231c1bcfe7602bcb3e8d742ef796142275 (diff)
ARM: omap: clk: add clk_prepare and clk_unprepare
As part of Common Clk Framework (CCF) the clk_enable() operation was split into a clk_prepare() which could sleep, and a clk_enable() which should never sleep. Similarly the clk_disable() was split into clk_disable() and clk_unprepare(). This was needed to handle complex cases where in a clk gate/ungate would require a slow and a fast part to be implemented. None of the clocks below seem to be in the 'complex' clocks category and are just simple clocks which are enabled/disabled through simple register writes. Most of the instances also seem to be called in non-atomic context which means its safe to move all of those from using a clk_enable() to clk_prepare_enable() and clk_disable() to clk_disable_unprepare(). For some others, mainly the ones handled through the hwmod framework there is a possibility that they get called in either an atomic or a non-atomic context. The way these get handled below work only as long as clk_prepare is implemented as a no-op (which is the case today) since this gets called very early at boot while most subsystems are unavailable. Hence these are marked with a *HACK* comment, which says we need to re-visit these once we start doing something meaningful with clk_prepare/clk_unprepare like doing voltage scaling or something that involves i2c. This is in preparation of OMAP moving to CCF. Based on initial changes from Mike Turquette. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/board-apollon.c4
-rw-r--r--arch/arm/mach-omap2/board-h4.c6
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c2
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c8
-rw-r--r--arch/arm/mach-omap2/display.c4
-rw-r--r--arch/arm/mach-omap2/gpmc.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c27
7 files changed, 40 insertions, 13 deletions
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 3e2d76f05af4..cea3abace815 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -202,7 +202,7 @@ static inline void __init apollon_init_smc91x(void)
202 return; 202 return;
203 } 203 }
204 204
205 clk_enable(gpmc_fck); 205 clk_prepare_enable(gpmc_fck);
206 rate = clk_get_rate(gpmc_fck); 206 rate = clk_get_rate(gpmc_fck);
207 207
208 eth_cs = APOLLON_ETH_CS; 208 eth_cs = APOLLON_ETH_CS;
@@ -246,7 +246,7 @@ static inline void __init apollon_init_smc91x(void)
246 gpmc_cs_free(APOLLON_ETH_CS); 246 gpmc_cs_free(APOLLON_ETH_CS);
247 } 247 }
248out: 248out:
249 clk_disable(gpmc_fck); 249 clk_disable_unprepare(gpmc_fck);
250 clk_put(gpmc_fck); 250 clk_put(gpmc_fck);
251} 251}
252 252
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 12569cb0eddd..313b3f426a56 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -265,9 +265,9 @@ static inline void __init h4_init_debug(void)
265 return; 265 return;
266 } 266 }
267 267
268 clk_enable(gpmc_fck); 268 clk_prepare_enable(gpmc_fck);
269 rate = clk_get_rate(gpmc_fck); 269 rate = clk_get_rate(gpmc_fck);
270 clk_disable(gpmc_fck); 270 clk_disable_unprepare(gpmc_fck);
271 clk_put(gpmc_fck); 271 clk_put(gpmc_fck);
272 272
273 if (is_gpmc_muxed()) 273 if (is_gpmc_muxed())
@@ -311,7 +311,7 @@ static inline void __init h4_init_debug(void)
311 gpmc_cs_free(eth_cs); 311 gpmc_cs_free(eth_cs);
312 312
313out: 313out:
314 clk_disable(gpmc_fck); 314 clk_disable_unprepare(gpmc_fck);
315 clk_put(gpmc_fck); 315 clk_put(gpmc_fck);
316} 316}
317 317
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 45fe2d3f59b1..8ae2c599dd7f 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -171,7 +171,7 @@ static void __init omap4_ehci_init(void)
171 return; 171 return;
172 } 172 }
173 clk_set_rate(phy_ref_clk, 19200000); 173 clk_set_rate(phy_ref_clk, 19200000);
174 clk_enable(phy_ref_clk); 174 clk_prepare_enable(phy_ref_clk);
175 175
176 /* disable the power to the usb hub prior to init and reset phy+hub */ 176 /* disable the power to the usb hub prior to init and reset phy+hub */
177 ret = gpio_request_array(panda_ehci_gpios, 177 ret = gpio_request_array(panda_ehci_gpios,
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
index fc2765bcdd40..319ff52220b8 100644
--- a/arch/arm/mach-omap2/clock3xxx.c
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -64,15 +64,15 @@ void __init omap3_clk_lock_dpll5(void)
64 64
65 dpll5_clk = clk_get(NULL, "dpll5_ck"); 65 dpll5_clk = clk_get(NULL, "dpll5_ck");
66 clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST); 66 clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
67 clk_enable(dpll5_clk); 67 clk_prepare_enable(dpll5_clk);
68 68
69 /* Program dpll5_m2_clk divider for no division */ 69 /* Program dpll5_m2_clk divider for no division */
70 dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck"); 70 dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
71 clk_enable(dpll5_m2_clk); 71 clk_prepare_enable(dpll5_m2_clk);
72 clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST); 72 clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
73 73
74 clk_disable(dpll5_m2_clk); 74 clk_disable_unprepare(dpll5_m2_clk);
75 clk_disable(dpll5_clk); 75 clk_disable_unprepare(dpll5_clk);
76 return; 76 return;
77} 77}
78 78
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index af1ed7d24a1f..5a3afd2b737d 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -488,7 +488,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
488 488
489 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) 489 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
490 if (oc->_clk) 490 if (oc->_clk)
491 clk_enable(oc->_clk); 491 clk_prepare_enable(oc->_clk);
492 492
493 dispc_disable_outputs(); 493 dispc_disable_outputs();
494 494
@@ -515,7 +515,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
515 515
516 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) 516 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
517 if (oc->_clk) 517 if (oc->_clk)
518 clk_disable(oc->_clk); 518 clk_disable_unprepare(oc->_clk);
519 519
520 r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; 520 r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
521 521
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 055ae8bd943f..5de0f7b852f7 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -879,7 +879,7 @@ static int __init gpmc_init(void)
879 BUG(); 879 BUG();
880 } 880 }
881 881
882 clk_enable(gpmc_l3_clk); 882 clk_prepare_enable(gpmc_l3_clk);
883 883
884 l = gpmc_read_reg(GPMC_REVISION); 884 l = gpmc_read_reg(GPMC_REVISION);
885 printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); 885 printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6504f0e8d96e..99fd3bb3c432 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -685,6 +685,15 @@ static int _init_main_clk(struct omap_hwmod *oh)
685 oh->name, oh->main_clk); 685 oh->name, oh->main_clk);
686 return -EINVAL; 686 return -EINVAL;
687 } 687 }
688 /*
689 * HACK: This needs a re-visit once clk_prepare() is implemented
690 * to do something meaningful. Today its just a no-op.
691 * If clk_prepare() is used at some point to do things like
692 * voltage scaling etc, then this would have to be moved to
693 * some point where subsystems like i2c and pmic become
694 * available.
695 */
696 clk_prepare(oh->_clk);
688 697
689 if (!oh->_clk->clkdm) 698 if (!oh->_clk->clkdm)
690 pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n", 699 pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
@@ -722,6 +731,15 @@ static int _init_interface_clks(struct omap_hwmod *oh)
722 ret = -EINVAL; 731 ret = -EINVAL;
723 } 732 }
724 os->_clk = c; 733 os->_clk = c;
734 /*
735 * HACK: This needs a re-visit once clk_prepare() is implemented
736 * to do something meaningful. Today its just a no-op.
737 * If clk_prepare() is used at some point to do things like
738 * voltage scaling etc, then this would have to be moved to
739 * some point where subsystems like i2c and pmic become
740 * available.
741 */
742 clk_prepare(os->_clk);
725 } 743 }
726 744
727 return ret; 745 return ret;
@@ -749,6 +767,15 @@ static int _init_opt_clks(struct omap_hwmod *oh)
749 ret = -EINVAL; 767 ret = -EINVAL;
750 } 768 }
751 oc->_clk = c; 769 oc->_clk = c;
770 /*
771 * HACK: This needs a re-visit once clk_prepare() is implemented
772 * to do something meaningful. Today its just a no-op.
773 * If clk_prepare() is used at some point to do things like
774 * voltage scaling etc, then this would have to be moved to
775 * some point where subsystems like i2c and pmic become
776 * available.
777 */
778 clk_prepare(oc->_clk);
752 } 779 }
753 780
754 return ret; 781 return ret;