clk_sandbox_test.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2016, NVIDIA CORPORATION.
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <clk.h>
  8. #include <asm/clk.h>
  9. #include <linux/err.h>
  10. struct sandbox_clk_test {
  11. struct clk clks[SANDBOX_CLK_TEST_NON_DEVM_COUNT];
  12. struct clk *clkps[SANDBOX_CLK_TEST_ID_COUNT];
  13. struct clk_bulk bulk;
  14. };
  15. static const char * const sandbox_clk_test_names[] = {
  16. [SANDBOX_CLK_TEST_ID_FIXED] = "fixed",
  17. [SANDBOX_CLK_TEST_ID_SPI] = "spi",
  18. [SANDBOX_CLK_TEST_ID_I2C] = "i2c",
  19. };
  20. int sandbox_clk_test_get(struct udevice *dev)
  21. {
  22. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  23. int i, ret;
  24. for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
  25. ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
  26. &sbct->clks[i]);
  27. if (ret)
  28. return ret;
  29. }
  30. return 0;
  31. }
  32. int sandbox_clk_test_devm_get(struct udevice *dev)
  33. {
  34. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  35. struct clk *clk;
  36. clk = devm_clk_get(dev, "no-an-existing-clock");
  37. if (!IS_ERR(clk)) {
  38. dev_err(dev, "devm_clk_get() should have failed\n");
  39. return -EINVAL;
  40. }
  41. clk = devm_clk_get(dev, "uart2");
  42. if (IS_ERR(clk))
  43. return PTR_ERR(clk);
  44. sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1] = clk;
  45. clk = devm_clk_get_optional(dev, "uart1");
  46. if (IS_ERR(clk))
  47. return PTR_ERR(clk);
  48. sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM2] = clk;
  49. sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM_NULL] = NULL;
  50. clk = devm_clk_get_optional(dev, "not_an_existing_clock");
  51. if (IS_ERR(clk))
  52. return PTR_ERR(clk);
  53. if (clk)
  54. return -EINVAL;
  55. return 0;
  56. }
  57. int sandbox_clk_test_get_bulk(struct udevice *dev)
  58. {
  59. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  60. return clk_get_bulk(dev, &sbct->bulk);
  61. }
  62. ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
  63. {
  64. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  65. if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  66. return -EINVAL;
  67. return clk_get_rate(sbct->clkps[id]);
  68. }
  69. ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
  70. {
  71. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  72. if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  73. return -EINVAL;
  74. return clk_set_rate(sbct->clkps[id], rate);
  75. }
  76. int sandbox_clk_test_enable(struct udevice *dev, int id)
  77. {
  78. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  79. if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  80. return -EINVAL;
  81. return clk_enable(sbct->clkps[id]);
  82. }
  83. int sandbox_clk_test_enable_bulk(struct udevice *dev)
  84. {
  85. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  86. return clk_enable_bulk(&sbct->bulk);
  87. }
  88. int sandbox_clk_test_disable(struct udevice *dev, int id)
  89. {
  90. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  91. if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
  92. return -EINVAL;
  93. return clk_disable(sbct->clkps[id]);
  94. }
  95. int sandbox_clk_test_disable_bulk(struct udevice *dev)
  96. {
  97. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  98. return clk_disable_bulk(&sbct->bulk);
  99. }
  100. int sandbox_clk_test_free(struct udevice *dev)
  101. {
  102. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  103. int i, ret;
  104. devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
  105. for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
  106. ret = clk_free(&sbct->clks[i]);
  107. if (ret)
  108. return ret;
  109. }
  110. return 0;
  111. }
  112. int sandbox_clk_test_release_bulk(struct udevice *dev)
  113. {
  114. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  115. return clk_release_bulk(&sbct->bulk);
  116. }
  117. int sandbox_clk_test_valid(struct udevice *dev)
  118. {
  119. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  120. int i;
  121. for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
  122. if (!clk_valid(sbct->clkps[i]))
  123. if (i != SANDBOX_CLK_TEST_ID_DEVM_NULL)
  124. return -EINVAL;
  125. }
  126. return 0;
  127. }
  128. static int sandbox_clk_test_probe(struct udevice *dev)
  129. {
  130. struct sandbox_clk_test *sbct = dev_get_priv(dev);
  131. int i;
  132. for (i = 0; i < SANDBOX_CLK_TEST_ID_DEVM1; i++)
  133. sbct->clkps[i] = &sbct->clks[i];
  134. for (i = SANDBOX_CLK_TEST_ID_DEVM1; i < SANDBOX_CLK_TEST_ID_COUNT; i++)
  135. sbct->clkps[i] = NULL;
  136. return 0;
  137. }
  138. static const struct udevice_id sandbox_clk_test_ids[] = {
  139. { .compatible = "sandbox,clk-test" },
  140. { }
  141. };
  142. U_BOOT_DRIVER(sandbox_clk_test) = {
  143. .name = "sandbox_clk_test",
  144. .id = UCLASS_MISC,
  145. .of_match = sandbox_clk_test_ids,
  146. .probe = sandbox_clk_test_probe,
  147. .priv_auto_alloc_size = sizeof(struct sandbox_clk_test),
  148. };