clk_test.c (66e72a01b60ae6950ddbb3585fdc1424d303e14b) clk_test.c (274aff8711b2e77c27bbda0ddc24caa39f154bfa)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Kunit tests for clk framework
4 */
5#include <linux/clk.h>
6#include <linux/clk-provider.h>
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Kunit tests for clk framework
4 */
5#include <linux/clk.h>
6#include <linux/clk-provider.h>
7#include <linux/of.h>
8#include <linux/platform_device.h>
7
8/* Needed for clk_hw_get_clk() */
9#include "clk.h"
10
9
10/* Needed for clk_hw_get_clk() */
11#include "clk.h"
12
13#include <kunit/clk.h>
14#include <kunit/of.h>
15#include <kunit/platform_device.h>
11#include <kunit/test.h>
12
16#include <kunit/test.h>
17
18#include "clk_parent_data_test.h"
19
13static const struct clk_ops empty_clk_ops = { };
14
15#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000)
16#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
17#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
18
19struct clk_dummy_context {
20 struct clk_hw hw;

--- 2633 unchanged lines hidden (view full) ---

2654 */
2655static struct kunit_suite clk_mux_no_reparent_test_suite = {
2656 .name = "clk-mux-no-reparent",
2657 .init = clk_mux_no_reparent_test_init,
2658 .exit = clk_mux_no_reparent_test_exit,
2659 .test_cases = clk_mux_no_reparent_test_cases,
2660};
2661
20static const struct clk_ops empty_clk_ops = { };
21
22#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000)
23#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
24#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
25
26struct clk_dummy_context {
27 struct clk_hw hw;

--- 2633 unchanged lines hidden (view full) ---

2661 */
2662static struct kunit_suite clk_mux_no_reparent_test_suite = {
2663 .name = "clk-mux-no-reparent",
2664 .init = clk_mux_no_reparent_test_init,
2665 .exit = clk_mux_no_reparent_test_exit,
2666 .test_cases = clk_mux_no_reparent_test_cases,
2667};
2668
2669struct clk_register_clk_parent_data_test_case {
2670 const char *desc;
2671 struct clk_parent_data pdata;
2672};
2673
2674static void
2675clk_register_clk_parent_data_test_case_to_desc(
2676 const struct clk_register_clk_parent_data_test_case *t, char *desc)
2677{
2678 strcpy(desc, t->desc);
2679}
2680
2681static const struct clk_register_clk_parent_data_test_case
2682clk_register_clk_parent_data_of_cases[] = {
2683 {
2684 /*
2685 * Test that a clk registered with a struct device_node can
2686 * find a parent based on struct clk_parent_data::index.
2687 */
2688 .desc = "clk_parent_data_of_index_test",
2689 .pdata.index = 0,
2690 },
2691 {
2692 /*
2693 * Test that a clk registered with a struct device_node can
2694 * find a parent based on struct clk_parent_data::fwname.
2695 */
2696 .desc = "clk_parent_data_of_fwname_test",
2697 .pdata.fw_name = CLK_PARENT_DATA_PARENT1,
2698 },
2699 {
2700 /*
2701 * Test that a clk registered with a struct device_node can
2702 * find a parent based on struct clk_parent_data::name.
2703 */
2704 .desc = "clk_parent_data_of_name_test",
2705 /* The index must be negative to indicate firmware not used */
2706 .pdata.index = -1,
2707 .pdata.name = CLK_PARENT_DATA_1MHZ_NAME,
2708 },
2709 {
2710 /*
2711 * Test that a clk registered with a struct device_node can
2712 * find a parent based on struct
2713 * clk_parent_data::{fw_name,name}.
2714 */
2715 .desc = "clk_parent_data_of_fwname_name_test",
2716 .pdata.fw_name = CLK_PARENT_DATA_PARENT1,
2717 .pdata.name = "not_matching",
2718 },
2719 {
2720 /*
2721 * Test that a clk registered with a struct device_node can
2722 * find a parent based on struct clk_parent_data::{index,name}.
2723 * Index takes priority.
2724 */
2725 .desc = "clk_parent_data_of_index_name_priority_test",
2726 .pdata.index = 0,
2727 .pdata.name = "not_matching",
2728 },
2729 {
2730 /*
2731 * Test that a clk registered with a struct device_node can
2732 * find a parent based on struct
2733 * clk_parent_data::{index,fwname,name}. The fw_name takes
2734 * priority over index and name.
2735 */
2736 .desc = "clk_parent_data_of_index_fwname_name_priority_test",
2737 .pdata.index = 1,
2738 .pdata.fw_name = CLK_PARENT_DATA_PARENT1,
2739 .pdata.name = "not_matching",
2740 },
2741};
2742
2743KUNIT_ARRAY_PARAM(clk_register_clk_parent_data_of_test, clk_register_clk_parent_data_of_cases,
2744 clk_register_clk_parent_data_test_case_to_desc)
2745
2746/**
2747 * struct clk_register_clk_parent_data_of_ctx - Context for clk_parent_data OF tests
2748 * @np: device node of clk under test
2749 * @hw: clk_hw for clk under test
2750 */
2751struct clk_register_clk_parent_data_of_ctx {
2752 struct device_node *np;
2753 struct clk_hw hw;
2754};
2755
2756static int clk_register_clk_parent_data_of_test_init(struct kunit *test)
2757{
2758 struct clk_register_clk_parent_data_of_ctx *ctx;
2759
2760 KUNIT_ASSERT_EQ(test, 0,
2761 of_overlay_apply_kunit(test, kunit_clk_parent_data_test));
2762
2763 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
2764 if (!ctx)
2765 return -ENOMEM;
2766 test->priv = ctx;
2767
2768 ctx->np = of_find_compatible_node(NULL, NULL, "test,clk-parent-data");
2769 if (!ctx->np)
2770 return -ENODEV;
2771
2772 of_node_put_kunit(test, ctx->np);
2773
2774 return 0;
2775}
2776
2777/*
2778 * Test that a clk registered with a struct device_node can find a parent based on
2779 * struct clk_parent_data when the hw member isn't set.
2780 */
2781static void clk_register_clk_parent_data_of_test(struct kunit *test)
2782{
2783 struct clk_register_clk_parent_data_of_ctx *ctx = test->priv;
2784 struct clk_hw *parent_hw;
2785 const struct clk_register_clk_parent_data_test_case *test_param;
2786 struct clk_init_data init = { };
2787 struct clk *expected_parent, *actual_parent;
2788
2789 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->np);
2790
2791 expected_parent = of_clk_get_kunit(test, ctx->np, 0);
2792 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_parent);
2793
2794 test_param = test->param_value;
2795 init.parent_data = &test_param->pdata;
2796 init.num_parents = 1;
2797 init.name = "parent_data_of_test_clk";
2798 init.ops = &clk_dummy_single_parent_ops;
2799 ctx->hw.init = &init;
2800 KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, ctx->np, &ctx->hw));
2801
2802 parent_hw = clk_hw_get_parent(&ctx->hw);
2803 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
2804
2805 actual_parent = clk_hw_get_clk_kunit(test, parent_hw, __func__);
2806 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, actual_parent);
2807
2808 KUNIT_EXPECT_TRUE(test, clk_is_match(expected_parent, actual_parent));
2809}
2810
2811static struct kunit_case clk_register_clk_parent_data_of_test_cases[] = {
2812 KUNIT_CASE_PARAM(clk_register_clk_parent_data_of_test,
2813 clk_register_clk_parent_data_of_test_gen_params),
2814 {}
2815};
2816
2817/*
2818 * Test suite for registering clks with struct clk_parent_data and a struct
2819 * device_node.
2820 */
2821static struct kunit_suite clk_register_clk_parent_data_of_suite = {
2822 .name = "clk_register_clk_parent_data_of",
2823 .init = clk_register_clk_parent_data_of_test_init,
2824 .test_cases = clk_register_clk_parent_data_of_test_cases,
2825};
2826
2827/**
2828 * struct clk_register_clk_parent_data_device_ctx - Context for clk_parent_data device tests
2829 * @dev: device of clk under test
2830 * @hw: clk_hw for clk under test
2831 * @pdrv: driver to attach to find @dev
2832 */
2833struct clk_register_clk_parent_data_device_ctx {
2834 struct device *dev;
2835 struct clk_hw hw;
2836 struct platform_driver pdrv;
2837};
2838
2839static inline struct clk_register_clk_parent_data_device_ctx *
2840clk_register_clk_parent_data_driver_to_test_context(struct platform_device *pdev)
2841{
2842 return container_of(to_platform_driver(pdev->dev.driver),
2843 struct clk_register_clk_parent_data_device_ctx, pdrv);
2844}
2845
2846static int clk_register_clk_parent_data_device_probe(struct platform_device *pdev)
2847{
2848 struct clk_register_clk_parent_data_device_ctx *ctx;
2849
2850 ctx = clk_register_clk_parent_data_driver_to_test_context(pdev);
2851 ctx->dev = &pdev->dev;
2852
2853 return 0;
2854}
2855
2856static void clk_register_clk_parent_data_device_driver(struct kunit *test)
2857{
2858 struct clk_register_clk_parent_data_device_ctx *ctx = test->priv;
2859 static const struct of_device_id match_table[] = {
2860 { .compatible = "test,clk-parent-data" },
2861 { }
2862 };
2863
2864 ctx->pdrv.probe = clk_register_clk_parent_data_device_probe;
2865 ctx->pdrv.driver.of_match_table = match_table;
2866 ctx->pdrv.driver.name = __func__;
2867 ctx->pdrv.driver.owner = THIS_MODULE;
2868
2869 KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
2870 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx->dev);
2871}
2872
2873static const struct clk_register_clk_parent_data_test_case
2874clk_register_clk_parent_data_device_cases[] = {
2875 {
2876 /*
2877 * Test that a clk registered with a struct device can find a
2878 * parent based on struct clk_parent_data::index.
2879 */
2880 .desc = "clk_parent_data_device_index_test",
2881 .pdata.index = 1,
2882 },
2883 {
2884 /*
2885 * Test that a clk registered with a struct device can find a
2886 * parent based on struct clk_parent_data::fwname.
2887 */
2888 .desc = "clk_parent_data_device_fwname_test",
2889 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
2890 },
2891 {
2892 /*
2893 * Test that a clk registered with a struct device can find a
2894 * parent based on struct clk_parent_data::name.
2895 */
2896 .desc = "clk_parent_data_device_name_test",
2897 /* The index must be negative to indicate firmware not used */
2898 .pdata.index = -1,
2899 .pdata.name = CLK_PARENT_DATA_50MHZ_NAME,
2900 },
2901 {
2902 /*
2903 * Test that a clk registered with a struct device can find a
2904 * parent based on struct clk_parent_data::{fw_name,name}.
2905 */
2906 .desc = "clk_parent_data_device_fwname_name_test",
2907 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
2908 .pdata.name = "not_matching",
2909 },
2910 {
2911 /*
2912 * Test that a clk registered with a struct device can find a
2913 * parent based on struct clk_parent_data::{index,name}. Index
2914 * takes priority.
2915 */
2916 .desc = "clk_parent_data_device_index_name_priority_test",
2917 .pdata.index = 1,
2918 .pdata.name = "not_matching",
2919 },
2920 {
2921 /*
2922 * Test that a clk registered with a struct device can find a
2923 * parent based on struct clk_parent_data::{index,fwname,name}.
2924 * The fw_name takes priority over index and name.
2925 */
2926 .desc = "clk_parent_data_device_index_fwname_name_priority_test",
2927 .pdata.index = 0,
2928 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
2929 .pdata.name = "not_matching",
2930 },
2931};
2932
2933KUNIT_ARRAY_PARAM(clk_register_clk_parent_data_device_test,
2934 clk_register_clk_parent_data_device_cases,
2935 clk_register_clk_parent_data_test_case_to_desc)
2936
2937/*
2938 * Test that a clk registered with a struct device can find a parent based on
2939 * struct clk_parent_data when the hw member isn't set.
2940 */
2941static void clk_register_clk_parent_data_device_test(struct kunit *test)
2942{
2943 struct clk_register_clk_parent_data_device_ctx *ctx;
2944 const struct clk_register_clk_parent_data_test_case *test_param;
2945 struct clk_hw *parent_hw;
2946 struct clk_init_data init = { };
2947 struct clk *expected_parent, *actual_parent;
2948
2949 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
2950 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
2951 test->priv = ctx;
2952
2953 clk_register_clk_parent_data_device_driver(test);
2954
2955 expected_parent = clk_get_kunit(test, ctx->dev, "50");
2956 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_parent);
2957
2958 test_param = test->param_value;
2959 init.parent_data = &test_param->pdata;
2960 init.num_parents = 1;
2961 init.name = "parent_data_device_test_clk";
2962 init.ops = &clk_dummy_single_parent_ops;
2963 ctx->hw.init = &init;
2964 KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, ctx->dev, &ctx->hw));
2965
2966 parent_hw = clk_hw_get_parent(&ctx->hw);
2967 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
2968
2969 actual_parent = clk_hw_get_clk_kunit(test, parent_hw, __func__);
2970 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, actual_parent);
2971
2972 KUNIT_EXPECT_TRUE(test, clk_is_match(expected_parent, actual_parent));
2973}
2974
2975static const struct clk_register_clk_parent_data_test_case
2976clk_register_clk_parent_data_device_hw_cases[] = {
2977 {
2978 /*
2979 * Test that a clk registered with a struct device can find a
2980 * parent based on struct clk_parent_data::hw.
2981 */
2982 .desc = "clk_parent_data_device_hw_index_test",
2983 /* The index must be negative to indicate firmware not used */
2984 .pdata.index = -1,
2985 },
2986 {
2987 /*
2988 * Test that a clk registered with a struct device can find a
2989 * parent based on struct clk_parent_data::hw when
2990 * struct clk_parent_data::fw_name is set.
2991 */
2992 .desc = "clk_parent_data_device_hw_fwname_test",
2993 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
2994 },
2995 {
2996 /*
2997 * Test that a clk registered with a struct device can find a
2998 * parent based on struct clk_parent_data::hw when struct
2999 * clk_parent_data::name is set.
3000 */
3001 .desc = "clk_parent_data_device_hw_name_test",
3002 /* The index must be negative to indicate firmware not used */
3003 .pdata.index = -1,
3004 .pdata.name = CLK_PARENT_DATA_50MHZ_NAME,
3005 },
3006 {
3007 /*
3008 * Test that a clk registered with a struct device can find a
3009 * parent based on struct clk_parent_data::hw when struct
3010 * clk_parent_data::{fw_name,name} are set.
3011 */
3012 .desc = "clk_parent_data_device_hw_fwname_name_test",
3013 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
3014 .pdata.name = "not_matching",
3015 },
3016 {
3017 /*
3018 * Test that a clk registered with a struct device can find a
3019 * parent based on struct clk_parent_data::hw when struct
3020 * clk_parent_data::index is set. The hw pointer takes
3021 * priority.
3022 */
3023 .desc = "clk_parent_data_device_hw_index_priority_test",
3024 .pdata.index = 0,
3025 },
3026 {
3027 /*
3028 * Test that a clk registered with a struct device can find a
3029 * parent based on struct clk_parent_data::hw when
3030 * struct clk_parent_data::{index,fwname,name} are set.
3031 * The hw pointer takes priority over everything else.
3032 */
3033 .desc = "clk_parent_data_device_hw_index_fwname_name_priority_test",
3034 .pdata.index = 0,
3035 .pdata.fw_name = CLK_PARENT_DATA_PARENT2,
3036 .pdata.name = "not_matching",
3037 },
3038};
3039
3040KUNIT_ARRAY_PARAM(clk_register_clk_parent_data_device_hw_test,
3041 clk_register_clk_parent_data_device_hw_cases,
3042 clk_register_clk_parent_data_test_case_to_desc)
3043
3044/*
3045 * Test that a clk registered with a struct device can find a
3046 * parent based on struct clk_parent_data::hw.
3047 */
3048static void clk_register_clk_parent_data_device_hw_test(struct kunit *test)
3049{
3050 struct clk_register_clk_parent_data_device_ctx *ctx;
3051 const struct clk_register_clk_parent_data_test_case *test_param;
3052 struct clk_dummy_context *parent;
3053 struct clk_hw *parent_hw;
3054 struct clk_parent_data pdata = { };
3055 struct clk_init_data init = { };
3056
3057 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
3058 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
3059 test->priv = ctx;
3060
3061 clk_register_clk_parent_data_device_driver(test);
3062
3063 parent = kunit_kzalloc(test, sizeof(*parent), GFP_KERNEL);
3064 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
3065
3066 parent_hw = &parent->hw;
3067 parent_hw->init = CLK_HW_INIT_NO_PARENT("parent-clk",
3068 &clk_dummy_rate_ops, 0);
3069
3070 KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, ctx->dev, parent_hw));
3071
3072 test_param = test->param_value;
3073 memcpy(&pdata, &test_param->pdata, sizeof(pdata));
3074 pdata.hw = parent_hw;
3075 init.parent_data = &pdata;
3076 init.num_parents = 1;
3077 init.ops = &clk_dummy_single_parent_ops;
3078 init.name = "parent_data_device_hw_test_clk";
3079 ctx->hw.init = &init;
3080 KUNIT_ASSERT_EQ(test, 0, clk_hw_register_kunit(test, ctx->dev, &ctx->hw));
3081
3082 KUNIT_EXPECT_PTR_EQ(test, parent_hw, clk_hw_get_parent(&ctx->hw));
3083}
3084
3085static struct kunit_case clk_register_clk_parent_data_device_test_cases[] = {
3086 KUNIT_CASE_PARAM(clk_register_clk_parent_data_device_test,
3087 clk_register_clk_parent_data_device_test_gen_params),
3088 KUNIT_CASE_PARAM(clk_register_clk_parent_data_device_hw_test,
3089 clk_register_clk_parent_data_device_hw_test_gen_params),
3090 {}
3091};
3092
3093static int clk_register_clk_parent_data_device_init(struct kunit *test)
3094{
3095 KUNIT_ASSERT_EQ(test, 0,
3096 of_overlay_apply_kunit(test, kunit_clk_parent_data_test));
3097
3098 return 0;
3099}
3100
3101/*
3102 * Test suite for registering clks with struct clk_parent_data and a struct
3103 * device.
3104 */
3105static struct kunit_suite clk_register_clk_parent_data_device_suite = {
3106 .name = "clk_register_clk_parent_data_device",
3107 .init = clk_register_clk_parent_data_device_init,
3108 .test_cases = clk_register_clk_parent_data_device_test_cases,
3109};
3110
2662kunit_test_suites(
2663 &clk_leaf_mux_set_rate_parent_test_suite,
2664 &clk_test_suite,
2665 &clk_multiple_parents_mux_test_suite,
2666 &clk_mux_no_reparent_test_suite,
2667 &clk_mux_notifier_test_suite,
2668 &clk_orphan_transparent_multiple_parent_mux_test_suite,
2669 &clk_orphan_transparent_single_parent_test_suite,
2670 &clk_orphan_two_level_root_last_test_suite,
2671 &clk_range_test_suite,
2672 &clk_range_maximize_test_suite,
2673 &clk_range_minimize_test_suite,
3111kunit_test_suites(
3112 &clk_leaf_mux_set_rate_parent_test_suite,
3113 &clk_test_suite,
3114 &clk_multiple_parents_mux_test_suite,
3115 &clk_mux_no_reparent_test_suite,
3116 &clk_mux_notifier_test_suite,
3117 &clk_orphan_transparent_multiple_parent_mux_test_suite,
3118 &clk_orphan_transparent_single_parent_test_suite,
3119 &clk_orphan_two_level_root_last_test_suite,
3120 &clk_range_test_suite,
3121 &clk_range_maximize_test_suite,
3122 &clk_range_minimize_test_suite,
3123 &clk_register_clk_parent_data_of_suite,
3124 &clk_register_clk_parent_data_device_suite,
2674 &clk_single_parent_mux_test_suite,
3125 &clk_single_parent_mux_test_suite,
2675 &clk_uncached_test_suite
3126 &clk_uncached_test_suite,
2676);
2677MODULE_DESCRIPTION("Kunit tests for clk framework");
2678MODULE_LICENSE("GPL v2");
3127);
3128MODULE_DESCRIPTION("Kunit tests for clk framework");
3129MODULE_LICENSE("GPL v2");