int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { u32 field_mask, field_val, reg_val, validrate, new_div = 0; void __iomem *div_addr; validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); if (validrate != rate) return -EINVAL; div_addr = omap2_get_clksel(clk, &field_mask); if (div_addr == 0) return -EINVAL; field_val = omap2_divisor_to_clksel(clk, new_div); if (field_val == ~0) return -EINVAL; reg_val = __raw_readl(div_addr); reg_val &= ~field_mask; reg_val |= (field_val << __ffs(field_mask)); __raw_writel(reg_val, div_addr); wmb(); clk->rate = clk->parent->rate / new_div; if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); wmb(); } return 0; }
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) { u32 v, field_val, validrate, new_div = 0; if (!clk->clksel_mask) return -EINVAL; validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); if (validrate != rate) return -EINVAL; field_val = omap2_divisor_to_clksel(clk, new_div); if (field_val == ~0) 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); /* OCP barrier */ clk->rate = clk->parent->rate / new_div; _omap2xxx_clk_commit(clk); return 0; }