clk-gate_test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Kunit test for clk gate basic type
  4. */
  5. #include <linux/clk.h>
  6. #include <linux/clk-provider.h>
  7. #include <linux/platform_device.h>
  8. #include <kunit/test.h>
  9. static void clk_gate_register_test_dev(struct kunit *test)
  10. {
  11. struct clk_hw *ret;
  12. struct platform_device *pdev;
  13. pdev = platform_device_register_simple("test_gate_device", -1, NULL, 0);
  14. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
  15. ret = clk_hw_register_gate(&pdev->dev, "test_gate", NULL, 0, NULL,
  16. 0, 0, NULL);
  17. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
  18. KUNIT_EXPECT_STREQ(test, "test_gate", clk_hw_get_name(ret));
  19. KUNIT_EXPECT_EQ(test, 0UL, clk_hw_get_flags(ret));
  20. clk_hw_unregister_gate(ret);
  21. platform_device_put(pdev);
  22. }
  23. static void clk_gate_register_test_parent_names(struct kunit *test)
  24. {
  25. struct clk_hw *parent;
  26. struct clk_hw *ret;
  27. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  28. 1000000);
  29. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  30. ret = clk_hw_register_gate(NULL, "test_gate", "test_parent", 0, NULL,
  31. 0, 0, NULL);
  32. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
  33. KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
  34. clk_hw_unregister_gate(ret);
  35. clk_hw_unregister_fixed_rate(parent);
  36. }
  37. static void clk_gate_register_test_parent_data(struct kunit *test)
  38. {
  39. struct clk_hw *parent;
  40. struct clk_hw *ret;
  41. struct clk_parent_data pdata = { };
  42. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  43. 1000000);
  44. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  45. pdata.hw = parent;
  46. ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
  47. NULL, 0, 0, NULL);
  48. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
  49. KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
  50. clk_hw_unregister_gate(ret);
  51. clk_hw_unregister_fixed_rate(parent);
  52. }
  53. static void clk_gate_register_test_parent_data_legacy(struct kunit *test)
  54. {
  55. struct clk_hw *parent;
  56. struct clk_hw *ret;
  57. struct clk_parent_data pdata = { };
  58. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  59. 1000000);
  60. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  61. pdata.name = "test_parent";
  62. ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
  63. NULL, 0, 0, NULL);
  64. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
  65. KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
  66. clk_hw_unregister_gate(ret);
  67. clk_hw_unregister_fixed_rate(parent);
  68. }
  69. static void clk_gate_register_test_parent_hw(struct kunit *test)
  70. {
  71. struct clk_hw *parent;
  72. struct clk_hw *ret;
  73. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  74. 1000000);
  75. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  76. ret = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0, NULL,
  77. 0, 0, NULL);
  78. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
  79. KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
  80. clk_hw_unregister_gate(ret);
  81. clk_hw_unregister_fixed_rate(parent);
  82. }
  83. static void clk_gate_register_test_hiword_invalid(struct kunit *test)
  84. {
  85. struct clk_hw *ret;
  86. ret = clk_hw_register_gate(NULL, "test_gate", NULL, 0, NULL,
  87. 20, CLK_GATE_HIWORD_MASK, NULL);
  88. KUNIT_EXPECT_TRUE(test, IS_ERR(ret));
  89. }
  90. static struct kunit_case clk_gate_register_test_cases[] = {
  91. KUNIT_CASE(clk_gate_register_test_dev),
  92. KUNIT_CASE(clk_gate_register_test_parent_names),
  93. KUNIT_CASE(clk_gate_register_test_parent_data),
  94. KUNIT_CASE(clk_gate_register_test_parent_data_legacy),
  95. KUNIT_CASE(clk_gate_register_test_parent_hw),
  96. KUNIT_CASE(clk_gate_register_test_hiword_invalid),
  97. {}
  98. };
  99. static struct kunit_suite clk_gate_register_test_suite = {
  100. .name = "clk-gate-register-test",
  101. .test_cases = clk_gate_register_test_cases,
  102. };
  103. struct clk_gate_test_context {
  104. void __iomem *fake_mem;
  105. struct clk_hw *hw;
  106. struct clk_hw *parent;
  107. u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
  108. };
  109. static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
  110. {
  111. struct clk_gate_test_context *ctx;
  112. test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
  113. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
  114. ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;
  115. return ctx;
  116. }
  117. static void clk_gate_test_parent_rate(struct kunit *test)
  118. {
  119. struct clk_gate_test_context *ctx = test->priv;
  120. struct clk_hw *parent = ctx->parent;
  121. struct clk_hw *hw = ctx->hw;
  122. unsigned long prate = clk_hw_get_rate(parent);
  123. unsigned long rate = clk_hw_get_rate(hw);
  124. KUNIT_EXPECT_EQ(test, prate, rate);
  125. }
  126. static void clk_gate_test_enable(struct kunit *test)
  127. {
  128. struct clk_gate_test_context *ctx = test->priv;
  129. struct clk_hw *parent = ctx->parent;
  130. struct clk_hw *hw = ctx->hw;
  131. struct clk *clk = hw->clk;
  132. u32 enable_val = BIT(5);
  133. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  134. KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
  135. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
  136. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
  137. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
  138. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
  139. }
  140. static void clk_gate_test_disable(struct kunit *test)
  141. {
  142. struct clk_gate_test_context *ctx = test->priv;
  143. struct clk_hw *parent = ctx->parent;
  144. struct clk_hw *hw = ctx->hw;
  145. struct clk *clk = hw->clk;
  146. u32 enable_val = BIT(5);
  147. u32 disable_val = 0;
  148. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  149. KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
  150. clk_disable_unprepare(clk);
  151. KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
  152. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
  153. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
  154. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
  155. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
  156. }
  157. static struct kunit_case clk_gate_test_cases[] = {
  158. KUNIT_CASE(clk_gate_test_parent_rate),
  159. KUNIT_CASE(clk_gate_test_enable),
  160. KUNIT_CASE(clk_gate_test_disable),
  161. {}
  162. };
  163. static int clk_gate_test_init(struct kunit *test)
  164. {
  165. struct clk_hw *parent;
  166. struct clk_hw *hw;
  167. struct clk_gate_test_context *ctx;
  168. ctx = clk_gate_test_alloc_ctx(test);
  169. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  170. 2000000);
  171. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  172. hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
  173. ctx->fake_mem, 5, 0, NULL);
  174. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  175. ctx->hw = hw;
  176. ctx->parent = parent;
  177. return 0;
  178. }
  179. static void clk_gate_test_exit(struct kunit *test)
  180. {
  181. struct clk_gate_test_context *ctx = test->priv;
  182. clk_hw_unregister_gate(ctx->hw);
  183. clk_hw_unregister_fixed_rate(ctx->parent);
  184. }
  185. static struct kunit_suite clk_gate_test_suite = {
  186. .name = "clk-gate-test",
  187. .init = clk_gate_test_init,
  188. .exit = clk_gate_test_exit,
  189. .test_cases = clk_gate_test_cases,
  190. };
  191. static void clk_gate_test_invert_enable(struct kunit *test)
  192. {
  193. struct clk_gate_test_context *ctx = test->priv;
  194. struct clk_hw *parent = ctx->parent;
  195. struct clk_hw *hw = ctx->hw;
  196. struct clk *clk = hw->clk;
  197. u32 enable_val = 0;
  198. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  199. KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
  200. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
  201. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
  202. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
  203. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
  204. }
  205. static void clk_gate_test_invert_disable(struct kunit *test)
  206. {
  207. struct clk_gate_test_context *ctx = test->priv;
  208. struct clk_hw *parent = ctx->parent;
  209. struct clk_hw *hw = ctx->hw;
  210. struct clk *clk = hw->clk;
  211. u32 enable_val = 0;
  212. u32 disable_val = BIT(15);
  213. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  214. KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
  215. clk_disable_unprepare(clk);
  216. KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
  217. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
  218. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
  219. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
  220. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
  221. }
  222. static struct kunit_case clk_gate_test_invert_cases[] = {
  223. KUNIT_CASE(clk_gate_test_invert_enable),
  224. KUNIT_CASE(clk_gate_test_invert_disable),
  225. {}
  226. };
  227. static int clk_gate_test_invert_init(struct kunit *test)
  228. {
  229. struct clk_hw *parent;
  230. struct clk_hw *hw;
  231. struct clk_gate_test_context *ctx;
  232. ctx = clk_gate_test_alloc_ctx(test);
  233. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  234. 2000000);
  235. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  236. ctx->fake_reg = BIT(15); /* Default to off */
  237. hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
  238. ctx->fake_mem, 15,
  239. CLK_GATE_SET_TO_DISABLE, NULL);
  240. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  241. ctx->hw = hw;
  242. ctx->parent = parent;
  243. return 0;
  244. }
  245. static struct kunit_suite clk_gate_test_invert_suite = {
  246. .name = "clk-gate-invert-test",
  247. .init = clk_gate_test_invert_init,
  248. .exit = clk_gate_test_exit,
  249. .test_cases = clk_gate_test_invert_cases,
  250. };
  251. static void clk_gate_test_hiword_enable(struct kunit *test)
  252. {
  253. struct clk_gate_test_context *ctx = test->priv;
  254. struct clk_hw *parent = ctx->parent;
  255. struct clk_hw *hw = ctx->hw;
  256. struct clk *clk = hw->clk;
  257. u32 enable_val = BIT(9) | BIT(9 + 16);
  258. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  259. KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
  260. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
  261. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
  262. KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
  263. KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
  264. }
  265. static void clk_gate_test_hiword_disable(struct kunit *test)
  266. {
  267. struct clk_gate_test_context *ctx = test->priv;
  268. struct clk_hw *parent = ctx->parent;
  269. struct clk_hw *hw = ctx->hw;
  270. struct clk *clk = hw->clk;
  271. u32 enable_val = BIT(9) | BIT(9 + 16);
  272. u32 disable_val = BIT(9 + 16);
  273. KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
  274. KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
  275. clk_disable_unprepare(clk);
  276. KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
  277. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
  278. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
  279. KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
  280. KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
  281. }
  282. static struct kunit_case clk_gate_test_hiword_cases[] = {
  283. KUNIT_CASE(clk_gate_test_hiword_enable),
  284. KUNIT_CASE(clk_gate_test_hiword_disable),
  285. {}
  286. };
  287. static int clk_gate_test_hiword_init(struct kunit *test)
  288. {
  289. struct clk_hw *parent;
  290. struct clk_hw *hw;
  291. struct clk_gate_test_context *ctx;
  292. ctx = clk_gate_test_alloc_ctx(test);
  293. parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
  294. 2000000);
  295. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
  296. hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
  297. ctx->fake_mem, 9,
  298. CLK_GATE_HIWORD_MASK, NULL);
  299. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  300. ctx->hw = hw;
  301. ctx->parent = parent;
  302. return 0;
  303. }
  304. static struct kunit_suite clk_gate_test_hiword_suite = {
  305. .name = "clk-gate-hiword-test",
  306. .init = clk_gate_test_hiword_init,
  307. .exit = clk_gate_test_exit,
  308. .test_cases = clk_gate_test_hiword_cases,
  309. };
  310. static void clk_gate_test_is_enabled(struct kunit *test)
  311. {
  312. struct clk_hw *hw;
  313. struct clk_gate_test_context *ctx;
  314. ctx = clk_gate_test_alloc_ctx(test);
  315. ctx->fake_reg = BIT(7);
  316. hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
  317. 0, NULL);
  318. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  319. KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
  320. clk_hw_unregister_gate(hw);
  321. }
  322. static void clk_gate_test_is_disabled(struct kunit *test)
  323. {
  324. struct clk_hw *hw;
  325. struct clk_gate_test_context *ctx;
  326. ctx = clk_gate_test_alloc_ctx(test);
  327. ctx->fake_reg = BIT(4);
  328. hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
  329. 0, NULL);
  330. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  331. KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
  332. clk_hw_unregister_gate(hw);
  333. }
  334. static void clk_gate_test_is_enabled_inverted(struct kunit *test)
  335. {
  336. struct clk_hw *hw;
  337. struct clk_gate_test_context *ctx;
  338. ctx = clk_gate_test_alloc_ctx(test);
  339. ctx->fake_reg = BIT(31);
  340. hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
  341. CLK_GATE_SET_TO_DISABLE, NULL);
  342. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  343. KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
  344. clk_hw_unregister_gate(hw);
  345. }
  346. static void clk_gate_test_is_disabled_inverted(struct kunit *test)
  347. {
  348. struct clk_hw *hw;
  349. struct clk_gate_test_context *ctx;
  350. ctx = clk_gate_test_alloc_ctx(test);
  351. ctx->fake_reg = BIT(29);
  352. hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
  353. CLK_GATE_SET_TO_DISABLE, NULL);
  354. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
  355. KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
  356. clk_hw_unregister_gate(hw);
  357. }
  358. static struct kunit_case clk_gate_test_enabled_cases[] = {
  359. KUNIT_CASE(clk_gate_test_is_enabled),
  360. KUNIT_CASE(clk_gate_test_is_disabled),
  361. KUNIT_CASE(clk_gate_test_is_enabled_inverted),
  362. KUNIT_CASE(clk_gate_test_is_disabled_inverted),
  363. {}
  364. };
  365. static struct kunit_suite clk_gate_test_enabled_suite = {
  366. .name = "clk-gate-is_enabled-test",
  367. .test_cases = clk_gate_test_enabled_cases,
  368. };
  369. kunit_test_suites(
  370. &clk_gate_register_test_suite,
  371. &clk_gate_test_suite,
  372. &clk_gate_test_invert_suite,
  373. &clk_gate_test_hiword_suite,
  374. &clk_gate_test_enabled_suite
  375. );
  376. MODULE_LICENSE("GPL v2");