Index: kernel/genarch/src/drivers/am335x/timer.c
===================================================================
--- kernel/genarch/src/drivers/am335x/timer.c	(revision 4c754f62d3b72f6ad32d4e299d025db3a4c3f3f8)
+++ kernel/genarch/src/drivers/am335x/timer.c	(revision f09f059c73939b7b0e498d8b9ec73abb78a3ae7b)
@@ -38,4 +38,10 @@
 #include <errno.h>
 
+typedef enum {
+	REG_TCLR = 0x00,
+	REG_TCRR = 0x01,
+	REG_TLDR = 0x02,
+	REG_TTGR = 0x04
+} timer_reg_t;
 
 typedef struct timer_regs_mmap {
@@ -54,4 +60,26 @@
 	{ .base = AM335x_DMTIMER7_BASE_ADDRESS, .size = AM335x_DMTIMER7_SIZE },
 };
+
+static void
+write_register_posted(am335x_timer_t *timer, timer_reg_t reg, uint32_t value)
+{
+	am335x_timer_regs_t *regs = timer->regs;
+
+	while (regs->twps & reg);
+
+	switch (reg) {
+	default:
+		return;
+	case REG_TCLR:
+		regs->tclr = value;
+		break;
+	case REG_TCRR:
+		regs->tcrr = value;
+		break;
+	case REG_TLDR:
+		regs->tldr = value;
+		break;
+	}
+}
 
 void
@@ -75,4 +103,7 @@
 	am335x_timer_regs_t *regs = timer->regs;
 
+	/* Enable the posted mode of operation */
+	regs->tsicr |= AM335x_TIMER_TSICR_POSTED_FLAG;
+
 	/* Stop the timer */
 	am335x_timer_stop(timer);
@@ -81,16 +112,21 @@
 	am335x_timer_reset(timer);
 
+	unsigned tclr = regs->tclr;
+
+	/* Disable compare mode */
+	tclr &= ~AM335x_TIMER_TCLR_CE_FLAG;
 	/* Disable the prescaler */
-	regs->tclr &= ~AM335x_TIMER_TCLR_PRE_FLAG;
+	tclr &= ~AM335x_TIMER_TCLR_PRE_FLAG;
+	/* Enable auto-reload mode */
+	tclr |= AM335x_TIMER_TCLR_AR_FLAG;
 
-	/* Enable auto-reload mode */
-	regs->tclr |= AM335x_TIMER_TCLR_AR_FLAG;
+	write_register_posted(timer, REG_TCLR, tclr);
 
 	/* Disable the emulation mode */
 	regs->tiocp_cfg |= AM335x_TIMER_TIOCPCFG_EMUFREE_FLAG;
 
-	unsigned const count = 0xFFFFFFFE - (srcclk_hz / hz);
-	regs->tcrr = count;
-	regs->tldr = count;
+	unsigned const count = 0xFFFFFFFF - (srcclk_hz / hz + 1);
+	write_register_posted(timer, REG_TCRR, count);
+	write_register_posted(timer, REG_TLDR, count);
 }
 
@@ -116,6 +152,8 @@
 	/* Disable the interrupt */
 	timer->regs->irqenable_clr |= AM335x_TIMER_IRQENABLE_CLR_OVF_FLAG;
+	timer->regs->irqwakeen &= ~AM335x_TIMER_IRQWAKEEN_OVF_FLAG;
 	/* Stop the timer */
-	timer->regs->tclr &= ~AM335x_TIMER_TCLR_ST_FLAG;
+	write_register_posted(timer, REG_TCLR,
+	    timer->regs->tclr & ~AM335x_TIMER_TCLR_ST_FLAG);
 }
 
@@ -125,6 +163,8 @@
 	/* Enable the interrupt */
 	timer->regs->irqenable_set |= AM335x_TIMER_IRQENABLE_SET_OVF_FLAG;
+	timer->regs->irqwakeen |= AM335x_TIMER_IRQWAKEEN_OVF_FLAG;
 	/* Start the clock */
-	timer->regs->tclr |= AM335x_TIMER_TCLR_ST_FLAG;
+	write_register_posted(timer, REG_TCLR,
+	    timer->regs->tclr | AM335x_TIMER_TCLR_ST_FLAG);
 }
 
