@@ -108,6 +108,39 @@ static const struct clk_ops clk_dummy_single_parent_ops = {
108108 .get_parent = clk_dummy_single_get_parent ,
109109};
110110
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+
111144static int clk_test_init_with_ops (struct kunit * test , const struct clk_ops * ops )
112145{
113146 struct clk_dummy_context * ctx ;
@@ -360,6 +393,93 @@ static struct kunit_suite clk_uncached_test_suite = {
360393 .test_cases = clk_uncached_test_cases ,
361394};
362395
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+
363483struct clk_single_parent_ctx {
364484 struct clk_dummy_context parent_ctx ;
365485 struct clk_hw hw ;
@@ -1339,6 +1459,7 @@ static struct kunit_suite clk_range_minimize_test_suite = {
13391459
13401460kunit_test_suites (
13411461 & clk_test_suite ,
1462+ & clk_multiple_parents_mux_test_suite ,
13421463 & clk_orphan_transparent_single_parent_test_suite ,
13431464 & clk_range_test_suite ,
13441465 & clk_range_maximize_test_suite ,
0 commit comments