为什么程序在Xilinx定时器驱动程序中对只读定时器中断状态寄存器执行写访问

时间:2013-12-08 12:29:44

标签: c linux timer arm xilinx

在Xilinx板的Linux Kernel versioin 3.2.52中,

https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/arch/arm/mach-zynq/timer.c?id=refs/tags/v3.2.53

在计时器驱动程序中存在针对只读寄存器的写入过程。 在第123行中,为什么这个函数对只读寄存器(XTTCPSS_ISR_OFFSET)执行写访问?

static irqreturn_t xttcpss_clock_event_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = &xttcpss_clockevent;
struct xttcpss_timer *timer = dev_id;

/* Acknowledge the interrupt and call event handler */
__raw_writel(__raw_readl(timer->base_addr + XTTCPSS_ISR_OFFSET), <--- this
        timer->base_addr + XTTCPSS_ISR_OFFSET);

evt->event_handler(evt);

XTTCPSS_ISR_OFFSET在L.63中定义。

#define XTTCPSS_ISR_OFFSET      0x54 /* Interrupt Status Reg, RO */

这是一种特殊的技术吗?

1 个答案:

答案 0 :(得分:1)

大约一年前已经删除了这个补丁,它告诉你写的原因:

Refs: v3.8-rc3-47-gaf7f032
Author:     Soren Brinkmann <soren.brinkmann@xilinx.com>
AuthorDate: Wed Dec 19 10:18:37 2012 -0800
Commit:     Michal Simek <michal.simek@xilinx.com>
CommitDate: Mon Jan 28 13:27:21 2013 +0100

    arm: zynq: timer: Remove unnecessary register write

    Acknowedging an interrupt requires to read the interrupt register
    only. The write was only required to work around a bug in
    the QEMU implementation of the TTC, which is fixed.

    Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
    Acked-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
    Tested-by: Josh Cartwright <josh.cartwright@ni.com>
---
 arch/arm/mach-zynq/timer.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
index 570491d..f1d224b 100644
--- a/arch/arm/mach-zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -121,8 +121,7 @@ static irqreturn_t xttcps_clock_event_interrupt(int irq, void *dev_id)
        struct xttcps_timer *timer = &xttce->xttc;

        /* Acknowledge the interrupt and call event handler */
-       __raw_writel(__raw_readl(timer->base_addr + XTTCPS_ISR_OFFSET),
-                       timer->base_addr + XTTCPS_ISR_OFFSET);
+       __raw_readl(timer->base_addr + XTTCPS_ISR_OFFSET);

        xttce->ce.event_handler(&xttce->ce);