diff options
Diffstat (limited to 'arch/arm/mach-omap2/dpll3xxx.c')
| -rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 377 |
1 files changed, 255 insertions, 122 deletions
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index fc56745676f..6d7ba37e225 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -28,9 +28,8 @@ #include <linux/bitops.h> #include <linux/clkdev.h> -#include <plat/cpu.h> -#include <plat/clock.h> - +#include "soc.h" +#include "clockdomain.h" #include "clock.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-34xx.h" @@ -44,42 +43,44 @@ /* Private functions */ /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ -static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) +static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits) { const struct dpll_data *dd; u32 v; dd = clk->dpll_data; - v = __raw_readl(dd->control_reg); + v = omap2_clk_readl(clk, dd->control_reg); v &= ~dd->enable_mask; v |= clken_bits << __ffs(dd->enable_mask); - __raw_writel(v, dd->control_reg); + omap2_clk_writel(v, clk, dd->control_reg); } /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ -static int _omap3_wait_dpll_status(struct clk *clk, u8 state) +static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state) { const struct dpll_data *dd; int i = 0; int ret = -EINVAL; + const char *clk_name; dd = clk->dpll_data; + clk_name = __clk_get_name(clk->hw.clk); state <<= __ffs(dd->idlest_mask); - while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) && - i < MAX_DPLL_WAIT_TRIES) { + while (((omap2_clk_readl(clk, dd->idlest_reg) & dd->idlest_mask) + != state) && i < MAX_DPLL_WAIT_TRIES) { i++; udelay(1); } if (i == MAX_DPLL_WAIT_TRIES) { printk(KERN_ERR "clock: %s failed transition to '%s'\n", - clk->name, (state) ? "locked" : "bypassed"); + clk_name, (state) ? "locked" : "bypassed"); } else { pr_debug("clock: %s transition to '%s' in %d loops\n", - clk->name, (state) ? "locked" : "bypassed", i); + clk_name, (state) ? "locked" : "bypassed", i); ret = 0; } @@ -88,12 +89,12 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state) } /* From 3430 TRM ES2 4.7.6.2 */ -static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n) +static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n) { unsigned long fint; u16 f = 0; - fint = clk->dpll_data->clk_ref->rate / n; + fint = __clk_get_rate(clk->dpll_data->clk_ref) / n; pr_debug("clock: fint is %lu\n", fint); @@ -133,16 +134,26 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n) * locked successfully, return 0; if the DPLL did not lock in the time * allotted, or DPLL3 was passed in, return -EINVAL. */ -static int _omap3_noncore_dpll_lock(struct clk *clk) +static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk) { + const struct dpll_data *dd; u8 ai; - int r; + u8 state = 1; + int r = 0; + + pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk)); + + dd = clk->dpll_data; + state <<= __ffs(dd->idlest_mask); - pr_debug("clock: locking DPLL %s\n", clk->name); + /* Check if already locked */ + if ((omap2_clk_readl(clk, dd->idlest_reg) & dd->idlest_mask) == state) + goto done; ai = omap3_dpll_autoidle_read(clk); - omap3_dpll_deny_idle(clk); + if (ai) + omap3_dpll_deny_idle(clk); _omap3_dpll_write_clken(clk, DPLL_LOCKED); @@ -151,6 +162,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk) if (ai) omap3_dpll_allow_idle(clk); +done: return r; } @@ -167,7 +179,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk) * DPLL3 was passed in, or the DPLL does not support low-power bypass, * return -EINVAL. */ -static int _omap3_noncore_dpll_bypass(struct clk *clk) +static int _omap3_noncore_dpll_bypass(struct clk_hw_omap *clk) { int r; u8 ai; @@ -176,7 +188,7 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk) return -EINVAL; pr_debug("clock: configuring DPLL %s for low-power bypass\n", - clk->name); + __clk_get_name(clk->hw.clk)); ai = omap3_dpll_autoidle_read(clk); @@ -186,8 +198,6 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk) if (ai) omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); return r; } @@ -201,14 +211,14 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk) * code. If DPLL3 was passed in, or the DPLL does not support * low-power stop, return -EINVAL; otherwise, return 0. */ -static int _omap3_noncore_dpll_stop(struct clk *clk) +static int _omap3_noncore_dpll_stop(struct clk_hw_omap *clk) { u8 ai; if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) return -EINVAL; - pr_debug("clock: stopping DPLL %s\n", clk->name); + pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk)); ai = omap3_dpll_autoidle_read(clk); @@ -216,8 +226,6 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) if (ai) omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); return 0; } @@ -234,11 +242,11 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) * XXX This code is not needed for 3430/AM35xx; can it be optimized * out in non-multi-OMAP builds for those chips? */ -static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n) +static void _lookup_dco(struct clk_hw_omap *clk, u8 *dco, u16 m, u8 n) { unsigned long fint, clkinp; /* watch out for overflow */ - clkinp = clk->parent->rate; + clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk)); fint = (clkinp / n) * m; if (fint < 1000000000) @@ -259,12 +267,12 @@ static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n) * XXX This code is not needed for 3430/AM35xx; can it be optimized * out in non-multi-OMAP builds for those chips? */ -static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n) +static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) { unsigned long clkinp, sd; /* watch out for overflow */ int mod1, mod2; - clkinp = clk->parent->rate; + clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk)); /* * target sigma-delta to near 250MHz @@ -283,15 +291,13 @@ static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n) /* * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly - * @clk: struct clk * of DPLL to set - * @m: DPLL multiplier to set - * @n: DPLL divider to set - * @freqsel: FREQSEL value to set + * @clk: struct clk * of DPLL to set + * @freqsel: FREQSEL value to set * - * Program the DPLL with the supplied M, N values, and wait for the DPLL to - * lock.. Returns -EINVAL upon error, or 0 upon success. + * Program the DPLL with the last M, N values calculated, and wait for + * the DPLL to lock. Returns -EINVAL upon error, or 0 upon success. */ -static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) +static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) { struct dpll_data *dd = clk->dpll_data; u8 dco, sd_div; @@ -301,35 +307,66 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) _omap3_noncore_dpll_bypass(clk); /* - * Set jitter correction. No jitter correction for OMAP4 and 3630 - * since freqsel field is no longer present + * Set jitter correction. Jitter correction applicable for OMAP343X + * only since freqsel field is no longer present on other devices. */ - if (!cpu_is_omap44xx() && !cpu_is_omap3630()) { - v = __raw_readl(dd->control_reg); + if (cpu_is_omap343x()) { + v = omap2_clk_readl(clk, dd->control_reg); v &= ~dd->freqsel_mask; v |= freqsel << __ffs(dd->freqsel_mask); - __raw_writel(v, dd->control_reg); + omap2_clk_writel(v, clk, dd->control_reg); } /* Set DPLL multiplier, divider */ - v = __raw_readl(dd->mult_div1_reg); + v = omap2_clk_readl(clk, dd->mult_div1_reg); + + /* Handle Duty Cycle Correction */ + if (dd->dcc_mask) { + if (dd->last_rounded_rate >= dd->dcc_rate) + v |= dd->dcc_mask; /* Enable DCC */ + else + v &= ~dd->dcc_mask; /* Disable DCC */ + } + v &= ~(dd->mult_mask | dd->div1_mask); - v |= m << __ffs(dd->mult_mask); - v |= (n - 1) << __ffs(dd->div1_mask); + v |= dd->last_rounded_m << __ffs(dd->mult_mask); + v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); /* Configure dco and sd_div for dplls that have these fields */ if (dd->dco_mask) { - _lookup_dco(clk, &dco, m, n); + _lookup_dco(clk, &dco, dd->last_rounded_m, dd->last_rounded_n); v &= ~(dd->dco_mask); v |= dco << __ffs(dd->dco_mask); } if (dd->sddiv_mask) { - _lookup_sddiv(clk, &sd_div, m, n); + _lookup_sddiv(clk, &sd_div, dd->last_rounded_m, + dd->last_rounded_n); v &= ~(dd->sddiv_mask); v |= sd_div << __ffs(dd->sddiv_mask); } - __raw_writel(v, dd->mult_div1_reg); + omap2_clk_writel(v, clk, dd->mult_div1_reg); + + /* Set 4X multiplier and low-power mode */ + if (dd->m4xen_mask || dd->lpmode_mask) { + v = omap2_clk_readl(clk, dd->control_reg); + + if (dd->m4xen_mask) { + if (dd->last_rounded_m4xen) + v |= dd->m4xen_mask; + else + v &= ~dd->m4xen_mask; + } + + if (dd->lpmode_mask) { + if (dd->last_rounded_lpmode) + v |= dd->lpmode_mask; + else + v &= ~dd->lpmode_mask; + } + + omap2_clk_writel(v, clk, dd->control_reg); + } /* We let the clock framework set the other output dividers later */ @@ -348,8 +385,10 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) * * Recalculate and propagate the DPLL rate. */ -unsigned long omap3_dpll_recalc(struct clk *clk) +unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate) { + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + return omap2_get_dpll_rate(clk); } @@ -369,29 +408,37 @@ unsigned long omap3_dpll_recalc(struct clk *clk) * support low-power stop, or if the DPLL took too long to enter * bypass or lock, return -EINVAL; otherwise, return 0. */ -int omap3_noncore_dpll_enable(struct clk *clk) +int omap3_noncore_dpll_enable(struct clk_hw *hw) { + struct clk_hw_omap *clk = to_clk_hw_omap(hw); int r; struct dpll_data *dd; + struct clk *parent; dd = clk->dpll_data; if (!dd) return -EINVAL; - if (clk->rate == dd->clk_bypass->rate) { - WARN_ON(clk->parent != dd->clk_bypass); + if (clk->clkdm) { + r = clkdm_clk_enable(clk->clkdm, hw->clk); + if (r) { + WARN(1, + "%s: could not enable %s's clockdomain %s: %d\n", + __func__, __clk_get_name(hw->clk), + clk->clkdm->name, r); + return r; + } + } + + parent = __clk_get_parent(hw->clk); + + if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) { + WARN_ON(parent != dd->clk_bypass); r = _omap3_noncore_dpll_bypass(clk); } else { - WARN_ON(clk->parent != dd->clk_ref); + WARN_ON(parent != dd->clk_ref); r = _omap3_noncore_dpll_lock(clk); } - /* - *FIXME: this is dubious - if clk->rate has changed, what about - * propagating? - */ - if (!r) - clk->rate = (clk->recalc) ? clk->recalc(clk) : - omap2_get_dpll_rate(clk); return r; } @@ -403,9 +450,13 @@ int omap3_noncore_dpll_enable(struct clk *clk) * Instructs a non-CORE DPLL to enter low-power stop. This function is * intended for use in struct clkops. No return value. */ -void omap3_noncore_dpll_disable(struct clk *clk) +void omap3_noncore_dpll_disable(struct clk_hw *hw) { + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + _omap3_noncore_dpll_stop(clk); + if (clk->clkdm) + clkdm_clk_disable(clk->clkdm, hw->clk); } @@ -422,79 +473,69 @@ void omap3_noncore_dpll_disable(struct clk *clk) * target rate if it hasn't been done already, then program and lock * the DPLL. Returns -EINVAL upon error, or 0 upon success. */ -int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) +int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) { + struct clk_hw_omap *clk = to_clk_hw_omap(hw); struct clk *new_parent = NULL; - unsigned long hw_rate; u16 freqsel = 0; struct dpll_data *dd; int ret; - if (!clk || !rate) + if (!hw || !rate) return -EINVAL; dd = clk->dpll_data; if (!dd) return -EINVAL; - hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk); - if (rate == hw_rate) - return 0; - - /* - * Ensure both the bypass and ref clocks are enabled prior to - * doing anything; we need the bypass clock running to reprogram - * the DPLL. - */ - omap2_clk_enable(dd->clk_bypass); - omap2_clk_enable(dd->clk_ref); - - if (dd->clk_bypass->rate == rate && - (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - pr_debug("clock: %s: set rate: entering bypass.\n", clk->name); + if (__clk_get_rate(dd->clk_bypass) == rate && + (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { + pr_debug("%s: %s: set rate: entering bypass.\n", + __func__, __clk_get_name(hw->clk)); + __clk_prepare(dd->clk_bypass); + clk_enable(dd->clk_bypass); ret = _omap3_noncore_dpll_bypass(clk); if (!ret) new_parent = dd->clk_bypass; + clk_disable(dd->clk_bypass); + __clk_unprepare(dd->clk_bypass); } else { + __clk_prepare(dd->clk_ref); + clk_enable(dd->clk_ref); + if (dd->last_rounded_rate != rate) - rate = clk->round_rate(clk, rate); + rate = __clk_round_rate(hw->clk, rate); if (dd->last_rounded_rate == 0) return -EINVAL; - /* No freqsel on OMAP4 and OMAP3630 */ - if (!cpu_is_omap44xx() && !cpu_is_omap3630()) { + /* Freqsel is available only on OMAP343X devices */ + if (cpu_is_omap343x()) { freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); - if (!freqsel) - WARN_ON(1); + WARN_ON(!freqsel); } - pr_debug("clock: %s: set rate: locking rate to %lu.\n", - clk->name, rate); + pr_debug("%s: %s: set rate: locking rate to %lu.\n", + __func__, __clk_get_name(hw->clk), rate); - ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m, - dd->last_rounded_n, freqsel); + ret = omap3_noncore_dpll_program(clk, freqsel); if (!ret) new_parent = dd->clk_ref; + clk_disable(dd->clk_ref); + __clk_unprepare(dd->clk_ref); } - if (!ret) { - /* - * Switch the parent clock in the hierarchy, and make sure - * that the new parent's usecount is correct. Note: we - * enable the new parent before disabling the old to avoid - * any unnecessary hardware disable->enable transitions. - */ - if (clk->usecount) { - omap2_clk_enable(new_parent); - omap2_clk_disable(clk->parent); - } - clk_reparent(clk, new_parent); - clk->rate = rate; - } - omap2_clk_disable(dd->clk_ref); - omap2_clk_disable(dd->clk_bypass); + /* + * FIXME - this is all wrong. common code handles reparenting and + * migrating prepare/enable counts. dplls should be a multiplexer + * clock and this should be a set_parent operation so that all of that + * stuff is inherited for free + */ + + if (!ret && clk_get_parent(hw->clk) != new_parent) + __clk_reparent(hw->clk, new_parent); return 0; } @@ -509,7 +550,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate) * -EINVAL if passed a null pointer or if the struct clk does not * appear to refer to a DPLL. */ -u32 omap3_dpll_autoidle_read(struct clk *clk) +u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk) { const struct dpll_data *dd; u32 v; @@ -519,7 +560,10 @@ u32 omap3_dpll_autoidle_read(struct clk *clk) dd = clk->dpll_data; - v = __raw_readl(dd->autoidle_reg); + if (!dd->autoidle_reg) + return -EINVAL; + + v = omap2_clk_readl(clk, dd->autoidle_reg); v &= dd->autoidle_mask; v >>= __ffs(dd->autoidle_mask); @@ -535,7 +579,7 @@ u32 omap3_dpll_autoidle_read(struct clk *clk) * OMAP3430. The DPLL will enter low-power stop when its downstream * clocks are gated. No return value. */ -void omap3_dpll_allow_idle(struct clk *clk) +void omap3_dpll_allow_idle(struct clk_hw_omap *clk) { const struct dpll_data *dd; u32 v; @@ -545,15 +589,19 @@ void omap3_dpll_allow_idle(struct clk *clk) dd = clk->dpll_data; + if (!dd->autoidle_reg) + return; + /* * REVISIT: CORE DPLL can optionally enter low-power bypass * by writing 0x5 instead of 0x1. Add some mechanism to * optionally enter this mode. */ - v = __raw_readl(dd->autoidle_reg); + v = omap2_clk_readl(clk, dd->autoidle_reg); v &= ~dd->autoidle_mask; v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); + omap2_clk_writel(v, clk, dd->autoidle_reg); + } /** @@ -562,7 +610,7 @@ void omap3_dpll_allow_idle(struct clk *clk) * * Disable DPLL automatic idle control. No return value. */ -void omap3_dpll_deny_idle(struct clk *clk) +void omap3_dpll_deny_idle(struct clk_hw_omap *clk) { const struct dpll_data *dd; u32 v; @@ -572,15 +620,44 @@ void omap3_dpll_deny_idle(struct clk *clk) dd = clk->dpll_data; - v = __raw_readl(dd->autoidle_reg); + if (!dd->autoidle_reg) + return; + + v = omap2_clk_readl(clk, dd->autoidle_reg); v &= ~dd->autoidle_mask; v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); - __raw_writel(v, dd->autoidle_reg); + omap2_clk_writel(v, clk, dd->autoidle_reg); } /* Clock control for DPLL outputs */ +/* Find the parent DPLL for the given clkoutx2 clock */ +static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw) +{ + struct clk_hw_omap *pclk = NULL; + struct clk *parent; + + /* Walk up the parents of clk, looking for a DPLL */ + do { + do { + parent = __clk_get_parent(hw->clk); + hw = __clk_get_hw(parent); + } while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC)); + if (!hw) + break; + pclk = to_clk_hw_omap(hw); + } while (pclk && !pclk->dpll_data); + + /* clk does not have a DPLL as a parent? error in the clock data */ + if (!pclk) { + WARN_ON(1); + return NULL; + } + + return pclk; +} + /** * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate * @clk: DPLL output struct clk @@ -588,30 +665,86 @@ void omap3_dpll_deny_idle(struct clk *clk) * Using parent clock DPLL data, look up DPLL state. If locked, set our * rate to the dpll_clk * 2; otherwise, just use dpll_clk. */ -unsigned long omap3_clkoutx2_recalc(struct clk *clk) +unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, + unsigned long parent_rate) { const struct dpll_data *dd; unsigned long rate; u32 v; - struct clk *pclk; + struct clk_hw_omap *pclk = NULL; - /* Walk up the parents of clk, looking for a DPLL */ - pclk = clk->parent; - while (pclk && !pclk->dpll_data) - pclk = pclk->parent; + if (!parent_rate) + return 0; - /* clk does not have a DPLL as a parent? */ - WARN_ON(!pclk); + pclk = omap3_find_clkoutx2_dpll(hw); + + if (!pclk) + return 0; dd = pclk->dpll_data; WARN_ON(!dd->enable_mask); - v = __raw_readl(dd->control_reg) & dd->enable_mask; + v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask; v >>= __ffs(dd->enable_mask); if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE)) - rate = clk->parent->rate; + rate = parent_rate; else - rate = clk->parent->rate * 2; + rate = parent_rate * 2; return rate; } + +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + const struct dpll_data *dd; + u32 v; + struct clk_hw_omap *pclk = NULL; + + if (!*prate) + return 0; + + pclk = omap3_find_clkoutx2_dpll(hw); + + if (!pclk) + return 0; + + dd = pclk->dpll_data; + + /* TYPE J does not have a clkoutx2 */ + if (dd->flags & DPLL_J_TYPE) { + *prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate); + return *prate; + } + + WARN_ON(!dd->enable_mask); + + v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask; + v >>= __ffs(dd->enable_mask); + + /* If in bypass, the rate is fixed to the bypass rate*/ + if (v != OMAP3XXX_EN_DPLL_LOCKED) + return *prate; + + if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) { + unsigned long best_parent; + + best_parent = (rate / 2); + *prate = __clk_round_rate(__clk_get_parent(hw->clk), + best_parent); + } + + return *prate * 2; +} + +/* OMAP3/4 non-CORE DPLL clkops */ +const struct clk_hw_omap_ops clkhwops_omap3_dpll = { + .allow_idle = omap3_dpll_allow_idle, + .deny_idle = omap3_dpll_deny_idle, +}; |
