/** * omap2_clksel_set_parent() - change a clock's parent clock * @clk: struct clk * of the child clock * @new_parent: struct clk * of the new parent clock * * This function is intended to be called only by the clock framework. * Change the parent clock of clock @clk to @new_parent. This is * intended to be used while @clk is disabled. This function does not * currently check the usecount of the clock, so if multiple drivers * are using the clock, and the parent is changed, they will all be * affected without any notification. Returns -EINVAL upon error, or * 0 upon success. */ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val = 0; u32 parent_div; if (!clk->clksel || !clk->clksel_mask) return -EINVAL; parent_div = _get_div_and_fieldval(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; _write_clksel_reg(clk, field_val); clk_reparent(clk, new_parent); /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = __clk_get_rate(new_parent); if (parent_div > 0) __clk_get_rate(clk) /= parent_div; pr_debug("clock: %s: set parent to %s (new rate %ld)\n", __clk_get_name(clk), __clk_get_name(__clk_get_parent(clk)), __clk_get_rate(clk)); return 0; }
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val = 0; u32 parent_div; if (!clk->clksel || !clk->clksel_mask) return -EINVAL; parent_div = _get_div_and_fieldval(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; _write_clksel_reg(clk, field_val); clk_reparent(clk, new_parent); clk->rate = new_parent->rate; if (parent_div > 0) clk->rate /= parent_div; pr_debug("clock: %s: set parent to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); return 0; }
/** * omap2_clksel_set_parent() - change a clock's parent clock * @clk: struct clk * of the child clock * @new_parent: struct clk * of the new parent clock * * This function is intended to be called only by the clock framework. * Change the parent clock of clock @clk to @new_parent. This is * intended to be used while @clk is disabled. This function does not * currently check the usecount of the clock, so if multiple drivers * are using the clock, and the parent is changed, they will all be * affected without any notification. Returns -EINVAL upon error, or * 0 upon success. */ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) { u32 field_val = 0; u32 parent_div; u32 parent_mul = 0; if (!clk->clksel || !clk->clksel_mask) return -EINVAL; parent_div = _get_div_and_fieldval(new_parent, clk, &field_val, &parent_mul); if (!parent_div) return -EINVAL; _write_clksel_reg(clk, field_val); clk_reparent(clk, new_parent); /* CLKSEL clocks follow their parents' rates, divided by a divisor */ clk->rate = _calculate_rate(new_parent->rate, parent_div, parent_mul); pr_debug("clock: %s: set parent to %s (new rate %ld)\n", clk->name, clk->parent->name, clk->rate); return 0; }
/* given a clock and its new parent, predict the new rate for clock */ long omap2_clk_round_rate_parent(struct clk *clk, struct clk *new_parent) { u32 field_val; u8 parent_div; long rate; if (!clk->clksel || !new_parent) return -EINVAL; parent_div = _get_div_and_fieldval(new_parent, clk, &field_val); if (!parent_div) return -EINVAL; /* CLKSEL clocks follow their parents' rates, divided by a divisor */ rate = new_parent->rate; if (parent_div > 0) rate /= parent_div; return rate; }