bootcount-uclass.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
  4. */
  5. #define LOG_CATEGORY UCLASS_BOOTCOUNT
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <bootcount.h>
  10. #include <log.h>
  11. int dm_bootcount_get(struct udevice *dev, u32 *bootcount)
  12. {
  13. struct bootcount_ops *ops = bootcount_get_ops(dev);
  14. assert(ops);
  15. if (!ops->get)
  16. return -ENOSYS;
  17. return ops->get(dev, bootcount);
  18. }
  19. int dm_bootcount_set(struct udevice *dev, const u32 bootcount)
  20. {
  21. struct bootcount_ops *ops = bootcount_get_ops(dev);
  22. assert(ops);
  23. if (!ops->set)
  24. return -ENOSYS;
  25. return ops->set(dev, bootcount);
  26. }
  27. /* Now implement the generic default functions */
  28. void bootcount_store(ulong val)
  29. {
  30. struct udevice *dev = NULL;
  31. ofnode node;
  32. const char *propname = "u-boot,bootcount-device";
  33. int ret = -ENODEV;
  34. /*
  35. * If there's a preferred bootcount device selected by the user (by
  36. * setting '/chosen/u-boot,bootcount-device' in the DTS), try to use
  37. * it if available.
  38. */
  39. node = ofnode_get_chosen_node(propname);
  40. if (ofnode_valid(node))
  41. ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev);
  42. /* If there was no user-selected device, use the first available one */
  43. if (ret)
  44. ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev);
  45. if (dev)
  46. ret = dm_bootcount_set(dev, val);
  47. if (ret)
  48. pr_debug("%s: failed to store 0x%lx\n", __func__, val);
  49. }
  50. ulong bootcount_load(void)
  51. {
  52. struct udevice *dev = NULL;
  53. ofnode node;
  54. const char *propname = "u-boot,bootcount-device";
  55. int ret = -ENODEV;
  56. u32 val;
  57. /*
  58. * If there's a preferred bootcount device selected by the user (by
  59. * setting '/chosen/u-boot,bootcount-device' in the DTS), try to use
  60. * it if available.
  61. */
  62. node = ofnode_get_chosen_node(propname);
  63. if (ofnode_valid(node))
  64. ret = uclass_get_device_by_ofnode(UCLASS_BOOTCOUNT, node, &dev);
  65. /* If there was no user-selected device, use the first available one */
  66. if (ret)
  67. ret = uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev);
  68. if (dev)
  69. ret = dm_bootcount_get(dev, &val);
  70. if (ret)
  71. pr_debug("%s: failed to load bootcount\n", __func__);
  72. /* Return the 0, if the call to dm_bootcount_get failed */
  73. return ret ? 0 : val;
  74. }
  75. UCLASS_DRIVER(bootcount) = {
  76. .name = "bootcount",
  77. .id = UCLASS_BOOTCOUNT,
  78. };