aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/firmware_class.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/firmware_class.c')
-rw-r--r--drivers/base/firmware_class.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 9fd4a8534146..b0be1d18fee2 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -49,6 +49,14 @@ struct firmware_priv {
49 struct timer_list timeout; 49 struct timer_list timeout;
50}; 50};
51 51
52#ifdef CONFIG_FW_LOADER
53extern struct builtin_fw __start_builtin_fw[];
54extern struct builtin_fw __end_builtin_fw[];
55#else /* Module case. Avoid ifdefs later; it'll all optimise out */
56static struct builtin_fw *__start_builtin_fw;
57static struct builtin_fw *__end_builtin_fw;
58#endif
59
52static void 60static void
53fw_load_abort(struct firmware_priv *fw_priv) 61fw_load_abort(struct firmware_priv *fw_priv)
54{ 62{
@@ -257,7 +265,7 @@ firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
257 if (retval) 265 if (retval)
258 goto out; 266 goto out;
259 267
260 memcpy(fw->data + offset, buffer, count); 268 memcpy((u8 *)fw->data + offset, buffer, count);
261 269
262 fw->size = max_t(size_t, offset + count, fw->size); 270 fw->size = max_t(size_t, offset + count, fw->size);
263 retval = count; 271 retval = count;
@@ -391,13 +399,12 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
391 struct device *f_dev; 399 struct device *f_dev;
392 struct firmware_priv *fw_priv; 400 struct firmware_priv *fw_priv;
393 struct firmware *firmware; 401 struct firmware *firmware;
402 struct builtin_fw *builtin;
394 int retval; 403 int retval;
395 404
396 if (!firmware_p) 405 if (!firmware_p)
397 return -EINVAL; 406 return -EINVAL;
398 407
399 printk(KERN_INFO "firmware: requesting %s\n", name);
400
401 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); 408 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
402 if (!firmware) { 409 if (!firmware) {
403 printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n", 410 printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
@@ -406,6 +413,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
406 goto out; 413 goto out;
407 } 414 }
408 415
416 for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
417 builtin++) {
418 if (strcmp(name, builtin->name))
419 continue;
420 printk(KERN_INFO "firmware: using built-in firmware %s\n",
421 name);
422 firmware->size = builtin->size;
423 firmware->data = builtin->data;
424 return 0;
425 }
426
427 if (uevent)
428 printk(KERN_INFO "firmware: requesting %s\n", name);
429
409 retval = fw_setup_device(firmware, &f_dev, name, device, uevent); 430 retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
410 if (retval) 431 if (retval)
411 goto error_kfree_fw; 432 goto error_kfree_fw;
@@ -473,8 +494,16 @@ request_firmware(const struct firmware **firmware_p, const char *name,
473void 494void
474release_firmware(const struct firmware *fw) 495release_firmware(const struct firmware *fw)
475{ 496{
497 struct builtin_fw *builtin;
498
476 if (fw) { 499 if (fw) {
500 for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
501 builtin++) {
502 if (fw->data == builtin->data)
503 goto free_fw;
504 }
477 vfree(fw->data); 505 vfree(fw->data);
506 free_fw:
478 kfree(fw); 507 kfree(fw);
479 } 508 }
480} 509}