]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
clk: ux500: Support prcmu ape opp voltage clock
authorUlf Hansson <ulf.hansson@linaro.org>
Mon, 24 Sep 2012 14:43:18 +0000 (16:43 +0200)
committerMike Turquette <mturquette@linaro.org>
Mon, 29 Oct 2012 17:34:11 +0000 (10:34 -0700)
Some scalable prcmu clocks needs to be handled in conjuction with the
ape opp 100 voltage. A new prcmu clock type clk_prcmu_opp_volt_scalable
is implemented to handle this.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/clk/ux500/clk-prcmu.c
drivers/clk/ux500/clk.h

index 930cdfeb47ab451659843446b3f8ebdcdee01776..04577ca6a3081d63a88fd78f68484db91a1bd011 100644 (file)
@@ -133,6 +133,40 @@ out_error:
                hw->init->name);
 }
 
+static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
+{
+       int err;
+       struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+       err = prcmu_request_ape_opp_100_voltage(true);
+       if (err) {
+               pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
+                       __func__, hw->init->name);
+               return err;
+       }
+
+       err = prcmu_request_clock(clk->cg_sel, true);
+       if (err)
+               prcmu_request_ape_opp_100_voltage(false);
+
+       return err;
+}
+
+static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
+{
+       struct clk_prcmu *clk = to_clk_prcmu(hw);
+
+       if (prcmu_request_clock(clk->cg_sel, false))
+               goto out_error;
+       if (prcmu_request_ape_opp_100_voltage(false))
+               goto out_error;
+       return;
+
+out_error:
+       pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+               hw->init->name);
+}
+
 static struct clk_ops clk_prcmu_scalable_ops = {
        .prepare = clk_prcmu_prepare,
        .unprepare = clk_prcmu_unprepare,
@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = {
        .recalc_rate = clk_prcmu_recalc_rate,
 };
 
+static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
+       .prepare = clk_prcmu_opp_volt_prepare,
+       .unprepare = clk_prcmu_opp_volt_unprepare,
+       .enable = clk_prcmu_enable,
+       .disable = clk_prcmu_disable,
+       .is_enabled = clk_prcmu_is_enabled,
+       .recalc_rate = clk_prcmu_recalc_rate,
+       .round_rate = clk_prcmu_round_rate,
+       .set_rate = clk_prcmu_set_rate,
+};
+
 static struct clk *clk_reg_prcmu(const char *name,
                                 const char *parent_name,
                                 u8 cg_sel,
@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,
        return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags,
                        &clk_prcmu_opp_gate_ops);
 }
+
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+                                           const char *parent_name,
+                                           u8 cg_sel,
+                                           unsigned long rate,
+                                           unsigned long flags)
+{
+       return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags,
+                       &clk_prcmu_opp_volt_scalable_ops);
+}
index 836d7d16751ea914616fda13878b177201fceb68..f36eeedca49305fdc52061006d00f51a5f1e5a6c 100644 (file)
@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,
                                   u8 cg_sel,
                                   unsigned long flags);
 
+struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name,
+                                           const char *parent_name,
+                                           u8 cg_sel,
+                                           unsigned long rate,
+                                           unsigned long flags);
+
 #endif /* __UX500_CLK_H */