aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apb_timer.c
diff options
context:
space:
mode:
authorJamie Iles <jamie@jamieiles.com>2011-06-06 07:43:07 -0400
committerJohn Stultz <john.stultz@linaro.org>2011-06-27 18:16:21 -0400
commit06c3df49521c1b112b777cc4946e5de057c814ba (patch)
tree34989a358e7554d82dd4e73328f492653ceeac88 /arch/x86/kernel/apb_timer.c
parentaf4087e0e682df12bdffec5cfafc2fec9208716e (diff)
clocksource: apb: Share APB timer code with other platforms
The APB timers are an IP block from Synopsys (DesignWare APB timers) and are also found in other systems including ARM SoC's. This patch adds functions for creating clock_event_devices and clocksources from APB timers but does not do the resource allocation. This is handled in a higher layer to allow the timers to be created from multiple methods such as platform_devices. Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'arch/x86/kernel/apb_timer.c')
-rw-r--r--arch/x86/kernel/apb_timer.c409
1 files changed, 69 insertions, 340 deletions
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
index 289e92862fd9..033d3ecc5744 100644
--- a/arch/x86/kernel/apb_timer.c
+++ b/arch/x86/kernel/apb_timer.c
@@ -27,15 +27,12 @@
27 * timer, but by default APB timer has higher rating than local APIC timers. 27 * timer, but by default APB timer has higher rating than local APIC timers.
28 */ 28 */
29 29
30#include <linux/clocksource.h>
31#include <linux/clockchips.h>
32#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/dw_apb_timer.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/init.h> 33#include <linux/init.h>
35#include <linux/sysdev.h>
36#include <linux/slab.h> 34#include <linux/slab.h>
37#include <linux/pm.h> 35#include <linux/pm.h>
38#include <linux/pci.h>
39#include <linux/sfi.h> 36#include <linux/sfi.h>
40#include <linux/interrupt.h> 37#include <linux/interrupt.h>
41#include <linux/cpu.h> 38#include <linux/cpu.h>
@@ -45,75 +42,46 @@
45#include <asm/apb_timer.h> 42#include <asm/apb_timer.h>
46#include <asm/mrst.h> 43#include <asm/mrst.h>
47 44
48#define APBT_MASK CLOCKSOURCE_MASK(32)
49#define APBT_SHIFT 22
50#define APBT_CLOCKEVENT_RATING 110 45#define APBT_CLOCKEVENT_RATING 110
51#define APBT_CLOCKSOURCE_RATING 250 46#define APBT_CLOCKSOURCE_RATING 250
52#define APBT_MIN_DELTA_USEC 200
53 47
54#define EVT_TO_APBT_DEV(evt) container_of(evt, struct apbt_dev, evt)
55#define APBT_CLOCKEVENT0_NUM (0) 48#define APBT_CLOCKEVENT0_NUM (0)
56#define APBT_CLOCKEVENT1_NUM (1)
57#define APBT_CLOCKSOURCE_NUM (2) 49#define APBT_CLOCKSOURCE_NUM (2)
58 50
59static unsigned long apbt_address; 51static phys_addr_t apbt_address;
60static int apb_timer_block_enabled; 52static int apb_timer_block_enabled;
61static void __iomem *apbt_virt_address; 53static void __iomem *apbt_virt_address;
62static int phy_cs_timer_id;
63 54
64/* 55/*
65 * Common DW APB timer info 56 * Common DW APB timer info
66 */ 57 */
67static uint64_t apbt_freq; 58static unsigned long apbt_freq;
68
69static void apbt_set_mode(enum clock_event_mode mode,
70 struct clock_event_device *evt);
71static int apbt_next_event(unsigned long delta,
72 struct clock_event_device *evt);
73static cycle_t apbt_read_clocksource(struct clocksource *cs);
74static void apbt_restart_clocksource(struct clocksource *cs);
75 59
76struct apbt_dev { 60struct apbt_dev {
77 struct clock_event_device evt; 61 struct dw_apb_clock_event_device *timer;
78 unsigned int num; 62 unsigned int num;
79 int cpu; 63 int cpu;
80 unsigned int irq; 64 unsigned int irq;
81 unsigned int tick; 65 char name[10];
82 unsigned int count;
83 unsigned int flags;
84 char name[10];
85}; 66};
86 67
87static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev); 68static struct dw_apb_clocksource *clocksource_apbt;
88 69
89#ifdef CONFIG_SMP 70static inline void __iomem *adev_virt_addr(struct apbt_dev *adev)
90static unsigned int apbt_num_timers_used;
91static struct apbt_dev *apbt_devs;
92#endif
93
94static inline unsigned long apbt_readl_reg(unsigned long a)
95{ 71{
96 return readl(apbt_virt_address + a); 72 return apbt_virt_address + adev->num * APBTMRS_REG_SIZE;
97} 73}
98 74
99static inline void apbt_writel_reg(unsigned long d, unsigned long a) 75static DEFINE_PER_CPU(struct apbt_dev, cpu_apbt_dev);
100{
101 writel(d, apbt_virt_address + a);
102}
103
104static inline unsigned long apbt_readl(int n, unsigned long a)
105{
106 return readl(apbt_virt_address + a + n * APBTMRS_REG_SIZE);
107}
108 76
109static inline void apbt_writel(int n, unsigned long d, unsigned long a) 77#ifdef CONFIG_SMP
110{ 78static unsigned int apbt_num_timers_used;
111 writel(d, apbt_virt_address + a + n * APBTMRS_REG_SIZE); 79#endif
112}
113 80
114static inline void apbt_set_mapping(void) 81static inline void apbt_set_mapping(void)
115{ 82{
116 struct sfi_timer_table_entry *mtmr; 83 struct sfi_timer_table_entry *mtmr;
84 int phy_cs_timer_id = 0;
117 85
118 if (apbt_virt_address) { 86 if (apbt_virt_address) {
119 pr_debug("APBT base already mapped\n"); 87 pr_debug("APBT base already mapped\n");
@@ -125,21 +93,18 @@ static inline void apbt_set_mapping(void)
125 APBT_CLOCKEVENT0_NUM); 93 APBT_CLOCKEVENT0_NUM);
126 return; 94 return;
127 } 95 }
128 apbt_address = (unsigned long)mtmr->phys_addr; 96 apbt_address = (phys_addr_t)mtmr->phys_addr;
129 if (!apbt_address) { 97 if (!apbt_address) {
130 printk(KERN_WARNING "No timer base from SFI, use default\n"); 98 printk(KERN_WARNING "No timer base from SFI, use default\n");
131 apbt_address = APBT_DEFAULT_BASE; 99 apbt_address = APBT_DEFAULT_BASE;
132 } 100 }
133 apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE); 101 apbt_virt_address = ioremap_nocache(apbt_address, APBT_MMAP_SIZE);
134 if (apbt_virt_address) { 102 if (!apbt_virt_address) {
135 pr_debug("Mapped APBT physical addr %p at virtual addr %p\n",\ 103 pr_debug("Failed mapping APBT phy address at %lu\n",\
136 (void *)apbt_address, (void *)apbt_virt_address); 104 (unsigned long)apbt_address);
137 } else {
138 pr_debug("Failed mapping APBT phy address at %p\n",\
139 (void *)apbt_address);
140 goto panic_noapbt; 105 goto panic_noapbt;
141 } 106 }
142 apbt_freq = mtmr->freq_hz / USEC_PER_SEC; 107 apbt_freq = mtmr->freq_hz;
143 sfi_free_mtmr(mtmr); 108 sfi_free_mtmr(mtmr);
144 109
145 /* Now figure out the physical timer id for clocksource device */ 110 /* Now figure out the physical timer id for clocksource device */
@@ -148,9 +113,14 @@ static inline void apbt_set_mapping(void)
148 goto panic_noapbt; 113 goto panic_noapbt;
149 114
150 /* Now figure out the physical timer id */ 115 /* Now figure out the physical timer id */
151 phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) 116 pr_debug("Use timer %d for clocksource\n",
152 / APBTMRS_REG_SIZE; 117 (int)(mtmr->phys_addr & 0xff) / APBTMRS_REG_SIZE);
153 pr_debug("Use timer %d for clocksource\n", phy_cs_timer_id); 118 phy_cs_timer_id = (unsigned int)(mtmr->phys_addr & 0xff) /
119 APBTMRS_REG_SIZE;
120
121 clocksource_apbt = dw_apb_clocksource_init(APBT_CLOCKSOURCE_RATING,
122 "apbt0", apbt_virt_address + phy_cs_timer_id *
123 APBTMRS_REG_SIZE, apbt_freq);
154 return; 124 return;
155 125
156panic_noapbt: 126panic_noapbt:
@@ -172,82 +142,6 @@ static inline int is_apbt_capable(void)
172 return apbt_virt_address ? 1 : 0; 142 return apbt_virt_address ? 1 : 0;
173} 143}
174 144
175static struct clocksource clocksource_apbt = {
176 .name = "apbt",
177 .rating = APBT_CLOCKSOURCE_RATING,
178 .read = apbt_read_clocksource,
179 .mask = APBT_MASK,
180 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
181 .resume = apbt_restart_clocksource,
182};
183
184/* boot APB clock event device */
185static struct clock_event_device apbt_clockevent = {
186 .name = "apbt0",
187 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
188 .set_mode = apbt_set_mode,
189 .set_next_event = apbt_next_event,
190 .shift = APBT_SHIFT,
191 .irq = 0,
192 .rating = APBT_CLOCKEVENT_RATING,
193};
194
195/*
196 * start count down from 0xffff_ffff. this is done by toggling the enable bit
197 * then load initial load count to ~0.
198 */
199static void apbt_start_counter(int n)
200{
201 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
202
203 ctrl &= ~APBTMR_CONTROL_ENABLE;
204 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
205 apbt_writel(n, ~0, APBTMR_N_LOAD_COUNT);
206 /* enable, mask interrupt */
207 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
208 ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
209 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
210 /* read it once to get cached counter value initialized */
211 apbt_read_clocksource(&clocksource_apbt);
212}
213
214static irqreturn_t apbt_interrupt_handler(int irq, void *data)
215{
216 struct apbt_dev *dev = (struct apbt_dev *)data;
217 struct clock_event_device *aevt = &dev->evt;
218
219 if (!aevt->event_handler) {
220 printk(KERN_INFO "Spurious APBT timer interrupt on %d\n",
221 dev->num);
222 return IRQ_NONE;
223 }
224 aevt->event_handler(aevt);
225 return IRQ_HANDLED;
226}
227
228static void apbt_restart_clocksource(struct clocksource *cs)
229{
230 apbt_start_counter(phy_cs_timer_id);
231}
232
233static void apbt_enable_int(int n)
234{
235 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
236 /* clear pending intr */
237 apbt_readl(n, APBTMR_N_EOI);
238 ctrl &= ~APBTMR_CONTROL_INT;
239 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
240}
241
242static void apbt_disable_int(int n)
243{
244 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
245
246 ctrl |= APBTMR_CONTROL_INT;
247 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
248}
249
250
251static int __init apbt_clockevent_register(void) 145static int __init apbt_clockevent_register(void)
252{ 146{
253 struct sfi_timer_table_entry *mtmr; 147 struct sfi_timer_table_entry *mtmr;
@@ -260,45 +154,21 @@ static int __init apbt_clockevent_register(void)
260 return -ENODEV; 154 return -ENODEV;
261 } 155 }
262 156
263 /*
264 * We need to calculate the scaled math multiplication factor for
265 * nanosecond to apbt tick conversion.
266 * mult = (nsec/cycle)*2^APBT_SHIFT
267 */
268 apbt_clockevent.mult = div_sc((unsigned long) mtmr->freq_hz
269 , NSEC_PER_SEC, APBT_SHIFT);
270
271 /* Calculate the min / max delta */
272 apbt_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
273 &apbt_clockevent);
274 apbt_clockevent.min_delta_ns = clockevent_delta2ns(
275 APBT_MIN_DELTA_USEC*apbt_freq,
276 &apbt_clockevent);
277 /*
278 * Start apbt with the boot cpu mask and make it
279 * global if not used for per cpu timer.
280 */
281 apbt_clockevent.cpumask = cpumask_of(smp_processor_id());
282 adev->num = smp_processor_id(); 157 adev->num = smp_processor_id();
283 memcpy(&adev->evt, &apbt_clockevent, sizeof(struct clock_event_device)); 158 adev->timer = dw_apb_clockevent_init(smp_processor_id(), "apbt0",
159 mrst_timer_options == MRST_TIMER_LAPIC_APBT ?
160 APBT_CLOCKEVENT_RATING - 100 : APBT_CLOCKEVENT_RATING,
161 adev_virt_addr(adev), 0, apbt_freq);
162 /* Firmware does EOI handling for us. */
163 adev->timer->eoi = NULL;
284 164
285 if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) { 165 if (mrst_timer_options == MRST_TIMER_LAPIC_APBT) {
286 adev->evt.rating = APBT_CLOCKEVENT_RATING - 100; 166 global_clock_event = &adev->timer->ced;
287 global_clock_event = &adev->evt;
288 printk(KERN_DEBUG "%s clockevent registered as global\n", 167 printk(KERN_DEBUG "%s clockevent registered as global\n",
289 global_clock_event->name); 168 global_clock_event->name);
290 } 169 }
291 170
292 if (request_irq(apbt_clockevent.irq, apbt_interrupt_handler, 171 dw_apb_clockevent_register(adev->timer);
293 IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
294 apbt_clockevent.name, adev)) {
295 printk(KERN_ERR "Failed request IRQ for APBT%d\n",
296 apbt_clockevent.irq);
297 }
298
299 clockevents_register_device(&adev->evt);
300 /* Start APBT 0 interrupts */
301 apbt_enable_int(APBT_CLOCKEVENT0_NUM);
302 172
303 sfi_free_mtmr(mtmr); 173 sfi_free_mtmr(mtmr);
304 return 0; 174 return 0;
@@ -316,52 +186,34 @@ static void apbt_setup_irq(struct apbt_dev *adev)
316 irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); 186 irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
317 /* APB timer irqs are set up as mp_irqs, timer is edge type */ 187 /* APB timer irqs are set up as mp_irqs, timer is edge type */
318 __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); 188 __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge");
319
320 if (system_state == SYSTEM_BOOTING) {
321 if (request_irq(adev->irq, apbt_interrupt_handler,
322 IRQF_TIMER | IRQF_DISABLED |
323 IRQF_NOBALANCING,
324 adev->name, adev)) {
325 printk(KERN_ERR "Failed request IRQ for APBT%d\n",
326 adev->num);
327 }
328 } else
329 enable_irq(adev->irq);
330} 189}
331 190
332/* Should be called with per cpu */ 191/* Should be called with per cpu */
333void apbt_setup_secondary_clock(void) 192void apbt_setup_secondary_clock(void)
334{ 193{
335 struct apbt_dev *adev; 194 struct apbt_dev *adev;
336 struct clock_event_device *aevt;
337 int cpu; 195 int cpu;
338 196
339 /* Don't register boot CPU clockevent */ 197 /* Don't register boot CPU clockevent */
340 cpu = smp_processor_id(); 198 cpu = smp_processor_id();
341 if (!cpu) 199 if (!cpu)
342 return; 200 return;
343 /*
344 * We need to calculate the scaled math multiplication factor for
345 * nanosecond to apbt tick conversion.
346 * mult = (nsec/cycle)*2^APBT_SHIFT
347 */
348 printk(KERN_INFO "Init per CPU clockevent %d\n", cpu);
349 adev = &per_cpu(cpu_apbt_dev, cpu);
350 aevt = &adev->evt;
351 201
352 memcpy(aevt, &apbt_clockevent, sizeof(*aevt)); 202 adev = &__get_cpu_var(cpu_apbt_dev);
353 aevt->cpumask = cpumask_of(cpu); 203 if (!adev->timer) {
354 aevt->name = adev->name; 204 adev->timer = dw_apb_clockevent_init(cpu, adev->name,
355 aevt->mode = CLOCK_EVT_MODE_UNUSED; 205 APBT_CLOCKEVENT_RATING, adev_virt_addr(adev),
206 adev->irq, apbt_freq);
207 adev->timer->eoi = NULL;
208 } else {
209 dw_apb_clockevent_resume(adev->timer);
210 }
356 211
357 printk(KERN_INFO "Registering CPU %d clockevent device %s, mask %08x\n", 212 printk(KERN_INFO "Registering CPU %d clockevent device %s, cpu %08x\n",
358 cpu, aevt->name, *(u32 *)aevt->cpumask); 213 cpu, adev->name, adev->cpu);
359 214
360 apbt_setup_irq(adev); 215 apbt_setup_irq(adev);
361 216 dw_apb_clockevent_register(adev->timer);
362 clockevents_register_device(aevt);
363
364 apbt_enable_int(cpu);
365 217
366 return; 218 return;
367} 219}
@@ -384,13 +236,12 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
384 236
385 switch (action & 0xf) { 237 switch (action & 0xf) {
386 case CPU_DEAD: 238 case CPU_DEAD:
387 disable_irq(adev->irq); 239 dw_apb_clockevent_pause(adev->timer);
388 apbt_disable_int(cpu);
389 if (system_state == SYSTEM_RUNNING) { 240 if (system_state == SYSTEM_RUNNING) {
390 pr_debug("skipping APBT CPU %lu offline\n", cpu); 241 pr_debug("skipping APBT CPU %lu offline\n", cpu);
391 } else if (adev) { 242 } else if (adev) {
392 pr_debug("APBT clockevent for cpu %lu offline\n", cpu); 243 pr_debug("APBT clockevent for cpu %lu offline\n", cpu);
393 free_irq(adev->irq, adev); 244 dw_apb_clockevent_stop(adev->timer);
394 } 245 }
395 break; 246 break;
396 default: 247 default:
@@ -415,116 +266,16 @@ void apbt_setup_secondary_clock(void) {}
415 266
416#endif /* CONFIG_SMP */ 267#endif /* CONFIG_SMP */
417 268
418static void apbt_set_mode(enum clock_event_mode mode,
419 struct clock_event_device *evt)
420{
421 unsigned long ctrl;
422 uint64_t delta;
423 int timer_num;
424 struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
425
426 BUG_ON(!apbt_virt_address);
427
428 timer_num = adev->num;
429 pr_debug("%s CPU %d timer %d mode=%d\n",
430 __func__, first_cpu(*evt->cpumask), timer_num, mode);
431
432 switch (mode) {
433 case CLOCK_EVT_MODE_PERIODIC:
434 delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * apbt_clockevent.mult;
435 delta >>= apbt_clockevent.shift;
436 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
437 ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
438 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
439 /*
440 * DW APB p. 46, have to disable timer before load counter,
441 * may cause sync problem.
442 */
443 ctrl &= ~APBTMR_CONTROL_ENABLE;
444 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
445 udelay(1);
446 pr_debug("Setting clock period %d for HZ %d\n", (int)delta, HZ);
447 apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
448 ctrl |= APBTMR_CONTROL_ENABLE;
449 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
450 break;
451 /* APB timer does not have one-shot mode, use free running mode */
452 case CLOCK_EVT_MODE_ONESHOT:
453 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
454 /*
455 * set free running mode, this mode will let timer reload max
456 * timeout which will give time (3min on 25MHz clock) to rearm
457 * the next event, therefore emulate the one-shot mode.
458 */
459 ctrl &= ~APBTMR_CONTROL_ENABLE;
460 ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
461
462 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
463 /* write again to set free running mode */
464 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
465
466 /*
467 * DW APB p. 46, load counter with all 1s before starting free
468 * running mode.
469 */
470 apbt_writel(timer_num, ~0, APBTMR_N_LOAD_COUNT);
471 ctrl &= ~APBTMR_CONTROL_INT;
472 ctrl |= APBTMR_CONTROL_ENABLE;
473 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
474 break;
475
476 case CLOCK_EVT_MODE_UNUSED:
477 case CLOCK_EVT_MODE_SHUTDOWN:
478 apbt_disable_int(timer_num);
479 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
480 ctrl &= ~APBTMR_CONTROL_ENABLE;
481 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
482 break;
483
484 case CLOCK_EVT_MODE_RESUME:
485 apbt_enable_int(timer_num);
486 break;
487 }
488}
489
490static int apbt_next_event(unsigned long delta,
491 struct clock_event_device *evt)
492{
493 unsigned long ctrl;
494 int timer_num;
495
496 struct apbt_dev *adev = EVT_TO_APBT_DEV(evt);
497
498 timer_num = adev->num;
499 /* Disable timer */
500 ctrl = apbt_readl(timer_num, APBTMR_N_CONTROL);
501 ctrl &= ~APBTMR_CONTROL_ENABLE;
502 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
503 /* write new count */
504 apbt_writel(timer_num, delta, APBTMR_N_LOAD_COUNT);
505 ctrl |= APBTMR_CONTROL_ENABLE;
506 apbt_writel(timer_num, ctrl, APBTMR_N_CONTROL);
507 return 0;
508}
509
510static cycle_t apbt_read_clocksource(struct clocksource *cs)
511{
512 unsigned long current_count;
513
514 current_count = apbt_readl(phy_cs_timer_id, APBTMR_N_CURRENT_VALUE);
515 return (cycle_t)~current_count;
516}
517
518static int apbt_clocksource_register(void) 269static int apbt_clocksource_register(void)
519{ 270{
520 u64 start, now; 271 u64 start, now;
521 cycle_t t1; 272 cycle_t t1;
522 273
523 /* Start the counter, use timer 2 as source, timer 0/1 for event */ 274 /* Start the counter, use timer 2 as source, timer 0/1 for event */
524 apbt_start_counter(phy_cs_timer_id); 275 dw_apb_clocksource_start(clocksource_apbt);
525 276
526 /* Verify whether apbt counter works */ 277 /* Verify whether apbt counter works */
527 t1 = apbt_read_clocksource(&clocksource_apbt); 278 t1 = dw_apb_clocksource_read(clocksource_apbt);
528 rdtscll(start); 279 rdtscll(start);
529 280
530 /* 281 /*
@@ -539,10 +290,10 @@ static int apbt_clocksource_register(void)
539 } while ((now - start) < 200000UL); 290 } while ((now - start) < 200000UL);
540 291
541 /* APBT is the only always on clocksource, it has to work! */ 292 /* APBT is the only always on clocksource, it has to work! */
542 if (t1 == apbt_read_clocksource(&clocksource_apbt)) 293 if (t1 == dw_apb_clocksource_read(clocksource_apbt))
543 panic("APBT counter not counting. APBT disabled\n"); 294 panic("APBT counter not counting. APBT disabled\n");
544 295
545 clocksource_register_khz(&clocksource_apbt, (u32)apbt_freq*1000); 296 dw_apb_clocksource_register(clocksource_apbt);
546 297
547 return 0; 298 return 0;
548} 299}
@@ -566,10 +317,7 @@ void __init apbt_time_init(void)
566 if (apb_timer_block_enabled) 317 if (apb_timer_block_enabled)
567 return; 318 return;
568 apbt_set_mapping(); 319 apbt_set_mapping();
569 if (apbt_virt_address) { 320 if (!apbt_virt_address)
570 pr_debug("Found APBT version 0x%lx\n",\
571 apbt_readl_reg(APBTMRS_COMP_VERSION));
572 } else
573 goto out_noapbt; 321 goto out_noapbt;
574 /* 322 /*
575 * Read the frequency and check for a sane value, for ESL model 323 * Read the frequency and check for a sane value, for ESL model
@@ -577,7 +325,7 @@ void __init apbt_time_init(void)
577 */ 325 */
578 326
579 if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) { 327 if (apbt_freq < APBT_MIN_FREQ || apbt_freq > APBT_MAX_FREQ) {
580 pr_debug("APBT has invalid freq 0x%llx\n", apbt_freq); 328 pr_debug("APBT has invalid freq 0x%lx\n", apbt_freq);
581 goto out_noapbt; 329 goto out_noapbt;
582 } 330 }
583 if (apbt_clocksource_register()) { 331 if (apbt_clocksource_register()) {
@@ -603,30 +351,20 @@ void __init apbt_time_init(void)
603 } else { 351 } else {
604 percpu_timer = 0; 352 percpu_timer = 0;
605 apbt_num_timers_used = 1; 353 apbt_num_timers_used = 1;
606 adev = &per_cpu(cpu_apbt_dev, 0);
607 adev->flags &= ~APBT_DEV_USED;
608 } 354 }
609 pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used); 355 pr_debug("%s: %d APB timers used\n", __func__, apbt_num_timers_used);
610 356
611 /* here we set up per CPU timer data structure */ 357 /* here we set up per CPU timer data structure */
612 apbt_devs = kzalloc(sizeof(struct apbt_dev) * apbt_num_timers_used,
613 GFP_KERNEL);
614 if (!apbt_devs) {
615 printk(KERN_ERR "Failed to allocate APB timer devices\n");
616 return;
617 }
618 for (i = 0; i < apbt_num_timers_used; i++) { 358 for (i = 0; i < apbt_num_timers_used; i++) {
619 adev = &per_cpu(cpu_apbt_dev, i); 359 adev = &per_cpu(cpu_apbt_dev, i);
620 adev->num = i; 360 adev->num = i;
621 adev->cpu = i; 361 adev->cpu = i;
622 p_mtmr = sfi_get_mtmr(i); 362 p_mtmr = sfi_get_mtmr(i);
623 if (p_mtmr) { 363 if (p_mtmr)
624 adev->tick = p_mtmr->freq_hz;
625 adev->irq = p_mtmr->irq; 364 adev->irq = p_mtmr->irq;
626 } else 365 else
627 printk(KERN_ERR "Failed to get timer for cpu %d\n", i); 366 printk(KERN_ERR "Failed to get timer for cpu %d\n", i);
628 adev->count = 0; 367 snprintf(adev->name, sizeof(adev->name) - 1, "apbt%d", i);
629 sprintf(adev->name, "apbt%d", i);
630 } 368 }
631#endif 369#endif
632 370
@@ -638,17 +376,8 @@ out_noapbt:
638 panic("failed to enable APB timer\n"); 376 panic("failed to enable APB timer\n");
639} 377}
640 378
641static inline void apbt_disable(int n)
642{
643 if (is_apbt_capable()) {
644 unsigned long ctrl = apbt_readl(n, APBTMR_N_CONTROL);
645 ctrl &= ~APBTMR_CONTROL_ENABLE;
646 apbt_writel(n, ctrl, APBTMR_N_CONTROL);
647 }
648}
649
650/* called before apb_timer_enable, use early map */ 379/* called before apb_timer_enable, use early map */
651unsigned long apbt_quick_calibrate() 380unsigned long apbt_quick_calibrate(void)
652{ 381{
653 int i, scale; 382 int i, scale;
654 u64 old, new; 383 u64 old, new;
@@ -657,31 +386,31 @@ unsigned long apbt_quick_calibrate()
657 u32 loop, shift; 386 u32 loop, shift;
658 387
659 apbt_set_mapping(); 388 apbt_set_mapping();
660 apbt_start_counter(phy_cs_timer_id); 389 dw_apb_clocksource_start(clocksource_apbt);
661 390
662 /* check if the timer can count down, otherwise return */ 391 /* check if the timer can count down, otherwise return */
663 old = apbt_read_clocksource(&clocksource_apbt); 392 old = dw_apb_clocksource_read(clocksource_apbt);
664 i = 10000; 393 i = 10000;
665 while (--i) { 394 while (--i) {
666 if (old != apbt_read_clocksource(&clocksource_apbt)) 395 if (old != dw_apb_clocksource_read(clocksource_apbt))
667 break; 396 break;
668 } 397 }
669 if (!i) 398 if (!i)
670 goto failed; 399 goto failed;
671 400
672 /* count 16 ms */ 401 /* count 16 ms */
673 loop = (apbt_freq * 1000) << 4; 402 loop = (apbt_freq / 1000) << 4;
674 403
675 /* restart the timer to ensure it won't get to 0 in the calibration */ 404 /* restart the timer to ensure it won't get to 0 in the calibration */
676 apbt_start_counter(phy_cs_timer_id); 405 dw_apb_clocksource_start(clocksource_apbt);
677 406
678 old = apbt_read_clocksource(&clocksource_apbt); 407 old = dw_apb_clocksource_read(clocksource_apbt);
679 old += loop; 408 old += loop;
680 409
681 t1 = __native_read_tsc(); 410 t1 = __native_read_tsc();
682 411
683 do { 412 do {
684 new = apbt_read_clocksource(&clocksource_apbt); 413 new = dw_apb_clocksource_read(clocksource_apbt);
685 } while (new < old); 414 } while (new < old);
686 415
687 t2 = __native_read_tsc(); 416 t2 = __native_read_tsc();
@@ -693,7 +422,7 @@ unsigned long apbt_quick_calibrate()
693 return 0; 422 return 0;
694 } 423 }
695 scale = (int)div_u64((t2 - t1), loop >> shift); 424 scale = (int)div_u64((t2 - t1), loop >> shift);
696 khz = (scale * apbt_freq * 1000) >> shift; 425 khz = (scale * (apbt_freq / 1000)) >> shift;
697 printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz); 426 printk(KERN_INFO "TSC freq calculated by APB timer is %lu khz\n", khz);
698 return khz; 427 return khz;
699failed: 428failed: