static void __clk_enable(struct clk *clk) { if (!clk) return; /* enable parent clock first */ if (clk->parent) __clk_enable(clk->parent); if (clk->use_cnt++ == 0) { if (clk_is_pll1(clk)) { /* PLL1 */ chipcHw_pll1Enable(clk->rate_hz, 0); } else if (clk_is_pll2(clk)) { /* PLL2 */ chipcHw_pll2Enable(clk->rate_hz); } else if (clk_is_using_xtal(clk)) { /* source is crystal */ if (!clk_is_primary(clk)) chipcHw_bypassClockEnable(clk->csp_id); } else { /* source is PLL */ chipcHw_setClockEnable(clk->csp_id); } } }
static void __clk_enable(struct clk *clk) { if (!clk) return; if (clk->parent) __clk_enable(clk->parent); if (clk->use_cnt++ == 0) { if (clk_is_pll1(clk)) { chipcHw_pll1Enable(clk->rate_hz, 0); } else if (clk_is_pll2(clk)) { chipcHw_pll2Enable(clk->rate_hz); } else if (clk_is_using_xtal(clk)) { if (!clk_is_primary(clk)) chipcHw_bypassClockEnable(clk->csp_id); } else { chipcHw_setClockEnable(clk->csp_id); } } }
int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; struct clk *old_parent; if (!clk || !parent) return -EINVAL; if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) return -EINVAL; /* if more than one user, parent is not allowed */ if (clk->use_cnt > 1) return -EBUSY; if (clk->parent == parent) return 0; spin_lock_irqsave(&clk_lock, flags); old_parent = clk->parent; clk->parent = parent; if (clk_is_using_xtal(parent)) clk->mode |= CLK_MODE_XTAL; else clk->mode &= (~CLK_MODE_XTAL); /* if clock is active */ if (clk->use_cnt != 0) { clk->use_cnt--; /* enable clock with the new parent */ __clk_enable(clk); /* disable the old parent */ __clk_disable(old_parent); } spin_unlock_irqrestore(&clk_lock, flags); return 0; }
int clk_set_parent(struct clk *clk, struct clk *parent) { unsigned long flags; struct clk *old_parent; if (!clk || !parent) return -EINVAL; if (!clk_is_primary(parent) || !clk_is_bypassable(clk)) return -EINVAL; if (clk->use_cnt > 1) return -EBUSY; if (clk->parent == parent) return 0; spin_lock_irqsave(&clk_lock, flags); old_parent = clk->parent; clk->parent = parent; if (clk_is_using_xtal(parent)) clk->mode |= CLK_MODE_XTAL; else clk->mode &= (~CLK_MODE_XTAL); if (clk->use_cnt != 0) { clk->use_cnt--; __clk_enable(clk); __clk_disable(old_parent); } spin_unlock_irqrestore(&clk_lock, flags); return 0; }
static void __clk_disable(struct clk *clk) { if (!clk) return; BUG_ON(clk->use_cnt == 0); if (--clk->use_cnt == 0) { if (clk_is_pll1(clk)) { /* PLL1 */ chipcHw_pll1Disable(); } else if (clk_is_pll2(clk)) { /* PLL2 */ chipcHw_pll2Disable(); } else if (clk_is_using_xtal(clk)) { /* source is crystal */ if (!clk_is_primary(clk)) chipcHw_bypassClockDisable(clk->csp_id); } else { /* source is PLL */ chipcHw_setClockDisable(clk->csp_id); } } if (clk->parent) __clk_disable(clk->parent); }