firmware.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __FIRMWARE_LOADER_H
  3. #define __FIRMWARE_LOADER_H
  4. #include <linux/bitops.h>
  5. #include <linux/firmware.h>
  6. #include <linux/types.h>
  7. #include <linux/kref.h>
  8. #include <linux/list.h>
  9. #include <linux/completion.h>
  10. #include <generated/utsrelease.h>
  11. /**
  12. * enum fw_opt - options to control firmware loading behaviour
  13. *
  14. * @FW_OPT_UEVENT: Enables the fallback mechanism to send a kobject uevent
  15. * when the firmware is not found. Userspace is in charge to load the
  16. * firmware using the sysfs loading facility.
  17. * @FW_OPT_NOWAIT: Used to describe the firmware request is asynchronous.
  18. * @FW_OPT_USERHELPER: Enable the fallback mechanism, in case the direct
  19. * filesystem lookup fails at finding the firmware. For details refer to
  20. * firmware_fallback_sysfs().
  21. * @FW_OPT_NO_WARN: Quiet, avoid printing warning messages.
  22. * @FW_OPT_NOCACHE: Disables firmware caching. Firmware caching is used to
  23. * cache the firmware upon suspend, so that upon resume races against the
  24. * firmware file lookup on storage is avoided. Used for calls where the
  25. * file may be too big, or where the driver takes charge of its own
  26. * firmware caching mechanism.
  27. * @FW_OPT_NOFALLBACK: Disable the fallback mechanism. Takes precedence over
  28. * &FW_OPT_UEVENT and &FW_OPT_USERHELPER.
  29. */
  30. enum fw_opt {
  31. FW_OPT_UEVENT = BIT(0),
  32. FW_OPT_NOWAIT = BIT(1),
  33. FW_OPT_USERHELPER = BIT(2),
  34. FW_OPT_NO_WARN = BIT(3),
  35. FW_OPT_NOCACHE = BIT(4),
  36. FW_OPT_NOFALLBACK = BIT(5),
  37. };
  38. enum fw_status {
  39. FW_STATUS_UNKNOWN,
  40. FW_STATUS_LOADING,
  41. FW_STATUS_DONE,
  42. FW_STATUS_ABORTED,
  43. };
  44. /*
  45. * Concurrent request_firmware() for the same firmware need to be
  46. * serialized. struct fw_state is simple state machine which hold the
  47. * state of the firmware loading.
  48. */
  49. struct fw_state {
  50. struct completion completion;
  51. enum fw_status status;
  52. };
  53. struct fw_priv {
  54. struct kref ref;
  55. struct list_head list;
  56. struct firmware_cache *fwc;
  57. struct fw_state fw_st;
  58. void *data;
  59. size_t size;
  60. size_t allocated_size;
  61. #ifdef CONFIG_FW_LOADER_USER_HELPER
  62. bool is_paged_buf;
  63. bool need_uevent;
  64. struct page **pages;
  65. int nr_pages;
  66. int page_array_size;
  67. struct list_head pending_list;
  68. #endif
  69. const char *fw_name;
  70. };
  71. extern struct mutex fw_lock;
  72. static inline bool __fw_state_check(struct fw_priv *fw_priv,
  73. enum fw_status status)
  74. {
  75. struct fw_state *fw_st = &fw_priv->fw_st;
  76. return fw_st->status == status;
  77. }
  78. static inline int __fw_state_wait_common(struct fw_priv *fw_priv, long timeout)
  79. {
  80. struct fw_state *fw_st = &fw_priv->fw_st;
  81. long ret;
  82. ret = wait_for_completion_killable_timeout(&fw_st->completion, timeout);
  83. if (ret != 0 && fw_st->status == FW_STATUS_ABORTED)
  84. return -ENOENT;
  85. if (!ret)
  86. return -ETIMEDOUT;
  87. return ret < 0 ? ret : 0;
  88. }
  89. static inline void __fw_state_set(struct fw_priv *fw_priv,
  90. enum fw_status status)
  91. {
  92. struct fw_state *fw_st = &fw_priv->fw_st;
  93. WRITE_ONCE(fw_st->status, status);
  94. if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED)
  95. complete_all(&fw_st->completion);
  96. }
  97. static inline void fw_state_aborted(struct fw_priv *fw_priv)
  98. {
  99. __fw_state_set(fw_priv, FW_STATUS_ABORTED);
  100. }
  101. static inline bool fw_state_is_aborted(struct fw_priv *fw_priv)
  102. {
  103. return __fw_state_check(fw_priv, FW_STATUS_ABORTED);
  104. }
  105. static inline void fw_state_start(struct fw_priv *fw_priv)
  106. {
  107. __fw_state_set(fw_priv, FW_STATUS_LOADING);
  108. }
  109. static inline void fw_state_done(struct fw_priv *fw_priv)
  110. {
  111. __fw_state_set(fw_priv, FW_STATUS_DONE);
  112. }
  113. int assign_fw(struct firmware *fw, struct device *device,
  114. enum fw_opt opt_flags);
  115. #endif /* __FIRMWARE_LOADER_H */