diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5c8c1a89be73..8a9a84c4adfd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -367,6 +367,8 @@ config ARCH_NS9XXX
 
 config ARCH_MXC
 	bool "Freescale MXC/iMX-based"
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
 	select ARCH_MTD_XIP
 	select GENERIC_GPIO
 	select HAVE_GPIO_LIB
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 68f062b70d33..562c75d2e379 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -4,5 +4,5 @@
 
 # Object file lists.
 
-obj-y			:= mm.o time.o clock.o devices.o iomux.o
+obj-y			:= mm.o clock.o devices.o iomux.o
 obj-$(CONFIG_MACH_MX31ADS)	+= mx31ads.o
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index 5addbb7f711c..eba3e0cd4283 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -26,6 +26,7 @@
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/time.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <asm/arch/common.h>
@@ -127,6 +128,16 @@ static void __init mxc_board_init(void)
 	mxc_init_extuart();
 }
 
+static void __init mx31ads_timer_init(void)
+{
+	mxc_clocks_init(26000000);
+	mxc_timer_init("ipg_clk.0");
+}
+
+struct sys_timer mx31ads_timer = {
+	.init	= mx31ads_timer_init,
+};
+
 /*
  * The following uses standard kernel macros defined in arch.h in order to
  * initialize __mach_desc_MX31ADS data structure.
@@ -139,5 +150,5 @@ MACHINE_START(MX31ADS, "Freescale MX31ADS")
 	.map_io         = mx31ads_map_io,
 	.init_irq       = mxc_init_irq,
 	.init_machine   = mxc_board_init,
-	.timer          = &mxc_timer,
+	.timer          = &mx31ads_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c
deleted file mode 100644
index fb565c98dbfb..000000000000
--- a/arch/arm/mach-mx3/time.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * System Timer Interrupt reconfigured to run in free-run mode.
- * Author: Vitaly Wool
- * Copyright 2004 MontaVista Software Inc.
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/*!
- * @file time.c
- * @brief This file contains OS tick and wdog timer implementations.
- *
- * This file contains OS tick and wdog timer implementations.
- *
- * @ingroup Timers
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/hardware.h>
-#include <asm/mach/time.h>
-#include <asm/io.h>
-#include <asm/arch/common.h>
-
-/*!
- * This is the timer interrupt service routine to do required tasks.
- * It also services the WDOG timer at the frequency of twice per WDOG
- * timeout value. For example, if the WDOG's timeout value is 4 (2
- * seconds since the WDOG runs at 0.5Hz), it will be serviced once
- * every 2/2=1 second.
- *
- * @param  irq          GPT interrupt source number (not used)
- * @param  dev_id       this parameter is not used
- * @return always returns \b IRQ_HANDLED as defined in
- *         include/linux/interrupt.h.
- */
-static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
-{
-	unsigned int next_match;
-
-	if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
-		do {
-			timer_tick();
-			next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH;
-			__raw_writel(GPTSR_OF1, MXC_GPT_GPTSR);
-			__raw_writel(next_match, MXC_GPT_GPTOCR1);
-		} while ((signed long)(next_match -
-				       __raw_readl(MXC_GPT_GPTCNT)) <= 0);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*!
- * This function is used to obtain the number of microseconds since the last
- * timer interrupt. Note that interrupts is disabled by do_gettimeofday().
- *
- * @return the number of microseconds since the last timer interrupt.
- */
-static unsigned long mxc_gettimeoffset(void)
-{
-	unsigned long ticks_to_match, elapsed, usec, tick_usec, i;
-
-	/* Get ticks before next timer match */
-	ticks_to_match =
-	    __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT);
-
-	/* We need elapsed ticks since last match */
-	elapsed = LATCH - ticks_to_match;
-
-	/* Now convert them to usec */
-	/* Insure no overflow when calculating the usec below */
-	for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) {
-		tick_usec /= i;
-		if ((0xFFFFFFFF / tick_usec) > elapsed)
-			break;
-	}
-	usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i);
-
-	return usec;
-}
-
-/*!
- * The OS tick timer interrupt structure.
- */
-static struct irqaction timer_irq = {
-	.name = "MXC Timer Tick",
-	.flags = IRQF_DISABLED | IRQF_TIMER,
-	.handler = mxc_timer_interrupt
-};
-
-/*!
- * This function is used to initialize the GPT to produce an interrupt
- * based on HZ.  It is called by start_kernel() during system startup.
- */
-void __init mxc_init_time(void)
-{
-	u32 reg, v;
-	reg = __raw_readl(MXC_GPT_GPTCR);
-	reg &= ~GPTCR_ENABLE;
-	__raw_writel(reg, MXC_GPT_GPTCR);
-	reg |= GPTCR_SWR;
-	__raw_writel(reg, MXC_GPT_GPTCR);
-
-	while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0)
-		cpu_relax();
-
-	reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ;
-	__raw_writel(reg, MXC_GPT_GPTCR);
-
-	/* TODO: get timer rate from clk driver */
-	v = 66500000;
-
-	__raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR);
-
-	if ((v % CLOCK_TICK_RATE) != 0) {
-		pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n",
-			CLOCK_TICK_RATE);
-	}
-	pr_info("Actual CLOCK_TICK_RATE is %d Hz\n",
-		v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1));
-
-	reg = __raw_readl(MXC_GPT_GPTCNT);
-	reg += LATCH;
-	__raw_writel(reg, MXC_GPT_GPTOCR1);
-
-	setup_irq(MXC_INT_GPT, &timer_irq);
-
-	reg = __raw_readl(MXC_GPT_GPTCR);
-	reg =
-	    GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN |
-	    GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE;
-	__raw_writel(reg, MXC_GPT_GPTCR);
-
-	__raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR);
-}
-
-struct sys_timer mxc_timer = {
-	.init = mxc_init_time,
-	.offset = mxc_gettimeoffset,
-};
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 66272a6fc323..e3cc25c6d46f 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,4 +3,4 @@
 #
 
 # Common support
-obj-y := irq.o clock.o gpio.o
+obj-y := irq.o clock.o gpio.o time.o
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
new file mode 100644
index 000000000000..3bf86343fdf4
--- /dev/null
+++ b/arch/arm/plat-mxc/time.c
@@ -0,0 +1,228 @@
+/*
+ *  linux/arch/arm/plat-mxc/time.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/hardware.h>
+#include <asm/mach/time.h>
+#include <asm/arch/common.h>
+#include <asm/arch/mxc_timer.h>
+
+static struct clock_event_device clockevent_mxc;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+/* clock source for the timer */
+static struct clk *timer_clk;
+
+/* clock source */
+
+static cycle_t mxc_get_cycles(void)
+{
+	return __raw_readl(TIMER_BASE + MXC_TCN);
+}
+
+static struct clocksource clocksource_mxc = {
+	.name 		= "mxc_timer1",
+	.rating		= 200,
+	.read		= mxc_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift 		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxc_clocksource_init(void)
+{
+	unsigned int clock;
+
+	clock = clk_get_rate(timer_clk);
+
+	clocksource_mxc.mult = clocksource_hz2mult(clock,
+					clocksource_mxc.shift);
+	clocksource_register(&clocksource_mxc);
+
+	return 0;
+}
+
+/* clock event */
+
+static int mxc_set_next_event(unsigned long evt,
+			      struct clock_event_device *unused)
+{
+	unsigned long tcmp;
+
+	tcmp = __raw_readl(TIMER_BASE + MXC_TCN) + evt;
+	__raw_writel(tcmp, TIMER_BASE + MXC_TCMP);
+
+	return (int)(tcmp - __raw_readl(TIMER_BASE + MXC_TCN)) < 0 ?
+				-ETIME : 0;
+}
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxc_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call mxc_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in GPT module */
+	gpt_irq_disable();
+
+	if (mode != clockevent_mode) {
+		/* Set event time into far-far future */
+		__raw_writel(__raw_readl(TIMER_BASE + MXC_TCN) - 3,
+				TIMER_BASE + MXC_TCMP);
+		/* Clear pending interrupt */
+		gpt_irq_acknowledge();
+	}
+
+#ifdef DEBUG
+	printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n",
+		clock_event_mode_label[clockevent_mode],
+		clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+	/* Remember timer mode */
+	clockevent_mode = mode;
+	local_irq_restore(flags);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
+				"supported for i.MX\n");
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * mxc_set_next_event(), the core has about 4 minutes
+	 * to call mxc_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+		local_irq_save(flags);
+		gpt_irq_enable();
+		local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_mxc;
+	uint32_t tstat;
+
+	tstat = __raw_readl(TIMER_BASE + MXC_TSTAT);
+
+	gpt_irq_acknowledge();
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mxc_timer_irq = {
+	.name		= "i.MX Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mxc_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_mxc = {
+	.name		= "mxc_timer1",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_mode	= mxc_set_mode,
+	.set_next_event	= mxc_set_next_event,
+	.rating		= 200,
+};
+
+static int __init mxc_clockevent_init(void)
+{
+	unsigned int clock;
+
+	clock = clk_get_rate(timer_clk);
+
+	clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC,
+					clockevent_mxc.shift);
+	clockevent_mxc.max_delta_ns =
+			clockevent_delta2ns(0xfffffffe, &clockevent_mxc);
+	clockevent_mxc.min_delta_ns =
+			clockevent_delta2ns(0xff, &clockevent_mxc);
+
+	clockevent_mxc.cpumask = cpumask_of_cpu(0);
+
+	clockevents_register_device(&clockevent_mxc);
+
+	return 0;
+}
+
+void __init mxc_timer_init(const char *clk_timer)
+{
+	timer_clk = clk_get(NULL, clk_timer);
+	if (!timer_clk) {
+		printk(KERN_ERR"Cannot determine timer clock. Giving up.\n");
+		return;
+	}
+
+	clk_enable(timer_clk);
+
+	/*
+	 * Initialise to a known state (all timers off, and timing reset)
+	 */
+	__raw_writel(0, TIMER_BASE + MXC_TCTL);
+	__raw_writel(0, TIMER_BASE + MXC_TPRER); /* see datasheet note */
+
+	__raw_writel(TCTL_FRR |	/* free running */
+		     TCTL_VAL |	/* set clocksource and arch specific bits */
+		     TCTL_TEN,	/* start the timer */
+		     TIMER_BASE + MXC_TCTL);
+
+	/* init and register the timer to the framework */
+	mxc_clocksource_init();
+	mxc_clockevent_init();
+
+	/* Make irqs happen */
+	setup_irq(TIMER_INTERRUPT, &mxc_timer_irq);
+}
+
diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h
index 8774783ed984..a6d2e24aab15 100644
--- a/include/asm-arm/arch-mxc/common.h
+++ b/include/asm-arm/arch-mxc/common.h
@@ -11,11 +11,9 @@
 #ifndef __ASM_ARCH_MXC_COMMON_H__
 #define __ASM_ARCH_MXC_COMMON_H__
 
-struct sys_timer;
-
 extern void mxc_map_io(void);
 extern void mxc_init_irq(void);
-extern struct sys_timer mxc_timer;
+extern void mxc_timer_init(const char *clk_timer);
 extern int mxc_clocks_init(unsigned long fref);
 extern int mxc_register_gpios(void);
 
diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h
index 146d3f60951a..1df4e2f24920 100644
--- a/include/asm-arm/arch-mxc/mxc.h
+++ b/include/asm-arm/arch-mxc/mxc.h
@@ -1,11 +1,20 @@
 /*
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
  */
 
 #ifndef __ASM_ARCH_MXC_H__
@@ -20,97 +29,6 @@
 # define cpu_is_mx31() (0)
 #endif
 
-/*
- *****************************************
- * GPT  Register definitions             *
- *****************************************
- */
-#define MXC_GPT_GPTCR		IO_ADDRESS(GPT1_BASE_ADDR + 0x00)
-#define MXC_GPT_GPTPR		IO_ADDRESS(GPT1_BASE_ADDR + 0x04)
-#define MXC_GPT_GPTSR		IO_ADDRESS(GPT1_BASE_ADDR + 0x08)
-#define MXC_GPT_GPTIR		IO_ADDRESS(GPT1_BASE_ADDR + 0x0C)
-#define MXC_GPT_GPTOCR1		IO_ADDRESS(GPT1_BASE_ADDR + 0x10)
-#define MXC_GPT_GPTOCR2		IO_ADDRESS(GPT1_BASE_ADDR + 0x14)
-#define MXC_GPT_GPTOCR3		IO_ADDRESS(GPT1_BASE_ADDR + 0x18)
-#define MXC_GPT_GPTICR1		IO_ADDRESS(GPT1_BASE_ADDR + 0x1C)
-#define MXC_GPT_GPTICR2		IO_ADDRESS(GPT1_BASE_ADDR + 0x20)
-#define MXC_GPT_GPTCNT		IO_ADDRESS(GPT1_BASE_ADDR + 0x24)
-
-/* GPT Control register bit definitions */
-#define GPTCR_FO3			(1 << 31)
-#define GPTCR_FO2			(1 << 30)
-#define GPTCR_FO1			(1 << 29)
-
-#define GPTCR_OM3_SHIFT			26
-#define GPTCR_OM3_MASK			(7 << GPTCR_OM3_SHIFT)
-#define GPTCR_OM3_DISCONNECTED		(0 << GPTCR_OM3_SHIFT)
-#define GPTCR_OM3_TOGGLE		(1 << GPTCR_OM3_SHIFT)
-#define GPTCR_OM3_CLEAR			(2 << GPTCR_OM3_SHIFT)
-#define GPTCR_OM3_SET			(3 << GPTCR_OM3_SHIFT)
-#define GPTCR_OM3_GENERATE_LOW		(7 << GPTCR_OM3_SHIFT)
-
-#define GPTCR_OM2_SHIFT			23
-#define GPTCR_OM2_MASK			(7 << GPTCR_OM2_SHIFT)
-#define GPTCR_OM2_DISCONNECTED		(0 << GPTCR_OM2_SHIFT)
-#define GPTCR_OM2_TOGGLE		(1 << GPTCR_OM2_SHIFT)
-#define GPTCR_OM2_CLEAR			(2 << GPTCR_OM2_SHIFT)
-#define GPTCR_OM2_SET			(3 << GPTCR_OM2_SHIFT)
-#define GPTCR_OM2_GENERATE_LOW		(7 << GPTCR_OM2_SHIFT)
-
-#define GPTCR_OM1_SHIFT			20
-#define GPTCR_OM1_MASK			(7 << GPTCR_OM1_SHIFT)
-#define GPTCR_OM1_DISCONNECTED		(0 << GPTCR_OM1_SHIFT)
-#define GPTCR_OM1_TOGGLE		(1 << GPTCR_OM1_SHIFT)
-#define GPTCR_OM1_CLEAR			(2 << GPTCR_OM1_SHIFT)
-#define GPTCR_OM1_SET			(3 << GPTCR_OM1_SHIFT)
-#define GPTCR_OM1_GENERATE_LOW		(7 << GPTCR_OM1_SHIFT)
-
-#define GPTCR_IM2_SHIFT			18
-#define GPTCR_IM2_MASK			(3 << GPTCR_IM2_SHIFT)
-#define GPTCR_IM2_CAPTURE_DISABLE	(0 << GPTCR_IM2_SHIFT)
-#define GPTCR_IM2_CAPTURE_RISING	(1 << GPTCR_IM2_SHIFT)
-#define GPTCR_IM2_CAPTURE_FALLING	(2 << GPTCR_IM2_SHIFT)
-#define GPTCR_IM2_CAPTURE_BOTH		(3 << GPTCR_IM2_SHIFT)
-
-#define GPTCR_IM1_SHIFT			16
-#define GPTCR_IM1_MASK			(3 << GPTCR_IM1_SHIFT)
-#define GPTCR_IM1_CAPTURE_DISABLE	(0 << GPTCR_IM1_SHIFT)
-#define GPTCR_IM1_CAPTURE_RISING	(1 << GPTCR_IM1_SHIFT)
-#define GPTCR_IM1_CAPTURE_FALLING	(2 << GPTCR_IM1_SHIFT)
-#define GPTCR_IM1_CAPTURE_BOTH		(3 << GPTCR_IM1_SHIFT)
-
-#define GPTCR_SWR			(1 << 15)
-#define GPTCR_FRR			(1 << 9)
-
-#define GPTCR_CLKSRC_SHIFT		6
-#define GPTCR_CLKSRC_MASK		(7 << GPTCR_CLKSRC_SHIFT)
-#define GPTCR_CLKSRC_NOCLOCK		(0 << GPTCR_CLKSRC_SHIFT)
-#define GPTCR_CLKSRC_HIGHFREQ		(2 << GPTCR_CLKSRC_SHIFT)
-#define GPTCR_CLKSRC_CLKIN		(3 << GPTCR_CLKSRC_SHIFT)
-#define GPTCR_CLKSRC_CLK32K		(7 << GPTCR_CLKSRC_SHIFT)
-
-#define GPTCR_STOPEN			(1 << 5)
-#define GPTCR_DOZEN			(1 << 4)
-#define GPTCR_WAITEN			(1 << 3)
-#define GPTCR_DBGEN			(1 << 2)
-
-#define GPTCR_ENMOD			(1 << 1)
-#define GPTCR_ENABLE			(1 << 0)
-
-#define GPTSR_OF1			(1 << 0)
-#define GPTSR_OF2			(1 << 1)
-#define GPTSR_OF3			(1 << 2)
-#define GPTSR_IF1			(1 << 3)
-#define GPTSR_IF2			(1 << 4)
-#define GPTSR_ROV			(1 << 5)
-
-#define GPTIR_OF1IE			GPTSR_OF1
-#define GPTIR_OF2IE			GPTSR_OF2
-#define GPTIR_OF3IE			GPTSR_OF3
-#define GPTIR_IF1IE			GPTSR_IF1
-#define GPTIR_IF2IE			GPTSR_IF2
-#define GPTIR_ROVIE			GPTSR_ROV
-
 /*
  *****************************************
  * AVIC Registers                        *
diff --git a/include/asm-arm/arch-mxc/mxc_timer.h b/include/asm-arm/arch-mxc/mxc_timer.h
new file mode 100644
index 000000000000..6cb11f4f1a06
--- /dev/null
+++ b/include/asm-arm/arch-mxc/mxc_timer.h
@@ -0,0 +1,158 @@
+/*
+ * mxc_timer.h
+ *
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * Platform independent (i.MX1, i.MX2, i.MX3) definition for timer handling.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __PLAT_MXC_TIMER_H
+#define __PLAT_MXC_TIMER_H
+
+#include <linux/clk.h>
+#include <asm/hardware.h>
+
+#ifdef CONFIG_ARCH_IMX
+#define TIMER_BASE		IO_ADDRESS(TIM1_BASE_ADDR)
+#define TIMER_INTERRUPT		TIM1_INT
+
+#define TCTL_VAL		TCTL_CLK_PCLK1
+#define TCTL_IRQEN		(1<<4)
+#define TCTL_FRR		(1<<8)
+#define TCTL_CLK_PCLK1		(1<<1)
+#define TCTL_CLK_PCLK1_4	(2<<1)
+#define TCTL_CLK_TIN		(3<<1)
+#define TCTL_CLK_32		(4<<1)
+
+#define MXC_TCTL   0x00
+#define MXC_TPRER  0x04
+#define MXC_TCMP   0x08
+#define MXC_TCR    0x0c
+#define MXC_TCN    0x10
+#define MXC_TSTAT  0x14
+#define TSTAT_CAPT		(1<<1)
+#define TSTAT_COMP		(1<<0)
+
+static inline void gpt_irq_disable(void)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(TIMER_BASE + MXC_TCTL);
+	__raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL);
+}
+
+static inline void gpt_irq_enable(void)
+{
+	__raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN,
+				TIMER_BASE + MXC_TCTL);
+}
+
+static void gpt_irq_acknowledge(void)
+{
+	__raw_writel(0, TIMER_BASE + MXC_TSTAT);
+}
+#endif /* CONFIG_ARCH_IMX */
+
+#ifdef CONFIG_ARCH_MX2
+#define TIMER_BASE		IO_ADDRESS(GPT1_BASE_ADDR)
+#define TIMER_INTERRUPT		MXC_INT_GPT1
+
+#define MXC_TCTL   0x00
+#define TCTL_VAL		TCTL_CLK_PCLK1
+#define TCTL_CLK_PCLK1		(1<<1)
+#define TCTL_CLK_PCLK1_4	(2<<1)
+#define TCTL_IRQEN		(1<<4)
+#define TCTL_FRR		(1<<8)
+#define MXC_TPRER  0x04
+#define MXC_TCMP   0x08
+#define MXC_TCR    0x0c
+#define MXC_TCN    0x10
+#define MXC_TSTAT  0x14
+#define TSTAT_CAPT		(1<<1)
+#define TSTAT_COMP		(1<<0)
+
+static inline void gpt_irq_disable(void)
+{
+	unsigned int tmp;
+
+	tmp = __raw_readl(TIMER_BASE + MXC_TCTL);
+	__raw_writel(tmp & ~TCTL_IRQEN, TIMER_BASE + MXC_TCTL);
+}
+
+static inline void gpt_irq_enable(void)
+{
+	__raw_writel(__raw_readl(TIMER_BASE + MXC_TCTL) | TCTL_IRQEN,
+				TIMER_BASE + MXC_TCTL);
+}
+
+static void gpt_irq_acknowledge(void)
+{
+	__raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT);
+}
+#endif /* CONFIG_ARCH_MX2 */
+
+#ifdef CONFIG_ARCH_MX3
+#define TIMER_BASE		IO_ADDRESS(GPT1_BASE_ADDR)
+#define TIMER_INTERRUPT		MXC_INT_GPT
+
+#define MXC_TCTL   0x00
+#define TCTL_VAL		(TCTL_CLK_IPG | TCTL_WAITEN)
+#define TCTL_CLK_IPG		(1<<6)
+#define TCTL_FRR		(1<<9)
+#define TCTL_WAITEN		(1<<3)
+
+#define MXC_TPRER  0x04
+#define MXC_TSTAT  0x08
+#define TSTAT_OF1		(1<<0)
+#define TSTAT_OF2		(1<<1)
+#define TSTAT_OF3		(1<<2)
+#define TSTAT_IF1		(1<<3)
+#define TSTAT_IF2		(1<<4)
+#define TSTAT_ROV		(1<<5)
+#define MXC_IR     0x0c
+#define MXC_TCMP   0x10
+#define MXC_TCMP2  0x14
+#define MXC_TCMP3  0x18
+#define MXC_TCR    0x1c
+#define MXC_TCN    0x24
+
+static inline void gpt_irq_disable(void)
+{
+	__raw_writel(0, TIMER_BASE + MXC_IR);
+}
+
+static inline void gpt_irq_enable(void)
+{
+	__raw_writel(1<<0, TIMER_BASE + MXC_IR);
+}
+
+static inline void gpt_irq_acknowledge(void)
+{
+	__raw_writel(TSTAT_OF1, TIMER_BASE + MXC_TSTAT);
+}
+#endif /* CONFIG_ARCH_MX3 */
+
+#define TCTL_SWR		(1<<15)
+#define TCTL_CC			(1<<10)
+#define TCTL_OM			(1<<9)
+#define TCTL_CAP_RIS		(1<<6)
+#define TCTL_CAP_FAL		(2<<6)
+#define TCTL_CAP_RIS_FAL	(3<<6)
+#define TCTL_CAP_ENA		(1<<5)
+#define TCTL_TEN		(1<<0)
+
+#endif