x86/mm/pat: Don't report PAT on CPUs that don't support it
[linux/fpc-iii.git] / drivers / staging / greybus / fw-download.c
blob8a1a413c6cb38f87b95fe4873465cd13ae99456f
1 /*
2 * Greybus Firmware Download Protocol Driver.
4 * Copyright 2016 Google Inc.
5 * Copyright 2016 Linaro Ltd.
7 * Released under the GPLv2 only.
8 */
10 #include <linux/firmware.h>
11 #include <linux/jiffies.h>
12 #include <linux/mutex.h>
13 #include <linux/workqueue.h>
14 #include "firmware.h"
15 #include "greybus.h"
17 /* Estimated minimum buffer size, actual size can be smaller than this */
18 #define MIN_FETCH_SIZE 512
19 /* Timeout, in jiffies, within which fetch or release firmware must be called */
20 #define NEXT_REQ_TIMEOUT_J msecs_to_jiffies(1000)
22 struct fw_request {
23 u8 firmware_id;
24 bool disabled;
25 bool timedout;
26 char name[FW_NAME_SIZE];
27 const struct firmware *fw;
28 struct list_head node;
30 struct delayed_work dwork;
31 /* Timeout, in jiffies, within which the firmware shall download */
32 unsigned long release_timeout_j;
33 struct kref kref;
34 struct fw_download *fw_download;
37 struct fw_download {
38 struct device *parent;
39 struct gb_connection *connection;
40 struct list_head fw_requests;
41 struct ida id_map;
42 struct mutex mutex;
45 static void fw_req_release(struct kref *kref)
47 struct fw_request *fw_req = container_of(kref, struct fw_request, kref);
49 dev_dbg(fw_req->fw_download->parent, "firmware %s released\n",
50 fw_req->name);
52 release_firmware(fw_req->fw);
55 * The request timed out and the module may send a fetch-fw or
56 * release-fw request later. Lets block the id we allocated for this
57 * request, so that the AP doesn't refer to a later fw-request (with
58 * same firmware_id) for the old timedout fw-request.
60 * NOTE:
62 * This also means that after 255 timeouts we will fail to service new
63 * firmware downloads. But what else can we do in that case anyway? Lets
64 * just hope that it never happens.
66 if (!fw_req->timedout)
67 ida_simple_remove(&fw_req->fw_download->id_map,
68 fw_req->firmware_id);
70 kfree(fw_req);
74 * Incoming requests are serialized for a connection, and the only race possible
75 * is between the timeout handler freeing this and an incoming request.
77 * The operations on the fw-request list are protected by the mutex and
78 * get_fw_req() increments the reference count before returning a fw_req pointer
79 * to the users.
81 * free_firmware() also takes the mutex while removing an entry from the list,
82 * it guarantees that every user of fw_req has taken a kref-reference by now and
83 * we wouldn't have any new users.
85 * Once the last user drops the reference, the fw_req structure is freed.
87 static void put_fw_req(struct fw_request *fw_req)
89 kref_put(&fw_req->kref, fw_req_release);
92 /* Caller must call put_fw_req() after using struct fw_request */
93 static struct fw_request *get_fw_req(struct fw_download *fw_download,
94 u8 firmware_id)
96 struct fw_request *fw_req;
98 mutex_lock(&fw_download->mutex);
100 list_for_each_entry(fw_req, &fw_download->fw_requests, node) {
101 if (fw_req->firmware_id == firmware_id) {
102 kref_get(&fw_req->kref);
103 goto unlock;
107 fw_req = NULL;
109 unlock:
110 mutex_unlock(&fw_download->mutex);
112 return fw_req;
115 static void free_firmware(struct fw_download *fw_download,
116 struct fw_request *fw_req)
118 /* Already disabled from timeout handlers */
119 if (fw_req->disabled)
120 return;
122 mutex_lock(&fw_download->mutex);
123 list_del(&fw_req->node);
124 mutex_unlock(&fw_download->mutex);
126 fw_req->disabled = true;
127 put_fw_req(fw_req);
130 static void fw_request_timedout(struct work_struct *work)
132 struct delayed_work *dwork = to_delayed_work(work);
133 struct fw_request *fw_req = container_of(dwork,
134 struct fw_request, dwork);
135 struct fw_download *fw_download = fw_req->fw_download;
137 dev_err(fw_download->parent,
138 "Timed out waiting for fetch / release firmware requests: %u\n",
139 fw_req->firmware_id);
141 fw_req->timedout = true;
142 free_firmware(fw_download, fw_req);
145 static int exceeds_release_timeout(struct fw_request *fw_req)
147 struct fw_download *fw_download = fw_req->fw_download;
149 if (time_before(jiffies, fw_req->release_timeout_j))
150 return 0;
152 dev_err(fw_download->parent,
153 "Firmware download didn't finish in time, abort: %d\n",
154 fw_req->firmware_id);
156 fw_req->timedout = true;
157 free_firmware(fw_download, fw_req);
159 return -ETIMEDOUT;
162 /* This returns path of the firmware blob on the disk */
163 static struct fw_request *find_firmware(struct fw_download *fw_download,
164 const char *tag)
166 struct gb_interface *intf = fw_download->connection->bundle->intf;
167 struct fw_request *fw_req;
168 int ret, req_count;
170 fw_req = kzalloc(sizeof(*fw_req), GFP_KERNEL);
171 if (!fw_req)
172 return ERR_PTR(-ENOMEM);
174 /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
175 ret = ida_simple_get(&fw_download->id_map, 1, 256, GFP_KERNEL);
176 if (ret < 0) {
177 dev_err(fw_download->parent,
178 "failed to allocate firmware id (%d)\n", ret);
179 goto err_free_req;
181 fw_req->firmware_id = ret;
183 snprintf(fw_req->name, sizeof(fw_req->name),
184 FW_NAME_PREFIX "%08x_%08x_%08x_%08x_%s.tftf",
185 intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
186 intf->vendor_id, intf->product_id, tag);
188 dev_info(fw_download->parent, "Requested firmware package '%s'\n",
189 fw_req->name);
191 ret = request_firmware(&fw_req->fw, fw_req->name, fw_download->parent);
192 if (ret) {
193 dev_err(fw_download->parent,
194 "firmware request failed for %s (%d)\n", fw_req->name,
195 ret);
196 goto err_free_id;
199 fw_req->fw_download = fw_download;
200 kref_init(&fw_req->kref);
202 mutex_lock(&fw_download->mutex);
203 list_add(&fw_req->node, &fw_download->fw_requests);
204 mutex_unlock(&fw_download->mutex);
206 /* Timeout, in jiffies, within which firmware should get loaded */
207 req_count = DIV_ROUND_UP(fw_req->fw->size, MIN_FETCH_SIZE);
208 fw_req->release_timeout_j = jiffies + req_count * NEXT_REQ_TIMEOUT_J;
210 INIT_DELAYED_WORK(&fw_req->dwork, fw_request_timedout);
211 schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
213 return fw_req;
215 err_free_id:
216 ida_simple_remove(&fw_download->id_map, fw_req->firmware_id);
217 err_free_req:
218 kfree(fw_req);
220 return ERR_PTR(ret);
223 static int fw_download_find_firmware(struct gb_operation *op)
225 struct gb_connection *connection = op->connection;
226 struct fw_download *fw_download = gb_connection_get_data(connection);
227 struct gb_fw_download_find_firmware_request *request;
228 struct gb_fw_download_find_firmware_response *response;
229 struct fw_request *fw_req;
230 const char *tag;
232 if (op->request->payload_size != sizeof(*request)) {
233 dev_err(fw_download->parent,
234 "illegal size of find firmware request (%zu != %zu)\n",
235 op->request->payload_size, sizeof(*request));
236 return -EINVAL;
239 request = op->request->payload;
240 tag = (const char *)request->firmware_tag;
242 /* firmware_tag must be null-terminated */
243 if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) ==
244 GB_FIRMWARE_TAG_MAX_SIZE) {
245 dev_err(fw_download->parent,
246 "firmware-tag is not null-terminated\n");
247 return -EINVAL;
250 fw_req = find_firmware(fw_download, tag);
251 if (IS_ERR(fw_req))
252 return PTR_ERR(fw_req);
254 if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL)) {
255 dev_err(fw_download->parent, "error allocating response\n");
256 free_firmware(fw_download, fw_req);
257 return -ENOMEM;
260 response = op->response->payload;
261 response->firmware_id = fw_req->firmware_id;
262 response->size = cpu_to_le32(fw_req->fw->size);
264 dev_dbg(fw_download->parent,
265 "firmware size is %zu bytes\n", fw_req->fw->size);
267 return 0;
270 static int fw_download_fetch_firmware(struct gb_operation *op)
272 struct gb_connection *connection = op->connection;
273 struct fw_download *fw_download = gb_connection_get_data(connection);
274 struct gb_fw_download_fetch_firmware_request *request;
275 struct gb_fw_download_fetch_firmware_response *response;
276 struct fw_request *fw_req;
277 const struct firmware *fw;
278 unsigned int offset, size;
279 u8 firmware_id;
280 int ret = 0;
282 if (op->request->payload_size != sizeof(*request)) {
283 dev_err(fw_download->parent,
284 "Illegal size of fetch firmware request (%zu %zu)\n",
285 op->request->payload_size, sizeof(*request));
286 return -EINVAL;
289 request = op->request->payload;
290 offset = le32_to_cpu(request->offset);
291 size = le32_to_cpu(request->size);
292 firmware_id = request->firmware_id;
294 fw_req = get_fw_req(fw_download, firmware_id);
295 if (!fw_req) {
296 dev_err(fw_download->parent,
297 "firmware not available for id: %02u\n", firmware_id);
298 return -EINVAL;
301 /* Make sure work handler isn't running in parallel */
302 cancel_delayed_work_sync(&fw_req->dwork);
304 /* We timed-out before reaching here ? */
305 if (fw_req->disabled) {
306 ret = -ETIMEDOUT;
307 goto put_fw;
311 * Firmware download must finish within a limited time interval. If it
312 * doesn't, then we might have a buggy Module on the other side. Abort
313 * download.
315 ret = exceeds_release_timeout(fw_req);
316 if (ret)
317 goto put_fw;
319 fw = fw_req->fw;
321 if (offset >= fw->size || size > fw->size - offset) {
322 dev_err(fw_download->parent,
323 "bad fetch firmware request (offs = %u, size = %u)\n",
324 offset, size);
325 ret = -EINVAL;
326 goto put_fw;
329 if (!gb_operation_response_alloc(op, sizeof(*response) + size,
330 GFP_KERNEL)) {
331 dev_err(fw_download->parent,
332 "error allocating fetch firmware response\n");
333 ret = -ENOMEM;
334 goto put_fw;
337 response = op->response->payload;
338 memcpy(response->data, fw->data + offset, size);
340 dev_dbg(fw_download->parent,
341 "responding with firmware (offs = %u, size = %u)\n", offset,
342 size);
344 /* Refresh timeout */
345 schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
347 put_fw:
348 put_fw_req(fw_req);
350 return ret;
353 static int fw_download_release_firmware(struct gb_operation *op)
355 struct gb_connection *connection = op->connection;
356 struct fw_download *fw_download = gb_connection_get_data(connection);
357 struct gb_fw_download_release_firmware_request *request;
358 struct fw_request *fw_req;
359 u8 firmware_id;
361 if (op->request->payload_size != sizeof(*request)) {
362 dev_err(fw_download->parent,
363 "Illegal size of release firmware request (%zu %zu)\n",
364 op->request->payload_size, sizeof(*request));
365 return -EINVAL;
368 request = op->request->payload;
369 firmware_id = request->firmware_id;
371 fw_req = get_fw_req(fw_download, firmware_id);
372 if (!fw_req) {
373 dev_err(fw_download->parent,
374 "firmware not available for id: %02u\n", firmware_id);
375 return -EINVAL;
378 cancel_delayed_work_sync(&fw_req->dwork);
380 free_firmware(fw_download, fw_req);
381 put_fw_req(fw_req);
383 dev_dbg(fw_download->parent, "release firmware\n");
385 return 0;
388 int gb_fw_download_request_handler(struct gb_operation *op)
390 u8 type = op->type;
392 switch (type) {
393 case GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE:
394 return fw_download_find_firmware(op);
395 case GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE:
396 return fw_download_fetch_firmware(op);
397 case GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE:
398 return fw_download_release_firmware(op);
399 default:
400 dev_err(&op->connection->bundle->dev,
401 "unsupported request: %u\n", type);
402 return -EINVAL;
406 int gb_fw_download_connection_init(struct gb_connection *connection)
408 struct fw_download *fw_download;
409 int ret;
411 if (!connection)
412 return 0;
414 fw_download = kzalloc(sizeof(*fw_download), GFP_KERNEL);
415 if (!fw_download)
416 return -ENOMEM;
418 fw_download->parent = &connection->bundle->dev;
419 INIT_LIST_HEAD(&fw_download->fw_requests);
420 ida_init(&fw_download->id_map);
421 gb_connection_set_data(connection, fw_download);
422 fw_download->connection = connection;
423 mutex_init(&fw_download->mutex);
425 ret = gb_connection_enable(connection);
426 if (ret)
427 goto err_destroy_id_map;
429 return 0;
431 err_destroy_id_map:
432 ida_destroy(&fw_download->id_map);
433 kfree(fw_download);
435 return ret;
438 void gb_fw_download_connection_exit(struct gb_connection *connection)
440 struct fw_download *fw_download;
441 struct fw_request *fw_req, *tmp;
443 if (!connection)
444 return;
446 fw_download = gb_connection_get_data(connection);
447 gb_connection_disable(fw_download->connection);
450 * Make sure we have a reference to the pending requests, before they
451 * are freed from the timeout handler.
453 mutex_lock(&fw_download->mutex);
454 list_for_each_entry(fw_req, &fw_download->fw_requests, node)
455 kref_get(&fw_req->kref);
456 mutex_unlock(&fw_download->mutex);
458 /* Release pending firmware packages */
459 list_for_each_entry_safe(fw_req, tmp, &fw_download->fw_requests, node) {
460 cancel_delayed_work_sync(&fw_req->dwork);
461 free_firmware(fw_download, fw_req);
462 put_fw_req(fw_req);
465 ida_destroy(&fw_download->id_map);
466 kfree(fw_download);