diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-10-25 03:19:59 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-10-25 03:19:59 -0400 |
commit | bdf4e9482360a3ddc1619efbd5d1c928ede8c3fa (patch) | |
tree | b02319e809c5b8abfca85409a11472775e27f597 /arch/arm/mach-integrator | |
parent | 06afb1a087d49ae0f676b2e5b9ffe5f4b3aba355 (diff) | |
parent | eb0474544bc16a9dab53b26abd846e86ba814eb1 (diff) |
Merge branch 'misc' into for-linus
Conflicts:
arch/arm/mach-integrator/integrator_ap.c
Diffstat (limited to 'arch/arm/mach-integrator')
-rw-r--r-- | arch/arm/mach-integrator/Makefile.boot | 2 | ||||
-rw-r--r-- | arch/arm/mach-integrator/core.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-integrator/include/mach/platform.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-integrator/integrator_ap.c | 86 |
4 files changed, 51 insertions, 53 deletions
diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot index c7e75acfe6c9..ff0a4b5b0a82 100644 --- a/arch/arm/mach-integrator/Makefile.boot +++ b/arch/arm/mach-integrator/Makefile.boot | |||
@@ -1,4 +1,4 @@ | |||
1 | zreladdr-y := 0x00008000 | 1 | zreladdr-y += 0x00008000 |
2 | params_phys-y := 0x00000100 | 2 | params_phys-y := 0x00000100 |
3 | initrd_phys-y := 0x00800000 | 3 | initrd_phys-y := 0x00800000 |
4 | 4 | ||
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 77315b995681..82ebc8d772d3 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -126,6 +126,10 @@ static struct clk_lookup lookups[] = { | |||
126 | { /* Bus clock */ | 126 | { /* Bus clock */ |
127 | .con_id = "apb_pclk", | 127 | .con_id = "apb_pclk", |
128 | .clk = &dummy_apb_pclk, | 128 | .clk = &dummy_apb_pclk, |
129 | }, { | ||
130 | /* Integrator/AP timer frequency */ | ||
131 | .dev_id = "ap_timer", | ||
132 | .clk = &clk24mhz, | ||
129 | }, { /* UART0 */ | 133 | }, { /* UART0 */ |
130 | .dev_id = "mb:16", | 134 | .dev_id = "mb:16", |
131 | .clk = &uartclk, | 135 | .clk = &uartclk, |
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h index 5e6ea5cfea6e..ec467baade09 100644 --- a/arch/arm/mach-integrator/include/mach/platform.h +++ b/arch/arm/mach-integrator/include/mach/platform.h | |||
@@ -13,9 +13,6 @@ | |||
13 | * along with this program; if not, write to the Free Software | 13 | * along with this program; if not, write to the Free Software |
14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 | */ | 15 | */ |
16 | /* DO NOT EDIT!! - this file automatically generated | ||
17 | * from .s file by awk -f s2h.awk | ||
18 | */ | ||
19 | /************************************************************************** | 16 | /************************************************************************** |
20 | * * Copyright © ARM Limited 1998. All rights reserved. | 17 | * * Copyright © ARM Limited 1998. All rights reserved. |
21 | * ***********************************************************************/ | 18 | * ***********************************************************************/ |
@@ -399,15 +396,6 @@ | |||
399 | #define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100) | 396 | #define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100) |
400 | #define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200) | 397 | #define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200) |
401 | 398 | ||
402 | #define TICKS_PER_uSEC 24 | ||
403 | |||
404 | /* | ||
405 | * These are useconds NOT ticks. | ||
406 | * | ||
407 | */ | ||
408 | #define mSEC_1 1000 | ||
409 | #define mSEC_10 (mSEC_1 * 10) | ||
410 | |||
411 | #define INTEGRATOR_CSR_BASE 0x10000000 | 399 | #define INTEGRATOR_CSR_BASE 0x10000000 |
412 | #define INTEGRATOR_CSR_SIZE 0x10000000 | 400 | #define INTEGRATOR_CSR_SIZE 0x10000000 |
413 | 401 | ||
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 8cdc730dcb3a..f2119908a0b3 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/mtd/physmap.h> | 34 | #include <linux/mtd/physmap.h> |
35 | #include <linux/clk.h> | ||
35 | #include <video/vga.h> | 36 | #include <video/vga.h> |
36 | 37 | ||
37 | #include <mach/hardware.h> | 38 | #include <mach/hardware.h> |
@@ -322,27 +323,16 @@ static void __init ap_init(void) | |||
322 | #define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) | 323 | #define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE) |
323 | #define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) | 324 | #define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE) |
324 | 325 | ||
325 | /* | ||
326 | * How long is the timer interval? | ||
327 | */ | ||
328 | #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) | ||
329 | #if TIMER_INTERVAL >= 0x100000 | ||
330 | #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) | ||
331 | #elif TIMER_INTERVAL >= 0x10000 | ||
332 | #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) | ||
333 | #else | ||
334 | #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) | ||
335 | #endif | ||
336 | |||
337 | static unsigned long timer_reload; | 326 | static unsigned long timer_reload; |
338 | 327 | ||
339 | static void integrator_clocksource_init(u32 khz) | 328 | static void integrator_clocksource_init(unsigned long inrate) |
340 | { | 329 | { |
341 | void __iomem *base = (void __iomem *)TIMER2_VA_BASE; | 330 | void __iomem *base = (void __iomem *)TIMER2_VA_BASE; |
342 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; | 331 | u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; |
332 | unsigned long rate = inrate; | ||
343 | 333 | ||
344 | if (khz >= 1500) { | 334 | if (rate >= 1500000) { |
345 | khz /= 16; | 335 | rate /= 16; |
346 | ctrl |= TIMER_CTRL_DIV16; | 336 | ctrl |= TIMER_CTRL_DIV16; |
347 | } | 337 | } |
348 | 338 | ||
@@ -350,7 +340,7 @@ static void integrator_clocksource_init(u32 khz) | |||
350 | writel(ctrl, base + TIMER_CTRL); | 340 | writel(ctrl, base + TIMER_CTRL); |
351 | 341 | ||
352 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", | 342 | clocksource_mmio_init(base + TIMER_VALUE, "timer2", |
353 | khz * 1000, 200, 16, clocksource_mmio_readl_down); | 343 | rate, 200, 16, clocksource_mmio_readl_down); |
354 | } | 344 | } |
355 | 345 | ||
356 | static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; | 346 | static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; |
@@ -374,15 +364,29 @@ static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_devic | |||
374 | { | 364 | { |
375 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; | 365 | u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; |
376 | 366 | ||
377 | BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT); | 367 | /* Disable timer */ |
368 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
378 | 369 | ||
379 | if (mode == CLOCK_EVT_MODE_PERIODIC) { | 370 | switch (mode) { |
380 | writel(ctrl, clkevt_base + TIMER_CTRL); | 371 | case CLOCK_EVT_MODE_PERIODIC: |
372 | /* Enable the timer and start the periodic tick */ | ||
381 | writel(timer_reload, clkevt_base + TIMER_LOAD); | 373 | writel(timer_reload, clkevt_base + TIMER_LOAD); |
382 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; | 374 | ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; |
375 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
376 | break; | ||
377 | case CLOCK_EVT_MODE_ONESHOT: | ||
378 | /* Leave the timer disabled, .set_next_event will enable it */ | ||
379 | ctrl &= ~TIMER_CTRL_PERIODIC; | ||
380 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
381 | break; | ||
382 | case CLOCK_EVT_MODE_UNUSED: | ||
383 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
384 | case CLOCK_EVT_MODE_RESUME: | ||
385 | default: | ||
386 | /* Just leave in disabled state */ | ||
387 | break; | ||
383 | } | 388 | } |
384 | 389 | ||
385 | writel(ctrl, clkevt_base + TIMER_CTRL); | ||
386 | } | 390 | } |
387 | 391 | ||
388 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) | 392 | static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) |
@@ -398,12 +402,10 @@ static int clkevt_set_next_event(unsigned long next, struct clock_event_device * | |||
398 | 402 | ||
399 | static struct clock_event_device integrator_clockevent = { | 403 | static struct clock_event_device integrator_clockevent = { |
400 | .name = "timer1", | 404 | .name = "timer1", |
401 | .shift = 34, | 405 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
402 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
403 | .set_mode = clkevt_set_mode, | 406 | .set_mode = clkevt_set_mode, |
404 | .set_next_event = clkevt_set_next_event, | 407 | .set_next_event = clkevt_set_next_event, |
405 | .rating = 300, | 408 | .rating = 300, |
406 | .cpumask = cpu_all_mask, | ||
407 | }; | 409 | }; |
408 | 410 | ||
409 | static struct irqaction integrator_timer_irq = { | 411 | static struct irqaction integrator_timer_irq = { |
@@ -413,29 +415,27 @@ static struct irqaction integrator_timer_irq = { | |||
413 | .dev_id = &integrator_clockevent, | 415 | .dev_id = &integrator_clockevent, |
414 | }; | 416 | }; |
415 | 417 | ||
416 | static void integrator_clockevent_init(u32 khz) | 418 | static void integrator_clockevent_init(unsigned long inrate) |
417 | { | 419 | { |
418 | struct clock_event_device *evt = &integrator_clockevent; | 420 | unsigned long rate = inrate; |
419 | unsigned int ctrl = 0; | 421 | unsigned int ctrl = 0; |
420 | 422 | ||
421 | if (khz * 1000 > 0x100000 * HZ) { | 423 | /* Calculate and program a divisor */ |
422 | khz /= 256; | 424 | if (rate > 0x100000 * HZ) { |
425 | rate /= 256; | ||
423 | ctrl |= TIMER_CTRL_DIV256; | 426 | ctrl |= TIMER_CTRL_DIV256; |
424 | } else if (khz * 1000 > 0x10000 * HZ) { | 427 | } else if (rate > 0x10000 * HZ) { |
425 | khz /= 16; | 428 | rate /= 16; |
426 | ctrl |= TIMER_CTRL_DIV16; | 429 | ctrl |= TIMER_CTRL_DIV16; |
427 | } | 430 | } |
428 | 431 | timer_reload = rate / HZ; | |
429 | timer_reload = khz * 1000 / HZ; | ||
430 | writel(ctrl, clkevt_base + TIMER_CTRL); | 432 | writel(ctrl, clkevt_base + TIMER_CTRL); |
431 | 433 | ||
432 | evt->irq = IRQ_TIMERINT1; | ||
433 | evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift); | ||
434 | evt->max_delta_ns = clockevent_delta2ns(0xffff, evt); | ||
435 | evt->min_delta_ns = clockevent_delta2ns(0xf, evt); | ||
436 | |||
437 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); | 434 | setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); |
438 | clockevents_register_device(evt); | 435 | clockevents_config_and_register(&integrator_clockevent, |
436 | rate, | ||
437 | 1, | ||
438 | 0xffffU); | ||
439 | } | 439 | } |
440 | 440 | ||
441 | /* | 441 | /* |
@@ -443,14 +443,20 @@ static void integrator_clockevent_init(u32 khz) | |||
443 | */ | 443 | */ |
444 | static void __init ap_init_timer(void) | 444 | static void __init ap_init_timer(void) |
445 | { | 445 | { |
446 | u32 khz = TICKS_PER_uSEC * 1000; | 446 | struct clk *clk; |
447 | unsigned long rate; | ||
448 | |||
449 | clk = clk_get_sys("ap_timer", NULL); | ||
450 | BUG_ON(IS_ERR(clk)); | ||
451 | clk_enable(clk); | ||
452 | rate = clk_get_rate(clk); | ||
447 | 453 | ||
448 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); | 454 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); |
449 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); | 455 | writel(0, TIMER1_VA_BASE + TIMER_CTRL); |
450 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); | 456 | writel(0, TIMER2_VA_BASE + TIMER_CTRL); |
451 | 457 | ||
452 | integrator_clocksource_init(khz); | 458 | integrator_clocksource_init(rate); |
453 | integrator_clockevent_init(khz); | 459 | integrator_clockevent_init(rate); |
454 | } | 460 | } |
455 | 461 | ||
456 | static struct sys_timer ap_timer = { | 462 | static struct sys_timer ap_timer = { |