aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/firmware_class.c51
1 files changed, 15 insertions, 36 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 45a20dd31c25..95f566c10a55 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -30,6 +30,7 @@
30#include <linux/syscore_ops.h> 30#include <linux/syscore_ops.h>
31#include <linux/reboot.h> 31#include <linux/reboot.h>
32#include <linux/security.h> 32#include <linux/security.h>
33#include <linux/swait.h>
33 34
34#include <generated/utsrelease.h> 35#include <generated/utsrelease.h>
35 36
@@ -111,13 +112,13 @@ static inline long firmware_loading_timeout(void)
111 * state of the firmware loading. 112 * state of the firmware loading.
112 */ 113 */
113struct fw_state { 114struct fw_state {
114 struct completion completion; 115 struct swait_queue_head wq;
115 enum fw_status status; 116 enum fw_status status;
116}; 117};
117 118
118static void fw_state_init(struct fw_state *fw_st) 119static void fw_state_init(struct fw_state *fw_st)
119{ 120{
120 init_completion(&fw_st->completion); 121 init_swait_queue_head(&fw_st->wq);
121 fw_st->status = FW_STATUS_UNKNOWN; 122 fw_st->status = FW_STATUS_UNKNOWN;
122} 123}
123 124
@@ -126,13 +127,19 @@ static int __fw_state_check(struct fw_state *fw_st, enum fw_status status)
126 return fw_st->status == status; 127 return fw_st->status == status;
127} 128}
128 129
130static inline bool __fw_state_is_done(enum fw_status status)
131{
132 return status == FW_STATUS_DONE || status == FW_STATUS_ABORTED;
133}
134
129static long __fw_state_wait_common(struct fw_state *fw_st, long timeout) 135static long __fw_state_wait_common(struct fw_state *fw_st, long timeout)
130{ 136{
131 long ret; 137 long ret;
132 138
133 ret = wait_for_completion_interruptible_timeout(&fw_st->completion, 139 ret = swait_event_interruptible_timeout(fw_st->wq,
134 timeout); 140 __fw_state_is_done(READ_ONCE(fw_st->status)),
135 if (ret != 0 && READ_ONCE(fw_st->status) == FW_STATUS_ABORTED) 141 timeout);
142 if (ret != 0 && fw_st->status == FW_STATUS_ABORTED)
136 return -ENOENT; 143 return -ENOENT;
137 144
138 return ret; 145 return ret;
@@ -144,7 +151,7 @@ static void __fw_state_set(struct fw_state *fw_st,
144 WRITE_ONCE(fw_st->status, status); 151 WRITE_ONCE(fw_st->status, status);
145 152
146 if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) 153 if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED)
147 complete_all(&fw_st->completion); 154 swake_up(&fw_st->wq);
148} 155}
149 156
150#define fw_state_start(fw_st) \ 157#define fw_state_start(fw_st) \
@@ -373,14 +380,6 @@ static const char * const fw_path[] = {
373module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); 380module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
374MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); 381MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path");
375 382
376static void fw_finish_direct_load(struct device *device,
377 struct firmware_buf *buf)
378{
379 mutex_lock(&fw_lock);
380 fw_state_done(&buf->fw_st);
381 mutex_unlock(&fw_lock);
382}
383
384static int 383static int
385fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf) 384fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf)
386{ 385{
@@ -427,7 +426,7 @@ fw_get_filesystem_firmware(struct device *device, struct firmware_buf *buf)
427 } 426 }
428 dev_dbg(device, "direct-loading %s\n", buf->fw_id); 427 dev_dbg(device, "direct-loading %s\n", buf->fw_id);
429 buf->size = size; 428 buf->size = size;
430 fw_finish_direct_load(device, buf); 429 fw_state_done(&buf->fw_st);
431 break; 430 break;
432 } 431 }
433 __putname(path); 432 __putname(path);
@@ -1084,26 +1083,6 @@ static inline void kill_requests_without_uevent(void) { }
1084 1083
1085#endif /* CONFIG_FW_LOADER_USER_HELPER */ 1084#endif /* CONFIG_FW_LOADER_USER_HELPER */
1086 1085
1087
1088/* wait until the shared firmware_buf becomes ready (or error) */
1089static int sync_cached_firmware_buf(struct firmware_buf *buf)
1090{
1091 int ret = 0;
1092
1093 mutex_lock(&fw_lock);
1094 while (!fw_state_is_done(&buf->fw_st)) {
1095 if (fw_state_is_aborted(&buf->fw_st)) {
1096 ret = -ENOENT;
1097 break;
1098 }
1099 mutex_unlock(&fw_lock);
1100 ret = fw_state_wait(&buf->fw_st);
1101 mutex_lock(&fw_lock);
1102 }
1103 mutex_unlock(&fw_lock);
1104 return ret;
1105}
1106
1107/* prepare firmware and firmware_buf structs; 1086/* prepare firmware and firmware_buf structs;
1108 * return 0 if a firmware is already assigned, 1 if need to load one, 1087 * return 0 if a firmware is already assigned, 1 if need to load one,
1109 * or a negative error code 1088 * or a negative error code
@@ -1137,7 +1116,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name,
1137 firmware->priv = buf; 1116 firmware->priv = buf;
1138 1117
1139 if (ret > 0) { 1118 if (ret > 0) {
1140 ret = sync_cached_firmware_buf(buf); 1119 ret = fw_state_wait(&buf->fw_st);
1141 if (!ret) { 1120 if (!ret) {
1142 fw_set_page_data(buf, firmware); 1121 fw_set_page_data(buf, firmware);
1143 return 0; /* assigned */ 1122 return 0; /* assigned */