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>
This commit is contained in:
parent
a04bcc231c
commit
4d7cb45ee8
@ -202,7 +202,7 @@ static inline void __init apollon_init_smc91x(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_enable(gpmc_fck);
|
clk_prepare_enable(gpmc_fck);
|
||||||
rate = clk_get_rate(gpmc_fck);
|
rate = clk_get_rate(gpmc_fck);
|
||||||
|
|
||||||
eth_cs = APOLLON_ETH_CS;
|
eth_cs = APOLLON_ETH_CS;
|
||||||
@ -246,7 +246,7 @@ static inline void __init apollon_init_smc91x(void)
|
|||||||
gpmc_cs_free(APOLLON_ETH_CS);
|
gpmc_cs_free(APOLLON_ETH_CS);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
clk_disable(gpmc_fck);
|
clk_disable_unprepare(gpmc_fck);
|
||||||
clk_put(gpmc_fck);
|
clk_put(gpmc_fck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,9 +265,9 @@ static inline void __init h4_init_debug(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_enable(gpmc_fck);
|
clk_prepare_enable(gpmc_fck);
|
||||||
rate = clk_get_rate(gpmc_fck);
|
rate = clk_get_rate(gpmc_fck);
|
||||||
clk_disable(gpmc_fck);
|
clk_disable_unprepare(gpmc_fck);
|
||||||
clk_put(gpmc_fck);
|
clk_put(gpmc_fck);
|
||||||
|
|
||||||
if (is_gpmc_muxed())
|
if (is_gpmc_muxed())
|
||||||
@ -311,7 +311,7 @@ static inline void __init h4_init_debug(void)
|
|||||||
gpmc_cs_free(eth_cs);
|
gpmc_cs_free(eth_cs);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
clk_disable(gpmc_fck);
|
clk_disable_unprepare(gpmc_fck);
|
||||||
clk_put(gpmc_fck);
|
clk_put(gpmc_fck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ static void __init omap4_ehci_init(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clk_set_rate(phy_ref_clk, 19200000);
|
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 */
|
/* disable the power to the usb hub prior to init and reset phy+hub */
|
||||||
ret = gpio_request_array(panda_ehci_gpios,
|
ret = gpio_request_array(panda_ehci_gpios,
|
||||||
|
@ -64,15 +64,15 @@ void __init omap3_clk_lock_dpll5(void)
|
|||||||
|
|
||||||
dpll5_clk = clk_get(NULL, "dpll5_ck");
|
dpll5_clk = clk_get(NULL, "dpll5_ck");
|
||||||
clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
|
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 */
|
/* Program dpll5_m2_clk divider for no division */
|
||||||
dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
|
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_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
|
||||||
|
|
||||||
clk_disable(dpll5_m2_clk);
|
clk_disable_unprepare(dpll5_m2_clk);
|
||||||
clk_disable(dpll5_clk);
|
clk_disable_unprepare(dpll5_clk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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++)
|
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
|
||||||
if (oc->_clk)
|
if (oc->_clk)
|
||||||
clk_enable(oc->_clk);
|
clk_prepare_enable(oc->_clk);
|
||||||
|
|
||||||
dispc_disable_outputs();
|
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++)
|
for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
|
||||||
if (oc->_clk)
|
if (oc->_clk)
|
||||||
clk_disable(oc->_clk);
|
clk_disable_unprepare(oc->_clk);
|
||||||
|
|
||||||
r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
|
r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
|
||||||
|
|
||||||
|
@ -879,7 +879,7 @@ static int __init gpmc_init(void)
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_enable(gpmc_l3_clk);
|
clk_prepare_enable(gpmc_l3_clk);
|
||||||
|
|
||||||
l = gpmc_read_reg(GPMC_REVISION);
|
l = gpmc_read_reg(GPMC_REVISION);
|
||||||
printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
|
printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
|
||||||
|
@ -685,6 +685,15 @@ static int _init_main_clk(struct omap_hwmod *oh)
|
|||||||
oh->name, oh->main_clk);
|
oh->name, oh->main_clk);
|
||||||
return -EINVAL;
|
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)
|
if (!oh->_clk->clkdm)
|
||||||
pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
|
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;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
os->_clk = c;
|
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;
|
return ret;
|
||||||
@ -749,6 +767,15 @@ static int _init_opt_clks(struct omap_hwmod *oh)
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
oc->_clk = c;
|
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;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user