sysreset-uclass.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /*
  2. * Copyright (C) 2015 Google, Inc
  3. * Written by Simon Glass <sjg@chromium.org>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <sysreset.h>
  9. #include <dm.h>
  10. #include <errno.h>
  11. #include <regmap.h>
  12. #include <dm/device-internal.h>
  13. #include <dm/lists.h>
  14. #include <dm/root.h>
  15. #include <linux/err.h>
  16. int sysreset_request(struct udevice *dev, enum sysreset_t type)
  17. {
  18. struct sysreset_ops *ops = sysreset_get_ops(dev);
  19. if (!ops->request)
  20. return -ENOSYS;
  21. return ops->request(dev, type);
  22. }
  23. int sysreset_walk(enum sysreset_t type)
  24. {
  25. struct udevice *dev;
  26. int ret = -ENOSYS;
  27. while (ret != -EINPROGRESS && type < SYSRESET_COUNT) {
  28. for (uclass_first_device(UCLASS_SYSRESET, &dev);
  29. dev;
  30. uclass_next_device(&dev)) {
  31. ret = sysreset_request(dev, type);
  32. if (ret == -EINPROGRESS)
  33. break;
  34. }
  35. type++;
  36. }
  37. return ret;
  38. }
  39. void sysreset_walk_halt(enum sysreset_t type)
  40. {
  41. int ret;
  42. ret = sysreset_walk(type);
  43. /* Wait for the reset to take effect */
  44. if (ret == -EINPROGRESS)
  45. mdelay(100);
  46. /* Still no reset? Give up */
  47. debug("System reset not supported on this platform\n");
  48. hang();
  49. }
  50. /**
  51. * reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
  52. */
  53. void reset_cpu(ulong addr)
  54. {
  55. sysreset_walk_halt(SYSRESET_WARM);
  56. }
  57. int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  58. {
  59. sysreset_walk_halt(SYSRESET_WARM);
  60. return 0;
  61. }
  62. UCLASS_DRIVER(sysreset) = {
  63. .id = UCLASS_SYSRESET,
  64. .name = "sysreset",
  65. };