int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val, v, parent_div; if (clk->flags & CONFIG_PARTICIPANT) return -EINVAL; if (!clk->clksel) return -EINVAL; parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; /* Set new source value (previous dividers if any in effect) */ v = __raw_readl(clk->clksel_reg); v &= ~clk->clksel_mask; v |= field_val << __ffs(clk->clksel_mask); __raw_writel(v, clk->clksel_reg); v = __raw_readl(clk->clksel_reg); /* OCP barrier */ _omap2xxx_clk_commit(clk); clk_reparent(clk, new_parent); /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = new_parent->rate; if (parent_div > 0) clk->rate /= parent_div; pr_debug("clock: set parent of %s to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); return 0; }
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val, v, parent_div; if (clk->flags & CONFIG_PARTICIPANT) return -EINVAL; if (!clk->clksel) return -EINVAL; parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; v = __raw_readl(clk->clksel_reg); v &= ~clk->clksel_mask; v |= field_val << __ffs(clk->clksel_mask); __raw_writel(v, clk->clksel_reg); v = __raw_readl(clk->clksel_reg); _omap2xxx_clk_commit(clk); clk_reparent(clk, new_parent); clk->rate = new_parent->rate; if (parent_div > 0) clk->rate /= parent_div; pr_debug("clock: set parent of %s to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); return 0; }