aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/firmware_class/README26
-rw-r--r--Documentation/zh_CN/IRQ.txt39
-rw-r--r--Documentation/zh_CN/arm64/booting.txt156
-rw-r--r--Documentation/zh_CN/arm64/memory.txt93
-rw-r--r--drivers/base/firmware_class.c266
-rw-r--r--fs/sysfs/dir.c16
-rw-r--r--include/linux/dynamic_debug.h2
7 files changed, 465 insertions, 133 deletions
diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README
index 7eceaff63f5f..815b711bcd85 100644
--- a/Documentation/firmware_class/README
+++ b/Documentation/firmware_class/README
@@ -18,32 +18,40 @@
18 High level behavior (mixed): 18 High level behavior (mixed):
19 ============================ 19 ============================
20 20
21 kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device) 21 1), kernel(driver):
22 22 - calls request_firmware(&fw_entry, $FIRMWARE, device)
23 userspace: 23 - kernel searchs the fimware image with name $FIRMWARE directly
24 in the below search path of root filesystem:
25 "/lib/firmware/updates/" UTS_RELEASE,
26 "/lib/firmware/updates",
27 "/lib/firmware/" UTS_RELEASE,
28 "/lib/firmware"
29 - If found, goto 7), else goto 2)
30
31 2), userspace:
24 - /sys/class/firmware/xxx/{loading,data} appear. 32 - /sys/class/firmware/xxx/{loading,data} appear.
25 - hotplug gets called with a firmware identifier in $FIRMWARE 33 - hotplug gets called with a firmware identifier in $FIRMWARE
26 and the usual hotplug environment. 34 and the usual hotplug environment.
27 - hotplug: echo 1 > /sys/class/firmware/xxx/loading 35 - hotplug: echo 1 > /sys/class/firmware/xxx/loading
28 36
29 kernel: Discard any previous partial load. 37 3), kernel: Discard any previous partial load.
30 38
31 userspace: 39 4), userspace:
32 - hotplug: cat appropriate_firmware_image > \ 40 - hotplug: cat appropriate_firmware_image > \
33 /sys/class/firmware/xxx/data 41 /sys/class/firmware/xxx/data
34 42
35 kernel: grows a buffer in PAGE_SIZE increments to hold the image as it 43 5), kernel: grows a buffer in PAGE_SIZE increments to hold the image as it
36 comes in. 44 comes in.
37 45
38 userspace: 46 6), userspace:
39 - hotplug: echo 0 > /sys/class/firmware/xxx/loading 47 - hotplug: echo 0 > /sys/class/firmware/xxx/loading
40 48
41 kernel: request_firmware() returns and the driver has the firmware 49 7), kernel: request_firmware() returns and the driver has the firmware
42 image in fw_entry->{data,size}. If something went wrong 50 image in fw_entry->{data,size}. If something went wrong
43 request_firmware() returns non-zero and fw_entry is set to 51 request_firmware() returns non-zero and fw_entry is set to
44 NULL. 52 NULL.
45 53
46 kernel(driver): Driver code calls release_firmware(fw_entry) releasing 54 8), kernel(driver): Driver code calls release_firmware(fw_entry) releasing
47 the firmware image and any related resource. 55 the firmware image and any related resource.
48 56
49 High level behavior (driver code): 57 High level behavior (driver code):
diff --git a/Documentation/zh_CN/IRQ.txt b/Documentation/zh_CN/IRQ.txt
new file mode 100644
index 000000000000..956026d5cf82
--- /dev/null
+++ b/Documentation/zh_CN/IRQ.txt
@@ -0,0 +1,39 @@
1Chinese translated version of Documentation/IRQ.txt
2
3If you have any comment or update to the content, please contact the
4original document maintainer directly. However, if you have a problem
5communicating in English you can also ask the Chinese maintainer for
6help. Contact the Chinese maintainer if this translation is outdated
7or if there is a problem with the translation.
8
9Maintainer: Eric W. Biederman <ebiederman@xmission.com>
10Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11---------------------------------------------------------------------
12Documentation/IRQ.txt 的中文翻译
13
14如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16译存在问题,请联系中文版维护者。
17英文版维护者: Eric W. Biederman <ebiederman@xmission.com>
18中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
19中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21
22
23以下为正文
24---------------------------------------------------------------------
25何为 IRQ?
26
27一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚,
28或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。
29
30一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个
31全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现,
32具体的细节是体系结构特定的。
33
34一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是
35该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况,
36枚举的是在两个 i8259 中断控制器中 16 个输入引脚。
37
38架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下,
39是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。
diff --git a/Documentation/zh_CN/arm64/booting.txt b/Documentation/zh_CN/arm64/booting.txt
new file mode 100644
index 000000000000..28fa325b7461
--- /dev/null
+++ b/Documentation/zh_CN/arm64/booting.txt
@@ -0,0 +1,156 @@
1Chinese translated version of Documentation/arm64/booting.txt
2
3If you have any comment or update to the content, please contact the
4original document maintainer directly. However, if you have a problem
5communicating in English you can also ask the Chinese maintainer for
6help. Contact the Chinese maintainer if this translation is outdated
7or if there is a problem with the translation.
8
9Maintainer: Will Deacon <will.deacon@arm.com>
10Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11---------------------------------------------------------------------
12Documentation/arm64/booting.txt 的中文翻译
13
14如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16译存在问题,请联系中文版维护者。
17
18英文版维护者: Will Deacon <will.deacon@arm.com>
19中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
22
23以下为正文
24---------------------------------------------------------------------
25 启动 AArch64 Linux
26 ==================
27
28作者: Will Deacon <will.deacon@arm.com>
29日期: 2012 年 09 月 07 日
30
31本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的
32AArch64 Linux 内核代码。
33
34AArch64 异常模型由多个异常级别(EL0 - EL3)组成,对于 EL0 和 EL1
35异常级有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于
36非安全模式下。EL3 是最高特权级,且仅存在于安全模式下。
37
38基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’)
39这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。
40这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动
41环境的指令。
42
43基本上,引导装载程序(至少)应实现以下操作:
44
451、设置和初始化 RAM
462、设置设备树数据
473、解压内核映像
484、调用内核映像
49
50
511、设置和初始化 RAM
52-----------------
53
54必要性: 强制
55
56引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。
57这个操作的执行是设备依赖的。(它可能使用内部算法来自动定位和计算所有
58RAM,或可能使用对这个设备已知的 RAM 信息,还可能使用任何引导装载程序
59设计者想到的匹配方法。)
60
61
622、设置设备树数据
63---------------
64
65必要性: 强制
66
67设备树数据块(dtb)大小必须不大于 2 MB,且位于从内核映像起始算起第一个
68512MB 内的 2MB 边界上。这使得内核可以通过初始页表中的单个节描述符来
69映射此数据块。
70
71
723、解压内核映像
73-------------
74
75必要性: 可选
76
77AArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件
78(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。
79若引导装载程序没有实现这个需求,就要使用非压缩内核映像文件。
80
81
824、调用内核映像
83-------------
84
85必要性: 强制
86
87已解压的内核映像包含一个 32 字节的头,内容如下:
88
89 u32 magic = 0x14000008; /* 跳转到 stext, 小端 */
90 u32 res0 = 0; /* 保留 */
91 u64 text_offset; /* 映像装载偏移 */
92 u64 res1 = 0; /* 保留 */
93 u64 res2 = 0; /* 保留 */
94
95映像必须位于系统 RAM 起始处的特定偏移(当前是 0x80000)。系统 RAM
96的起始地址必须是以 2MB 对齐的。
97
98在跳转入内核前,必须符合以下状态:
99
100- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而
101 被破坏。这可能可以节省你许多的调试时间。
102
103- 主 CPU 通用寄存器设置
104 x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。
105 x1 = 0 (保留,将来可能使用)
106 x2 = 0 (保留,将来可能使用)
107 x3 = 0 (保留,将来可能使用)
108
109- CPU 模式
110 所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ
111 和 FIQ)。
112 CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。
113
114- 高速缓存、MMU
115 MMU 必须关闭。
116 指令缓存开启或关闭都可以。
117 数据缓存必须关闭且无效。
118 外部高速缓存(如果存在)必须配置并禁用。
119
120- 架构计时器
121 CNTFRQ 必须设定为计时器的频率。
122 如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 EL1PCTEN (bit 0)
123 必须置位。
124
125- 一致性
126 通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。
127 这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的
128 接收。
129
130- 系统寄存器
131 在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件
132 在一个更高的异常级别下初始化,以防止在 未知 状态下运行。
133
134引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口:
135
136- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树
137 数据块必须在每个 CPU 节点中包含以下内容:
138
139 1、‘enable-method’属性。目前,此字段支持的值仅为字符串“spin-table”。
140
141 2、‘cpu-release-addr’标识一个 64-bit、初始化为零的内存位置。
142
143 引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入
144 数据块。
145
146- 任何辅助 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递
147 给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须
148 包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将
149 发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值
150 时,CPU 必须直接跳入此值所指向的地址。
151
152- 辅助 CPU 通用寄存器设置
153 x0 = 0 (保留,将来可能使用)
154 x1 = 0 (保留,将来可能使用)
155 x2 = 0 (保留,将来可能使用)
156 x3 = 0 (保留,将来可能使用)
diff --git a/Documentation/zh_CN/arm64/memory.txt b/Documentation/zh_CN/arm64/memory.txt
new file mode 100644
index 000000000000..83b519314706
--- /dev/null
+++ b/Documentation/zh_CN/arm64/memory.txt
@@ -0,0 +1,93 @@
1Chinese translated version of Documentation/arm64/memory.txt
2
3If you have any comment or update to the content, please contact the
4original document maintainer directly. However, if you have a problem
5communicating in English you can also ask the Chinese maintainer for
6help. Contact the Chinese maintainer if this translation is outdated
7or if there is a problem with the translation.
8
9Maintainer: Catalin Marinas <catalin.marinas@arm.com>
10Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
11---------------------------------------------------------------------
12Documentation/arm64/memory.txt 的中文翻译
13
14如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
15交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
16译存在问题,请联系中文版维护者。
17
18英文版维护者: Catalin Marinas <catalin.marinas@arm.com>
19中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
20中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
21中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com>
22
23以下为正文
24---------------------------------------------------------------------
25 Linux 在 AArch64 中的内存布局
26 ===========================
27
28作者: Catalin Marinas <catalin.marinas@arm.com>
29日期: 2012 年 02 月 20 日
30
31本文档描述 AArch64 Linux 内核所使用的虚拟内存布局。此构架可以实现
32页大小为 4KB 的 4 级转换表和页大小为 64KB 的 3 级转换表。
33
34AArch64 Linux 使用页大小为 4KB 的 3 级转换表配置,对于用户和内核
35都有 39-bit (512GB) 的虚拟地址空间。对于页大小为 64KB的配置,仅
36使用 2 级转换表,但内存布局相同。
37
38用户地址空间的 63:39 位为 0,而内核地址空间的相应位为 1。TTBRx 的
39选择由虚拟地址的 63 位给出。swapper_pg_dir 仅包含内核(全局)映射,
40而用户 pgd 仅包含用户(非全局)映射。swapper_pgd_dir 地址被写入
41TTBR1 中,且从不写入 TTBR0。
42
43
44AArch64 Linux 内存布局:
45
46起始地址 结束地址 大小 用途
47-----------------------------------------------------------------------
480000000000000000 0000007fffffffff 512GB 用户空间
49
50ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
51
52ffffffbbfffd0000 ffffffbcfffdffff 64KB [防护页]
53
54ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O 空间
55
56ffffffbbffff0000 ffffffbcffffffff 64KB [防护页]
57
58ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
59
60ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap]
61
62ffffffbffc000000 ffffffbfffffffff 64MB 模块
63
64ffffffc000000000 ffffffffffffffff 256GB 内存空间
65
66
674KB 页大小的转换表查找:
68
69+--------+--------+--------+--------+--------+--------+--------+--------+
70|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
71+--------+--------+--------+--------+--------+--------+--------+--------+
72 | | | | | |
73 | | | | | v
74 | | | | | [11:0] 页内偏移
75 | | | | +-> [20:12] L3 索引
76 | | | +-----------> [29:21] L2 索引
77 | | +---------------------> [38:30] L1 索引
78 | +-------------------------------> [47:39] L0 索引 (未使用)
79 +-------------------------------------------------> [63] TTBR0/1
80
81
8264KB 页大小的转换表查找:
83
84+--------+--------+--------+--------+--------+--------+--------+--------+
85|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0|
86+--------+--------+--------+--------+--------+--------+--------+--------+
87 | | | | |
88 | | | | v
89 | | | | [15:0] 页内偏移
90 | | | +----------> [28:16] L3 索引
91 | | +--------------------------> [41:29] L2 索引 (仅使用 38:29 )
92 | +-------------------------------> [47:42] L1 索引 (未使用)
93 +-------------------------------------------------> [63] TTBR0/1
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 81541452887b..8945f4e489ed 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -36,68 +36,6 @@ MODULE_AUTHOR("Manuel Estrada Sainz");
36MODULE_DESCRIPTION("Multi purpose firmware loading support"); 36MODULE_DESCRIPTION("Multi purpose firmware loading support");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39static const char *fw_path[] = {
40 "/lib/firmware/updates/" UTS_RELEASE,
41 "/lib/firmware/updates",
42 "/lib/firmware/" UTS_RELEASE,
43 "/lib/firmware"
44};
45
46/* Don't inline this: 'struct kstat' is biggish */
47static noinline long fw_file_size(struct file *file)
48{
49 struct kstat st;
50 if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
51 return -1;
52 if (!S_ISREG(st.mode))
53 return -1;
54 if (st.size != (long)st.size)
55 return -1;
56 return st.size;
57}
58
59static bool fw_read_file_contents(struct file *file, struct firmware *fw)
60{
61 long size;
62 char *buf;
63
64 size = fw_file_size(file);
65 if (size < 0)
66 return false;
67 buf = vmalloc(size);
68 if (!buf)
69 return false;
70 if (kernel_read(file, 0, buf, size) != size) {
71 vfree(buf);
72 return false;
73 }
74 fw->data = buf;
75 fw->size = size;
76 return true;
77}
78
79static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
80{
81 int i;
82 bool success = false;
83 char *path = __getname();
84
85 for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
86 struct file *file;
87 snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
88
89 file = filp_open(path, O_RDONLY, 0);
90 if (IS_ERR(file))
91 continue;
92 success = fw_read_file_contents(file, fw);
93 fput(file);
94 if (success)
95 break;
96 }
97 __putname(path);
98 return success;
99}
100
101/* Builtin firmware support */ 39/* Builtin firmware support */
102 40
103#ifdef CONFIG_FW_LOADER 41#ifdef CONFIG_FW_LOADER
@@ -150,6 +88,11 @@ enum {
150 FW_STATUS_ABORT, 88 FW_STATUS_ABORT,
151}; 89};
152 90
91enum fw_buf_fmt {
92 VMALLOC_BUF, /* used in direct loading */
93 PAGE_BUF, /* used in loading via userspace */
94};
95
153static int loading_timeout = 60; /* In seconds */ 96static int loading_timeout = 60; /* In seconds */
154 97
155static inline long firmware_loading_timeout(void) 98static inline long firmware_loading_timeout(void)
@@ -173,8 +116,6 @@ struct firmware_cache {
173 spinlock_t name_lock; 116 spinlock_t name_lock;
174 struct list_head fw_names; 117 struct list_head fw_names;
175 118
176 wait_queue_head_t wait_queue;
177 int cnt;
178 struct delayed_work work; 119 struct delayed_work work;
179 120
180 struct notifier_block pm_notify; 121 struct notifier_block pm_notify;
@@ -187,6 +128,7 @@ struct firmware_buf {
187 struct completion completion; 128 struct completion completion;
188 struct firmware_cache *fwc; 129 struct firmware_cache *fwc;
189 unsigned long status; 130 unsigned long status;
131 enum fw_buf_fmt fmt;
190 void *data; 132 void *data;
191 size_t size; 133 size_t size;
192 struct page **pages; 134 struct page **pages;
@@ -240,6 +182,7 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name,
240 strcpy(buf->fw_id, fw_name); 182 strcpy(buf->fw_id, fw_name);
241 buf->fwc = fwc; 183 buf->fwc = fwc;
242 init_completion(&buf->completion); 184 init_completion(&buf->completion);
185 buf->fmt = VMALLOC_BUF;
243 186
244 pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); 187 pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf);
245 188
@@ -307,10 +250,14 @@ static void __fw_free_buf(struct kref *ref)
307 list_del(&buf->list); 250 list_del(&buf->list);
308 spin_unlock(&fwc->lock); 251 spin_unlock(&fwc->lock);
309 252
310 vunmap(buf->data); 253
311 for (i = 0; i < buf->nr_pages; i++) 254 if (buf->fmt == PAGE_BUF) {
312 __free_page(buf->pages[i]); 255 vunmap(buf->data);
313 kfree(buf->pages); 256 for (i = 0; i < buf->nr_pages; i++)
257 __free_page(buf->pages[i]);
258 kfree(buf->pages);
259 } else
260 vfree(buf->data);
314 kfree(buf); 261 kfree(buf);
315} 262}
316 263
@@ -319,6 +266,69 @@ static void fw_free_buf(struct firmware_buf *buf)
319 kref_put(&buf->ref, __fw_free_buf); 266 kref_put(&buf->ref, __fw_free_buf);
320} 267}
321 268
269/* direct firmware loading support */
270static const char *fw_path[] = {
271 "/lib/firmware/updates/" UTS_RELEASE,
272 "/lib/firmware/updates",
273 "/lib/firmware/" UTS_RELEASE,
274 "/lib/firmware"
275};
276
277/* Don't inline this: 'struct kstat' is biggish */
278static noinline long fw_file_size(struct file *file)
279{
280 struct kstat st;
281 if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
282 return -1;
283 if (!S_ISREG(st.mode))
284 return -1;
285 if (st.size != (long)st.size)
286 return -1;
287 return st.size;
288}
289
290static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
291{
292 long size;
293 char *buf;
294
295 size = fw_file_size(file);
296 if (size < 0)
297 return false;
298 buf = vmalloc(size);
299 if (!buf)
300 return false;
301 if (kernel_read(file, 0, buf, size) != size) {
302 vfree(buf);
303 return false;
304 }
305 fw_buf->data = buf;
306 fw_buf->size = size;
307 return true;
308}
309
310static bool fw_get_filesystem_firmware(struct firmware_buf *buf)
311{
312 int i;
313 bool success = false;
314 char *path = __getname();
315
316 for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
317 struct file *file;
318 snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id);
319
320 file = filp_open(path, O_RDONLY, 0);
321 if (IS_ERR(file))
322 continue;
323 success = fw_read_file_contents(file, buf);
324 fput(file);
325 if (success)
326 break;
327 }
328 __putname(path);
329 return success;
330}
331
322static struct firmware_priv *to_firmware_priv(struct device *dev) 332static struct firmware_priv *to_firmware_priv(struct device *dev)
323{ 333{
324 return container_of(dev, struct firmware_priv, dev); 334 return container_of(dev, struct firmware_priv, dev);
@@ -423,6 +433,21 @@ static void firmware_free_data(const struct firmware *fw)
423#ifndef PAGE_KERNEL_RO 433#ifndef PAGE_KERNEL_RO
424#define PAGE_KERNEL_RO PAGE_KERNEL 434#define PAGE_KERNEL_RO PAGE_KERNEL
425#endif 435#endif
436
437/* one pages buffer should be mapped/unmapped only once */
438static int fw_map_pages_buf(struct firmware_buf *buf)
439{
440 if (buf->fmt != PAGE_BUF)
441 return 0;
442
443 if (buf->data)
444 vunmap(buf->data);
445 buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
446 if (!buf->data)
447 return -ENOMEM;
448 return 0;
449}
450
426/** 451/**
427 * firmware_loading_store - set value in the 'loading' control file 452 * firmware_loading_store - set value in the 'loading' control file
428 * @dev: device pointer 453 * @dev: device pointer
@@ -467,6 +492,14 @@ static ssize_t firmware_loading_store(struct device *dev,
467 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { 492 if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) {
468 set_bit(FW_STATUS_DONE, &fw_buf->status); 493 set_bit(FW_STATUS_DONE, &fw_buf->status);
469 clear_bit(FW_STATUS_LOADING, &fw_buf->status); 494 clear_bit(FW_STATUS_LOADING, &fw_buf->status);
495
496 /*
497 * Several loading requests may be pending on
498 * one same firmware buf, so let all requests
499 * see the mapped 'buf->data' once the loading
500 * is completed.
501 * */
502 fw_map_pages_buf(fw_buf);
470 complete_all(&fw_buf->completion); 503 complete_all(&fw_buf->completion);
471 break; 504 break;
472 } 505 }
@@ -670,15 +703,6 @@ exit:
670 return fw_priv; 703 return fw_priv;
671} 704}
672 705
673/* one pages buffer is mapped/unmapped only once */
674static int fw_map_pages_buf(struct firmware_buf *buf)
675{
676 buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO);
677 if (!buf->data)
678 return -ENOMEM;
679 return 0;
680}
681
682/* store the pages buffer info firmware from buf */ 706/* store the pages buffer info firmware from buf */
683static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) 707static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw)
684{ 708{
@@ -778,11 +802,6 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name,
778 return NULL; 802 return NULL;
779 } 803 }
780 804
781 if (fw_get_filesystem_firmware(firmware, name)) {
782 dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
783 return NULL;
784 }
785
786 ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); 805 ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf);
787 if (!ret) 806 if (!ret)
788 fw_priv = fw_create_instance(firmware, name, device, 807 fw_priv = fw_create_instance(firmware, name, device,
@@ -832,6 +851,21 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
832 struct device *f_dev = &fw_priv->dev; 851 struct device *f_dev = &fw_priv->dev;
833 struct firmware_buf *buf = fw_priv->buf; 852 struct firmware_buf *buf = fw_priv->buf;
834 struct firmware_cache *fwc = &fw_cache; 853 struct firmware_cache *fwc = &fw_cache;
854 int direct_load = 0;
855
856 /* try direct loading from fs first */
857 if (fw_get_filesystem_firmware(buf)) {
858 dev_dbg(f_dev->parent, "firmware: direct-loading"
859 " firmware %s\n", buf->fw_id);
860
861 set_bit(FW_STATUS_DONE, &buf->status);
862 complete_all(&buf->completion);
863 direct_load = 1;
864 goto handle_fw;
865 }
866
867 /* fall back on userspace loading */
868 buf->fmt = PAGE_BUF;
835 869
836 dev_set_uevent_suppress(f_dev, true); 870 dev_set_uevent_suppress(f_dev, true);
837 871
@@ -870,6 +904,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
870 904
871 del_timer_sync(&fw_priv->timeout); 905 del_timer_sync(&fw_priv->timeout);
872 906
907handle_fw:
873 mutex_lock(&fw_lock); 908 mutex_lock(&fw_lock);
874 if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) 909 if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status))
875 retval = -ENOENT; 910 retval = -ENOENT;
@@ -884,9 +919,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
884 if (!retval && f_dev->parent) 919 if (!retval && f_dev->parent)
885 fw_add_devm_name(f_dev->parent, buf->fw_id); 920 fw_add_devm_name(f_dev->parent, buf->fw_id);
886 921
887 if (!retval)
888 retval = fw_map_pages_buf(buf);
889
890 /* 922 /*
891 * After caching firmware image is started, let it piggyback 923 * After caching firmware image is started, let it piggyback
892 * on request firmware. 924 * on request firmware.
@@ -902,6 +934,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent,
902 fw_priv->buf = NULL; 934 fw_priv->buf = NULL;
903 mutex_unlock(&fw_lock); 935 mutex_unlock(&fw_lock);
904 936
937 if (direct_load)
938 goto err_put_dev;
939
905 device_remove_file(f_dev, &dev_attr_loading); 940 device_remove_file(f_dev, &dev_attr_loading);
906err_del_bin_attr: 941err_del_bin_attr:
907 device_remove_bin_file(f_dev, &firmware_attr_data); 942 device_remove_bin_file(f_dev, &firmware_attr_data);
@@ -1129,6 +1164,8 @@ int uncache_firmware(const char *fw_name)
1129} 1164}
1130 1165
1131#ifdef CONFIG_PM_SLEEP 1166#ifdef CONFIG_PM_SLEEP
1167static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
1168
1132static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) 1169static struct fw_cache_entry *alloc_fw_cache_entry(const char *name)
1133{ 1170{
1134 struct fw_cache_entry *fce; 1171 struct fw_cache_entry *fce;
@@ -1142,17 +1179,27 @@ exit:
1142 return fce; 1179 return fce;
1143} 1180}
1144 1181
1145static int fw_cache_piggyback_on_request(const char *name) 1182static int __fw_entry_found(const char *name)
1146{ 1183{
1147 struct firmware_cache *fwc = &fw_cache; 1184 struct firmware_cache *fwc = &fw_cache;
1148 struct fw_cache_entry *fce; 1185 struct fw_cache_entry *fce;
1149 int ret = 0;
1150 1186
1151 spin_lock(&fwc->name_lock);
1152 list_for_each_entry(fce, &fwc->fw_names, list) { 1187 list_for_each_entry(fce, &fwc->fw_names, list) {
1153 if (!strcmp(fce->name, name)) 1188 if (!strcmp(fce->name, name))
1154 goto found; 1189 return 1;
1155 } 1190 }
1191 return 0;
1192}
1193
1194static int fw_cache_piggyback_on_request(const char *name)
1195{
1196 struct firmware_cache *fwc = &fw_cache;
1197 struct fw_cache_entry *fce;
1198 int ret = 0;
1199
1200 spin_lock(&fwc->name_lock);
1201 if (__fw_entry_found(name))
1202 goto found;
1156 1203
1157 fce = alloc_fw_cache_entry(name); 1204 fce = alloc_fw_cache_entry(name);
1158 if (fce) { 1205 if (fce) {
@@ -1185,12 +1232,6 @@ static void __async_dev_cache_fw_image(void *fw_entry,
1185 1232
1186 free_fw_cache_entry(fce); 1233 free_fw_cache_entry(fce);
1187 } 1234 }
1188
1189 spin_lock(&fwc->name_lock);
1190 fwc->cnt--;
1191 spin_unlock(&fwc->name_lock);
1192
1193 wake_up(&fwc->wait_queue);
1194} 1235}
1195 1236
1196/* called with dev->devres_lock held */ 1237/* called with dev->devres_lock held */
@@ -1229,11 +1270,19 @@ static void dev_cache_fw_image(struct device *dev, void *data)
1229 list_del(&fce->list); 1270 list_del(&fce->list);
1230 1271
1231 spin_lock(&fwc->name_lock); 1272 spin_lock(&fwc->name_lock);
1232 fwc->cnt++; 1273 /* only one cache entry for one firmware */
1233 list_add(&fce->list, &fwc->fw_names); 1274 if (!__fw_entry_found(fce->name)) {
1275 list_add(&fce->list, &fwc->fw_names);
1276 } else {
1277 free_fw_cache_entry(fce);
1278 fce = NULL;
1279 }
1234 spin_unlock(&fwc->name_lock); 1280 spin_unlock(&fwc->name_lock);
1235 1281
1236 async_schedule(__async_dev_cache_fw_image, (void *)fce); 1282 if (fce)
1283 async_schedule_domain(__async_dev_cache_fw_image,
1284 (void *)fce,
1285 &fw_cache_domain);
1237 } 1286 }
1238} 1287}
1239 1288
@@ -1275,6 +1324,9 @@ static void device_cache_fw_images(void)
1275 1324
1276 pr_debug("%s\n", __func__); 1325 pr_debug("%s\n", __func__);
1277 1326
1327 /* cancel uncache work */
1328 cancel_delayed_work_sync(&fwc->work);
1329
1278 /* 1330 /*
1279 * use small loading timeout for caching devices' firmware 1331 * use small loading timeout for caching devices' firmware
1280 * because all these firmware images have been loaded 1332 * because all these firmware images have been loaded
@@ -1292,21 +1344,7 @@ static void device_cache_fw_images(void)
1292 mutex_unlock(&fw_lock); 1344 mutex_unlock(&fw_lock);
1293 1345
1294 /* wait for completion of caching firmware for all devices */ 1346 /* wait for completion of caching firmware for all devices */
1295 spin_lock(&fwc->name_lock); 1347 async_synchronize_full_domain(&fw_cache_domain);
1296 for (;;) {
1297 prepare_to_wait(&fwc->wait_queue, &wait,
1298 TASK_UNINTERRUPTIBLE);
1299 if (!fwc->cnt)
1300 break;
1301
1302 spin_unlock(&fwc->name_lock);
1303
1304 schedule();
1305
1306 spin_lock(&fwc->name_lock);
1307 }
1308 spin_unlock(&fwc->name_lock);
1309 finish_wait(&fwc->wait_queue, &wait);
1310 1348
1311 loading_timeout = old_timeout; 1349 loading_timeout = old_timeout;
1312} 1350}
@@ -1394,9 +1432,7 @@ static void __init fw_cache_init(void)
1394#ifdef CONFIG_PM_SLEEP 1432#ifdef CONFIG_PM_SLEEP
1395 spin_lock_init(&fw_cache.name_lock); 1433 spin_lock_init(&fw_cache.name_lock);
1396 INIT_LIST_HEAD(&fw_cache.fw_names); 1434 INIT_LIST_HEAD(&fw_cache.fw_names);
1397 fw_cache.cnt = 0;
1398 1435
1399 init_waitqueue_head(&fw_cache.wait_queue);
1400 INIT_DELAYED_WORK(&fw_cache.work, 1436 INIT_DELAYED_WORK(&fw_cache.work,
1401 device_uncache_fw_images_work); 1437 device_uncache_fw_images_work);
1402 1438
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 6b0bb00d4d2b..2fbdff6be25c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -485,20 +485,18 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
485/** 485/**
486 * sysfs_pathname - return full path to sysfs dirent 486 * sysfs_pathname - return full path to sysfs dirent
487 * @sd: sysfs_dirent whose path we want 487 * @sd: sysfs_dirent whose path we want
488 * @path: caller allocated buffer 488 * @path: caller allocated buffer of size PATH_MAX
489 * 489 *
490 * Gives the name "/" to the sysfs_root entry; any path returned 490 * Gives the name "/" to the sysfs_root entry; any path returned
491 * is relative to wherever sysfs is mounted. 491 * is relative to wherever sysfs is mounted.
492 *
493 * XXX: does no error checking on @path size
494 */ 492 */
495static char *sysfs_pathname(struct sysfs_dirent *sd, char *path) 493static char *sysfs_pathname(struct sysfs_dirent *sd, char *path)
496{ 494{
497 if (sd->s_parent) { 495 if (sd->s_parent) {
498 sysfs_pathname(sd->s_parent, path); 496 sysfs_pathname(sd->s_parent, path);
499 strcat(path, "/"); 497 strlcat(path, "/", PATH_MAX);
500 } 498 }
501 strcat(path, sd->s_name); 499 strlcat(path, sd->s_name, PATH_MAX);
502 return path; 500 return path;
503} 501}
504 502
@@ -531,9 +529,11 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
531 char *path = kzalloc(PATH_MAX, GFP_KERNEL); 529 char *path = kzalloc(PATH_MAX, GFP_KERNEL);
532 WARN(1, KERN_WARNING 530 WARN(1, KERN_WARNING
533 "sysfs: cannot create duplicate filename '%s'\n", 531 "sysfs: cannot create duplicate filename '%s'\n",
534 (path == NULL) ? sd->s_name : 532 (path == NULL) ? sd->s_name
535 strcat(strcat(sysfs_pathname(acxt->parent_sd, path), "/"), 533 : (sysfs_pathname(acxt->parent_sd, path),
536 sd->s_name)); 534 strlcat(path, "/", PATH_MAX),
535 strlcat(path, sd->s_name, PATH_MAX),
536 path));
537 kfree(path); 537 kfree(path);
538 } 538 }
539 539
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index c18257b0fa72..6dd4787a798a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -61,7 +61,7 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
61 const char *fmt, ...); 61 const char *fmt, ...);
62 62
63#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ 63#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \
64 static struct _ddebug __used __aligned(8) \ 64 static struct _ddebug __aligned(8) \
65 __attribute__((section("__verbose"))) name = { \ 65 __attribute__((section("__verbose"))) name = { \
66 .modname = KBUILD_MODNAME, \ 66 .modname = KBUILD_MODNAME, \
67 .function = __func__, \ 67 .function = __func__, \