Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: Add set_rate_and_parent() op

Some of Qualcomm's clocks can change their parent and rate at the
same time with a single register write. Add support for this
hardware to the common clock framework by adding a new
set_rate_and_parent() op. When the clock framework determines
that both the parent and the rate are going to change during
clk_set_rate() it will call the .set_rate_and_parent() op if
available and fall back to calling .set_parent() followed by
.set_rate() otherwise.

Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>

authored by

Stephen Boyd and committed by
Mike Turquette
3fa2252b d0d44dd4

+77 -19
+3
Documentation/clk.txt
··· 77 77 int (*set_parent)(struct clk_hw *hw, u8 index); 78 78 u8 (*get_parent)(struct clk_hw *hw); 79 79 int (*set_rate)(struct clk_hw *hw, unsigned long); 80 + int (*set_rate_and_parent)(struct clk_hw *hw, 81 + unsigned long rate, 82 + unsigned long parent_rate, u8 index); 80 83 unsigned long (*recalc_accuracy)(struct clk_hw *hw, 81 84 unsigned long parent_accuracy); 82 85 void (*init)(struct clk_hw *hw);
+59 -19
drivers/clk/clk.c
··· 1218 1218 clk->parent = new_parent; 1219 1219 } 1220 1220 1221 - static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) 1221 + static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent) 1222 1222 { 1223 1223 unsigned long flags; 1224 - int ret = 0; 1225 1224 struct clk *old_parent = clk->parent; 1226 1225 1227 1226 /* ··· 1251 1252 clk_reparent(clk, parent); 1252 1253 clk_enable_unlock(flags); 1253 1254 1255 + return old_parent; 1256 + } 1257 + 1258 + static void __clk_set_parent_after(struct clk *clk, struct clk *parent, 1259 + struct clk *old_parent) 1260 + { 1261 + /* 1262 + * Finish the migration of prepare state and undo the changes done 1263 + * for preventing a race with clk_enable(). 1264 + */ 1265 + if (clk->prepare_count) { 1266 + clk_disable(clk); 1267 + clk_disable(old_parent); 1268 + __clk_unprepare(old_parent); 1269 + } 1270 + 1271 + /* update debugfs with new clk tree topology */ 1272 + clk_debug_reparent(clk, parent); 1273 + } 1274 + 1275 + static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) 1276 + { 1277 + unsigned long flags; 1278 + int ret = 0; 1279 + struct clk *old_parent; 1280 + 1281 + old_parent = __clk_set_parent_before(clk, parent); 1282 + 1254 1283 /* change clock input source */ 1255 1284 if (parent && clk->ops->set_parent) 1256 1285 ret = clk->ops->set_parent(clk->hw, p_index); ··· 1296 1269 return ret; 1297 1270 } 1298 1271 1299 - /* 1300 - * Finish the migration of prepare state and undo the changes done 1301 - * for preventing a race with clk_enable(). 1302 - */ 1303 - if (clk->prepare_count) { 1304 - clk_disable(clk); 1305 - clk_disable(old_parent); 1306 - __clk_unprepare(old_parent); 1307 - } 1272 + __clk_set_parent_after(clk, parent, old_parent); 1308 1273 1309 - /* update debugfs with new clk tree topology */ 1310 - clk_debug_reparent(clk, parent); 1311 1274 return 0; 1312 1275 } 1313 1276 ··· 1482 1465 struct clk *child; 1483 1466 unsigned long old_rate; 1484 1467 unsigned long best_parent_rate = 0; 1468 + bool skip_set_rate = false; 1469 + struct clk *old_parent; 1485 1470 1486 1471 old_rate = clk->rate; 1487 1472 1488 - /* set parent */ 1489 - if (clk->new_parent && clk->new_parent != clk->parent) 1490 - __clk_set_parent(clk, clk->new_parent, clk->new_parent_index); 1491 - 1492 - if (clk->parent) 1473 + if (clk->new_parent) 1474 + best_parent_rate = clk->new_parent->rate; 1475 + else if (clk->parent) 1493 1476 best_parent_rate = clk->parent->rate; 1494 1477 1495 - if (clk->ops->set_rate) 1478 + if (clk->new_parent && clk->new_parent != clk->parent) { 1479 + old_parent = __clk_set_parent_before(clk, clk->new_parent); 1480 + 1481 + if (clk->ops->set_rate_and_parent) { 1482 + skip_set_rate = true; 1483 + clk->ops->set_rate_and_parent(clk->hw, clk->new_rate, 1484 + best_parent_rate, 1485 + clk->new_parent_index); 1486 + } else if (clk->ops->set_parent) { 1487 + clk->ops->set_parent(clk->hw, clk->new_parent_index); 1488 + } 1489 + 1490 + __clk_set_parent_after(clk, clk->new_parent, old_parent); 1491 + } 1492 + 1493 + if (!skip_set_rate && clk->ops->set_rate) 1496 1494 clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); 1497 1495 1498 1496 if (clk->ops->recalc_rate) ··· 1797 1765 1798 1766 if (clk->ops->set_parent && !clk->ops->get_parent) { 1799 1767 pr_warning("%s: %s must implement .get_parent & .set_parent\n", 1768 + __func__, clk->name); 1769 + ret = -EINVAL; 1770 + goto out; 1771 + } 1772 + 1773 + if (clk->ops->set_rate_and_parent && 1774 + !(clk->ops->set_parent && clk->ops->set_rate)) { 1775 + pr_warn("%s: %s must implement .set_parent & .set_rate\n", 1800 1776 __func__, clk->name); 1801 1777 ret = -EINVAL; 1802 1778 goto out;
+15
include/linux/clk-provider.h
··· 116 116 * set then clock accuracy will be initialized to parent accuracy 117 117 * or 0 (perfect clock) if clock has no parent. 118 118 * 119 + * @set_rate_and_parent: Change the rate and the parent of this clock. The 120 + * requested rate is specified by the second argument, which 121 + * should typically be the return of .round_rate call. The 122 + * third argument gives the parent rate which is likely helpful 123 + * for most .set_rate_and_parent implementation. The fourth 124 + * argument gives the parent index. This callback is optional (and 125 + * unnecessary) for clocks with 0 or 1 parents as well as 126 + * for clocks that can tolerate switching the rate and the parent 127 + * separately via calls to .set_parent and .set_rate. 128 + * Returns 0 on success, -EERROR otherwise. 129 + * 130 + * 119 131 * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow 120 132 * implementations to split any work between atomic (enable) and sleepable 121 133 * (prepare) contexts. If enabling a clock requires code that might sleep, ··· 159 147 u8 (*get_parent)(struct clk_hw *hw); 160 148 int (*set_rate)(struct clk_hw *hw, unsigned long, 161 149 unsigned long); 150 + int (*set_rate_and_parent)(struct clk_hw *hw, 151 + unsigned long rate, 152 + unsigned long parent_rate, u8 index); 162 153 unsigned long (*recalc_accuracy)(struct clk_hw *hw, 163 154 unsigned long parent_accuracy); 164 155 void (*init)(struct clk_hw *hw);