lkml.org 
[lkml]   [2023]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 2/2] clk: Introduce kunit wrapper around __clk_determine_rate
    Some kunit tests are meant to test the behaviour of providers but don't
    run those functions with the clk prepare_lock held which results in
    lockdep warning.

    __clk_determine_rate is one of the functions being executed from a test
    which should have the lock held. Let's introduce a wrapper around it
    meant to be used only by kunit tests.

    Reported-by: Guenter Roeck <linux@roeck-us.net>
    Link: https://lore.kernel.org/linux-clk/2b594e50-2bbf-4a2d-88e6-49fc39f3957a@roeck-us.net/
    Reported-by: kernel test robot <yujie.liu@intel.com>
    Link: https://lore.kernel.org/oe-lkp/202301310919.b9d56ee3-yujie.liu@intel.com
    Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent")
    Signed-off-by: Maxime Ripard <mripard@kernel.org>
    ---
    drivers/clk/clk.c | 25 +++++++++++++++++++++++++
    drivers/clk/clk_test.c | 2 +-
    include/linux/clk-provider.h | 10 ++++++++++
    3 files changed, 36 insertions(+), 1 deletion(-)

    diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
    index 8ee9bd02af76..8fdbfec6bd85 100644
    --- a/drivers/clk/clk.c
    +++ b/drivers/clk/clk.c
    @@ -1669,6 +1669,31 @@ int __clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
    }
    EXPORT_SYMBOL_GPL(__clk_determine_rate);

    +#if IS_ENABLED(CONFIG_KUNIT)
    +/**
    + * __clk_kunit_determine_rate - get the closest rate actually supported by a clock
    + * @hw: determine the rate of this clock
    + * @req: target rate request
    + *
    + * Useful for clk_ops such as .set_rate and .determine_rate. Only usable
    + * in a kunit test context. Use __clk_determine_rate() otherwise.
    + */
    +int __clk_kunit_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
    +{
    + int ret;
    +
    + if (!kunit_get_current_test())
    + return -EINVAL;
    +
    + clk_prepare_lock();
    + ret = __clk_determine_rate(hw, req);
    + clk_prepare_unlock();
    +
    + return ret;
    +}
    +EXPORT_SYMBOL_GPL(__clk_kunit_determine_rate);
    +#endif
    +
    /**
    * clk_hw_round_rate() - round the given rate for a hw clk
    * @hw: the hw clk for which we are rounding a rate
    diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
    index a64f7036baa3..b835e08892b4 100644
    --- a/drivers/clk/clk_test.c
    +++ b/drivers/clk/clk_test.c
    @@ -2232,7 +2232,7 @@ static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test)

    clk_kunit_init_rate_request(hw, &req, DUMMY_CLOCK_RATE_2);

    - ret = __clk_determine_rate(hw, &req);
    + ret = __clk_kunit_determine_rate(hw, &req);
    KUNIT_ASSERT_EQ(test, ret, 0);

    KUNIT_EXPECT_EQ(test, req.rate, DUMMY_CLOCK_RATE_2);
    diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
    index efdebfa3fce9..43049f2c1dd2 100644
    --- a/include/linux/clk-provider.h
    +++ b/include/linux/clk-provider.h
    @@ -1352,6 +1352,16 @@ void clk_hw_get_rate_range(struct clk_hw *hw, unsigned long *min_rate,
    void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
    unsigned long max_rate);

    +#if IS_ENABLED(CONFIG_KUNIT)
    +int __clk_kunit_determine_rate(struct clk_hw *hw, struct clk_rate_request *req);
    +#else
    +static inline int __clk_kunit_determine_rate(struct clk_hw *hw,
    + struct clk_rate_request *req)
    +{
    + return -ENOENT;
    +}
    +#endif
    +
    static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
    {
    dst->clk = src->clk;
    --
    2.41.0

    \
     
     \ /
      Last update: 2023-07-21 09:10    [W:3.127 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site