fdt_ipi.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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/ipi/fdt_ipi.h>
  13. /* List of FDT ipi drivers generated at compile time */
  14. extern struct fdt_ipi *fdt_ipi_drivers[];
  15. extern unsigned long fdt_ipi_drivers_size;
  16. static struct fdt_ipi dummy = {
  17. .match_table = NULL,
  18. .cold_init = NULL,
  19. .warm_init = NULL,
  20. .exit = NULL,
  21. };
  22. static struct fdt_ipi *current_driver = &dummy;
  23. void fdt_ipi_exit(void)
  24. {
  25. if (current_driver->exit)
  26. current_driver->exit();
  27. }
  28. static int fdt_ipi_warm_init(void)
  29. {
  30. if (current_driver->warm_init)
  31. return current_driver->warm_init();
  32. return 0;
  33. }
  34. static int fdt_ipi_cold_init(void)
  35. {
  36. int pos, noff, rc;
  37. struct fdt_ipi *drv;
  38. const struct fdt_match *match;
  39. void *fdt = fdt_get_address();
  40. for (pos = 0; pos < fdt_ipi_drivers_size; pos++) {
  41. drv = fdt_ipi_drivers[pos];
  42. noff = -1;
  43. while ((noff = fdt_find_match(fdt, noff,
  44. drv->match_table, &match)) >= 0) {
  45. if (drv->cold_init) {
  46. rc = drv->cold_init(fdt, noff, match);
  47. if (rc == SBI_ENODEV)
  48. continue;
  49. if (rc)
  50. return rc;
  51. }
  52. current_driver = drv;
  53. }
  54. if (current_driver != &dummy)
  55. break;
  56. }
  57. return 0;
  58. }
  59. int fdt_ipi_init(bool cold_boot)
  60. {
  61. int rc;
  62. if (cold_boot) {
  63. rc = fdt_ipi_cold_init();
  64. if (rc)
  65. return rc;
  66. }
  67. return fdt_ipi_warm_init();
  68. }