diff options
Diffstat (limited to 'drivers/clocksource/timer-prima2.c')
-rw-r--r-- | drivers/clocksource/timer-prima2.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c index 1a6b2d6356d6..a722aac7ac02 100644 --- a/drivers/clocksource/timer-prima2.c +++ b/drivers/clocksource/timer-prima2.c | |||
@@ -61,7 +61,8 @@ static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id) | |||
61 | { | 61 | { |
62 | struct clock_event_device *ce = dev_id; | 62 | struct clock_event_device *ce = dev_id; |
63 | 63 | ||
64 | WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & BIT(0))); | 64 | WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & |
65 | BIT(0))); | ||
65 | 66 | ||
66 | /* clear timer0 interrupt */ | 67 | /* clear timer0 interrupt */ |
67 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); | 68 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); |
@@ -77,9 +78,11 @@ static cycle_t sirfsoc_timer_read(struct clocksource *cs) | |||
77 | u64 cycles; | 78 | u64 cycles; |
78 | 79 | ||
79 | /* latch the 64-bit timer counter */ | 80 | /* latch the 64-bit timer counter */ |
80 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 81 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
82 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
81 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI); | 83 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI); |
82 | cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 84 | cycles = (cycles << 32) | |
85 | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | ||
83 | 86 | ||
84 | return cycles; | 87 | return cycles; |
85 | } | 88 | } |
@@ -89,11 +92,13 @@ static int sirfsoc_timer_set_next_event(unsigned long delta, | |||
89 | { | 92 | { |
90 | unsigned long now, next; | 93 | unsigned long now, next; |
91 | 94 | ||
92 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 95 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
96 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
93 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 97 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); |
94 | next = now + delta; | 98 | next = now + delta; |
95 | writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0); | 99 | writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0); |
96 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 100 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
101 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
97 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 102 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); |
98 | 103 | ||
99 | return next - now > delta ? -ETIME : 0; | 104 | return next - now > delta ? -ETIME : 0; |
@@ -108,10 +113,12 @@ static void sirfsoc_timer_set_mode(enum clock_event_mode mode, | |||
108 | WARN_ON(1); | 113 | WARN_ON(1); |
109 | break; | 114 | break; |
110 | case CLOCK_EVT_MODE_ONESHOT: | 115 | case CLOCK_EVT_MODE_ONESHOT: |
111 | writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | 116 | writel_relaxed(val | BIT(0), |
117 | sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | ||
112 | break; | 118 | break; |
113 | case CLOCK_EVT_MODE_SHUTDOWN: | 119 | case CLOCK_EVT_MODE_SHUTDOWN: |
114 | writel_relaxed(val & ~BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | 120 | writel_relaxed(val & ~BIT(0), |
121 | sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | ||
115 | break; | 122 | break; |
116 | case CLOCK_EVT_MODE_UNUSED: | 123 | case CLOCK_EVT_MODE_UNUSED: |
117 | case CLOCK_EVT_MODE_RESUME: | 124 | case CLOCK_EVT_MODE_RESUME: |
@@ -123,10 +130,13 @@ static void sirfsoc_clocksource_suspend(struct clocksource *cs) | |||
123 | { | 130 | { |
124 | int i; | 131 | int i; |
125 | 132 | ||
126 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 133 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
134 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
127 | 135 | ||
128 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | 136 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) |
129 | sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 137 | sirfsoc_timer_reg_val[i] = |
138 | readl_relaxed(sirfsoc_timer_base + | ||
139 | sirfsoc_timer_reg_list[i]); | ||
130 | } | 140 | } |
131 | 141 | ||
132 | static void sirfsoc_clocksource_resume(struct clocksource *cs) | 142 | static void sirfsoc_clocksource_resume(struct clocksource *cs) |
@@ -134,10 +144,13 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) | |||
134 | int i; | 144 | int i; |
135 | 145 | ||
136 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) | 146 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) |
137 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 147 | writel_relaxed(sirfsoc_timer_reg_val[i], |
148 | sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
138 | 149 | ||
139 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 150 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], |
140 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 151 | sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
152 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], | ||
153 | sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | ||
141 | } | 154 | } |
142 | 155 | ||
143 | static struct clock_event_device sirfsoc_clockevent = { | 156 | static struct clock_event_device sirfsoc_clockevent = { |
@@ -185,11 +198,8 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
185 | unsigned long rate; | 198 | unsigned long rate; |
186 | struct clk *clk; | 199 | struct clk *clk; |
187 | 200 | ||
188 | /* timer's input clock is io clock */ | 201 | clk = of_clk_get(np, 0); |
189 | clk = clk_get_sys("io", NULL); | ||
190 | |||
191 | BUG_ON(IS_ERR(clk)); | 202 | BUG_ON(IS_ERR(clk)); |
192 | |||
193 | rate = clk_get_rate(clk); | 203 | rate = clk_get_rate(clk); |
194 | 204 | ||
195 | BUG_ON(rate < PRIMA2_CLOCK_FREQ); | 205 | BUG_ON(rate < PRIMA2_CLOCK_FREQ); |
@@ -202,7 +212,7 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
202 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | 212 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); |
203 | 213 | ||
204 | writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1, | 214 | writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1, |
205 | sirfsoc_timer_base + SIRFSOC_TIMER_DIV); | 215 | sirfsoc_timer_base + SIRFSOC_TIMER_DIV); |
206 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 216 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
207 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 217 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
208 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); | 218 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); |
@@ -216,4 +226,5 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
216 | 226 | ||
217 | sirfsoc_clockevent_init(); | 227 | sirfsoc_clockevent_init(); |
218 | } | 228 | } |
219 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, "sirf,prima2-tick", sirfsoc_prima2_timer_init); | 229 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, |
230 | "sirf,prima2-tick", sirfsoc_prima2_timer_init); | ||