Linux|__raw_writel, writel_relaxed 和 writel的区别

因为对别的平台不了解,下面仅谈它们在ARM上的区别


__raw_writel: 因为有volatile关键字, 所以编译器不会打乱多个__raw_writel的执行顺序。
对于ARM而言,当多个写以代码的顺序到达相同设备时,执行的顺序也是被保证的,不过
对于不同的设备,执行的顺序就不被保证了。


write_relaxed: 在ARM平台上与__raw_writel一样,因为与__raw_writel相比,它只多做
了一个大端到小端转换。


writel: 当CONFIG_ARM_DMA_MEM_BUFFERABLE被定义时,在写之前,它会多做
一个DSB和L2的sync。 为什么需要这样呢? 因为,DMA buffer都是 bufferable了,
(详见加入CONFIG_ARM_DMA_MEM_BUFFERABLE的commit log)

在DMA进行之前要保证write buffer里的数据都到memory里。
所以说: 只有在有DMA操作的代码里,writel才是必须的,其实它是一个
当DMA buffer变成bufferable之后的一个补充品。因为要保证DMA buffer里的
内容在DMA开始之前都到memory里,所以开始DMA的指令(writel)里加了
sync memory的指令。


其实: writel也不能保证写的东西一定完成,它只能保证写的指令或写的内容
已经到了设备端,但具体有没有写完成是不知道的。如果有一定要设备端
【Linux|__raw_writel, writel_relaxed 和 writel的区别】写完成才能做下面的指令的要求,最好再用readl把它读回来。


    推荐阅读