fdt_timer.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2020 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #include <sbi/sbi_error.h>
  10. #include <sbi/sbi_scratch.h>
  11. #include <sbi_utils/fdt/fdt_helper.h>
  12. #include <sbi_utils/timer/fdt_timer.h>
  13. extern struct fdt_timer fdt_timer_clint;
  14. static struct fdt_timer *timer_drivers[] = {
  15. &fdt_timer_clint
  16. };
  17. static struct fdt_timer dummy = {
  18. .match_table = NULL,
  19. .cold_init = NULL,
  20. .warm_init = NULL,
  21. .exit = NULL,
  22. };
  23. static struct fdt_timer *current_driver = &dummy;
  24. void fdt_timer_exit(void)
  25. {
  26. if (current_driver->exit)
  27. current_driver->exit();
  28. }
  29. static int fdt_timer_warm_init(void)
  30. {
  31. if (current_driver->warm_init)
  32. return current_driver->warm_init();
  33. return 0;
  34. }
  35. static int fdt_timer_cold_init(void)
  36. {
  37. int pos, noff, rc;
  38. struct fdt_timer *drv;
  39. const struct fdt_match *match;
  40. void *fdt = sbi_scratch_thishart_arg1_ptr();
  41. for (pos = 0; pos < array_size(timer_drivers); pos++) {
  42. drv = timer_drivers[pos];
  43. noff = -1;
  44. while ((noff = fdt_find_match(fdt, noff,
  45. drv->match_table, &match)) >= 0) {
  46. if (drv->cold_init) {
  47. rc = drv->cold_init(fdt, noff, match);
  48. if (rc == SBI_ENODEV)
  49. continue;
  50. if (rc)
  51. return rc;
  52. }
  53. current_driver = drv;
  54. }
  55. if (current_driver != &dummy)
  56. break;
  57. }
  58. return 0;
  59. }
  60. int fdt_timer_init(bool cold_boot)
  61. {
  62. int rc;
  63. if (cold_boot) {
  64. rc = fdt_timer_cold_init();
  65. if (rc)
  66. return rc;
  67. }
  68. return fdt_timer_warm_init();
  69. }