diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 19:53:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 19:53:11 -0400 |
| commit | e0e170bd7ded2ec16e2813d63c0faff43193fde8 (patch) | |
| tree | 2f06008b61ef2eedf8f77d1326e286a64e426ef6 /arch/microblaze/kernel/timer.c | |
| parent | b20f9e5bddddb5ef0d743d6e0d409ffc8cf9fc56 (diff) | |
| parent | b843e4ec01991a386a9e0e9030703524446e03da (diff) | |
Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze
* 'next' of git://git.monstr.eu/linux-2.6-microblaze: (42 commits)
microblaze: Fix build with make 3.82
fbdev/xilinxfb: Microblaze driver support
microblaze: Support C optimized lib functions for little-endian
microblaze: Separate library optimized functions
microblaze: Support timer on AXI lite
microblaze: Add support for little-endian Microblaze
microblaze: KGDB little endian support
microblaze: Add PVR for endians plus detection
net: emaclite: Add support for little-endian platforms
microblaze: trivial: Add comment for AXI pvr
microblaze: pci-common cleanup
microblaze: Support early console on uart16550
microblaze: Do not compile early console support for uartlite if is disabled
microblaze: Setup early console dynamically
microblaze: Rename all uartlite early printk functions
microblaze: remove early printk uarlite console dependency from header
microblaze: Remove additional compatible properties
microblaze: Remove hardcoded asm instraction for PVR loading
microblaze: Use static const char * const where possible
microblaze: Define VMALLOC_START/END
...
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
| -rw-r--r-- | arch/microblaze/kernel/timer.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b1380ae93ae1..a5aa33db1df3 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c | |||
| @@ -38,6 +38,9 @@ static unsigned int timer_baseaddr; | |||
| 38 | #define TIMER_BASE timer_baseaddr | 38 | #define TIMER_BASE timer_baseaddr |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | unsigned int freq_div_hz; | ||
| 42 | unsigned int timer_clock_freq; | ||
| 43 | |||
| 41 | #define TCSR0 (0x00) | 44 | #define TCSR0 (0x00) |
| 42 | #define TLR0 (0x04) | 45 | #define TLR0 (0x04) |
| 43 | #define TCR0 (0x08) | 46 | #define TCR0 (0x08) |
| @@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode, | |||
| 115 | switch (mode) { | 118 | switch (mode) { |
| 116 | case CLOCK_EVT_MODE_PERIODIC: | 119 | case CLOCK_EVT_MODE_PERIODIC: |
| 117 | printk(KERN_INFO "%s: periodic\n", __func__); | 120 | printk(KERN_INFO "%s: periodic\n", __func__); |
| 118 | microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); | 121 | microblaze_timer0_start_periodic(freq_div_hz); |
| 119 | break; | 122 | break; |
| 120 | case CLOCK_EVT_MODE_ONESHOT: | 123 | case CLOCK_EVT_MODE_ONESHOT: |
| 121 | printk(KERN_INFO "%s: oneshot\n", __func__); | 124 | printk(KERN_INFO "%s: oneshot\n", __func__); |
| @@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = { | |||
| 168 | static __init void microblaze_clockevent_init(void) | 171 | static __init void microblaze_clockevent_init(void) |
| 169 | { | 172 | { |
| 170 | clockevent_microblaze_timer.mult = | 173 | clockevent_microblaze_timer.mult = |
| 171 | div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, | 174 | div_sc(timer_clock_freq, NSEC_PER_SEC, |
| 172 | clockevent_microblaze_timer.shift); | 175 | clockevent_microblaze_timer.shift); |
| 173 | clockevent_microblaze_timer.max_delta_ns = | 176 | clockevent_microblaze_timer.max_delta_ns = |
| 174 | clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); | 177 | clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); |
| @@ -201,7 +204,7 @@ static struct cyclecounter microblaze_cc = { | |||
| 201 | 204 | ||
| 202 | int __init init_microblaze_timecounter(void) | 205 | int __init init_microblaze_timecounter(void) |
| 203 | { | 206 | { |
| 204 | microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, | 207 | microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, |
| 205 | microblaze_cc.shift); | 208 | microblaze_cc.shift); |
| 206 | 209 | ||
| 207 | timecounter_init(µblaze_tc, µblaze_cc, sched_clock()); | 210 | timecounter_init(µblaze_tc, µblaze_cc, sched_clock()); |
| @@ -221,7 +224,7 @@ static struct clocksource clocksource_microblaze = { | |||
| 221 | static int __init microblaze_clocksource_init(void) | 224 | static int __init microblaze_clocksource_init(void) |
| 222 | { | 225 | { |
| 223 | clocksource_microblaze.mult = | 226 | clocksource_microblaze.mult = |
| 224 | clocksource_hz2mult(cpuinfo.cpu_clock_freq, | 227 | clocksource_hz2mult(timer_clock_freq, |
| 225 | clocksource_microblaze.shift); | 228 | clocksource_microblaze.shift); |
| 226 | if (clocksource_register(&clocksource_microblaze)) | 229 | if (clocksource_register(&clocksource_microblaze)) |
| 227 | panic("failed to register clocksource"); | 230 | panic("failed to register clocksource"); |
| @@ -247,6 +250,7 @@ void __init time_init(void) | |||
| 247 | u32 irq, i = 0; | 250 | u32 irq, i = 0; |
| 248 | u32 timer_num = 1; | 251 | u32 timer_num = 1; |
| 249 | struct device_node *timer = NULL; | 252 | struct device_node *timer = NULL; |
| 253 | const void *prop; | ||
| 250 | #ifdef CONFIG_SELFMOD_TIMER | 254 | #ifdef CONFIG_SELFMOD_TIMER |
| 251 | unsigned int timer_baseaddr = 0; | 255 | unsigned int timer_baseaddr = 0; |
| 252 | int arr_func[] = { | 256 | int arr_func[] = { |
| @@ -258,12 +262,10 @@ void __init time_init(void) | |||
| 258 | 0 | 262 | 0 |
| 259 | }; | 263 | }; |
| 260 | #endif | 264 | #endif |
| 261 | char *timer_list[] = { | 265 | const char * const timer_list[] = { |
| 262 | "xlnx,xps-timer-1.00.a", | 266 | "xlnx,xps-timer-1.00.a", |
| 263 | "xlnx,opb-timer-1.00.b", | 267 | NULL |
| 264 | "xlnx,opb-timer-1.00.a", | 268 | }; |
| 265 | NULL | ||
| 266 | }; | ||
| 267 | 269 | ||
| 268 | for (i = 0; timer_list[i] != NULL; i++) { | 270 | for (i = 0; timer_list[i] != NULL; i++) { |
| 269 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); | 271 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); |
| @@ -272,13 +274,13 @@ void __init time_init(void) | |||
| 272 | } | 274 | } |
| 273 | BUG_ON(!timer); | 275 | BUG_ON(!timer); |
| 274 | 276 | ||
| 275 | timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); | 277 | timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL)); |
| 276 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); | 278 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); |
| 277 | irq = *(int *) of_get_property(timer, "interrupts", NULL); | 279 | irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL)); |
| 278 | timer_num = | 280 | timer_num = be32_to_cpup(of_get_property(timer, |
| 279 | *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); | 281 | "xlnx,one-timer-only", NULL)); |
| 280 | if (timer_num) { | 282 | if (timer_num) { |
| 281 | printk(KERN_EMERG "Please enable two timers in HW\n"); | 283 | eprintk(KERN_EMERG "Please enable two timers in HW\n"); |
| 282 | BUG(); | 284 | BUG(); |
| 283 | } | 285 | } |
| 284 | 286 | ||
| @@ -288,7 +290,14 @@ void __init time_init(void) | |||
| 288 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", | 290 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", |
| 289 | timer_list[i], timer_baseaddr, irq); | 291 | timer_list[i], timer_baseaddr, irq); |
| 290 | 292 | ||
| 291 | cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; | 293 | /* If there is clock-frequency property than use it */ |
| 294 | prop = of_get_property(timer, "clock-frequency", NULL); | ||
| 295 | if (prop) | ||
| 296 | timer_clock_freq = be32_to_cpup(prop); | ||
| 297 | else | ||
| 298 | timer_clock_freq = cpuinfo.cpu_clock_freq; | ||
| 299 | |||
| 300 | freq_div_hz = timer_clock_freq / HZ; | ||
| 292 | 301 | ||
| 293 | setup_irq(irq, &timer_irqaction); | 302 | setup_irq(irq, &timer_irqaction); |
| 294 | #ifdef CONFIG_HEART_BEAT | 303 | #ifdef CONFIG_HEART_BEAT |
