diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/ux500/clk-prcmu.c | 55 | ||||
-rw-r--r-- | drivers/clk/ux500/clk.h | 6 |
2 files changed, 61 insertions, 0 deletions
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 930cdfeb47ab..04577ca6a308 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c | |||
@@ -133,6 +133,40 @@ out_error: | |||
133 | hw->init->name); | 133 | hw->init->name); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) | ||
137 | { | ||
138 | int err; | ||
139 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
140 | |||
141 | err = prcmu_request_ape_opp_100_voltage(true); | ||
142 | if (err) { | ||
143 | pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n", | ||
144 | __func__, hw->init->name); | ||
145 | return err; | ||
146 | } | ||
147 | |||
148 | err = prcmu_request_clock(clk->cg_sel, true); | ||
149 | if (err) | ||
150 | prcmu_request_ape_opp_100_voltage(false); | ||
151 | |||
152 | return err; | ||
153 | } | ||
154 | |||
155 | static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) | ||
156 | { | ||
157 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
158 | |||
159 | if (prcmu_request_clock(clk->cg_sel, false)) | ||
160 | goto out_error; | ||
161 | if (prcmu_request_ape_opp_100_voltage(false)) | ||
162 | goto out_error; | ||
163 | return; | ||
164 | |||
165 | out_error: | ||
166 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | ||
167 | hw->init->name); | ||
168 | } | ||
169 | |||
136 | static struct clk_ops clk_prcmu_scalable_ops = { | 170 | static struct clk_ops clk_prcmu_scalable_ops = { |
137 | .prepare = clk_prcmu_prepare, | 171 | .prepare = clk_prcmu_prepare, |
138 | .unprepare = clk_prcmu_unprepare, | 172 | .unprepare = clk_prcmu_unprepare, |
@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { | |||
167 | .recalc_rate = clk_prcmu_recalc_rate, | 201 | .recalc_rate = clk_prcmu_recalc_rate, |
168 | }; | 202 | }; |
169 | 203 | ||
204 | static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { | ||
205 | .prepare = clk_prcmu_opp_volt_prepare, | ||
206 | .unprepare = clk_prcmu_opp_volt_unprepare, | ||
207 | .enable = clk_prcmu_enable, | ||
208 | .disable = clk_prcmu_disable, | ||
209 | .is_enabled = clk_prcmu_is_enabled, | ||
210 | .recalc_rate = clk_prcmu_recalc_rate, | ||
211 | .round_rate = clk_prcmu_round_rate, | ||
212 | .set_rate = clk_prcmu_set_rate, | ||
213 | }; | ||
214 | |||
170 | static struct clk *clk_reg_prcmu(const char *name, | 215 | static struct clk *clk_reg_prcmu(const char *name, |
171 | const char *parent_name, | 216 | const char *parent_name, |
172 | u8 cg_sel, | 217 | u8 cg_sel, |
@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, | |||
250 | return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, | 295 | return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, |
251 | &clk_prcmu_opp_gate_ops); | 296 | &clk_prcmu_opp_gate_ops); |
252 | } | 297 | } |
298 | |||
299 | struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, | ||
300 | const char *parent_name, | ||
301 | u8 cg_sel, | ||
302 | unsigned long rate, | ||
303 | unsigned long flags) | ||
304 | { | ||
305 | return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, | ||
306 | &clk_prcmu_opp_volt_scalable_ops); | ||
307 | } | ||
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h index 836d7d16751e..f36eeedca493 100644 --- a/drivers/clk/ux500/clk.h +++ b/drivers/clk/ux500/clk.h | |||
@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, | |||
45 | u8 cg_sel, | 45 | u8 cg_sel, |
46 | unsigned long flags); | 46 | unsigned long flags); |
47 | 47 | ||
48 | struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, | ||
49 | const char *parent_name, | ||
50 | u8 cg_sel, | ||
51 | unsigned long rate, | ||
52 | unsigned long flags); | ||
53 | |||
48 | #endif /* __UX500_CLK_H */ | 54 | #endif /* __UX500_CLK_H */ |