@@ -889,21 +889,24 @@ EXPORT_SYMBOL_GPL(clk_enable);
889
889
unsigned long __clk_round_rate (struct clk * clk , unsigned long rate )
890
890
{
891
891
unsigned long parent_rate = 0 ;
892
+ struct clk * parent ;
892
893
893
894
if (!clk )
894
895
return 0 ;
895
896
896
- if (!clk -> ops -> round_rate ) {
897
- if (clk -> flags & CLK_SET_RATE_PARENT )
898
- return __clk_round_rate (clk -> parent , rate );
899
- else
900
- return clk -> rate ;
901
- }
902
-
903
- if (clk -> parent )
904
- parent_rate = clk -> parent -> rate ;
905
-
906
- return clk -> ops -> round_rate (clk -> hw , rate , & parent_rate );
897
+ parent = clk -> parent ;
898
+ if (parent )
899
+ parent_rate = parent -> rate ;
900
+
901
+ if (clk -> ops -> determine_rate )
902
+ return clk -> ops -> determine_rate (clk -> hw , rate , & parent_rate ,
903
+ & parent );
904
+ else if (clk -> ops -> round_rate )
905
+ return clk -> ops -> round_rate (clk -> hw , rate , & parent_rate );
906
+ else if (clk -> flags & CLK_SET_RATE_PARENT )
907
+ return __clk_round_rate (clk -> parent , rate );
908
+ else
909
+ return clk -> rate ;
907
910
}
908
911
909
912
/**
@@ -1056,6 +1059,10 @@ static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent)
1056
1059
1057
1060
static void clk_reparent (struct clk * clk , struct clk * new_parent )
1058
1061
{
1062
+ /* avoid duplicate POST_RATE_CHANGE notifications */
1063
+ if (new_parent -> new_child == clk )
1064
+ new_parent -> new_child = NULL ;
1065
+
1059
1066
hlist_del (& clk -> child_node );
1060
1067
1061
1068
if (new_parent )
@@ -1176,18 +1183,25 @@ static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
1176
1183
return ret ;
1177
1184
}
1178
1185
1179
- static void clk_calc_subtree (struct clk * clk , unsigned long new_rate )
1186
+ static void clk_calc_subtree (struct clk * clk , unsigned long new_rate ,
1187
+ struct clk * new_parent , u8 p_index )
1180
1188
{
1181
1189
struct clk * child ;
1182
1190
1183
1191
clk -> new_rate = new_rate ;
1192
+ clk -> new_parent = new_parent ;
1193
+ clk -> new_parent_index = p_index ;
1194
+ /* include clk in new parent's PRE_RATE_CHANGE notifications */
1195
+ clk -> new_child = NULL ;
1196
+ if (new_parent && new_parent != clk -> parent )
1197
+ new_parent -> new_child = clk ;
1184
1198
1185
1199
hlist_for_each_entry (child , & clk -> children , child_node ) {
1186
1200
if (child -> ops -> recalc_rate )
1187
1201
child -> new_rate = child -> ops -> recalc_rate (child -> hw , new_rate );
1188
1202
else
1189
1203
child -> new_rate = new_rate ;
1190
- clk_calc_subtree (child , child -> new_rate );
1204
+ clk_calc_subtree (child , child -> new_rate , NULL , 0 );
1191
1205
}
1192
1206
}
1193
1207
@@ -1198,50 +1212,63 @@ static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
1198
1212
static struct clk * clk_calc_new_rates (struct clk * clk , unsigned long rate )
1199
1213
{
1200
1214
struct clk * top = clk ;
1215
+ struct clk * old_parent , * parent ;
1201
1216
unsigned long best_parent_rate = 0 ;
1202
1217
unsigned long new_rate ;
1218
+ u8 p_index = 0 ;
1203
1219
1204
1220
/* sanity */
1205
1221
if (IS_ERR_OR_NULL (clk ))
1206
1222
return NULL ;
1207
1223
1208
1224
/* save parent rate, if it exists */
1209
- if (clk -> parent )
1210
- best_parent_rate = clk -> parent -> rate ;
1211
-
1212
- /* never propagate up to the parent */
1213
- if (!(clk -> flags & CLK_SET_RATE_PARENT )) {
1214
- if (!clk -> ops -> round_rate ) {
1215
- clk -> new_rate = clk -> rate ;
1216
- return NULL ;
1217
- }
1218
- new_rate = clk -> ops -> round_rate (clk -> hw , rate , & best_parent_rate );
1225
+ parent = old_parent = clk -> parent ;
1226
+ if (parent )
1227
+ best_parent_rate = parent -> rate ;
1228
+
1229
+ /* find the closest rate and parent clk/rate */
1230
+ if (clk -> ops -> determine_rate ) {
1231
+ new_rate = clk -> ops -> determine_rate (clk -> hw , rate ,
1232
+ & best_parent_rate ,
1233
+ & parent );
1234
+ } else if (clk -> ops -> round_rate ) {
1235
+ new_rate = clk -> ops -> round_rate (clk -> hw , rate ,
1236
+ & best_parent_rate );
1237
+ } else if (!parent || !(clk -> flags & CLK_SET_RATE_PARENT )) {
1238
+ /* pass-through clock without adjustable parent */
1239
+ clk -> new_rate = clk -> rate ;
1240
+ return NULL ;
1241
+ } else {
1242
+ /* pass-through clock with adjustable parent */
1243
+ top = clk_calc_new_rates (parent , rate );
1244
+ new_rate = parent -> new_rate ;
1219
1245
goto out ;
1220
1246
}
1221
1247
1222
- /* need clk->parent from here on out */
1223
- if (!clk -> parent ) {
1224
- pr_debug ("%s: %s has NULL parent\n" , __func__ , clk -> name );
1248
+ /* some clocks must be gated to change parent */
1249
+ if (parent != old_parent &&
1250
+ (clk -> flags & CLK_SET_PARENT_GATE ) && clk -> prepare_count ) {
1251
+ pr_debug ("%s: %s not gated but wants to reparent\n" ,
1252
+ __func__ , clk -> name );
1225
1253
return NULL ;
1226
1254
}
1227
1255
1228
- if (!clk -> ops -> round_rate ) {
1229
- top = clk_calc_new_rates (clk -> parent , rate );
1230
- new_rate = clk -> parent -> new_rate ;
1231
-
1232
- goto out ;
1256
+ /* try finding the new parent index */
1257
+ if (parent ) {
1258
+ p_index = clk_fetch_parent_index (clk , parent );
1259
+ if (p_index == clk -> num_parents ) {
1260
+ pr_debug ("%s: clk %s can not be parent of clk %s\n" ,
1261
+ __func__ , parent -> name , clk -> name );
1262
+ return NULL ;
1263
+ }
1233
1264
}
1234
1265
1235
- new_rate = clk -> ops -> round_rate (clk -> hw , rate , & best_parent_rate );
1236
-
1237
- if (best_parent_rate != clk -> parent -> rate ) {
1238
- top = clk_calc_new_rates (clk -> parent , best_parent_rate );
1239
-
1240
- goto out ;
1241
- }
1266
+ if ((clk -> flags & CLK_SET_RATE_PARENT ) && parent &&
1267
+ best_parent_rate != parent -> rate )
1268
+ top = clk_calc_new_rates (parent , best_parent_rate );
1242
1269
1243
1270
out :
1244
- clk_calc_subtree (clk , new_rate );
1271
+ clk_calc_subtree (clk , new_rate , parent , p_index );
1245
1272
1246
1273
return top ;
1247
1274
}
@@ -1253,7 +1280,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
1253
1280
*/
1254
1281
static struct clk * clk_propagate_rate_change (struct clk * clk , unsigned long event )
1255
1282
{
1256
- struct clk * child , * fail_clk = NULL ;
1283
+ struct clk * child , * tmp_clk , * fail_clk = NULL ;
1257
1284
int ret = NOTIFY_DONE ;
1258
1285
1259
1286
if (clk -> rate == clk -> new_rate )
@@ -1266,9 +1293,19 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
1266
1293
}
1267
1294
1268
1295
hlist_for_each_entry (child , & clk -> children , child_node ) {
1269
- clk = clk_propagate_rate_change (child , event );
1270
- if (clk )
1271
- fail_clk = clk ;
1296
+ /* Skip children who will be reparented to another clock */
1297
+ if (child -> new_parent && child -> new_parent != clk )
1298
+ continue ;
1299
+ tmp_clk = clk_propagate_rate_change (child , event );
1300
+ if (tmp_clk )
1301
+ fail_clk = tmp_clk ;
1302
+ }
1303
+
1304
+ /* handle the new child who might not be in clk->children yet */
1305
+ if (clk -> new_child ) {
1306
+ tmp_clk = clk_propagate_rate_change (clk -> new_child , event );
1307
+ if (tmp_clk )
1308
+ fail_clk = tmp_clk ;
1272
1309
}
1273
1310
1274
1311
return fail_clk ;
@@ -1286,6 +1323,10 @@ static void clk_change_rate(struct clk *clk)
1286
1323
1287
1324
old_rate = clk -> rate ;
1288
1325
1326
+ /* set parent */
1327
+ if (clk -> new_parent && clk -> new_parent != clk -> parent )
1328
+ __clk_set_parent (clk , clk -> new_parent , clk -> new_parent_index );
1329
+
1289
1330
if (clk -> parent )
1290
1331
best_parent_rate = clk -> parent -> rate ;
1291
1332
@@ -1300,8 +1341,16 @@ static void clk_change_rate(struct clk *clk)
1300
1341
if (clk -> notifier_count && old_rate != clk -> rate )
1301
1342
__clk_notify (clk , POST_RATE_CHANGE , old_rate , clk -> rate );
1302
1343
1303
- hlist_for_each_entry (child , & clk -> children , child_node )
1344
+ hlist_for_each_entry (child , & clk -> children , child_node ) {
1345
+ /* Skip children who will be reparented to another clock */
1346
+ if (child -> new_parent && child -> new_parent != clk )
1347
+ continue ;
1304
1348
clk_change_rate (child );
1349
+ }
1350
+
1351
+ /* handle the new child who might not be in clk->children yet */
1352
+ if (clk -> new_child )
1353
+ clk_change_rate (clk -> new_child );
1305
1354
}
1306
1355
1307
1356
/**
@@ -1552,8 +1601,9 @@ int __clk_init(struct device *dev, struct clk *clk)
1552
1601
1553
1602
/* check that clk_ops are sane. See Documentation/clk.txt */
1554
1603
if (clk -> ops -> set_rate &&
1555
- !(clk -> ops -> round_rate && clk -> ops -> recalc_rate )) {
1556
- pr_warning ("%s: %s must implement .round_rate & .recalc_rate\n" ,
1604
+ !((clk -> ops -> round_rate || clk -> ops -> determine_rate ) &&
1605
+ clk -> ops -> recalc_rate )) {
1606
+ pr_warning ("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n" ,
1557
1607
__func__ , clk -> name );
1558
1608
ret = - EINVAL ;
1559
1609
goto out ;
0 commit comments