diff --git a/include/odp_drv.h b/include/odp_drv.h
index 35e070c..776cf12 100644
--- a/include/odp_drv.h
+++ b/include/odp_drv.h
@@ -22,6 +22,7 @@ extern C {
 #include <odp/drv/atomic.h>
 #include <odp/drv/byteorder.h>
 #include <odp/drv/compiler.h>
+#include <odp/drv/spinlock.h>
 #include <odp/drv/std_types.h>
 #include <odp/drv/sync.h>
 
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 109b42e..6bd95a3 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -97,13 +97,15 @@ odpdrvinclude_HEADERS = \
 		  $(srcdir)/include/odp/drv/atomic.h \
 		  $(srcdir)/include/odp/drv/byteorder.h \
 		  $(srcdir)/include/odp/drv/compiler.h \
+		  $(srcdir)/include/odp/drv/spinlock.h \
 		  $(srcdir)/include/odp/drv/std_types.h \
 		  $(srcdir)/include/odp/drv/sync.h
 
 odpdrvplatincludedir = $(includedir)/odp/drv/plat
 odpdrvplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/drv/plat/atomic_types.h \
-		  $(srcdir)/include/odp/drv/plat/byteorder_types.h
+		  $(srcdir)/include/odp/drv/plat/byteorder_types.h \
+		  $(srcdir)/include/odp/drv/plat/spinlock_types.h
 
 noinst_HEADERS = \
 		  ${srcdir}/include/odp_align_internal.h \
@@ -201,6 +203,7 @@ __LIB__libodp_linux_la_SOURCES = \
 			   odp_version.c \
 			   odp_weak.c \
 			   drv_atomic.c \
+			   drv_spinlock.c \
 			   arch/@ARCH_DIR@/odp_cpu_arch.c \
 			   arch/@ARCH_DIR@/odp_sysinfo_parse.c
 
diff --git a/platform/linux-generic/drv_spinlock.c b/platform/linux-generic/drv_spinlock.c
new file mode 100644
index 0000000..69e3da7
--- /dev/null
+++ b/platform/linux-generic/drv_spinlock.c
@@ -0,0 +1,39 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp/drv/spinlock.h>
+#include <odp_atomic_internal.h>
+
+void odpdrv_spinlock_init(odpdrv_spinlock_t *spinlock)
+{
+	_odp_atomic_flag_init(&spinlock->lock, 0);
+}
+
+void odpdrv_spinlock_lock(odpdrv_spinlock_t *spinlock)
+{
+	/* While the lock is already taken... */
+	while (_odp_atomic_flag_tas(&spinlock->lock))
+		/* ...spin reading the flag (relaxed MM),
+		 * the loop will exit when the lock becomes available
+		 * and we will retry the TAS operation above */
+		while (_odp_atomic_flag_load(&spinlock->lock))
+			odp_cpu_pause();
+}
+
+int odpdrv_spinlock_trylock(odpdrv_spinlock_t *spinlock)
+{
+	return (_odp_atomic_flag_tas(&spinlock->lock) == 0);
+}
+
+void odpdrv_spinlock_unlock(odpdrv_spinlock_t *spinlock)
+{
+	_odp_atomic_flag_clear(&spinlock->lock);
+}
+
+int odpdrv_spinlock_is_locked(odpdrv_spinlock_t *spinlock)
+{
+	return _odp_atomic_flag_load(&spinlock->lock) != 0;
+}
diff --git a/platform/linux-generic/include/odp/drv/plat/spinlock_types.h b/platform/linux-generic/include/odp/drv/plat/spinlock_types.h
new file mode 100644
index 0000000..41dd9ac
--- /dev/null
+++ b/platform/linux-generic/include/odp/drv/plat/spinlock_types.h
@@ -0,0 +1,33 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODPDRV spinlock
+ */
+
+#ifndef ODPDRV_SPINLOCK_TYPES_H_
+#define ODPDRV_SPINLOCK_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/drv/std_types.h>
+
+/** @internal */
+struct odpdrv_spinlock_s {
+	char lock;  /**< lock flag, should match odpdrv_atomic_flag_t */
+};
+
+typedef struct odpdrv_spinlock_s odpdrv_spinlock_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/drv/spinlock.h b/platform/linux-generic/include/odp/drv/spinlock.h
new file mode 100644
index 0000000..dd05f8c
--- /dev/null
+++ b/platform/linux-generic/include/odp/drv/spinlock.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODPDRV spinlock
+ */
+
+#ifndef ODPDRV_PLAT_SPINLOCK_H_
+#define ODPDRV_PLAT_SPINLOCK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/drv/plat/spinlock_types.h>
+
+#include <odp/drv/spec/spinlock.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
