diff options
Diffstat (limited to 'arch/arm/mach-orion')
-rw-r--r-- | arch/arm/mach-orion/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-orion/common.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-orion/common.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-orion/time.c | 181 |
4 files changed, 18 insertions, 187 deletions
diff --git a/arch/arm/mach-orion/Makefile b/arch/arm/mach-orion/Makefile index f91d937a73e..d894caa5060 100644 --- a/arch/arm/mach-orion/Makefile +++ b/arch/arm/mach-orion/Makefile @@ -1,4 +1,4 @@ -obj-y += common.o addr-map.o pci.o gpio.o irq.o time.o +obj-y += common.o addr-map.o pci.o gpio.o irq.o obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index a32fe8e108b..86d7f7ccfae 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -23,8 +23,11 @@ #include <asm/timex.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/time.h> #include <asm/arch/hardware.h> +#include <asm/arch/orion.h> #include <asm/arch/platform.h> +#include <asm/plat-orion/time.h> #include "common.h" /***************************************************************************** @@ -296,6 +299,19 @@ void __init orion_sata_init(struct mv_sata_platform_data *sata_data) } /***************************************************************************** + * Time handling + ****************************************************************************/ + +static void orion_timer_init(void) +{ + orion_time_init(IRQ_ORION_BRIDGE, ORION_TCLK); +} + +struct sys_timer orion_timer = { + .init = orion_timer_init, +}; + +/***************************************************************************** * General ****************************************************************************/ diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 9a5afefac4d..3898e1b78ee 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -8,6 +8,7 @@ void __init orion_map_io(void); void __init orion_init_irq(void); void __init orion_init(void); +extern struct sys_timer orion_timer; /* * Enumerations and functions for Orion windows mapping. Used by Orion core @@ -57,11 +58,6 @@ void __init orion_gpio_set_valid_pins(u32 pins); void gpio_display(void); /* debug */ /* - * Orion system timer (clocksource + clockevnt, /mach-orion/time.c) - */ -extern struct sys_timer orion_timer; - -/* * Pull in Orion Ethernet platform_data, used by machine-setup */ diff --git a/arch/arm/mach-orion/time.c b/arch/arm/mach-orion/time.c deleted file mode 100644 index bd4262da4f4..00000000000 --- a/arch/arm/mach-orion/time.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * arch/arm/mach-orion/time.c - * - * Core time functions for Marvell Orion System On Chip - * - * Maintainer: Tzachi Perelstein <tzachi@marvell.com> - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include <linux/kernel.h> -#include <linux/clockchips.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <asm/mach/time.h> -#include <asm/arch/orion.h> -#include "common.h" - -/* - * Timer0: clock_event_device, Tick. - * Timer1: clocksource, Free running. - * WatchDog: Not used. - * - * Timers are counting down. - */ -#define CLOCKEVENT 0 -#define CLOCKSOURCE 1 - -/* - * Timers bits - */ -#define BRIDGE_INT_TIMER(x) (1 << ((x) + 1)) -#define TIMER_EN(x) (1 << ((x) * 2)) -#define TIMER_RELOAD_EN(x) (1 << (((x) * 2) + 1)) -#define BRIDGE_INT_TIMER_WD (1 << 3) -#define TIMER_WD_EN (1 << 4) -#define TIMER_WD_RELOAD_EN (1 << 5) - -static cycle_t orion_clksrc_read(void) -{ - return (0xffffffff - orion_read(TIMER_VAL(CLOCKSOURCE))); -} - -static struct clocksource orion_clksrc = { - .name = "orion_clocksource", - .shift = 20, - .rating = 300, - .read = orion_clksrc_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int -orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev) -{ - unsigned long flags; - - if (delta == 0) - return -ETIME; - - local_irq_save(flags); - - /* - * Clear and enable timer interrupt bit - */ - orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); - orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); - - /* - * Setup new timer value - */ - orion_write(TIMER_VAL(CLOCKEVENT), delta); - - /* - * Disable auto reload and kickoff the timer - */ - orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT)); - orion_setbits(TIMER_CTRL, TIMER_EN(CLOCKEVENT)); - - local_irq_restore(flags); - - return 0; -} - -static void -orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev) -{ - unsigned long flags; - - local_irq_save(flags); - - if (mode == CLOCK_EVT_MODE_PERIODIC) { - /* - * Setup latch cycles in timer and enable reload interrupt. - */ - orion_write(TIMER_VAL_RELOAD(CLOCKEVENT), LATCH); - orion_write(TIMER_VAL(CLOCKEVENT), LATCH); - orion_setbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); - orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) | - TIMER_EN(CLOCKEVENT)); - } else { - /* - * Disable timer and interrupt - */ - orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKEVENT)); - orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); - orion_clrbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKEVENT) | - TIMER_EN(CLOCKEVENT)); - } - - local_irq_restore(flags); -} - -static struct clock_event_device orion_clkevt = { - .name = "orion_tick", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .rating = 300, - .cpumask = CPU_MASK_CPU0, - .set_next_event = orion_clkevt_next_event, - .set_mode = orion_clkevt_mode, -}; - -static irqreturn_t orion_timer_interrupt(int irq, void *dev_id) -{ - /* - * Clear cause bit and do event - */ - orion_write(BRIDGE_CAUSE, ~BRIDGE_INT_TIMER(CLOCKEVENT)); - orion_clkevt.event_handler(&orion_clkevt); - return IRQ_HANDLED; -} - -static struct irqaction orion_timer_irq = { - .name = "orion_tick", - .flags = IRQF_DISABLED | IRQF_TIMER, - .handler = orion_timer_interrupt -}; - -static void orion_timer_init(void) -{ - /* - * Setup clocksource free running timer (no interrupt on reload) - */ - orion_write(TIMER_VAL(CLOCKSOURCE), 0xffffffff); - orion_write(TIMER_VAL_RELOAD(CLOCKSOURCE), 0xffffffff); - orion_clrbits(BRIDGE_MASK, BRIDGE_INT_TIMER(CLOCKSOURCE)); - orion_setbits(TIMER_CTRL, TIMER_RELOAD_EN(CLOCKSOURCE) | - TIMER_EN(CLOCKSOURCE)); - - /* - * Register clocksource - */ - orion_clksrc.mult = - clocksource_hz2mult(CLOCK_TICK_RATE, orion_clksrc.shift); - - clocksource_register(&orion_clksrc); - - /* - * Connect and enable tick handler - */ - setup_irq(IRQ_ORION_BRIDGE, &orion_timer_irq); - - /* - * Register clockevent - */ - orion_clkevt.mult = - div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, orion_clkevt.shift); - orion_clkevt.max_delta_ns = - clockevent_delta2ns(0xfffffffe, &orion_clkevt); - orion_clkevt.min_delta_ns = - clockevent_delta2ns(1, &orion_clkevt); - - clockevents_register_device(&orion_clkevt); -} - -struct sys_timer orion_timer = { - .init = orion_timer_init, -}; |