Index: uspace/drv/audio/hdaudio/hdactl.c
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.c	(revision fff4f210c7226cb6fc673764a98c4ed46b3884d3)
+++ uspace/drv/audio/hdaudio/hdactl.c	(revision 57a2208356e6cbd6dde020a912beee44deb45657)
@@ -595,5 +595,4 @@
 	}
 
-	async_usleep(5*1000*1000);
 	ddf_msg(LVL_NOTE, "intsts=0x%x", hda_reg32_read(&hda->regs->intsts));
 	ddf_msg(LVL_NOTE, "sdesc[%d].sts=0x%x",
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision fff4f210c7226cb6fc673764a98c4ed46b3884d3)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 57a2208356e6cbd6dde020a912beee44deb45657)
@@ -172,4 +172,6 @@
 	}
 
+	fibril_mutex_initialize(&hda->lock);
+
 	ddf_msg(LVL_NOTE, "create parent sess");
 	hda->parent_sess = ddf_dev_parent_sess_create(dev,
@@ -373,15 +375,27 @@
 	if (0) ddf_msg(LVL_NOTE, "## interrupt ##");
 //	ddf_msg(LVL_NOTE, "interrupt arg4=0x%x", (int)IPC_GET_ARG4(*icall));
+	hda_ctl_interrupt(hda->ctl);
+
 	if (IPC_GET_ARG3(*icall) != 0) {
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-/*		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
-		hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);*/
-	}
-	hda_ctl_interrupt(hda->ctl);
+		/* Buffer completed */
+		hda_lock(hda);
+		if (hda->playing) {
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		}
+		hda_unlock(hda);
+	}
+}
+
+void hda_lock(hda_t *hda)
+{
+	fibril_mutex_lock(&hda->lock);
+}
+
+void hda_unlock(hda_t *hda)
+{
+	fibril_mutex_unlock(&hda->lock);
 }
 
Index: uspace/drv/audio/hdaudio/hdaudio.h
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.h	(revision fff4f210c7226cb6fc673764a98c4ed46b3884d3)
+++ uspace/drv/audio/hdaudio/hdaudio.h	(revision 57a2208356e6cbd6dde020a912beee44deb45657)
@@ -38,4 +38,6 @@
 #include <async.h>
 #include <ddf/driver.h>
+#include <fibril_synch.h>
+#include <stdbool.h>
 #include <stdint.h>
 
@@ -44,4 +46,5 @@
 /** High Definition Audio driver instance */
 typedef struct hda {
+	fibril_mutex_t lock;
 	async_sess_t *parent_sess;
 	async_sess_t *ev_sess;
@@ -52,5 +55,9 @@
 	struct hda_ctl *ctl;
 	struct hda_stream *pcm_stream;
+	bool playing;
 } hda_t;
+
+extern void hda_lock(hda_t *);
+extern void hda_unlock(hda_t *);
 
 #endif
Index: uspace/drv/audio/hdaudio/pcm_iface.c
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.c	(revision fff4f210c7226cb6fc673764a98c4ed46b3884d3)
+++ uspace/drv/audio/hdaudio/pcm_iface.c	(revision 57a2208356e6cbd6dde020a912beee44deb45657)
@@ -149,7 +149,11 @@
 	hda_t *hda = fun_to_hda(fun);
 
+	hda_lock(hda);
+
 	ddf_msg(LVL_NOTE, "hda_get_buffer(): hda=%p", hda);
-	if (hda->pcm_stream != NULL)
+	if (hda->pcm_stream != NULL) {
+		hda_unlock(hda);
 		return EBUSY;
+	}
 
 	/* XXX Choose appropriate parameters */
@@ -160,6 +164,8 @@
 	ddf_msg(LVL_NOTE, "hda_get_buffer() - create stream");
 	hda->pcm_stream = hda_stream_create(hda, sdir_output, fmt);
-	if (hda->pcm_stream == NULL)
+	if (hda->pcm_stream == NULL) {
+		hda_unlock(hda);
 		return EIO;
+	}
 
 	ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
@@ -170,4 +176,6 @@
 	ddf_msg(LVL_NOTE, "hda_get_buffer() retturing EOK, buffer=%p, size=%zu",
 	    *buffer, *size);
+
+	hda_unlock(hda);
 	return EOK;
 }
@@ -184,5 +192,8 @@
 
 	ddf_msg(LVL_NOTE, "hda_set_event_session()");
+	hda_lock(hda);
 	hda->ev_sess = sess;
+	hda_unlock(hda);
+
 	return EOK;
 }
@@ -191,7 +202,13 @@
 {
 	hda_t *hda = fun_to_hda(fun);
+	async_sess_t *sess;
 
 	ddf_msg(LVL_NOTE, "hda_get_event_session()");
-	return hda->ev_sess;
+
+	hda_lock(hda);
+	sess = hda->ev_sess;
+	hda_unlock(hda);
+
+	return sess;
 }
 
@@ -200,10 +217,16 @@
 	hda_t *hda = fun_to_hda(fun);
 
+	hda_lock(hda);
+
 	ddf_msg(LVL_NOTE, "hda_release_buffer()");
-	if (hda->pcm_stream == NULL)
+	if (hda->pcm_stream == NULL) {
+		hda_unlock(hda);
 		return EINVAL;
+	}
 
 	hda_stream_destroy(hda->pcm_stream);
 	hda->pcm_stream = NULL;
+
+	hda_unlock(hda);
 	return EOK;
 }
@@ -216,11 +239,15 @@
 
 	ddf_msg(LVL_NOTE, "hda_start_playback()");
+	hda_lock(hda);
 
 	rc = hda_out_converter_setup(hda->ctl->codec, hda->pcm_stream);
-	if (rc != EOK)
+	if (rc != EOK) {
+		hda_unlock(hda);
 		return rc;
-
-	async_usleep(1000*1000);
+	}
+
 	hda_stream_start(hda->pcm_stream);
+	hda->playing = true;
+	hda_unlock(hda);
 	return EOK;
 }
@@ -231,6 +258,9 @@
 
 	ddf_msg(LVL_NOTE, "hda_stop_playback()");
+	hda_lock(hda);
 	hda_stream_stop(hda->pcm_stream);
 	hda_stream_reset(hda->pcm_stream);
+	hda->playing = false;
+	hda_unlock(hda);
 
 	hda_pcm_event(hda, PCM_EVENT_PLAYBACK_TERMINATED);
Index: uspace/drv/audio/hdaudio/stream.c
===================================================================
--- uspace/drv/audio/hdaudio/stream.c	(revision fff4f210c7226cb6fc673764a98c4ed46b3884d3)
+++ uspace/drv/audio/hdaudio/stream.c	(revision 57a2208356e6cbd6dde020a912beee44deb45657)
@@ -109,5 +109,4 @@
 	}
 */
-//	async_usleep(1000*1000);
 	/* audio_pcm_iface requires a single contiguous buffer */
 	buffer = AS_AREA_ANY;
