diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-15 18:29:07 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-15 18:29:07 -0400 |
commit | 82638844d9a8581bbf33201cc209a14876eca167 (patch) | |
tree | 961d7f9360194421a71aa644a9d0c176a960ce49 /drivers/base | |
parent | 9982fbface82893e77d211fbabfbd229da6bdde6 (diff) | |
parent | 63cf13b77ab785e87c867defa8545e6d4a989774 (diff) |
Merge branch 'linus' into cpus4096
Conflicts:
arch/x86/xen/smp.c
kernel/sched_rt.c
net/iucv/iucv.c
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/Kconfig | 64 | ||||
-rw-r--r-- | drivers/base/firmware_class.c | 35 | ||||
-rw-r--r-- | drivers/base/power/trace.c | 2 | ||||
-rw-r--r-- | drivers/base/topology.c | 57 |
4 files changed, 126 insertions, 32 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d7da109c24fd..d47482fa1d21 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -34,6 +34,70 @@ config FW_LOADER | |||
34 | require userspace firmware loading support, but a module built outside | 34 | require userspace firmware loading support, but a module built outside |
35 | the kernel tree does. | 35 | the kernel tree does. |
36 | 36 | ||
37 | config FIRMWARE_IN_KERNEL | ||
38 | bool "Include in-kernel firmware blobs in kernel binary" | ||
39 | depends on FW_LOADER | ||
40 | default y | ||
41 | help | ||
42 | The kernel source tree includes a number of firmware 'blobs' | ||
43 | which are used by various drivers. The recommended way to | ||
44 | use these is to run "make firmware_install" and to copy the | ||
45 | resulting binary files created in usr/lib/firmware directory | ||
46 | of the kernel tree to the /lib/firmware on your system so | ||
47 | that they can be loaded by userspace helpers on request. | ||
48 | |||
49 | Enabling this option will build each required firmware blob | ||
50 | into the kernel directly, where request_firmware() will find | ||
51 | them without having to call out to userspace. This may be | ||
52 | useful if your root file system requires a device which uses | ||
53 | such firmware, and do not wish to use an initrd. | ||
54 | |||
55 | This single option controls the inclusion of firmware for | ||
56 | every driver which usees request_firmare() and ships its | ||
57 | firmware in the kernel source tree, to avoid a proliferation | ||
58 | of 'Include firmware for xxx device' options. | ||
59 | |||
60 | Say 'N' and let firmware be loaded from userspace. | ||
61 | |||
62 | config EXTRA_FIRMWARE | ||
63 | string "External firmware blobs to build into the kernel binary" | ||
64 | depends on FW_LOADER | ||
65 | help | ||
66 | This option allows firmware to be built into the kernel, for the | ||
67 | cases where the user either cannot or doesn't want to provide it from | ||
68 | userspace at runtime (for example, when the firmware in question is | ||
69 | required for accessing the boot device, and the user doesn't want to | ||
70 | use an initrd). | ||
71 | |||
72 | This option is a string, and takes the (space-separated) names of the | ||
73 | firmware files -- the same names which appear in MODULE_FIRMWARE() | ||
74 | and request_firmware() in the source. These files should exist under | ||
75 | the directory specified by the EXTRA_FIRMWARE_DIR option, which is | ||
76 | by default the firmware/ subdirectory of the kernel source tree. | ||
77 | |||
78 | So, for example, you might set CONFIG_EXTRA_FIRMWARE="usb8388.bin", | ||
79 | copy the usb8388.bin file into the firmware/ directory, and build the | ||
80 | kernel. Then any request_firmware("usb8388.bin") will be | ||
81 | satisfied internally without needing to call out to userspace. | ||
82 | |||
83 | WARNING: If you include additional firmware files into your binary | ||
84 | kernel image which are not available under the terms of the GPL, | ||
85 | then it may be a violation of the GPL to distribute the resulting | ||
86 | image -- since it combines both GPL and non-GPL work. You should | ||
87 | consult a lawyer of your own before distributing such an image. | ||
88 | |||
89 | config EXTRA_FIRMWARE_DIR | ||
90 | string "Firmware blobs root directory" | ||
91 | depends on EXTRA_FIRMWARE != "" | ||
92 | default "firmware" | ||
93 | help | ||
94 | This option controls the directory in which the kernel build system | ||
95 | looks for the firmware files listed in the EXTRA_FIRMWARE option. | ||
96 | The default is the firmware/ directory in the kernel source tree, | ||
97 | but by changing this option you can point it elsewhere, such as | ||
98 | the /lib/firmware/ directory or another separate directory | ||
99 | containing firmware files. | ||
100 | |||
37 | config DEBUG_DRIVER | 101 | config DEBUG_DRIVER |
38 | bool "Driver Core verbose debug messages" | 102 | bool "Driver Core verbose debug messages" |
39 | depends on DEBUG_KERNEL | 103 | depends on DEBUG_KERNEL |
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 | ||
53 | extern struct builtin_fw __start_builtin_fw[]; | ||
54 | extern struct builtin_fw __end_builtin_fw[]; | ||
55 | #else /* Module case. Avoid ifdefs later; it'll all optimise out */ | ||
56 | static struct builtin_fw *__start_builtin_fw; | ||
57 | static struct builtin_fw *__end_builtin_fw; | ||
58 | #endif | ||
59 | |||
52 | static void | 60 | static void |
53 | fw_load_abort(struct firmware_priv *fw_priv) | 61 | fw_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, | |||
473 | void | 494 | void |
474 | release_firmware(const struct firmware *fw) | 495 | release_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 | } |
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 2b4b392dcbc1..87a7f1d02578 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -153,7 +153,7 @@ EXPORT_SYMBOL(set_trace_device); | |||
153 | * it's not any guarantee, but it's a high _likelihood_ that | 153 | * it's not any guarantee, but it's a high _likelihood_ that |
154 | * the match is valid). | 154 | * the match is valid). |
155 | */ | 155 | */ |
156 | void generate_resume_trace(void *tracedata, unsigned int user) | 156 | void generate_resume_trace(const void *tracedata, unsigned int user) |
157 | { | 157 | { |
158 | unsigned short lineno = *(unsigned short *)tracedata; | 158 | unsigned short lineno = *(unsigned short *)tracedata; |
159 | const char *file = *(const char **)(tracedata + 2); | 159 | const char *file = *(const char **)(tracedata + 2); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index fdf4044d2e74..3f6d9b0a6abe 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -40,6 +40,7 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \ | |||
40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | 40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ |
41 | } | 41 | } |
42 | 42 | ||
43 | #if defined(topology_thread_siblings) || defined(topology_core_siblings) | ||
43 | static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) | 44 | static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) |
44 | { | 45 | { |
45 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; | 46 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; |
@@ -54,65 +55,65 @@ static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) | |||
54 | } | 55 | } |
55 | return n; | 56 | return n; |
56 | } | 57 | } |
58 | #endif | ||
57 | 59 | ||
60 | #ifdef arch_provides_topology_pointers | ||
58 | #define define_siblings_show_map(name) \ | 61 | #define define_siblings_show_map(name) \ |
59 | static inline ssize_t show_##name(struct sys_device *dev, char *buf) \ | 62 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ |
60 | { \ | 63 | { \ |
61 | unsigned int cpu = dev->id; \ | 64 | unsigned int cpu = dev->id; \ |
62 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ | 65 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ |
63 | } | 66 | } |
64 | 67 | ||
65 | #define define_siblings_show_list(name) \ | 68 | #define define_siblings_show_list(name) \ |
66 | static inline ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | 69 | static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ |
67 | { \ | 70 | { \ |
68 | unsigned int cpu = dev->id; \ | 71 | unsigned int cpu = dev->id; \ |
69 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ | 72 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ |
70 | } | 73 | } |
71 | 74 | ||
75 | #else | ||
76 | #define define_siblings_show_map(name) \ | ||
77 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
78 | { \ | ||
79 | unsigned int cpu = dev->id; \ | ||
80 | cpumask_t mask = topology_##name(cpu); \ | ||
81 | return show_cpumap(0, &mask, buf); \ | ||
82 | } | ||
83 | |||
84 | #define define_siblings_show_list(name) \ | ||
85 | static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | ||
86 | { \ | ||
87 | unsigned int cpu = dev->id; \ | ||
88 | cpumask_t mask = topology_##name(cpu); \ | ||
89 | return show_cpumap(1, &mask, buf); \ | ||
90 | } | ||
91 | #endif | ||
92 | |||
72 | #define define_siblings_show_func(name) \ | 93 | #define define_siblings_show_func(name) \ |
73 | define_siblings_show_map(name); define_siblings_show_list(name) | 94 | define_siblings_show_map(name); define_siblings_show_list(name) |
74 | 95 | ||
75 | #ifdef topology_physical_package_id | ||
76 | define_id_show_func(physical_package_id); | 96 | define_id_show_func(physical_package_id); |
77 | define_one_ro(physical_package_id); | 97 | define_one_ro(physical_package_id); |
78 | #define ref_physical_package_id_attr &attr_physical_package_id.attr, | ||
79 | #else | ||
80 | #define ref_physical_package_id_attr | ||
81 | #endif | ||
82 | 98 | ||
83 | #ifdef topology_core_id | ||
84 | define_id_show_func(core_id); | 99 | define_id_show_func(core_id); |
85 | define_one_ro(core_id); | 100 | define_one_ro(core_id); |
86 | #define ref_core_id_attr &attr_core_id.attr, | ||
87 | #else | ||
88 | #define ref_core_id_attr | ||
89 | #endif | ||
90 | 101 | ||
91 | #ifdef topology_thread_siblings | ||
92 | define_siblings_show_func(thread_siblings); | 102 | define_siblings_show_func(thread_siblings); |
93 | define_one_ro(thread_siblings); | 103 | define_one_ro(thread_siblings); |
94 | define_one_ro(thread_siblings_list); | 104 | define_one_ro(thread_siblings_list); |
95 | #define ref_thread_siblings_attr \ | ||
96 | &attr_thread_siblings.attr, &attr_thread_siblings_list.attr, | ||
97 | #else | ||
98 | #define ref_thread_siblings_attr | ||
99 | #endif | ||
100 | 105 | ||
101 | #ifdef topology_core_siblings | ||
102 | define_siblings_show_func(core_siblings); | 106 | define_siblings_show_func(core_siblings); |
103 | define_one_ro(core_siblings); | 107 | define_one_ro(core_siblings); |
104 | define_one_ro(core_siblings_list); | 108 | define_one_ro(core_siblings_list); |
105 | #define ref_core_siblings_attr \ | ||
106 | &attr_core_siblings.attr, &attr_core_siblings_list.attr, | ||
107 | #else | ||
108 | #define ref_core_siblings_attr | ||
109 | #endif | ||
110 | 109 | ||
111 | static struct attribute *default_attrs[] = { | 110 | static struct attribute *default_attrs[] = { |
112 | ref_physical_package_id_attr | 111 | &attr_physical_package_id.attr, |
113 | ref_core_id_attr | 112 | &attr_core_id.attr, |
114 | ref_thread_siblings_attr | 113 | &attr_thread_siblings.attr, |
115 | ref_core_siblings_attr | 114 | &attr_thread_siblings_list.attr, |
115 | &attr_core_siblings.attr, | ||
116 | &attr_core_siblings_list.attr, | ||
116 | NULL | 117 | NULL |
117 | }; | 118 | }; |
118 | 119 | ||