]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/base/firmware_class.c
Merge branch 'linus' into cpus4096
[linux-2.6-omap-h63xx.git] / drivers / base / firmware_class.c
index 4a1b9bfc5471fe91ade02cedfaab22f6cec0d636..b0be1d18fee23d5c25d865bba20c0a3560546195 100644 (file)
@@ -49,6 +49,14 @@ struct firmware_priv {
        struct timer_list timeout;
 };
 
+#ifdef CONFIG_FW_LOADER
+extern struct builtin_fw __start_builtin_fw[];
+extern struct builtin_fw __end_builtin_fw[];
+#else /* Module case. Avoid ifdefs later; it'll all optimise out */
+static struct builtin_fw *__start_builtin_fw;
+static struct builtin_fw *__end_builtin_fw;
+#endif
+
 static void
 fw_load_abort(struct firmware_priv *fw_priv)
 {
@@ -156,7 +164,7 @@ static ssize_t firmware_loading_store(struct device *dev,
                }
                /* fallthrough */
        default:
-               printk(KERN_ERR "%s: unexpected value (%d)\n", __FUNCTION__,
+               printk(KERN_ERR "%s: unexpected value (%d)\n", __func__,
                       loading);
                /* fallthrough */
        case -1:
@@ -209,7 +217,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
        new_size = ALIGN(min_size, PAGE_SIZE);
        new_data = vmalloc(new_size);
        if (!new_data) {
-               printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
+               printk(KERN_ERR "%s: unable to alloc buffer\n", __func__);
                /* Make sure that we don't keep incomplete data */
                fw_load_abort(fw_priv);
                return -ENOMEM;
@@ -257,7 +265,7 @@ firmware_data_write(struct kobject *kobj, struct bin_attribute *bin_attr,
        if (retval)
                goto out;
 
-       memcpy(fw->data + offset, buffer, count);
+       memcpy((u8 *)fw->data + offset, buffer, count);
 
        fw->size = max_t(size_t, offset + count, fw->size);
        retval = count;
@@ -307,7 +315,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
        *dev_p = NULL;
 
        if (!fw_priv || !f_dev) {
-               printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__);
+               printk(KERN_ERR "%s: kmalloc failed\n", __func__);
                retval = -ENOMEM;
                goto error_kfree;
        }
@@ -328,7 +336,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
        retval = device_register(f_dev);
        if (retval) {
                printk(KERN_ERR "%s: device_register failed\n",
-                      __FUNCTION__);
+                      __func__);
                goto error_kfree;
        }
        *dev_p = f_dev;
@@ -362,14 +370,14 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
        retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
        if (retval) {
                printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
-                      __FUNCTION__);
+                      __func__);
                goto error_unreg;
        }
 
        retval = device_create_file(f_dev, &dev_attr_loading);
        if (retval) {
                printk(KERN_ERR "%s: device_create_file failed\n",
-                      __FUNCTION__);
+                      __func__);
                goto error_unreg;
        }
 
@@ -391,6 +399,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
        struct device *f_dev;
        struct firmware_priv *fw_priv;
        struct firmware *firmware;
+       struct builtin_fw *builtin;
        int retval;
 
        if (!firmware_p)
@@ -399,11 +408,25 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
        *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
        if (!firmware) {
                printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-                      __FUNCTION__);
+                      __func__);
                retval = -ENOMEM;
                goto out;
        }
 
+       for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+            builtin++) {
+               if (strcmp(name, builtin->name))
+                       continue;
+               printk(KERN_INFO "firmware: using built-in firmware %s\n",
+                      name);
+               firmware->size = builtin->size;
+               firmware->data = builtin->data;
+               return 0;
+       }
+
+       if (uevent)
+               printk(KERN_INFO "firmware: requesting %s\n", name);
+
        retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
        if (retval)
                goto error_kfree_fw;
@@ -471,8 +494,16 @@ request_firmware(const struct firmware **firmware_p, const char *name,
 void
 release_firmware(const struct firmware *fw)
 {
+       struct builtin_fw *builtin;
+
        if (fw) {
+               for (builtin = __start_builtin_fw; builtin != __end_builtin_fw;
+                    builtin++) {
+                       if (fw->data == builtin->data)
+                               goto free_fw;
+               }
                vfree(fw->data);
+       free_fw:
                kfree(fw);
        }
 }
@@ -570,13 +601,13 @@ firmware_class_init(void)
        int error;
        error = class_register(&firmware_class);
        if (error) {
-               printk(KERN_ERR "%s: class_register failed\n", __FUNCTION__);
+               printk(KERN_ERR "%s: class_register failed\n", __func__);
                return error;
        }
        error = class_create_file(&firmware_class, &class_attr_timeout);
        if (error) {
                printk(KERN_ERR "%s: class_create_file failed\n",
-                      __FUNCTION__);
+                      __func__);
                class_unregister(&firmware_class);
        }
        return error;