Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 100974
b: refs/heads/master
c: 5658c76
h: refs/heads/master
v: v3
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jul 10, 2008
1 parent c3a43e3 commit 73c6fd3
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b7a39bd0afc4021e8ad2b1189e884551e147427f
refs/heads/master: 5658c769443d543728b6c5c673dffc2df8676317
33 changes: 31 additions & 2 deletions trunk/drivers/base/firmware_class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -391,13 +399,12 @@ _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)
return -EINVAL;

printk(KERN_INFO "firmware: requesting %s\n", name);

*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware) {
printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
Expand All @@ -406,6 +413,20 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
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;
Expand Down Expand Up @@ -473,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);
}
}
Expand Down
7 changes: 7 additions & 0 deletions trunk/include/asm-generic/vmlinux.lds.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@
VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
} \
\
/* Built-in firmware blobs */ \
.builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_builtin_fw) = .; \
*(.builtin_fw) \
VMLINUX_SYMBOL(__end_builtin_fw) = .; \
} \
\
/* RapidIO route ops */ \
.rio_route : AT(ADDR(.rio_route) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_rio_route_ops) = .; \
Expand Down
21 changes: 21 additions & 0 deletions trunk/include/linux/firmware.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#ifndef _LINUX_FIRMWARE_H
#define _LINUX_FIRMWARE_H

#include <linux/module.h>
#include <linux/types.h>
#include <linux/compiler.h>

#define FIRMWARE_NAME_MAX 30
#define FW_ACTION_NOHOTPLUG 0
#define FW_ACTION_HOTPLUG 1
Expand All @@ -13,6 +16,24 @@ struct firmware {

struct device;

struct builtin_fw {
char *name;
void *data;
unsigned long size;
};

/* We have to play tricks here much like stringify() to get the
__COUNTER__ macro to be expanded as we want it */
#define __fw_concat1(x, y) x##y
#define __fw_concat(x, y) __fw_concat1(x, y)

#define DECLARE_BUILTIN_FIRMWARE(name, blob) \
DECLARE_BUILTIN_FIRMWARE_SIZE(name, &(blob), sizeof(blob))

#define DECLARE_BUILTIN_FIRMWARE_SIZE(name, blob, size) \
static const struct builtin_fw __fw_concat(__builtin_fw,__COUNTER__) \
__used __section(.builtin_fw) = { name, blob, size }

#if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
Expand Down

0 comments on commit 73c6fd3

Please sign in to comment.