wdt.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2017 Google, Inc
  4. */
  5. #include <common.h>
  6. #include <cyclic.h>
  7. #include <dm.h>
  8. #include <wdt.h>
  9. #include <asm/gpio.h>
  10. #include <asm/state.h>
  11. #include <asm/test.h>
  12. #include <dm/test.h>
  13. #include <test/test.h>
  14. #include <test/ut.h>
  15. #include <linux/delay.h>
  16. #include <watchdog.h>
  17. /* Test that watchdog driver functions are called */
  18. static int dm_test_wdt_base(struct unit_test_state *uts)
  19. {
  20. struct sandbox_state *state = state_get_current();
  21. struct udevice *dev;
  22. const u64 timeout = 42;
  23. ut_assertok(uclass_get_device_by_driver(UCLASS_WDT,
  24. DM_DRIVER_GET(wdt_sandbox), &dev));
  25. ut_assertnonnull(dev);
  26. ut_asserteq(0, state->wdt.counter);
  27. ut_asserteq(false, state->wdt.running);
  28. ut_assertok(wdt_start(dev, timeout, 0));
  29. ut_asserteq(timeout, state->wdt.counter);
  30. ut_asserteq(true, state->wdt.running);
  31. uint reset_count = state->wdt.reset_count;
  32. ut_assertok(wdt_reset(dev));
  33. ut_asserteq(reset_count + 1, state->wdt.reset_count);
  34. ut_asserteq(true, state->wdt.running);
  35. ut_assertok(wdt_stop(dev));
  36. ut_asserteq(false, state->wdt.running);
  37. return 0;
  38. }
  39. DM_TEST(dm_test_wdt_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  40. static int dm_test_wdt_gpio_toggle(struct unit_test_state *uts)
  41. {
  42. /*
  43. * The sandbox wdt gpio is "connected" to gpio bank a, offset
  44. * 7. Use the sandbox back door to verify that the gpio-wdt
  45. * driver behaves as expected when using the 'toggle' algorithm.
  46. */
  47. struct udevice *wdt, *gpio;
  48. const u64 timeout = 42;
  49. const int offset = 7;
  50. int val;
  51. ut_assertok(uclass_get_device_by_name(UCLASS_WDT,
  52. "wdt-gpio-toggle", &wdt));
  53. ut_assertnonnull(wdt);
  54. ut_assertok(uclass_get_device_by_name(UCLASS_GPIO, "base-gpios", &gpio));
  55. ut_assertnonnull(gpio);
  56. ut_assertok(wdt_start(wdt, timeout, 0));
  57. val = sandbox_gpio_get_value(gpio, offset);
  58. ut_assertok(wdt_reset(wdt));
  59. ut_asserteq(!val, sandbox_gpio_get_value(gpio, offset));
  60. ut_assertok(wdt_reset(wdt));
  61. ut_asserteq(val, sandbox_gpio_get_value(gpio, offset));
  62. ut_asserteq(-ENOSYS, wdt_stop(wdt));
  63. return 0;
  64. }
  65. DM_TEST(dm_test_wdt_gpio_toggle, UT_TESTF_SCAN_FDT);
  66. static int dm_test_wdt_gpio_level(struct unit_test_state *uts)
  67. {
  68. /*
  69. * The sandbox wdt gpio is "connected" to gpio bank a, offset
  70. * 7. Use the sandbox back door to verify that the gpio-wdt
  71. * driver behaves as expected when using the 'level' algorithm.
  72. */
  73. struct udevice *wdt, *gpio;
  74. const u64 timeout = 42;
  75. const int offset = 7;
  76. int val;
  77. ut_assertok(uclass_get_device_by_name(UCLASS_WDT,
  78. "wdt-gpio-level", &wdt));
  79. ut_assertnonnull(wdt);
  80. ut_assertok(uclass_get_device_by_name(UCLASS_GPIO, "base-gpios", &gpio));
  81. ut_assertnonnull(gpio);
  82. ut_assertok(wdt_start(wdt, timeout, 0));
  83. val = sandbox_gpio_get_value(gpio, offset);
  84. ut_assertok(wdt_reset(wdt));
  85. ut_asserteq(val, sandbox_gpio_get_value(gpio, offset));
  86. ut_assertok(wdt_reset(wdt));
  87. ut_asserteq(val, sandbox_gpio_get_value(gpio, offset));
  88. ut_asserteq(-ENOSYS, wdt_stop(wdt));
  89. return 0;
  90. }
  91. DM_TEST(dm_test_wdt_gpio_level, UT_TESTF_SCAN_FDT);
  92. static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts)
  93. {
  94. struct sandbox_state *state = state_get_current();
  95. struct udevice *gpio_wdt, *sandbox_wdt;
  96. struct udevice *gpio;
  97. const u64 timeout = 42;
  98. const int offset = 7;
  99. uint reset_count;
  100. int val;
  101. ut_assertok(uclass_get_device_by_name(UCLASS_WDT,
  102. "wdt-gpio-toggle", &gpio_wdt));
  103. ut_assertnonnull(gpio_wdt);
  104. ut_assertok(uclass_get_device_by_driver(UCLASS_WDT,
  105. DM_DRIVER_GET(wdt_sandbox), &sandbox_wdt));
  106. ut_assertnonnull(sandbox_wdt);
  107. ut_assertok(uclass_get_device_by_name(UCLASS_GPIO, "base-gpios", &gpio));
  108. ut_assertnonnull(gpio);
  109. /* Neither device should be "started", so watchdog_reset() should be a no-op. */
  110. reset_count = state->wdt.reset_count;
  111. val = sandbox_gpio_get_value(gpio, offset);
  112. cyclic_run();
  113. ut_asserteq(reset_count, state->wdt.reset_count);
  114. ut_asserteq(val, sandbox_gpio_get_value(gpio, offset));
  115. /* Start both devices. */
  116. ut_assertok(wdt_start(gpio_wdt, timeout, 0));
  117. ut_assertok(wdt_start(sandbox_wdt, timeout, 0));
  118. /* Make sure both devices have just been pinged. */
  119. timer_test_add_offset(100);
  120. cyclic_run();
  121. reset_count = state->wdt.reset_count;
  122. val = sandbox_gpio_get_value(gpio, offset);
  123. /* The gpio watchdog should be pinged, the sandbox one not. */
  124. timer_test_add_offset(30);
  125. cyclic_run();
  126. ut_asserteq(reset_count, state->wdt.reset_count);
  127. ut_asserteq(!val, sandbox_gpio_get_value(gpio, offset));
  128. /* After another ~30ms, both devices should get pinged. */
  129. timer_test_add_offset(30);
  130. cyclic_run();
  131. ut_asserteq(reset_count + 1, state->wdt.reset_count);
  132. ut_asserteq(val, sandbox_gpio_get_value(gpio, offset));
  133. return 0;
  134. }
  135. DM_TEST(dm_test_wdt_watchdog_reset, UT_TESTF_SCAN_FDT);