aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-realview
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-01-14 08:30:16 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-02 04:35:34 -0400
commite388771458b4ff3ad81ab70e390b24d069647da4 (patch)
tree43f130464e60cabf5a1357355277f3d959cd1789 /arch/arm/mach-realview
parentf4b8b319bf21bf3576014ce7336763cd3e1684ef (diff)
ARM: Realview/Versatile: separate out common SP804 timer code
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-realview')
-rw-r--r--arch/arm/mach-realview/core.c139
1 files changed, 3 insertions, 136 deletions
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 17eb7eb780d8..80b8142463c1 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -25,8 +25,6 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/amba/bus.h> 26#include <linux/amba/bus.h>
27#include <linux/amba/clcd.h> 27#include <linux/amba/clcd.h>
28#include <linux/clocksource.h>
29#include <linux/clockchips.h>
30#include <linux/io.h> 28#include <linux/io.h>
31#include <linux/smsc911x.h> 29#include <linux/smsc911x.h>
32#include <linux/ata_platform.h> 30#include <linux/ata_platform.h>
@@ -51,6 +49,7 @@
51#include <mach/clkdev.h> 49#include <mach/clkdev.h>
52#include <mach/platform.h> 50#include <mach/platform.h>
53#include <mach/irqs.h> 51#include <mach/irqs.h>
52#include <plat/timer-sp.h>
54 53
55#include "core.h" 54#include "core.h"
56 55
@@ -646,133 +645,6 @@ void __iomem *timer2_va_base;
646void __iomem *timer3_va_base; 645void __iomem *timer3_va_base;
647 646
648/* 647/*
649 * How long is the timer interval?
650 */
651#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
652#if TIMER_INTERVAL >= 0x100000
653#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
654#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
655#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
656#elif TIMER_INTERVAL >= 0x10000
657#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
658#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
659#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
660#else
661#define TIMER_RELOAD (TIMER_INTERVAL)
662#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
663#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
664#endif
665
666static void timer_set_mode(enum clock_event_mode mode,
667 struct clock_event_device *clk)
668{
669 unsigned long ctrl;
670
671 switch(mode) {
672 case CLOCK_EVT_MODE_PERIODIC:
673 writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD);
674
675 ctrl = TIMER_CTRL_PERIODIC;
676 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
677 break;
678 case CLOCK_EVT_MODE_ONESHOT:
679 /* period set, and timer enabled in 'next_event' hook */
680 ctrl = TIMER_CTRL_ONESHOT;
681 ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
682 break;
683 case CLOCK_EVT_MODE_UNUSED:
684 case CLOCK_EVT_MODE_SHUTDOWN:
685 default:
686 ctrl = 0;
687 }
688
689 writel(ctrl, timer0_va_base + TIMER_CTRL);
690}
691
692static int timer_set_next_event(unsigned long evt,
693 struct clock_event_device *unused)
694{
695 unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL);
696
697 writel(evt, timer0_va_base + TIMER_LOAD);
698 writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL);
699
700 return 0;
701}
702
703static struct clock_event_device timer0_clockevent = {
704 .name = "timer0",
705 .shift = 32,
706 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
707 .set_mode = timer_set_mode,
708 .set_next_event = timer_set_next_event,
709 .rating = 300,
710 .cpumask = cpu_all_mask,
711};
712
713static void __init realview_clockevents_init(unsigned int timer_irq)
714{
715 timer0_clockevent.irq = timer_irq;
716 timer0_clockevent.mult =
717 div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
718 timer0_clockevent.max_delta_ns =
719 clockevent_delta2ns(0xffffffff, &timer0_clockevent);
720 timer0_clockevent.min_delta_ns =
721 clockevent_delta2ns(0xf, &timer0_clockevent);
722
723 clockevents_register_device(&timer0_clockevent);
724}
725
726/*
727 * IRQ handler for the timer
728 */
729static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
730{
731 struct clock_event_device *evt = &timer0_clockevent;
732
733 /* clear the interrupt */
734 writel(1, timer0_va_base + TIMER_INTCLR);
735
736 evt->event_handler(evt);
737
738 return IRQ_HANDLED;
739}
740
741static struct irqaction realview_timer_irq = {
742 .name = "RealView Timer Tick",
743 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
744 .handler = realview_timer_interrupt,
745};
746
747static cycle_t realview_get_cycles(struct clocksource *cs)
748{
749 return ~readl(timer3_va_base + TIMER_VALUE);
750}
751
752static struct clocksource clocksource_realview = {
753 .name = "timer3",
754 .rating = 200,
755 .read = realview_get_cycles,
756 .mask = CLOCKSOURCE_MASK(32),
757 .shift = 20,
758 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
759};
760
761static void __init realview_clocksource_init(void)
762{
763 /* setup timer 0 as free-running clocksource */
764 writel(0, timer3_va_base + TIMER_CTRL);
765 writel(0xffffffff, timer3_va_base + TIMER_LOAD);
766 writel(0xffffffff, timer3_va_base + TIMER_VALUE);
767 writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
768 timer3_va_base + TIMER_CTRL);
769
770 clocksource_realview.mult =
771 clocksource_khz2mult(1000, clocksource_realview.shift);
772 clocksource_register(&clocksource_realview);
773}
774
775/*
776 * Set up the clock source and clock events devices 648 * Set up the clock source and clock events devices
777 */ 649 */
778void __init realview_timer_init(unsigned int timer_irq) 650void __init realview_timer_init(unsigned int timer_irq)
@@ -799,13 +671,8 @@ void __init realview_timer_init(unsigned int timer_irq)
799 writel(0, timer2_va_base + TIMER_CTRL); 671 writel(0, timer2_va_base + TIMER_CTRL);
800 writel(0, timer3_va_base + TIMER_CTRL); 672 writel(0, timer3_va_base + TIMER_CTRL);
801 673
802 /* 674 sp804_clocksource_init(timer3_va_base);
803 * Make irqs happen for the system timer 675 sp804_clockevents_init(timer0_va_base, timer_irq);
804 */
805 setup_irq(timer_irq, &realview_timer_irq);
806
807 realview_clocksource_init();
808 realview_clockevents_init(timer_irq);
809} 676}
810 677
811/* 678/*