static int local_clk_enable(struct clk *clk) { int ret = 0; if (clk->usecount == 0) { if (clk->parent) { ret = local_clk_enable(clk->parent); if (ret != 0) goto out; } if (clk->enable) ret = clk->enable(clk); else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate && clk->user_rate) ret = clk->set_rate(clk, clk->user_rate); if (ret != 0 && clk->parent) { local_clk_disable(clk->parent); goto out; } clk->usecount++; } out: return ret; }
int clk_enable(struct clk *clk) { int ret; clock_lock(); ret = local_clk_enable(clk); clock_unlock(); return ret; }
static int __init clk_init(void) { struct clk **clkp; /* Disable autoclocking, as it doesn't seem to work */ __raw_writel(0xff, AUTOCLK_CTRL); for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks); clkp++) { struct clk *clk = *clkp; if (clk->flags & NEEDS_INITIALIZATION) { if (clk->set_rate) { clk->user_rate = clk->rate; local_set_rate(clk, clk->user_rate); if (clk->set_parent) clk->set_parent(clk, clk->parent); } if (clk->enable && clk->usecount) clk->enable(clk); if (clk->disable && !clk->usecount) clk->disable(clk); } pr_debug("%s: clock %s, rate %ld\n", __func__, clk->name, clk->rate); } local_clk_enable(&ck_pll4); /* if ck_13MHz is not used, disable it. */ if (ck_13MHz.usecount == 0) local_clk_disable(&ck_13MHz); /* Disable autoclocking */ __raw_writeb(0xff, AUTOCLK_CTRL); clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg)); return 0; }
static int local_clk_use(struct clk *clk) { int ret = 0; if (clk->usecount++ == 0) { if (clk->parent) ret = local_clk_use(clk->parent); if (ret != 0) { clk->usecount--; goto out; } ret = local_clk_enable(clk); if (ret != 0 && clk->parent) { local_clk_unuse(clk->parent); clk->usecount--; } } out: return ret; }