diff --git a/Makefile.target b/Makefile.target
index 70b0b37..f6234bc 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -265,7 +265,7 @@ obj-arm-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
 obj-arm-y += gumstix.o
 obj-arm-y += zaurus.o ide/microdrive.o spitz.o tosa.o tc6393xb.o
 obj-arm-y += omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o omap_gpio.o
-obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o
+obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o
 obj-arm-y += omap_sx1.o palm.o tsc210x.o
 obj-arm-y += nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
 obj-arm-y += mst_fpga.o mainstone.o
diff --git a/hw/omap.h b/hw/omap.h
index 14fdb6f..b898230 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -645,8 +645,11 @@ struct omap_32khz_timer_s;
 struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
                 qemu_irq irq, omap_clk clk);
 
-void omap_synctimer_init(struct omap_target_agent_s *ta,
+/* OMAP2 sysctimer */
+struct omap_synctimer_s;
+struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
                 struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk);
+void omap_synctimer_reset(struct omap_synctimer_s *s);
 
 struct omap_tipb_bridge_s;
 struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
@@ -939,11 +942,7 @@ struct omap_mpu_state_s {
     struct omap_l4_s *l4;
 
     struct omap_gp_timer_s *gptimer[12];
-
-    struct omap_synctimer_s {
-        uint32_t val;
-        uint16_t readh;
-    } synctimer;
+    struct omap_synctimer_s *synctimer;
 
     struct omap_prcm_s *prcm;
     struct omap_sdrc_s *sdrc;
diff --git a/hw/omap2.c b/hw/omap2.c
index 890397b..e310eef 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -27,74 +27,6 @@
 #include "soc_dma.h"
 #include "audio/audio.h"
 
-/* 32-kHz Sync Timer of the OMAP2 */
-static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
-    return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec());
-}
-
-static void omap_synctimer_reset(struct omap_synctimer_s *s)
-{
-    s->val = omap_synctimer_read(s);
-}
-
-static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
-
-    switch (addr) {
-    case 0x00:	/* 32KSYNCNT_REV */
-        return 0x21;
-
-    case 0x10:	/* CR */
-        return omap_synctimer_read(s) - s->val;
-    }
-
-    OMAP_BAD_REG(addr);
-    return 0;
-}
-
-static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
-{
-    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
-    uint32_t ret;
-
-    if (addr & 2)
-        return s->readh;
-    else {
-        ret = omap_synctimer_readw(opaque, addr);
-        s->readh = ret >> 16;
-        return ret & 0xffff;
-    }
-}
-
-static CPUReadMemoryFunc * const omap_synctimer_readfn[] = {
-    omap_badwidth_read32,
-    omap_synctimer_readh,
-    omap_synctimer_readw,
-};
-
-static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    OMAP_BAD_REG(addr);
-}
-
-static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = {
-    omap_badwidth_write32,
-    omap_synctimer_write,
-    omap_synctimer_write,
-};
-
-void omap_synctimer_init(struct omap_target_agent_s *ta,
-                struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
-{
-    struct omap_synctimer_s *s = &mpu->synctimer;
-
-    omap_synctimer_reset(s);
-    omap_l4_attach(ta, 0, l4_register_io_memory(
-                      omap_synctimer_readfn, omap_synctimer_writefn, s));
-}
-
 /* Multichannel SPI */
 struct omap_mcspi_s {
     qemu_irq irq;
@@ -3473,7 +3405,7 @@ static void omap2_mpu_reset(void *opaque)
     omap_gp_timer_reset(mpu->gptimer[9]);
     omap_gp_timer_reset(mpu->gptimer[10]);
     omap_gp_timer_reset(mpu->gptimer[11]);
-    omap_synctimer_reset(&mpu->synctimer);
+    omap_synctimer_reset(mpu->synctimer);
     omap_sdrc_reset(mpu->sdrc);
     omap_gpmc_reset(mpu->gpmc);
     omap_dss_reset(mpu->dss);
@@ -3634,7 +3566,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
 
     omap_tap_init(omap_l4ta(s->l4, 2), s);
 
-    omap_synctimer_init(omap_l4tao(s->l4, 2), s,
+    s->synctimer = omap_synctimer_init(omap_l4tao(s->l4, 2), s,
                     omap_findclk(s, "clk32-kHz"),
                     omap_findclk(s, "core_l4_iclk"));
 
diff --git a/hw/omap_synctimer.c b/hw/omap_synctimer.c
new file mode 100644
index 0000000..118668a
--- /dev/null
+++ b/hw/omap_synctimer.c
@@ -0,0 +1,96 @@
+/*
+ * TI OMAP2 32kHz sync timer emulation.
+ *
+ * Copyright (C) 2007-2008 Nokia Corporation
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
+ *
+ * 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 or
+ * (at your option) any later version of the License.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include "hw.h"
+#include "qemu-timer.h"
+#include "omap.h"
+struct omap_synctimer_s {
+    uint32_t val;
+    uint16_t readh;
+};
+
+/* 32-kHz Sync Timer of the OMAP2 */
+static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
+    return muldiv64(qemu_get_clock(vm_clock), 0x8000, get_ticks_per_sec());
+}
+
+void omap_synctimer_reset(struct omap_synctimer_s *s)
+{
+    s->val = omap_synctimer_read(s);
+}
+
+static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
+
+    switch (addr) {
+    case 0x00:	/* 32KSYNCNT_REV */
+        return 0x21;
+
+    case 0x10:	/* CR */
+        return omap_synctimer_read(s) - s->val;
+    }
+
+    OMAP_BAD_REG(addr);
+    return 0;
+}
+
+static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
+{
+    struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
+    uint32_t ret;
+
+    if (addr & 2)
+        return s->readh;
+    else {
+        ret = omap_synctimer_readw(opaque, addr);
+        s->readh = ret >> 16;
+        return ret & 0xffff;
+    }
+}
+
+static CPUReadMemoryFunc * const omap_synctimer_readfn[] = {
+    omap_badwidth_read32,
+    omap_synctimer_readh,
+    omap_synctimer_readw,
+};
+
+static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    OMAP_BAD_REG(addr);
+}
+
+static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = {
+    omap_badwidth_write32,
+    omap_synctimer_write,
+    omap_synctimer_write,
+};
+
+struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
+                struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
+{
+    struct omap_synctimer_s *s = qemu_mallocz(sizeof(*s));
+
+    omap_synctimer_reset(s);
+    omap_l4_attach(ta, 0, l4_register_io_memory(
+                      omap_synctimer_readfn, omap_synctimer_writefn, s));
+
+    return s;
+}
