sysreset-uclass.c 1.4 KB

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