diff --git a/platform/linux-keystone2/Makefile.am b/platform/linux-keystone2/Makefile.am
index c482142..282f406 100644
--- a/platform/linux-keystone2/Makefile.am
+++ b/platform/linux-keystone2/Makefile.am
@@ -29,6 +29,7 @@ odpinclude_HEADERS = \
 		  $(srcdir)/include/odp/packet_io.h \
 		  $(srcdir)/include/odp/packet.h \
 		  $(srcdir)/include/odp/pool.h \
+		  $(srcdir)/include/odp/queue.h \
 		  $(linux_generic_srcdir)/include/odp/align.h \
 		  $(linux_generic_srcdir)/include/odp/atomic.h \
 		  $(linux_generic_srcdir)/include/odp/barrier.h \
@@ -42,7 +43,6 @@ odpinclude_HEADERS = \
 		  $(linux_generic_srcdir)/include/odp/hints.h \
 		  $(linux_generic_srcdir)/include/odp/init.h \
 		  $(linux_generic_srcdir)/include/odp/random.h \
-		  $(linux_generic_srcdir)/include/odp/queue.h \
 		  $(linux_generic_srcdir)/include/odp/rwlock.h \
 		  $(linux_generic_srcdir)/include/odp/schedule.h \
 		  $(linux_generic_srcdir)/include/odp/shared_memory.h \
@@ -66,6 +66,7 @@ odpplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/plat/osal.h \
 		  $(srcdir)/include/odp/plat/packet_types.h \
 		  $(srcdir)/include/odp/plat/pool_types.h \
+		  $(srcdir)/include/odp/plat/queue_types.h \
 		  $(srcdir)/include/odp/plat/state.h \
 		  $(srcdir)/include/odp/plat/ti_mcsdk.h \
 		  $(linux_generic_srcdir)/include/odp/plat/atomic_types.h \
@@ -74,7 +75,6 @@ odpplatinclude_HEADERS = \
 		  $(linux_generic_srcdir)/include/odp/plat/cpumask_types.h \
 		  $(linux_generic_srcdir)/include/odp/plat/crypto_types.h \
 		  $(linux_generic_srcdir)/include/odp/plat/packet_io_types.h \
-		  $(linux_generic_srcdir)/include/odp/plat/queue_types.h \
 		  $(linux_generic_srcdir)/include/odp/plat/schedule_types.h \
 		  $(linux_generic_srcdir)/include/odp/plat/shared_memory_types.h \
 		  $(linux_generic_srcdir)/include/odp/plat/strong_types.h \
@@ -135,6 +135,7 @@ __LIB__libodp_la_SOURCES = \
 			   odp_pool.c \
 			   odp_buffer.c \
 			   odp_packet.c \
+			   odp_queue.c \
 			   mcsdk/mcsdk_init.c \
 			   mcsdk/mcsdk_navig.c \
 			   mcsdk/mcsdk_rmclient.c \
@@ -147,6 +148,7 @@ __LIB__libodp_la_SOURCES = \
 			   ../linux-generic/odp_ring.c \
 			   ../linux-generic/odp_rwlock.c \
 			   ../linux-generic/odp_shared_memory.c \
+			   ../linux-generic/odp_schedule.c \
 			   ../linux-generic/odp_spinlock.c \
 			   ../linux-generic/odp_system_info.c \
 			   ../linux-generic/odp_thread.c \
diff --git a/platform/linux-keystone2/include/odp.h b/platform/linux-keystone2/include/odp.h
index 8737b9f..57fb5bc 100644
--- a/platform/linux-keystone2/include/odp.h
+++ b/platform/linux-keystone2/include/odp.h
@@ -39,6 +39,8 @@ extern "C" {
 #include <odp/buffer.h>
 #include <odp/pool.h>
 #include <odp/packet.h>
+#include <odp/queue.h>
+#include <odp/schedule.h>
 #include <odp/packet_flags.h>
 #include <odp/ticketlock.h>
 #include <odp/time.h>
diff --git a/platform/linux-keystone2/include/odp/plat/queue_types.h b/platform/linux-keystone2/include/odp/plat/queue_types.h
new file mode 100644
index 0000000..8bf97b6
--- /dev/null
+++ b/platform/linux-keystone2/include/odp/plat/queue_types.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, Linaro Limited
+ * Copyright (c) 2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP queue types
+ */
+
+#ifndef ODP_PLAT_QUEUE_TYPES_H_
+#define ODP_PLAT_QUEUE_TYPES_H_
+
+#include <odp/std_types.h>
+#include <odp/plat/strong_types.h>
+
+/**
+ * ODP queue
+ */
+typedef odp_handle_t odp_queue_t;
+
+/**
+ * Queue group instance type
+ */
+typedef odp_handle_t odp_queue_group_t;
+
+/** Invalid queue */
+#define ODP_QUEUE_INVALID ((odp_queue_t)-1)
+
+/** Maximum queue name lenght in chars */
+#define ODP_QUEUE_NAME_LEN 32
+
+
+/**
+ * ODP queue type
+ */
+typedef int odp_queue_type_t;
+
+#define ODP_QUEUE_TYPE_SCHED  0  /**< Scheduled queue */
+#define ODP_QUEUE_TYPE_POLL   1  /**< Not scheduled queue */
+#define ODP_QUEUE_TYPE_PKTIN  2  /**< Packet input queue */
+#define ODP_QUEUE_TYPE_PKTOUT 3  /**< Packet output queue */
+
+/**
+ * ODP schedule priority
+ */
+typedef int odp_schedule_prio_t;
+
+/** Highest scheduling priority */
+#define ODP_SCHED_PRIO_HIGHEST  0
+
+/** Normal scheduling priority */
+#define ODP_SCHED_PRIO_NORMAL   (ODP_CONFIG_SCHED_PRIOS / 2)
+
+/** Lowest scheduling priority */
+#define ODP_SCHED_PRIO_LOWEST   (ODP_CONFIG_SCHED_PRIOS - 1)
+
+/** Default scheduling priority */
+#define ODP_SCHED_PRIO_DEFAULT  ODP_SCHED_PRIO_NORMAL
+
+
+/**
+ * ODP schedule synchronisation
+ */
+typedef int odp_schedule_sync_t;
+
+#define ODP_SCHED_SYNC_NONE     0  /**< Queue not synchronised */
+#define ODP_SCHED_SYNC_ATOMIC   1  /**< Atomic queue */
+#define ODP_SCHED_SYNC_ORDERED  2  /**< Ordered queue */
+
+/** Default queue synchronisation */
+#define ODP_SCHED_SYNC_DEFAULT  ODP_SCHED_SYNC_ATOMIC
+
+/**
+ * ODP schedule core group
+ */
+typedef int odp_schedule_group_t;
+
+/** Group of all cores */
+#define ODP_SCHED_GROUP_ALL     0
+
+/** Default core group */
+#define ODP_SCHED_GROUP_DEFAULT ODP_SCHED_GROUP_ALL
+
+static inline uint64_t odp_queue_to_u64(odp_queue_t hdl)
+{
+	return _odp_pri(hdl);
+}
+
+#endif
diff --git a/platform/linux-keystone2/include/odp/queue.h b/platform/linux-keystone2/include/odp/queue.h
new file mode 100644
index 0000000..89a703a
--- /dev/null
+++ b/platform/linux-keystone2/include/odp/queue.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014, Linaro Limited
+ * Copyright (c) 2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+
+/**
+ * @file
+ *
+ * ODP queue
+ */
+
+#ifndef ODP_QUEUE_H_
+#define ODP_QUEUE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <odp/std_types.h>
+#include <odp/event.h>
+#include <odp/buffer.h>
+#include <odp/config.h>
+#include <odp/ticketlock.h>
+#include <odp/align.h>
+#include <odp/plat/queue_types.h>
+#include <odp/plat/debug.h>
+
+/**
+ * Internal implementation structures
+ */
+#define QUEUE_MULTI_MAX 8
+
+typedef struct queue_entry_s {
+	int               status ODP_ALIGNED_CACHE;
+	odp_queue_type_t  type;
+	Qmss_QueueHnd     qmss_queue;
+	void             *context;
+	int (*enqueue)(struct queue_entry_s *, odp_event_t);
+	odp_event_t (*dequeue)(struct queue_entry_s *);
+	int (*enqueue_multi)(struct queue_entry_s *, const odp_event_t *, int);
+	int (*dequeue_multi)(struct queue_entry_s *, odp_event_t *, int);
+	odp_ticketlock_t  lock;
+	odp_queue_t       handle;
+
+	odp_buffer_t      sched_buf;
+	struct {
+		odp_schedule_prio_t  prio;
+		odp_schedule_sync_t  sync;
+		odp_schedule_group_t group;
+	} sched;
+	char              name[ODP_QUEUE_NAME_LEN];
+} queue_entry_t;
+
+typedef struct {
+	queue_entry_t     queue[ODP_CONFIG_QUEUES];
+} queue_table_t;
+
+
+extern queue_table_t *queue_tbl;
+static inline queue_entry_t *queue_get_qentry(uint32_t queue_id)
+{
+	return &queue_tbl->queue[queue_id];
+}
+
+static inline uint32_t queue_to_id(odp_queue_t handle)
+{
+	return (uint32_t)handle;
+}
+
+static inline odp_queue_t queue_from_id(uint32_t queue_id)
+{
+	return (odp_queue_t)queue_id;
+}
+
+static inline queue_entry_t *_odp_queue_to_qentry(odp_queue_t handle)
+{
+	return queue_get_qentry(queue_to_id(handle));
+}
+
+static inline Qmss_QueueHnd _odp_queue_to_qmss_queue(odp_queue_t queue)
+{
+	queue_entry_t *entry = _odp_queue_to_qentry(queue);
+	return entry->qmss_queue;
+}
+
+static inline int odp_queue_set_context(odp_queue_t queue, void *context)
+{
+	_odp_queue_to_qentry(queue)->context = context;
+	return 0;
+}
+
+static inline void *odp_queue_get_context(odp_queue_t queue)
+{
+	return _odp_queue_to_qentry(queue)->context;
+}
+
+static inline int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
+{
+	queue_entry_t *qentry = _odp_queue_to_qentry(queue);
+
+	odp_pr_vdbg(">>>>>> handle: %u, event: %p\n", queue, ev);
+	ODP_ASSERT(qentry->enqueue, "No enqueue function");
+	return qentry->enqueue(qentry, ev);
+}
+
+static inline int odp_queue_enq_multi(odp_queue_t queue, const odp_event_t ev[],
+				      int num)
+{
+	queue_entry_t *qentry = _odp_queue_to_qentry(queue);
+
+	if (num > QUEUE_MULTI_MAX)
+		num = QUEUE_MULTI_MAX;
+
+	ODP_ASSERT(qentry->enqueue_multi, "No multi enqueue function");
+	return qentry->enqueue_multi(qentry, ev, num);
+}
+
+static inline odp_event_t odp_queue_deq(odp_queue_t queue)
+{
+	queue_entry_t *qentry = _odp_queue_to_qentry(queue);
+	ODP_ASSERT(qentry->dequeue, "No dequeue function");
+	return qentry->dequeue(qentry);
+}
+
+static inline int odp_queue_deq_multi(odp_queue_t queue, odp_event_t ev[],
+				      int num)
+{
+	queue_entry_t *qentry = _odp_queue_to_qentry(queue);
+
+	if (num > QUEUE_MULTI_MAX)
+		num = QUEUE_MULTI_MAX;
+
+	ODP_ASSERT(qentry->dequeue_multi, "No multi dequeue function");
+	return qentry->dequeue_multi(qentry, ev, num);
+}
+
+static inline odp_queue_type_t odp_queue_type(odp_queue_t queue)
+{
+	return _odp_queue_to_qentry(queue)->type;
+}
+
+#include <odp/api/queue.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-keystone2/include/odp_queue_internal.h b/platform/linux-keystone2/include/odp_queue_internal.h
index a0df1ac..38a59d4 100644
--- a/platform/linux-keystone2/include/odp_queue_internal.h
+++ b/platform/linux-keystone2/include/odp_queue_internal.h
@@ -19,75 +19,21 @@
 extern "C" {
 #endif
 
-#include <odp_queue.h>
-#include <odp_buffer_internal.h>
-#include <odp_packet_io.h>
-#include <odp_packet_io_internal.h>
-#include <odp_align.h>
+#include <odp/queue.h>
+#include <odp/align.h>
 
 
-#define USE_TICKETLOCK
-
-#ifdef USE_TICKETLOCK
-#include <odp_ticketlock.h>
-#else
-#include <odp_spinlock.h>
-#endif
-
-#define QUEUE_MULTI_MAX 8
-
 #define QUEUE_STATUS_FREE     0
 #define QUEUE_STATUS_READY    1
 #define QUEUE_STATUS_NOTSCHED 2
 #define QUEUE_STATUS_SCHED    3
+#define QUEUE_STATUS_DESTROYED    4
 
-/* forward declaration */
-union queue_entry_u;
-
-typedef int (*enq_func_t)(union queue_entry_u *, odp_buffer_t);
-typedef	odp_buffer_t (*deq_func_t)(union queue_entry_u *);
-
-typedef int (*enq_multi_func_t)(union queue_entry_u *, odp_buffer_t *, int);
-typedef	int (*deq_multi_func_t)(union queue_entry_u *, odp_buffer_t *, int);
-
-struct queue_entry_s {
-#ifdef USE_TICKETLOCK
-	odp_ticketlock_t  lock ODP_ALIGNED_CACHE;
-#else
-	odp_spinlock_t    lock ODP_ALIGNED_CACHE;
-#endif
-
-	int               status;
-	void             *context;
-
-	enq_func_t        enqueue ODP_ALIGNED_CACHE;
-	deq_func_t        dequeue;
-	enq_multi_func_t  enqueue_multi;
-	deq_multi_func_t  dequeue_multi;
+int queue_enq(queue_entry_t *queue, odp_event_t buf);
+odp_event_t queue_deq(queue_entry_t *queue);
 
-	odp_queue_t       handle;
-	odp_buffer_t      sched_buf;
-	odp_queue_type_t  type;
-	odp_queue_param_t param;
-	odp_pktio_t       pktin;
-	pktio_entry_t    *pktout_entry;
-	Qmss_QueueHnd     qmss_queue;
-	char              name[ODP_QUEUE_NAME_LEN];
-};
-
-typedef union queue_entry_u {
-	struct queue_entry_s s;
-	uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct queue_entry_s))];
-} queue_entry_t;
-
-
-queue_entry_t *get_qentry(uint32_t queue_id);
-
-int queue_enq(queue_entry_t *queue, odp_buffer_t buf);
-odp_buffer_t queue_deq(queue_entry_t *queue);
-
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num);
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num);
+int queue_enq_multi(queue_entry_t *queue, const odp_event_t buf[], int num);
+int queue_deq_multi(queue_entry_t *queue, odp_event_t buf[], int num);
 
 void queue_lock(queue_entry_t *queue);
 void queue_unlock(queue_entry_t *queue);
@@ -95,39 +41,29 @@ void queue_unlock(queue_entry_t *queue);
 odp_buffer_t queue_sched_buf(odp_queue_t queue);
 int queue_sched_atomic(odp_queue_t handle);
 
-static inline uint32_t queue_to_id(odp_queue_t handle)
+static inline const char *odp_queue_name(odp_queue_t queue)
 {
-	return handle - 1;
+	return _odp_queue_to_qentry(queue)->name;
 }
 
-static inline odp_queue_t queue_from_id(uint32_t queue_id)
+static inline int queue_is_free(odp_queue_t handle)
 {
-	return queue_id + 1;
-}
+	queue_entry_t *queue;
 
-static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
-{
-	uint32_t queue_id;
+	queue = _odp_queue_to_qentry(handle);
 
-	queue_id = queue_to_id(handle);
-	return get_qentry(queue_id);
+	return queue->status == QUEUE_STATUS_FREE;
 }
 
-static inline const char *odp_queue_name(odp_queue_t handle)
+static inline int queue_is_sched(odp_queue_t handle)
 {
-	return queue_to_qentry(handle)->s.name;
-}
+	queue_entry_t *queue;
 
+	queue = _odp_queue_to_qentry(handle);
 
-static inline Qmss_QueueHnd _odp_queue_to_qmss_queue(odp_queue_t queue)
-{
-	queue_entry_t *entry = queue_to_qentry(queue);
-	return entry->s.qmss_queue;
+	return (queue->status == QUEUE_STATUS_SCHED);
 }
 
-odp_queue_t _odp_queue_create(const char *name, odp_queue_type_t type,
-			     odp_queue_param_t *param, int32_t hw_queue);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-keystone2/odp_init.c b/platform/linux-keystone2/odp_init.c
index 38055e0..d6ac135 100644
--- a/platform/linux-keystone2/odp_init.c
+++ b/platform/linux-keystone2/odp_init.c
@@ -50,12 +50,11 @@ int odp_init_global(odp_init_t *params ODP_UNUSED,
 		return -1;
 	}
 
-#if 0
 	if (odp_queue_init_global()) {
 		odp_pr_err("ODP queue init failed.\n");
 		return -1;
 	}
-
+#if 0
 	if (odp_schedule_init_global()) {
 		odp_pr_err("ODP schedule init failed.\n");
 		return -1;
diff --git a/platform/linux-keystone2/odp_queue.c b/platform/linux-keystone2/odp_queue.c
index 6f77a41..f59a884 100644
--- a/platform/linux-keystone2/odp_queue.c
+++ b/platform/linux-keystone2/odp_queue.c
@@ -6,102 +6,87 @@
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp_ti_mcsdk.h>
-#include <odp_queue.h>
+#include <odp/plat/ti_mcsdk.h>
+#include <odp/queue.h>
 #include <odp_queue_internal.h>
-#include <odp_std_types.h>
-#include <odp_align.h>
-#include <odp_buffer.h>
+#include <odp/std_types.h>
+#include <odp/align.h>
+#include <odp/buffer.h>
 #include <odp_buffer_internal.h>
-#include <odp_buffer_pool_internal.h>
+#include <odp_pool_internal.h>
 #include <odp_internal.h>
-#include <odp_shared_memory.h>
+#include <odp/shared_memory.h>
 #include <odp_schedule_internal.h>
-#include <odp_config.h>
-#include <odp_packet_io_internal.h>
+#include <odp/config.h>
 #include <odp_packet_io_queue.h>
-#include <odp_debug.h>
-#include <odp_hints.h>
+#include <odp/debug.h>
+#include <odp/hints.h>
 
-#ifdef USE_TICKETLOCK
-#include <odp_ticketlock.h>
+#include <odp/ticketlock.h>
 #define LOCK(a)      odp_ticketlock_lock(a)
 #define UNLOCK(a)    odp_ticketlock_unlock(a)
 #define LOCK_INIT(a) odp_ticketlock_init(a)
-#else
-#include <odp_spinlock.h>
-#define LOCK(a)      odp_spinlock_lock(a)
-#define UNLOCK(a)    odp_spinlock_unlock(a)
-#define LOCK_INIT(a) odp_spinlock_init(a)
-#endif
 
 #include <string.h>
 
+queue_table_t *queue_tbl;
 
-typedef struct queue_table_t {
-	queue_entry_t  queue[ODP_CONFIG_QUEUES];
-} queue_table_t;
-
-static queue_table_t *queue_tbl;
-
-
-queue_entry_t *get_qentry(uint32_t queue_id)
-{
-	return &queue_tbl->queue[queue_id];
-}
-
-static int queue_init(queue_entry_t *queue, const char *name,
+static int queue_init(queue_entry_t *qentry, const char *name,
 		       odp_queue_type_t type, odp_queue_param_t *param)
 {
-	strncpy(queue->s.name, name, ODP_QUEUE_NAME_LEN - 1);
-	queue->s.type = type;
+	strncpy(qentry->name, name, ODP_QUEUE_NAME_LEN - 1);
+	qentry->type = type;
 
 	if (type != ODP_QUEUE_TYPE_PKTOUT) {
 		uint8_t allocated = 0;
-		queue->s.qmss_queue = Qmss_queueOpen(
+		qentry->qmss_queue = Qmss_queueOpen(
 				Qmss_QueueType_GENERAL_PURPOSE_QUEUE,
 				QMSS_PARAM_NOT_SPECIFIED,
 				&allocated);
 		if (allocated)
-			Qmss_queueEmpty(queue->s.qmss_queue);
+			Qmss_queueEmpty(qentry->qmss_queue);
 		odp_pr_vdbg(">>>>>> queue_s: %p, qmss_queue: %d\n",
-			    queue, queue->s.qmss_queue);
-		if (queue->s.qmss_queue < 0)
+			    qentry, qentry->qmss_queue);
+		if (qentry->qmss_queue < 0)
 			return -1;
 	}
 
 	if (param) {
-		memcpy(&queue->s.param, param, sizeof(odp_queue_param_t));
+		qentry->sched.prio  = param->sched.prio;
+		qentry->sched.sync  = param->sched.sync;
+		qentry->sched.group = param->sched.group;
+		qentry->context = param->context;
 	} else {
 		/* Defaults */
-		memset(&queue->s.param, 0, sizeof(odp_queue_param_t));
-		queue->s.param.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
-		queue->s.param.sched.sync  = ODP_SCHED_SYNC_DEFAULT;
-		queue->s.param.sched.group = ODP_SCHED_GROUP_DEFAULT;
+		qentry->sched.prio  = ODP_SCHED_PRIO_DEFAULT;
+		qentry->sched.sync  = ODP_SCHED_SYNC_DEFAULT;
+		qentry->sched.group = ODP_SCHED_GROUP_DEFAULT;
+		qentry->context = NULL;
 	}
 
 	switch (type) {
+#if 0
 	case ODP_QUEUE_TYPE_PKTIN:
-		queue->s.enqueue = NULL;
-		queue->s.dequeue = pktin_dequeue;
-		queue->s.enqueue_multi = NULL;
-		queue->s.dequeue_multi = pktin_deq_multi;
+		qentry->enqueue = NULL;
+		qentry->dequeue = pktin_dequeue;
+		qentry->enqueue_multi = NULL;
+		qentry->dequeue_multi = pktin_deq_multi;
 		break;
 	case ODP_QUEUE_TYPE_PKTOUT:
-		queue->s.enqueue = pktout_enqueue;
-		queue->s.dequeue = NULL;
-		queue->s.enqueue_multi = pktout_enq_multi;
-		queue->s.dequeue_multi = NULL;
+		qentry->enqueue = pktout_enqueue;
+		qentry->dequeue = NULL;
+		qentry->enqueue_multi = pktout_enq_multi;
+		qentry->dequeue_multi = NULL;
 		break;
+#endif
 	default:
-		queue->s.enqueue = queue_enq;
-		queue->s.dequeue = queue_deq;
-		queue->s.enqueue_multi = queue_enq_multi;
-		queue->s.dequeue_multi = queue_deq_multi;
+		qentry->enqueue = queue_enq;
+		qentry->dequeue = queue_deq;
+		qentry->enqueue_multi = queue_enq_multi;
+		qentry->dequeue_multi = queue_deq_multi;
 		break;
 	}
 
-	queue->s.sched_buf = ODP_BUFFER_INVALID;
 	return 0;
 }
 
@@ -126,16 +111,14 @@ int odp_queue_init_global(void)
 
 	for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
 		/* init locks */
-		queue_entry_t *queue = get_qentry(i);
-		LOCK_INIT(&queue->s.lock);
-		queue->s.handle = queue_from_id(i);
-		queue->s.status = QUEUE_STATUS_FREE;
+		queue_entry_t *qentry = queue_get_qentry(i);
+		LOCK_INIT(&qentry->lock);
+		qentry->handle = queue_from_id(i);
+		qentry->status = QUEUE_STATUS_FREE;
 	}
 
 	odp_pr_dbg("done\n");
 	odp_pr_dbg("Queue init global\n");
-	odp_pr_dbg("  struct queue_entry_s size %zu\n",
-		   sizeof(struct queue_entry_s));
 	odp_pr_dbg("  queue_entry_t size        %zu\n",
 		   sizeof(queue_entry_t));
 	odp_pr_dbg("\n");
@@ -143,148 +126,161 @@ int odp_queue_init_global(void)
 	return 0;
 }
 
-odp_queue_type_t odp_queue_type(odp_queue_t handle)
+int odp_queue_destroy(odp_queue_t queue)
 {
-	queue_entry_t *queue;
+	queue_entry_t *qentry = _odp_queue_to_qentry(queue);
 
-	queue = queue_to_qentry(handle);
+	if (qentry->type == ODP_QUEUE_TYPE_SCHED) {
+		ODP_ERR("Destroying of ODP_QUEUE_TYPE_SCHED is not implemented\n");
+		return -1;
+	}
+	if (qentry->status == QUEUE_STATUS_FREE) {
+		ODP_ERR("Queue is already freed\n");
+		return -1;
+	}
 
-	return queue->s.type;
+	LOCK(&qentry->lock);
+	if (qentry->type != ODP_QUEUE_TYPE_PKTOUT) {
+		uint32_t count = Qmss_getQueueEntryCount(qentry->qmss_queue);
+		if (count) {
+			ODP_ERR("Queue still has %d events\n", count);
+			UNLOCK(&qentry->lock);
+			return -1;
+		}
+		Qmss_Result qmss_ret = Qmss_queueClose(qentry->qmss_queue);
+		if (qmss_ret != QMSS_SOK) {
+			ODP_ERR("QMSS queue close failed: %d\n", qmss_ret);
+			UNLOCK(&qentry->lock);
+			return -1;
+		}
+	}
+	qentry->status = QUEUE_STATUS_FREE;
+	UNLOCK(&qentry->lock);
+
+	return 0;
 }
 
-odp_schedule_sync_t odp_queue_sched_type(odp_queue_t handle)
+odp_schedule_sync_t odp_queue_sched_type(odp_queue_t queue)
 {
-	queue_entry_t *queue;
-
-	queue = queue_to_qentry(handle);
-
-	return queue->s.param.sched.sync;
+	return _odp_queue_to_qentry(queue)->sched.sync;
 }
 
 odp_queue_t odp_queue_create(const char *name, odp_queue_type_t type,
 			      odp_queue_param_t *param)
 {
 	uint32_t i;
-	queue_entry_t *queue;
-	odp_queue_t handle = ODP_QUEUE_INVALID;
+	queue_entry_t *qentry;
+	odp_queue_t queue = ODP_QUEUE_INVALID;
 
 	odp_pr_vdbg(">>>>>> name: %s, type: %d\n", name, type);
 
 	for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
-		queue = &queue_tbl->queue[i];
+		qentry = &queue_tbl->queue[i];
 
-		if (queue->s.status != QUEUE_STATUS_FREE)
+		if (qentry->status != QUEUE_STATUS_FREE)
 			continue;
 
-		LOCK(&queue->s.lock);
-		if (queue->s.status != QUEUE_STATUS_FREE) {
-			UNLOCK(&queue->s.lock);
+		LOCK(&qentry->lock);
+		if (qentry->status != QUEUE_STATUS_FREE) {
+			UNLOCK(&qentry->lock);
 			continue;
 		}
 
-		if (queue_init(queue, name, type, param)) {
-			UNLOCK(&queue->s.lock);
+		if (queue_init(qentry, name, type, param)) {
+			UNLOCK(&qentry->lock);
 			break;
 		}
 
 		if (type == ODP_QUEUE_TYPE_SCHED ||
 		    type == ODP_QUEUE_TYPE_PKTIN)
-			queue->s.status = QUEUE_STATUS_NOTSCHED;
+			qentry->status = QUEUE_STATUS_NOTSCHED;
 		else
-			queue->s.status = QUEUE_STATUS_READY;
+			qentry->status = QUEUE_STATUS_READY;
 
-		handle = queue->s.handle;
-		odp_pr_vdbg(">>>>>> handle: %u\n", handle);
-		UNLOCK(&queue->s.lock);
+		queue = qentry->handle;
+		odp_pr_vdbg(">>>>>> handle: %u\n", queue);
+		UNLOCK(&qentry->lock);
 		break;
 	}
 
-	if (handle != ODP_QUEUE_INVALID &&
+	if (queue != ODP_QUEUE_INVALID &&
 	    (type == ODP_QUEUE_TYPE_SCHED || type == ODP_QUEUE_TYPE_PKTIN)) {
 		odp_buffer_t buf;
 
-		buf = odp_schedule_buffer_alloc(handle);
+		buf = odp_schedule_buffer_alloc(queue);
 		if (buf == ODP_BUFFER_INVALID) {
 			odp_pr_err("queue_init: sched buf alloc failed\n");
 			return ODP_QUEUE_INVALID;
 		}
 
-		queue->s.sched_buf = buf;
-		odp_schedule_mask_set(handle, queue->s.param.sched.prio);
+		qentry->sched_buf = buf;
+		odp_schedule_mask_set(queue, qentry->sched.prio);
 	}
 
-	return handle;
+	return queue;
 }
 
-odp_buffer_t queue_sched_buf(odp_queue_t handle)
-{
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
 
-	return queue->s.sched_buf;
+odp_buffer_t queue_sched_buf(odp_queue_t queue)
+{
+	return _odp_queue_to_qentry(queue)->sched_buf;
 }
 
-
 int queue_sched_atomic(odp_queue_t handle)
 {
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
-
-	return queue->s.param.sched.sync == ODP_SCHED_SYNC_ATOMIC;
+	queue_entry_t *qentry = _odp_queue_to_qentry(handle);
+	return qentry->sched.sync == ODP_SCHED_SYNC_ATOMIC;
 }
 
-
 odp_queue_t odp_queue_lookup(const char *name)
 {
 	uint32_t i;
 
 	for (i = 0; i < ODP_CONFIG_QUEUES; i++) {
-		queue_entry_t *queue = &queue_tbl->queue[i];
+		queue_entry_t *qentry = &queue_tbl->queue[i];
 
-		if (queue->s.status == QUEUE_STATUS_FREE)
+		if (qentry->status == QUEUE_STATUS_FREE)
 			continue;
 
-		LOCK(&queue->s.lock);
-		if (strcmp(name, queue->s.name) == 0) {
+		LOCK(&qentry->lock);
+		if (strcmp(name, qentry->name) == 0) {
 			/* found it */
-			UNLOCK(&queue->s.lock);
-			return queue->s.handle;
+			UNLOCK(&qentry->lock);
+			return qentry->handle;
 		}
-		UNLOCK(&queue->s.lock);
+		UNLOCK(&qentry->lock);
 	}
 
 	return ODP_QUEUE_INVALID;
 }
 
-
-int queue_enq(queue_entry_t *queue, odp_buffer_t buf)
+int queue_enq(queue_entry_t *qentry, odp_event_t ev)
 {
 	odp_pr_vdbg("queue: %s, buf: %p, qmss_queue: %d\n",
-		    queue->s.name, buf, queue->s.qmss_queue);
-	Qmss_queuePushDescSize(queue->s.qmss_queue,
-			       _odp_buf_to_cppi_desc(buf),
+		    qentry->name, ev, qentry->qmss_queue);
+	Qmss_queuePushDescSize(qentry->qmss_queue,
+			       _odp_ev_to_cppi_desc(ev),
 			       NWAL_DESC_SIZE);
 #if 1
-	if (queue->s.type == ODP_QUEUE_TYPE_SCHED) {
+	if (qentry->type == ODP_QUEUE_TYPE_SCHED) {
 		int sched = 0;
-		LOCK(&queue->s.lock);
-		if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
-			queue->s.status = QUEUE_STATUS_SCHED;
+		LOCK(&qentry->lock);
+		if (qentry->status == QUEUE_STATUS_NOTSCHED) {
+			qentry->status = QUEUE_STATUS_SCHED;
 			sched = 1;
 		}
-		odp_pr_vdbg("status: %d, sched: %d\n", queue->s.status, sched);
-		UNLOCK(&queue->s.lock);
+		odp_pr_vdbg("status: %d, sched: %d\n", qentry->status, sched);
+		UNLOCK(&qentry->lock);
 		/* Add queue to scheduling */
 		if (sched)
-			odp_schedule_queue(queue->s.handle,
-					   queue->s.param.sched.prio);
+			odp_schedule_queue(qentry->handle,
+					   qentry->sched.prio);
 	}
 #endif
 	return 0;
 }
 
-
-int queue_enq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
+int queue_enq_multi(queue_entry_t *qentry, const odp_event_t ev[], int num)
 {
 	int i;
 
@@ -295,92 +291,67 @@ int queue_enq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
 	for (i = 0; i < num; i++) {
 		/** @todo: Implement multi dequeue a lower level */
 		odp_pr_vdbg("queue: %s, buf: %p, qmss_queue: %d\n",
-			    queue->s.name, buf[i], queue->s.qmss_queue);
-		Qmss_queuePushDescSize(queue->s.qmss_queue,
-				       _odp_buf_to_cppi_desc(buf[i]),
+			    qentry->name, ev[i], qentry->qmss_queue);
+		Qmss_queuePushDescSize(qentry->qmss_queue,
+				       _odp_ev_to_cppi_desc(ev[i]),
 				       NWAL_DESC_SIZE);
 	}
 
-	if (queue->s.type == ODP_QUEUE_TYPE_SCHED) {
+	if (qentry->type == ODP_QUEUE_TYPE_SCHED) {
 		int sched = 0;
-		LOCK(&queue->s.lock);
-		if (queue->s.status == QUEUE_STATUS_NOTSCHED) {
-			queue->s.status = QUEUE_STATUS_SCHED;
+		LOCK(&qentry->lock);
+		if (qentry->status == QUEUE_STATUS_NOTSCHED) {
+			qentry->status = QUEUE_STATUS_SCHED;
 			sched = 1;
 		}
-		odp_pr_vdbg("status: %d, sched: %d\n", queue->s.status, sched);
-		UNLOCK(&queue->s.lock);
+		odp_pr_vdbg("status: %d, sched: %d\n", qentry->status, sched);
+		UNLOCK(&qentry->lock);
 		/* Add queue to scheduling */
 		if (sched)
-			odp_schedule_queue(queue->s.handle,
-					   queue->s.param.sched.prio);
+			odp_schedule_queue(qentry->handle,
+					   qentry->sched.prio);
 	}
-	return 0;
-}
-
-
-int odp_queue_enq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
-{
-	queue_entry_t *queue;
-
-	if (num > QUEUE_MULTI_MAX)
-		num = QUEUE_MULTI_MAX;
-
-	queue = queue_to_qentry(handle);
-
-	ODP_ASSERT(queue->s.enqueue_multi, "No multi enqueue function");
-	return queue->s.enqueue_multi(queue, buf, num);
+	return num;
 }
 
 
-int odp_queue_enq(odp_queue_t handle, odp_buffer_t buf)
-{
-	queue_entry_t *queue;
-
-	queue   = queue_to_qentry(handle);
-
-	odp_pr_vdbg(">>>>>> handle: %u, buf: %p\n", handle, buf);
-	ODP_ASSERT(queue->s.enqueue, "No enqueue function");
-	return queue->s.enqueue(queue, buf);
-}
-
-odp_buffer_t queue_deq(queue_entry_t *queue)
+odp_event_t queue_deq(queue_entry_t *qentry)
 {
 	Cppi_HostDesc *desc;
 
-	desc = (void *)QMSS_DESC_PTR(Qmss_queuePop(queue->s.qmss_queue));
+	desc = (void *)QMSS_DESC_PTR(Qmss_queuePop(qentry->qmss_queue));
 	odp_pr_vdbg("queue: %s, buf: %p, qmss_queue: %d\n",
-		    queue->s.name, desc, queue->s.qmss_queue);
-
-	if (!desc && queue->s.type == ODP_QUEUE_TYPE_SCHED) {
-		LOCK(&queue->s.lock);
-		if (!desc && queue->s.status == QUEUE_STATUS_SCHED)
-			queue->s.status = QUEUE_STATUS_NOTSCHED;
-		odp_pr_vdbg("status: %d\n", queue->s.status);
-		UNLOCK(&queue->s.lock);
+		    qentry->name, desc, qentry->qmss_queue);
+
+	if (!desc && qentry->type == ODP_QUEUE_TYPE_SCHED) {
+		LOCK(&qentry->lock);
+		if (!desc && qentry->status == QUEUE_STATUS_SCHED)
+			qentry->status = QUEUE_STATUS_NOTSCHED;
+		odp_pr_vdbg("status: %d\n", qentry->status);
+		UNLOCK(&qentry->lock);
 	}
 
-	return _cppi_desc_to_odp_buf(desc);
+	return _cppi_desc_to_odp_ev(desc);
 }
 
 
-int queue_deq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
+int queue_deq_multi(queue_entry_t *qentry, odp_event_t ev[], int num)
 {
 	int i;
 	for (i = 0; i < num; i++) {
 		Cppi_HostDesc *desc;
 		/** @todo: Implement multi dequeue a lower level */
-		desc = Qmss_queuePop(queue->s.qmss_queue);
+		desc = Qmss_queuePop(qentry->qmss_queue);
 		desc = (void *)QMSS_DESC_PTR(desc);
-		buf[i] = _cppi_desc_to_odp_buf(desc);
-		if (!buf[i]) {
-			if (queue->s.type != ODP_QUEUE_TYPE_SCHED)
+		ev[i] = _cppi_desc_to_odp_ev(desc);
+		if (!ev[i]) {
+			if (qentry->type != ODP_QUEUE_TYPE_SCHED)
 				break;
-			LOCK(&queue->s.lock);
-			if (queue->s.status == QUEUE_STATUS_SCHED)
-				queue->s.status = QUEUE_STATUS_NOTSCHED;
-			odp_pr_vdbg("status: %d\n", queue->s.status);
-			UNLOCK(&queue->s.lock);
+			LOCK(&qentry->lock);
+			if (qentry->status == QUEUE_STATUS_SCHED)
+				qentry->status = QUEUE_STATUS_NOTSCHED;
+			odp_pr_vdbg("status: %d\n", qentry->status);
+			UNLOCK(&qentry->lock);
 			break;
 		}
 	}
@@ -388,53 +359,12 @@ int queue_deq_multi(queue_entry_t *queue, odp_buffer_t buf[], int num)
 	return i;
 }
 
-
-int odp_queue_deq_multi(odp_queue_t handle, odp_buffer_t buf[], int num)
+void queue_lock(queue_entry_t *qentry)
 {
-	queue_entry_t *queue;
-
-	if (num > QUEUE_MULTI_MAX)
-		num = QUEUE_MULTI_MAX;
-
-	queue = queue_to_qentry(handle);
-
-	ODP_ASSERT(queue->s.dequeue_multi, "No multi dequeue function");
-	return queue->s.dequeue_multi(queue, buf, num);
+	LOCK(&qentry->lock);
 }
 
-
-odp_buffer_t odp_queue_deq(odp_queue_t handle)
-{
-	queue_entry_t *queue;
-
-	queue   = queue_to_qentry(handle);
-	ODP_ASSERT(queue->s.dequeue, "No dequeue function");
-	return queue->s.dequeue(queue);
-}
-
-int odp_queue_set_context(odp_queue_t handle, void *context)
-{
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
-	queue->s.context = context;
-	return 0;
-}
-
-void *odp_queue_get_context(odp_queue_t handle)
-{
-	queue_entry_t *queue;
-	queue = queue_to_qentry(handle);
-	return queue->s.context;
-}
-
-
-void queue_lock(queue_entry_t *queue)
-{
-	LOCK(&queue->s.lock);
-}
-
-
-void queue_unlock(queue_entry_t *queue)
+void queue_unlock(queue_entry_t *qentry)
 {
-	UNLOCK(&queue->s.lock);
+	UNLOCK(&qentry->lock);
 }
