1*d690bd11SStephen Boyd // SPDX-License-Identifier: GPL-2.0 2*d690bd11SStephen Boyd /* 3*d690bd11SStephen Boyd * KUnit helpers for clk providers and consumers 4*d690bd11SStephen Boyd */ 5*d690bd11SStephen Boyd #include <linux/clk.h> 6*d690bd11SStephen Boyd #include <linux/clk-provider.h> 7*d690bd11SStephen Boyd #include <linux/err.h> 8*d690bd11SStephen Boyd #include <linux/kernel.h> 9*d690bd11SStephen Boyd #include <linux/slab.h> 10*d690bd11SStephen Boyd 11*d690bd11SStephen Boyd #include <kunit/clk.h> 12*d690bd11SStephen Boyd #include <kunit/resource.h> 13*d690bd11SStephen Boyd 14*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_disable_unprepare_wrapper, 15*d690bd11SStephen Boyd clk_disable_unprepare, struct clk *); 16*d690bd11SStephen Boyd /** 17*d690bd11SStephen Boyd * clk_prepare_enable_kunit() - Test managed clk_prepare_enable() 18*d690bd11SStephen Boyd * @test: The test context 19*d690bd11SStephen Boyd * @clk: clk to prepare and enable 20*d690bd11SStephen Boyd * 21*d690bd11SStephen Boyd * Return: 0 on success, or negative errno on failure. 22*d690bd11SStephen Boyd */ 23*d690bd11SStephen Boyd int clk_prepare_enable_kunit(struct kunit *test, struct clk *clk) 24*d690bd11SStephen Boyd { 25*d690bd11SStephen Boyd int ret; 26*d690bd11SStephen Boyd 27*d690bd11SStephen Boyd ret = clk_prepare_enable(clk); 28*d690bd11SStephen Boyd if (ret) 29*d690bd11SStephen Boyd return ret; 30*d690bd11SStephen Boyd 31*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_disable_unprepare_wrapper, 32*d690bd11SStephen Boyd clk); 33*d690bd11SStephen Boyd } 34*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_prepare_enable_kunit); 35*d690bd11SStephen Boyd 36*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_put_wrapper, clk_put, struct clk *); 37*d690bd11SStephen Boyd 38*d690bd11SStephen Boyd static struct clk *__clk_get_kunit(struct kunit *test, struct clk *clk) 39*d690bd11SStephen Boyd { 40*d690bd11SStephen Boyd int ret; 41*d690bd11SStephen Boyd 42*d690bd11SStephen Boyd if (IS_ERR(clk)) 43*d690bd11SStephen Boyd return clk; 44*d690bd11SStephen Boyd 45*d690bd11SStephen Boyd ret = kunit_add_action_or_reset(test, clk_put_wrapper, clk); 46*d690bd11SStephen Boyd if (ret) 47*d690bd11SStephen Boyd return ERR_PTR(ret); 48*d690bd11SStephen Boyd 49*d690bd11SStephen Boyd return clk; 50*d690bd11SStephen Boyd } 51*d690bd11SStephen Boyd 52*d690bd11SStephen Boyd /** 53*d690bd11SStephen Boyd * clk_get_kunit() - Test managed clk_get() 54*d690bd11SStephen Boyd * @test: The test context 55*d690bd11SStephen Boyd * @dev: device for clock "consumer" 56*d690bd11SStephen Boyd * @con_id: clock consumer ID 57*d690bd11SStephen Boyd * 58*d690bd11SStephen Boyd * Just like clk_get(), except the clk is managed by the test case and is 59*d690bd11SStephen Boyd * automatically put with clk_put() after the test case concludes. 60*d690bd11SStephen Boyd * 61*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure. 62*d690bd11SStephen Boyd */ 63*d690bd11SStephen Boyd struct clk * 64*d690bd11SStephen Boyd clk_get_kunit(struct kunit *test, struct device *dev, const char *con_id) 65*d690bd11SStephen Boyd { 66*d690bd11SStephen Boyd struct clk *clk; 67*d690bd11SStephen Boyd 68*d690bd11SStephen Boyd clk = clk_get(dev, con_id); 69*d690bd11SStephen Boyd 70*d690bd11SStephen Boyd return __clk_get_kunit(test, clk); 71*d690bd11SStephen Boyd } 72*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_get_kunit); 73*d690bd11SStephen Boyd 74*d690bd11SStephen Boyd /** 75*d690bd11SStephen Boyd * of_clk_get_kunit() - Test managed of_clk_get() 76*d690bd11SStephen Boyd * @test: The test context 77*d690bd11SStephen Boyd * @np: device_node for clock "consumer" 78*d690bd11SStephen Boyd * @index: index in 'clocks' property of @np 79*d690bd11SStephen Boyd * 80*d690bd11SStephen Boyd * Just like of_clk_get(), except the clk is managed by the test case and is 81*d690bd11SStephen Boyd * automatically put with clk_put() after the test case concludes. 82*d690bd11SStephen Boyd * 83*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure. 84*d690bd11SStephen Boyd */ 85*d690bd11SStephen Boyd struct clk * 86*d690bd11SStephen Boyd of_clk_get_kunit(struct kunit *test, struct device_node *np, int index) 87*d690bd11SStephen Boyd { 88*d690bd11SStephen Boyd struct clk *clk; 89*d690bd11SStephen Boyd 90*d690bd11SStephen Boyd clk = of_clk_get(np, index); 91*d690bd11SStephen Boyd 92*d690bd11SStephen Boyd return __clk_get_kunit(test, clk); 93*d690bd11SStephen Boyd } 94*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_get_kunit); 95*d690bd11SStephen Boyd 96*d690bd11SStephen Boyd /** 97*d690bd11SStephen Boyd * clk_hw_get_clk_kunit() - Test managed clk_hw_get_clk() 98*d690bd11SStephen Boyd * @test: The test context 99*d690bd11SStephen Boyd * @hw: clk_hw associated with the clk being consumed 100*d690bd11SStephen Boyd * @con_id: connection ID string on device 101*d690bd11SStephen Boyd * 102*d690bd11SStephen Boyd * Just like clk_hw_get_clk(), except the clk is managed by the test case and 103*d690bd11SStephen Boyd * is automatically put with clk_put() after the test case concludes. 104*d690bd11SStephen Boyd * 105*d690bd11SStephen Boyd * Return: new clk consumer or ERR_PTR on failure. 106*d690bd11SStephen Boyd */ 107*d690bd11SStephen Boyd struct clk * 108*d690bd11SStephen Boyd clk_hw_get_clk_kunit(struct kunit *test, struct clk_hw *hw, const char *con_id) 109*d690bd11SStephen Boyd { 110*d690bd11SStephen Boyd struct clk *clk; 111*d690bd11SStephen Boyd 112*d690bd11SStephen Boyd clk = clk_hw_get_clk(hw, con_id); 113*d690bd11SStephen Boyd 114*d690bd11SStephen Boyd return __clk_get_kunit(test, clk); 115*d690bd11SStephen Boyd } 116*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_clk_kunit); 117*d690bd11SStephen Boyd 118*d690bd11SStephen Boyd /** 119*d690bd11SStephen Boyd * clk_hw_get_clk_prepared_enabled_kunit() - Test managed clk_hw_get_clk() + clk_prepare_enable() 120*d690bd11SStephen Boyd * @test: The test context 121*d690bd11SStephen Boyd * @hw: clk_hw associated with the clk being consumed 122*d690bd11SStephen Boyd * @con_id: connection ID string on device 123*d690bd11SStephen Boyd * 124*d690bd11SStephen Boyd * Just like 125*d690bd11SStephen Boyd * 126*d690bd11SStephen Boyd * .. code-block:: c 127*d690bd11SStephen Boyd * 128*d690bd11SStephen Boyd * struct clk *clk = clk_hw_get_clk(...); 129*d690bd11SStephen Boyd * clk_prepare_enable(clk); 130*d690bd11SStephen Boyd * 131*d690bd11SStephen Boyd * except the clk is managed by the test case and is automatically disabled and 132*d690bd11SStephen Boyd * unprepared with clk_disable_unprepare() and put with clk_put() after the 133*d690bd11SStephen Boyd * test case concludes. 134*d690bd11SStephen Boyd * 135*d690bd11SStephen Boyd * Return: new clk consumer that is prepared and enabled or ERR_PTR on failure. 136*d690bd11SStephen Boyd */ 137*d690bd11SStephen Boyd struct clk * 138*d690bd11SStephen Boyd clk_hw_get_clk_prepared_enabled_kunit(struct kunit *test, struct clk_hw *hw, 139*d690bd11SStephen Boyd const char *con_id) 140*d690bd11SStephen Boyd { 141*d690bd11SStephen Boyd int ret; 142*d690bd11SStephen Boyd struct clk *clk; 143*d690bd11SStephen Boyd 144*d690bd11SStephen Boyd clk = clk_hw_get_clk_kunit(test, hw, con_id); 145*d690bd11SStephen Boyd if (IS_ERR(clk)) 146*d690bd11SStephen Boyd return clk; 147*d690bd11SStephen Boyd 148*d690bd11SStephen Boyd ret = clk_prepare_enable_kunit(test, clk); 149*d690bd11SStephen Boyd if (ret) 150*d690bd11SStephen Boyd return ERR_PTR(ret); 151*d690bd11SStephen Boyd 152*d690bd11SStephen Boyd return clk; 153*d690bd11SStephen Boyd } 154*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_get_clk_prepared_enabled_kunit); 155*d690bd11SStephen Boyd 156*d690bd11SStephen Boyd KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_wrapper, 157*d690bd11SStephen Boyd clk_hw_unregister, struct clk_hw *); 158*d690bd11SStephen Boyd 159*d690bd11SStephen Boyd /** 160*d690bd11SStephen Boyd * clk_hw_register_kunit() - Test managed clk_hw_register() 161*d690bd11SStephen Boyd * @test: The test context 162*d690bd11SStephen Boyd * @dev: device that is registering this clock 163*d690bd11SStephen Boyd * @hw: link to hardware-specific clock data 164*d690bd11SStephen Boyd * 165*d690bd11SStephen Boyd * Just like clk_hw_register(), except the clk registration is managed by the 166*d690bd11SStephen Boyd * test case and is automatically unregistered after the test case concludes. 167*d690bd11SStephen Boyd * 168*d690bd11SStephen Boyd * Return: 0 on success or a negative errno value on failure. 169*d690bd11SStephen Boyd */ 170*d690bd11SStephen Boyd int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw *hw) 171*d690bd11SStephen Boyd { 172*d690bd11SStephen Boyd int ret; 173*d690bd11SStephen Boyd 174*d690bd11SStephen Boyd ret = clk_hw_register(dev, hw); 175*d690bd11SStephen Boyd if (ret) 176*d690bd11SStephen Boyd return ret; 177*d690bd11SStephen Boyd 178*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw); 179*d690bd11SStephen Boyd } 180*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(clk_hw_register_kunit); 181*d690bd11SStephen Boyd 182*d690bd11SStephen Boyd /** 183*d690bd11SStephen Boyd * of_clk_hw_register_kunit() - Test managed of_clk_hw_register() 184*d690bd11SStephen Boyd * @test: The test context 185*d690bd11SStephen Boyd * @node: device_node of device that is registering this clock 186*d690bd11SStephen Boyd * @hw: link to hardware-specific clock data 187*d690bd11SStephen Boyd * 188*d690bd11SStephen Boyd * Just like of_clk_hw_register(), except the clk registration is managed by 189*d690bd11SStephen Boyd * the test case and is automatically unregistered after the test case 190*d690bd11SStephen Boyd * concludes. 191*d690bd11SStephen Boyd * 192*d690bd11SStephen Boyd * Return: 0 on success or a negative errno value on failure. 193*d690bd11SStephen Boyd */ 194*d690bd11SStephen Boyd int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struct clk_hw *hw) 195*d690bd11SStephen Boyd { 196*d690bd11SStephen Boyd int ret; 197*d690bd11SStephen Boyd 198*d690bd11SStephen Boyd ret = of_clk_hw_register(node, hw); 199*d690bd11SStephen Boyd if (ret) 200*d690bd11SStephen Boyd return ret; 201*d690bd11SStephen Boyd 202*d690bd11SStephen Boyd return kunit_add_action_or_reset(test, clk_hw_unregister_wrapper, hw); 203*d690bd11SStephen Boyd } 204*d690bd11SStephen Boyd EXPORT_SYMBOL_GPL(of_clk_hw_register_kunit); 205*d690bd11SStephen Boyd 206*d690bd11SStephen Boyd MODULE_LICENSE("GPL"); 207*d690bd11SStephen Boyd MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers"); 208