ARM: omap: clk: add clk_prepare and clk_unprepare
authorRajendra Nayak <rnayak@ti.com>
Sat, 22 Sep 2012 08:24:16 +0000 (02:24 -0600)
committerPaul Walmsley <paul@pwsan.com>
Sat, 22 Sep 2012 16:50:01 +0000 (10:50 -0600)
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>
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/clock3xxx.c
arch/arm/mach-omap2/display.c
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/omap_hwmod.c

index 3e2d76f05af4e4328ba9eb970ca8c118eff9e491..cea3abace815716b4fea93aa1e9aae1c61238740 100644 (file)
@@ -202,7 +202,7 @@ static inline void __init apollon_init_smc91x(void)
                return;
        }
 
-       clk_enable(gpmc_fck);
+       clk_prepare_enable(gpmc_fck);
        rate = clk_get_rate(gpmc_fck);
 
        eth_cs = APOLLON_ETH_CS;
@@ -246,7 +246,7 @@ static inline void __init apollon_init_smc91x(void)
                gpmc_cs_free(APOLLON_ETH_CS);
        }
 out:
-       clk_disable(gpmc_fck);
+       clk_disable_unprepare(gpmc_fck);
        clk_put(gpmc_fck);
 }
 
index 12569cb0eddd8ce24a59ad3cf46315cf39a001dc..313b3f426a56324551bacd0baa2779609ec0820f 100644 (file)
@@ -265,9 +265,9 @@ static inline void __init h4_init_debug(void)
                return;
        }
 
-       clk_enable(gpmc_fck);
+       clk_prepare_enable(gpmc_fck);
        rate = clk_get_rate(gpmc_fck);
-       clk_disable(gpmc_fck);
+       clk_disable_unprepare(gpmc_fck);
        clk_put(gpmc_fck);
 
        if (is_gpmc_muxed())
@@ -311,7 +311,7 @@ static inline void __init h4_init_debug(void)
                gpmc_cs_free(eth_cs);
 
 out:
-       clk_disable(gpmc_fck);
+       clk_disable_unprepare(gpmc_fck);
        clk_put(gpmc_fck);
 }
 
index 45fe2d3f59b1312a7b7652664029fda5b9f03cf5..8ae2c599dd7f326208530511e48e6487b78d042d 100644 (file)
@@ -171,7 +171,7 @@ static void __init omap4_ehci_init(void)
                return;
        }
        clk_set_rate(phy_ref_clk, 19200000);
-       clk_enable(phy_ref_clk);
+       clk_prepare_enable(phy_ref_clk);
 
        /* disable the power to the usb hub prior to init and reset phy+hub */
        ret = gpio_request_array(panda_ehci_gpios,
index fc2765bcdd404aed3127391501757d8d24aa1318..319ff52220b87eb2a8d1ab0246b84e90c9e6b359 100644 (file)
@@ -64,15 +64,15 @@ void __init omap3_clk_lock_dpll5(void)
 
        dpll5_clk = clk_get(NULL, "dpll5_ck");
        clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
-       clk_enable(dpll5_clk);
+       clk_prepare_enable(dpll5_clk);
 
        /* Program dpll5_m2_clk divider for no division */
        dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
-       clk_enable(dpll5_m2_clk);
+       clk_prepare_enable(dpll5_m2_clk);
        clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
 
-       clk_disable(dpll5_m2_clk);
-       clk_disable(dpll5_clk);
+       clk_disable_unprepare(dpll5_m2_clk);
+       clk_disable_unprepare(dpll5_clk);
        return;
 }
 
index af1ed7d24a1fbb20fd7e1fffba8ebb1f12bbcca5..5a3afd2b737d3587f26ec731fdb70dadcf092e64 100644 (file)
@@ -488,7 +488,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
 
        for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
                if (oc->_clk)
-                       clk_enable(oc->_clk);
+                       clk_prepare_enable(oc->_clk);
 
        dispc_disable_outputs();
 
@@ -515,7 +515,7 @@ int omap_dss_reset(struct omap_hwmod *oh)
 
        for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
                if (oc->_clk)
-                       clk_disable(oc->_clk);
+                       clk_disable_unprepare(oc->_clk);
 
        r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
 
index 055ae8bd943faee478134e4e783a5a878f3a345f..5de0f7b852f765e16219c76f2b52917b573c3cc7 100644 (file)
@@ -879,7 +879,7 @@ static int __init gpmc_init(void)
                BUG();
        }
 
-       clk_enable(gpmc_l3_clk);
+       clk_prepare_enable(gpmc_l3_clk);
 
        l = gpmc_read_reg(GPMC_REVISION);
        printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
index 6504f0e8d96eb8cbb04fbcbf833de2d1b674dcb6..99fd3bb3c432e1e0a0d2f19a862a6054cfcbfa0e 100644 (file)
@@ -685,6 +685,15 @@ static int _init_main_clk(struct omap_hwmod *oh)
                           oh->name, oh->main_clk);
                return -EINVAL;
        }
+       /*
+        * HACK: This needs a re-visit once clk_prepare() is implemented
+        * to do something meaningful. Today its just a no-op.
+        * If clk_prepare() is used at some point to do things like
+        * voltage scaling etc, then this would have to be moved to
+        * some point where subsystems like i2c and pmic become
+        * available.
+        */
+       clk_prepare(oh->_clk);
 
        if (!oh->_clk->clkdm)
                pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
@@ -722,6 +731,15 @@ static int _init_interface_clks(struct omap_hwmod *oh)
                        ret = -EINVAL;
                }
                os->_clk = c;
+               /*
+                * HACK: This needs a re-visit once clk_prepare() is implemented
+                * to do something meaningful. Today its just a no-op.
+                * If clk_prepare() is used at some point to do things like
+                * voltage scaling etc, then this would have to be moved to
+                * some point where subsystems like i2c and pmic become
+                * available.
+                */
+               clk_prepare(os->_clk);
        }
 
        return ret;
@@ -749,6 +767,15 @@ static int _init_opt_clks(struct omap_hwmod *oh)
                        ret = -EINVAL;
                }
                oc->_clk = c;
+               /*
+                * HACK: This needs a re-visit once clk_prepare() is implemented
+                * to do something meaningful. Today its just a no-op.
+                * If clk_prepare() is used at some point to do things like
+                * voltage scaling etc, then this would have to be moved to
+                * some point where subsystems like i2c and pmic become
+                * available.
+                */
+               clk_prepare(oc->_clk);
        }
 
        return ret;