diff options
Diffstat (limited to 'drivers/clocksource/arm_arch_timer.c')
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 7624ba574144..a9ca28447b49 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -43,14 +43,28 @@ static bool arch_timer_use_virtual = true; | |||
43 | * Architected system timer support. | 43 | * Architected system timer support. |
44 | */ | 44 | */ |
45 | 45 | ||
46 | static __always_inline | ||
47 | void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, | ||
48 | struct clock_event_device *clk) | ||
49 | { | ||
50 | arch_timer_reg_write_cp15(access, reg, val); | ||
51 | } | ||
52 | |||
53 | static __always_inline | ||
54 | u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, | ||
55 | struct clock_event_device *clk) | ||
56 | { | ||
57 | return arch_timer_reg_read_cp15(access, reg); | ||
58 | } | ||
59 | |||
46 | static __always_inline irqreturn_t timer_handler(const int access, | 60 | static __always_inline irqreturn_t timer_handler(const int access, |
47 | struct clock_event_device *evt) | 61 | struct clock_event_device *evt) |
48 | { | 62 | { |
49 | unsigned long ctrl; | 63 | unsigned long ctrl; |
50 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 64 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, evt); |
51 | if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { | 65 | if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { |
52 | ctrl |= ARCH_TIMER_CTRL_IT_MASK; | 66 | ctrl |= ARCH_TIMER_CTRL_IT_MASK; |
53 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 67 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, evt); |
54 | evt->event_handler(evt); | 68 | evt->event_handler(evt); |
55 | return IRQ_HANDLED; | 69 | return IRQ_HANDLED; |
56 | } | 70 | } |
@@ -72,15 +86,16 @@ static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id) | |||
72 | return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt); | 86 | return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt); |
73 | } | 87 | } |
74 | 88 | ||
75 | static __always_inline void timer_set_mode(const int access, int mode) | 89 | static __always_inline void timer_set_mode(const int access, int mode, |
90 | struct clock_event_device *clk) | ||
76 | { | 91 | { |
77 | unsigned long ctrl; | 92 | unsigned long ctrl; |
78 | switch (mode) { | 93 | switch (mode) { |
79 | case CLOCK_EVT_MODE_UNUSED: | 94 | case CLOCK_EVT_MODE_UNUSED: |
80 | case CLOCK_EVT_MODE_SHUTDOWN: | 95 | case CLOCK_EVT_MODE_SHUTDOWN: |
81 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 96 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); |
82 | ctrl &= ~ARCH_TIMER_CTRL_ENABLE; | 97 | ctrl &= ~ARCH_TIMER_CTRL_ENABLE; |
83 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 98 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); |
84 | break; | 99 | break; |
85 | default: | 100 | default: |
86 | break; | 101 | break; |
@@ -90,36 +105,37 @@ static __always_inline void timer_set_mode(const int access, int mode) | |||
90 | static void arch_timer_set_mode_virt(enum clock_event_mode mode, | 105 | static void arch_timer_set_mode_virt(enum clock_event_mode mode, |
91 | struct clock_event_device *clk) | 106 | struct clock_event_device *clk) |
92 | { | 107 | { |
93 | timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode); | 108 | timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode, clk); |
94 | } | 109 | } |
95 | 110 | ||
96 | static void arch_timer_set_mode_phys(enum clock_event_mode mode, | 111 | static void arch_timer_set_mode_phys(enum clock_event_mode mode, |
97 | struct clock_event_device *clk) | 112 | struct clock_event_device *clk) |
98 | { | 113 | { |
99 | timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode); | 114 | timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode, clk); |
100 | } | 115 | } |
101 | 116 | ||
102 | static __always_inline void set_next_event(const int access, unsigned long evt) | 117 | static __always_inline void set_next_event(const int access, unsigned long evt, |
118 | struct clock_event_device *clk) | ||
103 | { | 119 | { |
104 | unsigned long ctrl; | 120 | unsigned long ctrl; |
105 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 121 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); |
106 | ctrl |= ARCH_TIMER_CTRL_ENABLE; | 122 | ctrl |= ARCH_TIMER_CTRL_ENABLE; |
107 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; | 123 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; |
108 | arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt); | 124 | arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); |
109 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 125 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); |
110 | } | 126 | } |
111 | 127 | ||
112 | static int arch_timer_set_next_event_virt(unsigned long evt, | 128 | static int arch_timer_set_next_event_virt(unsigned long evt, |
113 | struct clock_event_device *unused) | 129 | struct clock_event_device *clk) |
114 | { | 130 | { |
115 | set_next_event(ARCH_TIMER_VIRT_ACCESS, evt); | 131 | set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk); |
116 | return 0; | 132 | return 0; |
117 | } | 133 | } |
118 | 134 | ||
119 | static int arch_timer_set_next_event_phys(unsigned long evt, | 135 | static int arch_timer_set_next_event_phys(unsigned long evt, |
120 | struct clock_event_device *unused) | 136 | struct clock_event_device *clk) |
121 | { | 137 | { |
122 | set_next_event(ARCH_TIMER_PHYS_ACCESS, evt); | 138 | set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk); |
123 | return 0; | 139 | return 0; |
124 | } | 140 | } |
125 | 141 | ||