Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
2 | #ifndef _LINUX_FIRMWARE_H |
3 | #define _LINUX_FIRMWARE_H | |
5658c769 | 4 | |
1da177e4 | 5 | #include <linux/types.h> |
5658c769 | 6 | #include <linux/compiler.h> |
9ebfbd45 | 7 | #include <linux/gfp.h> |
5658c769 | 8 | |
0733d839 SG |
9 | #define FW_ACTION_NOUEVENT 0 |
10 | #define FW_ACTION_UEVENT 1 | |
6e3eaab0 | 11 | |
1da177e4 LT |
12 | struct firmware { |
13 | size_t size; | |
b7a39bd0 | 14 | const u8 *data; |
1f2b7959 ML |
15 | |
16 | /* firmware loader private fields */ | |
17 | void *priv; | |
1da177e4 | 18 | }; |
fbab976d | 19 | |
97730bbb RW |
20 | /** |
21 | * enum fw_upload_err - firmware upload error codes | |
22 | * @FW_UPLOAD_ERR_NONE: returned to indicate success | |
23 | * @FW_UPLOAD_ERR_HW_ERROR: error signalled by hardware, see kernel log | |
24 | * @FW_UPLOAD_ERR_TIMEOUT: SW timed out on handshake with HW/firmware | |
25 | * @FW_UPLOAD_ERR_CANCELED: upload was cancelled by the user | |
26 | * @FW_UPLOAD_ERR_BUSY: there is an upload operation already in progress | |
27 | * @FW_UPLOAD_ERR_INVALID_SIZE: invalid firmware image size | |
28 | * @FW_UPLOAD_ERR_RW_ERROR: read or write to HW failed, see kernel log | |
29 | * @FW_UPLOAD_ERR_WEAROUT: FLASH device is approaching wear-out, wait & retry | |
30 | * @FW_UPLOAD_ERR_MAX: Maximum error code marker | |
31 | */ | |
32 | enum fw_upload_err { | |
33 | FW_UPLOAD_ERR_NONE, | |
34 | FW_UPLOAD_ERR_HW_ERROR, | |
35 | FW_UPLOAD_ERR_TIMEOUT, | |
36 | FW_UPLOAD_ERR_CANCELED, | |
37 | FW_UPLOAD_ERR_BUSY, | |
38 | FW_UPLOAD_ERR_INVALID_SIZE, | |
39 | FW_UPLOAD_ERR_RW_ERROR, | |
40 | FW_UPLOAD_ERR_WEAROUT, | |
41 | FW_UPLOAD_ERR_MAX | |
42 | }; | |
43 | ||
44 | struct fw_upload { | |
45 | void *dd_handle; /* reference to parent driver */ | |
46 | void *priv; /* firmware loader private fields */ | |
47 | }; | |
48 | ||
49 | /** | |
50 | * struct fw_upload_ops - device specific operations to support firmware upload | |
51 | * @prepare: Required: Prepare secure update | |
52 | * @write: Required: The write() op receives the remaining | |
53 | * size to be written and must return the actual | |
54 | * size written or a negative error code. The write() | |
55 | * op will be called repeatedly until all data is | |
56 | * written. | |
57 | * @poll_complete: Required: Check for the completion of the | |
58 | * HW authentication/programming process. | |
59 | * @cancel: Required: Request cancellation of update. This op | |
60 | * is called from the context of a different kernel | |
61 | * thread, so race conditions need to be considered. | |
62 | * @cleanup: Optional: Complements the prepare() | |
63 | * function and is called at the completion | |
64 | * of the update, on success or failure, if the | |
65 | * prepare function succeeded. | |
66 | */ | |
67 | struct fw_upload_ops { | |
68 | enum fw_upload_err (*prepare)(struct fw_upload *fw_upload, | |
69 | const u8 *data, u32 size); | |
70 | enum fw_upload_err (*write)(struct fw_upload *fw_upload, | |
71 | const u8 *data, u32 offset, | |
72 | u32 size, u32 *written); | |
73 | enum fw_upload_err (*poll_complete)(struct fw_upload *fw_upload); | |
74 | void (*cancel)(struct fw_upload *fw_upload); | |
75 | void (*cleanup)(struct fw_upload *fw_upload); | |
76 | }; | |
77 | ||
de477254 | 78 | struct module; |
1da177e4 | 79 | struct device; |
fbab976d | 80 | |
48d09e97 LC |
81 | /* |
82 | * Built-in firmware functionality is only available if FW_LOADER=y, but not | |
83 | * FW_LOADER=m | |
84 | */ | |
85 | #ifdef CONFIG_FW_LOADER | |
48d09e97 | 86 | bool firmware_request_builtin(struct firmware *fw, const char *name); |
48d09e97 LC |
87 | #else |
88 | static inline bool firmware_request_builtin(struct firmware *fw, | |
89 | const char *name) | |
90 | { | |
91 | return false; | |
92 | } | |
93 | #endif | |
94 | ||
bb6e8c28 | 95 | #if IS_REACHABLE(CONFIG_FW_LOADER) |
1da177e4 LT |
96 | int request_firmware(const struct firmware **fw, const char *name, |
97 | struct device *device); | |
7dcc0134 AR |
98 | int firmware_request_nowarn(const struct firmware **fw, const char *name, |
99 | struct device *device); | |
e4c2c0ff HG |
100 | int firmware_request_platform(const struct firmware **fw, const char *name, |
101 | struct device *device); | |
1da177e4 | 102 | int request_firmware_nowait( |
072fc8f0 | 103 | struct module *module, bool uevent, |
9ebfbd45 | 104 | const char *name, struct device *device, gfp_t gfp, void *context, |
1da177e4 | 105 | void (*cont)(const struct firmware *fw, void *context)); |
c868edf4 LR |
106 | int request_firmware_direct(const struct firmware **fw, const char *name, |
107 | struct device *device); | |
a098ecd2 SB |
108 | int request_firmware_into_buf(const struct firmware **firmware_p, |
109 | const char *name, struct device *device, void *buf, size_t size); | |
59cdb23c SB |
110 | int request_partial_firmware_into_buf(const struct firmware **firmware_p, |
111 | const char *name, struct device *device, | |
112 | void *buf, size_t size, size_t offset); | |
1da177e4 LT |
113 | |
114 | void release_firmware(const struct firmware *fw); | |
fbab976d JB |
115 | #else |
116 | static inline int request_firmware(const struct firmware **fw, | |
117 | const char *name, | |
118 | struct device *device) | |
119 | { | |
120 | return -EINVAL; | |
121 | } | |
7dcc0134 AR |
122 | |
123 | static inline int firmware_request_nowarn(const struct firmware **fw, | |
124 | const char *name, | |
125 | struct device *device) | |
126 | { | |
127 | return -EINVAL; | |
128 | } | |
129 | ||
e4c2c0ff HG |
130 | static inline int firmware_request_platform(const struct firmware **fw, |
131 | const char *name, | |
132 | struct device *device) | |
133 | { | |
134 | return -EINVAL; | |
135 | } | |
136 | ||
fbab976d | 137 | static inline int request_firmware_nowait( |
072fc8f0 | 138 | struct module *module, bool uevent, |
9ebfbd45 | 139 | const char *name, struct device *device, gfp_t gfp, void *context, |
fbab976d JB |
140 | void (*cont)(const struct firmware *fw, void *context)) |
141 | { | |
142 | return -EINVAL; | |
143 | } | |
144 | ||
145 | static inline void release_firmware(const struct firmware *fw) | |
146 | { | |
147 | } | |
2887b395 | 148 | |
c868edf4 LR |
149 | static inline int request_firmware_direct(const struct firmware **fw, |
150 | const char *name, | |
151 | struct device *device) | |
152 | { | |
153 | return -EINVAL; | |
154 | } | |
fbab976d | 155 | |
a098ecd2 SB |
156 | static inline int request_firmware_into_buf(const struct firmware **firmware_p, |
157 | const char *name, struct device *device, void *buf, size_t size) | |
158 | { | |
159 | return -EINVAL; | |
160 | } | |
161 | ||
59cdb23c SB |
162 | static inline int request_partial_firmware_into_buf |
163 | (const struct firmware **firmware_p, | |
164 | const char *name, | |
165 | struct device *device, | |
166 | void *buf, size_t size, size_t offset) | |
167 | { | |
168 | return -EINVAL; | |
169 | } | |
170 | ||
bba3a87e | 171 | #endif |
5d42c96e | 172 | |
97730bbb RW |
173 | #ifdef CONFIG_FW_UPLOAD |
174 | ||
175 | struct fw_upload * | |
176 | firmware_upload_register(struct module *module, struct device *parent, | |
177 | const char *name, const struct fw_upload_ops *ops, | |
178 | void *dd_handle); | |
179 | void firmware_upload_unregister(struct fw_upload *fw_upload); | |
180 | ||
181 | #else | |
182 | ||
183 | static inline struct fw_upload * | |
184 | firmware_upload_register(struct module *module, struct device *parent, | |
185 | const char *name, const struct fw_upload_ops *ops, | |
186 | void *dd_handle) | |
187 | { | |
188 | return ERR_PTR(-EINVAL); | |
189 | } | |
190 | ||
191 | static inline void firmware_upload_unregister(struct fw_upload *fw_upload) | |
192 | { | |
193 | } | |
194 | ||
195 | #endif | |
196 | ||
5d42c96e LR |
197 | int firmware_request_cache(struct device *device, const char *name); |
198 | ||
1da177e4 | 199 | #endif |