@@ -108,6 +108,39 @@ static const struct clk_ops clk_dummy_single_parent_ops = {
108
108
.get_parent = clk_dummy_single_get_parent ,
109
109
};
110
110
111
+ struct clk_multiple_parent_ctx {
112
+ struct clk_dummy_context parents_ctx [2 ];
113
+ struct clk_hw hw ;
114
+ u8 current_parent ;
115
+ };
116
+
117
+ static int clk_multiple_parents_mux_set_parent (struct clk_hw * hw , u8 index )
118
+ {
119
+ struct clk_multiple_parent_ctx * ctx =
120
+ container_of (hw , struct clk_multiple_parent_ctx , hw );
121
+
122
+ if (index >= clk_hw_get_num_parents (hw ))
123
+ return - EINVAL ;
124
+
125
+ ctx -> current_parent = index ;
126
+
127
+ return 0 ;
128
+ }
129
+
130
+ static u8 clk_multiple_parents_mux_get_parent (struct clk_hw * hw )
131
+ {
132
+ struct clk_multiple_parent_ctx * ctx =
133
+ container_of (hw , struct clk_multiple_parent_ctx , hw );
134
+
135
+ return ctx -> current_parent ;
136
+ }
137
+
138
+ static const struct clk_ops clk_multiple_parents_mux_ops = {
139
+ .get_parent = clk_multiple_parents_mux_get_parent ,
140
+ .set_parent = clk_multiple_parents_mux_set_parent ,
141
+ .determine_rate = __clk_mux_determine_rate_closest ,
142
+ };
143
+
111
144
static int clk_test_init_with_ops (struct kunit * test , const struct clk_ops * ops )
112
145
{
113
146
struct clk_dummy_context * ctx ;
@@ -360,6 +393,93 @@ static struct kunit_suite clk_uncached_test_suite = {
360
393
.test_cases = clk_uncached_test_cases ,
361
394
};
362
395
396
+ static int
397
+ clk_multiple_parents_mux_test_init (struct kunit * test )
398
+ {
399
+ struct clk_multiple_parent_ctx * ctx ;
400
+ const char * parents [2 ] = { "parent-0" , "parent-1" };
401
+ int ret ;
402
+
403
+ ctx = kunit_kzalloc (test , sizeof (* ctx ), GFP_KERNEL );
404
+ if (!ctx )
405
+ return - ENOMEM ;
406
+ test -> priv = ctx ;
407
+
408
+ ctx -> parents_ctx [0 ].hw .init = CLK_HW_INIT_NO_PARENT ("parent-0" ,
409
+ & clk_dummy_rate_ops ,
410
+ 0 );
411
+ ctx -> parents_ctx [0 ].rate = DUMMY_CLOCK_RATE_1 ;
412
+ ret = clk_hw_register (NULL , & ctx -> parents_ctx [0 ].hw );
413
+ if (ret )
414
+ return ret ;
415
+
416
+ ctx -> parents_ctx [1 ].hw .init = CLK_HW_INIT_NO_PARENT ("parent-1" ,
417
+ & clk_dummy_rate_ops ,
418
+ 0 );
419
+ ctx -> parents_ctx [1 ].rate = DUMMY_CLOCK_RATE_2 ;
420
+ ret = clk_hw_register (NULL , & ctx -> parents_ctx [1 ].hw );
421
+ if (ret )
422
+ return ret ;
423
+
424
+ ctx -> current_parent = 0 ;
425
+ ctx -> hw .init = CLK_HW_INIT_PARENTS ("test-mux" , parents ,
426
+ & clk_multiple_parents_mux_ops ,
427
+ CLK_SET_RATE_PARENT );
428
+ ret = clk_hw_register (NULL , & ctx -> hw );
429
+ if (ret )
430
+ return ret ;
431
+
432
+ return 0 ;
433
+ }
434
+
435
+ static void
436
+ clk_multiple_parents_mux_test_exit (struct kunit * test )
437
+ {
438
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
439
+
440
+ clk_hw_unregister (& ctx -> hw );
441
+ clk_hw_unregister (& ctx -> parents_ctx [0 ].hw );
442
+ clk_hw_unregister (& ctx -> parents_ctx [1 ].hw );
443
+ }
444
+
445
+ /*
446
+ * Test that for a clock with multiple parents, clk_get_parent()
447
+ * actually returns the current one.
448
+ */
449
+ static void
450
+ clk_test_multiple_parents_mux_get_parent (struct kunit * test )
451
+ {
452
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
453
+ struct clk_hw * hw = & ctx -> hw ;
454
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
455
+ struct clk * parent = clk_hw_get_clk (& ctx -> parents_ctx [0 ].hw , NULL );
456
+
457
+ KUNIT_EXPECT_TRUE (test , clk_is_match (clk_get_parent (clk ), parent ));
458
+
459
+ clk_put (parent );
460
+ clk_put (clk );
461
+ }
462
+
463
+ static struct kunit_case clk_multiple_parents_mux_test_cases [] = {
464
+ KUNIT_CASE (clk_test_multiple_parents_mux_get_parent ),
465
+ {}
466
+ };
467
+
468
+ /*
469
+ * Test suite for a basic mux clock with two parents, with
470
+ * CLK_SET_RATE_PARENT on the child.
471
+ *
472
+ * These tests exercise the consumer API and check that the state of the
473
+ * child and parents are sane and consistent.
474
+ */
475
+ static struct kunit_suite
476
+ clk_multiple_parents_mux_test_suite = {
477
+ .name = "clk-multiple-parents-mux-test" ,
478
+ .init = clk_multiple_parents_mux_test_init ,
479
+ .exit = clk_multiple_parents_mux_test_exit ,
480
+ .test_cases = clk_multiple_parents_mux_test_cases ,
481
+ };
482
+
363
483
struct clk_single_parent_ctx {
364
484
struct clk_dummy_context parent_ctx ;
365
485
struct clk_hw hw ;
@@ -1339,6 +1459,7 @@ static struct kunit_suite clk_range_minimize_test_suite = {
1339
1459
1340
1460
kunit_test_suites (
1341
1461
& clk_test_suite ,
1462
+ & clk_multiple_parents_mux_test_suite ,
1342
1463
& clk_orphan_transparent_single_parent_test_suite ,
1343
1464
& clk_range_test_suite ,
1344
1465
& clk_range_maximize_test_suite ,
0 commit comments