@@ -480,6 +480,242 @@ clk_multiple_parents_mux_test_suite = {
480
480
.test_cases = clk_multiple_parents_mux_test_cases ,
481
481
};
482
482
483
+ static int
484
+ clk_orphan_transparent_multiple_parent_mux_test_init (struct kunit * test )
485
+ {
486
+ struct clk_multiple_parent_ctx * ctx ;
487
+ const char * parents [2 ] = { "missing-parent" , "proper-parent" };
488
+ int ret ;
489
+
490
+ ctx = kunit_kzalloc (test , sizeof (* ctx ), GFP_KERNEL );
491
+ if (!ctx )
492
+ return - ENOMEM ;
493
+ test -> priv = ctx ;
494
+
495
+ ctx -> parents_ctx [1 ].hw .init = CLK_HW_INIT_NO_PARENT ("proper-parent" ,
496
+ & clk_dummy_rate_ops ,
497
+ 0 );
498
+ ctx -> parents_ctx [1 ].rate = DUMMY_CLOCK_INIT_RATE ;
499
+ ret = clk_hw_register (NULL , & ctx -> parents_ctx [1 ].hw );
500
+ if (ret )
501
+ return ret ;
502
+
503
+ ctx -> hw .init = CLK_HW_INIT_PARENTS ("test-orphan-mux" , parents ,
504
+ & clk_multiple_parents_mux_ops ,
505
+ CLK_SET_RATE_PARENT );
506
+ ret = clk_hw_register (NULL , & ctx -> hw );
507
+ if (ret )
508
+ return ret ;
509
+
510
+ return 0 ;
511
+ }
512
+
513
+ static void
514
+ clk_orphan_transparent_multiple_parent_mux_test_exit (struct kunit * test )
515
+ {
516
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
517
+
518
+ clk_hw_unregister (& ctx -> hw );
519
+ clk_hw_unregister (& ctx -> parents_ctx [1 ].hw );
520
+ }
521
+
522
+ /*
523
+ * Test that, for a mux whose current parent hasn't been registered yet and is
524
+ * thus orphan, clk_get_parent() will return NULL.
525
+ */
526
+ static void
527
+ clk_test_orphan_transparent_multiple_parent_mux_get_parent (struct kunit * test )
528
+ {
529
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
530
+ struct clk_hw * hw = & ctx -> hw ;
531
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
532
+
533
+ KUNIT_EXPECT_PTR_EQ (test , clk_get_parent (clk ), NULL );
534
+
535
+ clk_put (clk );
536
+ }
537
+
538
+ /*
539
+ * Test that, for a mux whose current parent hasn't been registered yet,
540
+ * calling clk_set_parent() to a valid parent will properly update the
541
+ * mux parent and its orphan status.
542
+ */
543
+ static void
544
+ clk_test_orphan_transparent_multiple_parent_mux_set_parent (struct kunit * test )
545
+ {
546
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
547
+ struct clk_hw * hw = & ctx -> hw ;
548
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
549
+ struct clk * parent , * new_parent ;
550
+ int ret ;
551
+
552
+ parent = clk_hw_get_clk (& ctx -> parents_ctx [1 ].hw , NULL );
553
+ KUNIT_ASSERT_NOT_ERR_OR_NULL (test , parent );
554
+
555
+ ret = clk_set_parent (clk , parent );
556
+ KUNIT_ASSERT_EQ (test , ret , 0 );
557
+
558
+ new_parent = clk_get_parent (clk );
559
+ KUNIT_ASSERT_NOT_ERR_OR_NULL (test , parent );
560
+ KUNIT_EXPECT_TRUE (test , clk_is_match (parent , new_parent ));
561
+
562
+ clk_put (parent );
563
+ clk_put (clk );
564
+ }
565
+
566
+ /*
567
+ * Test that, for a mux that started orphan but got switched to a valid
568
+ * parent, the rate of the mux and its new parent are consistent.
569
+ */
570
+ static void
571
+ clk_test_orphan_transparent_multiple_parent_mux_set_parent_get_rate (struct kunit * test )
572
+ {
573
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
574
+ struct clk_hw * hw = & ctx -> hw ;
575
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
576
+ struct clk * parent ;
577
+ unsigned long parent_rate , rate ;
578
+ int ret ;
579
+
580
+ parent = clk_hw_get_clk (& ctx -> parents_ctx [1 ].hw , NULL );
581
+ KUNIT_ASSERT_NOT_ERR_OR_NULL (test , parent );
582
+
583
+ parent_rate = clk_get_rate (parent );
584
+ KUNIT_ASSERT_GT (test , parent_rate , 0 );
585
+
586
+ ret = clk_set_parent (clk , parent );
587
+ KUNIT_ASSERT_EQ (test , ret , 0 );
588
+
589
+ rate = clk_get_rate (clk );
590
+ KUNIT_ASSERT_GT (test , rate , 0 );
591
+ KUNIT_EXPECT_EQ (test , parent_rate , rate );
592
+
593
+ clk_put (parent );
594
+ clk_put (clk );
595
+ }
596
+
597
+ /*
598
+ * Test that, for a mux that started orphan but got switched to a valid
599
+ * parent, calling clk_set_rate_range() will affect the parent state if
600
+ * its rate is out of range.
601
+ */
602
+ static void
603
+ clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_modified (struct kunit * test )
604
+ {
605
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
606
+ struct clk_hw * hw = & ctx -> hw ;
607
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
608
+ struct clk * parent ;
609
+ unsigned long rate ;
610
+ int ret ;
611
+
612
+ parent = clk_hw_get_clk (& ctx -> parents_ctx [1 ].hw , NULL );
613
+ KUNIT_ASSERT_NOT_ERR_OR_NULL (test , parent );
614
+
615
+ ret = clk_set_parent (clk , parent );
616
+ KUNIT_ASSERT_EQ (test , ret , 0 );
617
+
618
+ ret = clk_set_rate_range (clk , DUMMY_CLOCK_RATE_1 , DUMMY_CLOCK_RATE_2 );
619
+ KUNIT_ASSERT_EQ (test , ret , 0 );
620
+
621
+ rate = clk_get_rate (clk );
622
+ KUNIT_ASSERT_GT (test , rate , 0 );
623
+ KUNIT_EXPECT_GE (test , rate , DUMMY_CLOCK_RATE_1 );
624
+ KUNIT_EXPECT_LE (test , rate , DUMMY_CLOCK_RATE_2 );
625
+
626
+ clk_put (parent );
627
+ clk_put (clk );
628
+ }
629
+
630
+ /*
631
+ * Test that, for a mux whose current parent hasn't been registered yet,
632
+ * calling clk_set_rate_range() will succeed, and will be taken into
633
+ * account when rounding a rate.
634
+ */
635
+ static void
636
+ clk_test_orphan_transparent_multiple_parent_mux_set_range_round_rate (struct kunit * test )
637
+ {
638
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
639
+ struct clk_hw * hw = & ctx -> hw ;
640
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
641
+ unsigned long rate ;
642
+ int ret ;
643
+
644
+ ret = clk_set_rate_range (clk , DUMMY_CLOCK_RATE_1 , DUMMY_CLOCK_RATE_2 );
645
+ KUNIT_ASSERT_EQ (test , ret , 0 );
646
+
647
+ rate = clk_round_rate (clk , DUMMY_CLOCK_RATE_1 - 1000 );
648
+ KUNIT_ASSERT_GT (test , rate , 0 );
649
+ KUNIT_EXPECT_GE (test , rate , DUMMY_CLOCK_RATE_1 );
650
+ KUNIT_EXPECT_LE (test , rate , DUMMY_CLOCK_RATE_2 );
651
+
652
+ clk_put (clk );
653
+ }
654
+
655
+ /*
656
+ * Test that, for a mux that started orphan, was assigned and rate and
657
+ * then got switched to a valid parent, its rate is eventually within
658
+ * range.
659
+ *
660
+ * FIXME: Even though we update the rate as part of clk_set_parent(), we
661
+ * don't evaluate whether that new rate is within range and needs to be
662
+ * adjusted.
663
+ */
664
+ static void
665
+ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate (struct kunit * test )
666
+ {
667
+ struct clk_multiple_parent_ctx * ctx = test -> priv ;
668
+ struct clk_hw * hw = & ctx -> hw ;
669
+ struct clk * clk = clk_hw_get_clk (hw , NULL );
670
+ struct clk * parent ;
671
+ unsigned long rate ;
672
+ int ret ;
673
+
674
+ kunit_skip (test , "This needs to be fixed in the core." );
675
+
676
+ clk_hw_set_rate_range (hw , DUMMY_CLOCK_RATE_1 , DUMMY_CLOCK_RATE_2 );
677
+
678
+ parent = clk_hw_get_clk (& ctx -> parents_ctx [1 ].hw , NULL );
679
+ KUNIT_ASSERT_NOT_ERR_OR_NULL (test , parent );
680
+
681
+ ret = clk_set_parent (clk , parent );
682
+ KUNIT_ASSERT_EQ (test , ret , 0 );
683
+
684
+ rate = clk_get_rate (clk );
685
+ KUNIT_ASSERT_GT (test , rate , 0 );
686
+ KUNIT_EXPECT_GE (test , rate , DUMMY_CLOCK_RATE_1 );
687
+ KUNIT_EXPECT_LE (test , rate , DUMMY_CLOCK_RATE_2 );
688
+
689
+ clk_put (parent );
690
+ clk_put (clk );
691
+ }
692
+
693
+ static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases [] = {
694
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_get_parent ),
695
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_set_parent ),
696
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_set_parent_get_rate ),
697
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_set_parent_set_range_modified ),
698
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_set_range_round_rate ),
699
+ KUNIT_CASE (clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate ),
700
+ {}
701
+ };
702
+
703
+ /*
704
+ * Test suite for a basic mux clock with two parents. The default parent
705
+ * isn't registered, only the second parent is. By default, the clock
706
+ * will thus be orphan.
707
+ *
708
+ * These tests exercise the behaviour of the consumer API when dealing
709
+ * with an orphan clock, and how we deal with the transition to a valid
710
+ * parent.
711
+ */
712
+ static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = {
713
+ .name = "clk-orphan-transparent-multiple-parent-mux-test" ,
714
+ .init = clk_orphan_transparent_multiple_parent_mux_test_init ,
715
+ .exit = clk_orphan_transparent_multiple_parent_mux_test_exit ,
716
+ .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases ,
717
+ };
718
+
483
719
struct clk_single_parent_ctx {
484
720
struct clk_dummy_context parent_ctx ;
485
721
struct clk_hw hw ;
@@ -1460,6 +1696,7 @@ static struct kunit_suite clk_range_minimize_test_suite = {
1460
1696
kunit_test_suites (
1461
1697
& clk_test_suite ,
1462
1698
& clk_multiple_parents_mux_test_suite ,
1699
+ & clk_orphan_transparent_multiple_parent_mux_test_suite ,
1463
1700
& clk_orphan_transparent_single_parent_test_suite ,
1464
1701
& clk_range_test_suite ,
1465
1702
& clk_range_maximize_test_suite ,
0 commit comments