arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / Documentation / translations / zh_CN / driver-api / io_ordering.rst
1 .. SPDX-License-Identifier: GPL-2.0
2
3 .. include:: ../disclaimer-zh_CN.rst
4
5 :Original: Documentation/driver-api/io_ordering.rst
6
7 :翻译:
8
9  林永听 Lin Yongting <linyongting@gmail.com>
10  司延腾 Yanteng Si <siyanteng@loongson.cn>
11
12 :校译:
13
14 ===========================
15 对内存映射地址的I/O写入排序
16 ===========================
17
18 在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
19 保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
20 设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
21 而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
22 这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
23 屏障操作,mb(),不过仅适用于I/O)。
24
25 假设一个设备驱动程的具体例子::
26
27                 ...
28         CPU A:  spin_lock_irqsave(&dev_lock, flags)
29         CPU A:  val = readl(my_status);
30         CPU A:  ...
31         CPU A:  writel(newval, ring_ptr);
32         CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
33                 ...
34         CPU B:  spin_lock_irqsave(&dev_lock, flags)
35         CPU B:  val = readl(my_status);
36         CPU B:  ...
37         CPU B:  writel(newval2, ring_ptr);
38         CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
39                 ...
40
41 上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
42 发生了。不过很容易通过下面方法来修复::
43
44                 ...
45         CPU A:  spin_lock_irqsave(&dev_lock, flags)
46         CPU A:  val = readl(my_status);
47         CPU A:  ...
48         CPU A:  writel(newval, ring_ptr);
49         CPU A:  (void)readl(safe_register); /* 配置寄存器?*/
50         CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
51                 ...
52         CPU B:  spin_lock_irqsave(&dev_lock, flags)
53         CPU B:  val = readl(my_status);
54         CPU B:  ...
55         CPU B:  writel(newval2, ring_ptr);
56         CPU B:  (void)readl(safe_register); /* 配置寄存器?*/
57         CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
58
59 在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
60 再处理后面的读操作,防止引发数据不一致问题。