syscon-reboot-mode.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define DBG_TAG "reset.syscon.reboot-mode"
  13. #define DBG_LVL DBG_INFO
  14. #include <rtdbg.h>
  15. #include "reboot-mode.h"
  16. struct syscon_reboot_mode
  17. {
  18. struct rt_syscon *map;
  19. struct reboot_mode reboot;
  20. rt_uint32_t offset;
  21. rt_uint32_t mask;
  22. };
  23. static rt_err_t syscon_reboot_mode_write(struct reboot_mode *reboot,
  24. rt_uint32_t magic)
  25. {
  26. rt_err_t err;
  27. struct syscon_reboot_mode *srbm;
  28. srbm = rt_container_of(reboot, struct syscon_reboot_mode, reboot);
  29. err = rt_syscon_update_bits(srbm->map, srbm->offset, srbm->mask, magic);
  30. if (err)
  31. {
  32. LOG_E("Update reboot mode bits failed");
  33. }
  34. return err;
  35. }
  36. static rt_err_t syscon_reboot_mode_probe(struct rt_platform_device *pdev)
  37. {
  38. rt_err_t err;
  39. struct rt_ofw_node *np;
  40. struct rt_device *dev = &pdev->parent;
  41. struct syscon_reboot_mode *srbm = rt_calloc(1, sizeof(*srbm));
  42. if (!srbm)
  43. {
  44. return -RT_ENOMEM;
  45. }
  46. np = rt_ofw_get_parent(dev->ofw_node);
  47. srbm->map = rt_syscon_find_by_ofw_node(np);
  48. rt_ofw_node_put(np);
  49. if (!srbm->map)
  50. {
  51. err = -RT_EIO;
  52. goto _fail;
  53. }
  54. srbm->reboot.dev = dev;
  55. srbm->reboot.write = syscon_reboot_mode_write;
  56. srbm->mask = 0xffffffff;
  57. if (rt_dm_dev_prop_read_u32(dev, "offset", &srbm->offset))
  58. {
  59. err = -RT_EINVAL;
  60. goto _fail;
  61. }
  62. rt_dm_dev_prop_read_u32(dev, "mask", &srbm->mask);
  63. if ((err = reboot_mode_register(&srbm->reboot)))
  64. {
  65. goto _fail;
  66. }
  67. return RT_EOK;
  68. _fail:
  69. rt_free(srbm);
  70. return err;
  71. }
  72. static const struct rt_ofw_node_id syscon_reboot_mode_ofw_ids[] =
  73. {
  74. { .compatible = "syscon-reboot-mode" },
  75. { /* sentinel */ }
  76. };
  77. static struct rt_platform_driver syscon_reboot_mode_driver =
  78. {
  79. .name = "reset-syscon-reboot-mode",
  80. .ids = syscon_reboot_mode_ofw_ids,
  81. .probe = syscon_reboot_mode_probe,
  82. };
  83. static int syscon_reboot_mode_driver_register(void)
  84. {
  85. rt_platform_driver_register(&syscon_reboot_mode_driver);
  86. return 0;
  87. }
  88. INIT_SUBSYS_EXPORT(syscon_reboot_mode_driver_register);