static void sysclk_init_disable(struct work_struct *not_used) { int i; mutex_lock(&sysclk_mutex); /* Enable SWAT */ if (ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE)) goto err_swat; for (i = 0; i < ARRAY_SIZE(u8500_v2_sysclks); i++) { struct clk *clk = u8500_v2_sysclks[i].clk; /* Disable sysclks */ if (!clk->enabled && clk->cg_sel) { if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, (u8)clk->cg_sel)) goto err_sysclk; } } goto unlock_and_exit; err_sysclk: pr_err("clock: Disable %s failed", u8500_v2_sysclks[i].clk->name); ab8500_sysctrl_clear(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); goto unlock_and_exit; err_swat: pr_err("clock: Enable SWAT failed"); unlock_and_exit: mutex_unlock(&sysclk_mutex); }
static int ab_intclk_set_parent(struct clk *clk, struct clk *parent) { int err; if (!clk->enabled) return 0; err = __clk_enable(parent, clk->mutex); if (unlikely(err)) goto parent_enable_error; if (parent == clk->parents[AB_INTCLK_PARENT_ULPCLK]) { err = ab8500_sysctrl_write(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK, (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT)); } else { err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK); } if (unlikely(err)) goto config_error; __clk_disable(clk->parent, clk->mutex); return 0; config_error: __clk_disable(parent, clk->mutex); parent_enable_error: return err; }
static int ab_ulpclk_enable(struct clk *clk) { int err; if (clk->regulator == NULL) { struct regulator *reg; reg = regulator_get(NULL, "v-intcore"); if (IS_ERR(reg)) return PTR_ERR(reg); clk->regulator = reg; } err = regulator_set_optimum_mode(clk->regulator, 1500); if (unlikely(err < 0)) goto regulator_enable_error; err = regulator_enable(clk->regulator); if (unlikely(err)) goto regulator_enable_error; err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCONF, AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK); if (unlikely(err)) goto enable_error; err = ab8500_sysctrl_set(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ); if (unlikely(err)) goto enable_error; /* Unknown/undocumented PLL locking time => wait 1 ms. */ msleep(1); return 0; enable_error: (void)regulator_disable(clk->regulator); regulator_enable_error: return err; }
static int clk_sysctrl_set_parent(struct clk_hw *hw, u8 index) { struct clk_sysctrl *clk = to_clk_sysctrl(hw); u8 old_index = clk->parent_index; int ret = 0; if (clk->reg_sel[old_index]) { ret = ab8500_sysctrl_clear(clk->reg_sel[old_index], clk->reg_mask[old_index]); if (ret) return ret; } if (clk->reg_sel[index]) { ret = ab8500_sysctrl_write(clk->reg_sel[index], clk->reg_mask[index], clk->reg_bits[index]); if (ret) { if (clk->reg_sel[old_index]) ab8500_sysctrl_write(clk->reg_sel[old_index], clk->reg_mask[old_index], clk->reg_bits[old_index]); return ret; } } clk->parent_index = index; return ret; }
static void clk_sysctrl_unprepare(struct clk_hw *hw) { struct clk_sysctrl *clk = to_clk_sysctrl(hw); if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0])) dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n", __func__, clk_hw_get_name(hw)); }
static void audioclk_disable(struct clk *clk) { if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA)) { pr_err("clock: %s failed to disable %s.\n", __func__, clk->name); } }
static void ab_intclk_disable(struct clk *clk) { if (clk->parent == clk->parents[AB_INTCLK_PARENT_SYSCLK]) return; if (ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK)) { pr_err("clock: %s failed to disable %s.\n", __func__, clk->name); } }
static void ab_ulpclk_disable(struct clk *clk) { int err; err = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ); if (unlikely(regulator_disable(clk->regulator) || err)) goto out_err; regulator_set_optimum_mode(clk->regulator, 0); return; out_err: pr_err("clock: %s failed to disable %s.\n", __func__, clk->name); }
static void sysclk_disable(struct clk *clk) { int r; if (clk->cg_sel) { r = ab8500_sysctrl_clear(AB8500_SYSULPCLKCTRL1, (u8)clk->cg_sel); if (r) goto disable_failed; } r = request_sysclk(false); if (r) goto disable_failed; return; disable_failed: pr_err("clock: failed to disable %s.\n", clk->name); }