diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 75ca703..d0938c9 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -24,6 +24,7 @@ odpinclude_HEADERS = \
 		  $(srcdir)/include/odp/cpumask.h \
 		  $(srcdir)/include/odp/crypto.h \
 		  $(srcdir)/include/odp/debug.h \
+		  $(srcdir)/include/odp/dma.h \
 		  $(srcdir)/include/odp/errno.h \
 		  $(srcdir)/include/odp/event.h \
 		  $(srcdir)/include/odp/hash.h \
@@ -63,6 +64,7 @@ odpplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/plat/classification_types.h \
 		  $(srcdir)/include/odp/plat/cpumask_types.h \
 		  $(srcdir)/include/odp/plat/crypto_types.h \
+		  $(srcdir)/include/odp/plat/dma_types.h \
 		  $(srcdir)/include/odp/plat/event_types.h \
 		  $(srcdir)/include/odp/plat/packet_types.h \
 		  $(srcdir)/include/odp/plat/packet_io_types.h \
@@ -93,6 +95,7 @@ noinst_HEADERS = \
 		  ${srcdir}/include/odp_classification_internal.h \
 		  ${srcdir}/include/odp_crypto_internal.h \
 		  ${srcdir}/include/odp_debug_internal.h \
+		  ${srcdir}/include/odp_dma_internal.h \
 		  ${srcdir}/include/odp_forward_typedefs_internal.h \
 		  ${srcdir}/include/odp_internal.h \
 		  ${srcdir}/include/odp_name_table_internal.h \
@@ -122,6 +125,7 @@ __LIB__libodp_la_SOURCES = \
 			   odp_cpumask.c \
 			   odp_cpumask_task.c \
 			   odp_crypto.c \
+			   odp_dma.c \
 			   odp_errno.c \
 			   odp_event.c \
 			   odp_hash.c \
diff --git a/platform/linux-generic/include/odp/dma.h b/platform/linux-generic/include/odp/dma.h
new file mode 100644
index 0000000..af7aaeb
--- /dev/null
+++ b/platform/linux-generic/include/odp/dma.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP dma interface
+ */
+
+#include <odp/plat/dma_types.h>
+
+#ifndef ODP_PLAT_DMA_H_
+#define ODP_PLAT_DMA_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup odp_dma
+ *  @{
+ */
+
+/**
+ * @}
+ */
+
+#include <odp/api/dma.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ODP_PLAT_DMA_H_ */
diff --git a/platform/linux-generic/include/odp/plat/dma_types.h b/platform/linux-generic/include/odp/plat/dma_types.h
new file mode 100644
index 0000000..8f180de
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/dma_types.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP dma interface
+ */
+
+#ifndef ODP_DMA_TYPES_H_
+#define ODP_DMA_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/std_types.h>
+#include <odp/plat/strong_types.h>
+
+/** @addtogroup odp_dma
+ *  @{
+ */
+
+/** A address usable by a DMA (i.e. either physical or iova, if iommu ) */
+typedef uint64_t odp_dma_addr_t;
+
+/** DMA descriptor */
+typedef ODP_HANDLE_T(odp_dma_map_t);
+#define ODP_DMA_REGION_INVALID  _odp_cast_scalar(odp_dma_map_t, 0)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ODP_DMA_TYPES_H_ */
diff --git a/platform/linux-generic/include/odp_dma_internal.h b/platform/linux-generic/include/odp_dma_internal.h
new file mode 100644
index 0000000..888ef3b
--- /dev/null
+++ b/platform/linux-generic/include/odp_dma_internal.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP dma interface - implementation internal
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ODP_DMA_INTERNAL_H_
+#define ODP_DMA_INTERNAL_H_
+
+#include <odp/std_types.h>
+#include <odp/debug.h>
+#include <odp/align.h>
+#include <odp_align_internal.h>
+#include <odp/byteorder.h>
+
+/** @addtogroup odp_dma
+ *  @{
+ */
+
+/** the linux implementation of a DMA map descriptor (odp_dma_map_t) */
+typedef struct dma_map_t dma_map_t;
+typedef struct dma_map_t {
+	/**< address (virtual, in driver user space) of the region */
+	void *addr;
+	/**< DMA address (either physical, or IO virtual if iommu) for region */
+	odp_dma_addr_t dma_addr;
+	/**< size of the region, in bytes */
+	uint64_t size;
+	/**< link to next dma region, or NULL for last */
+	dma_map_t *next;
+} dma_map_t;
+
+/**
+ * Returns a pointer to a linux DMA map descriptor from the related ODP
+ * handle.
+ */
+static inline dma_map_t *dma_map_handle_to_map(odp_dma_map_t map_hdl)
+{
+	return (dma_map_t *)map_hdl;
+}
+
+/**
+ * Allocate a (not filled) DMA map structure.
+ */
+dma_map_t *_odp_dma_map_alloc(void);
+
+/**
+ * Link two DMA map descriptors (hence describing a scattered area)
+ * returns a pointer to the second structure (map2).
+ */
+dma_map_t *_odp_dma_map_link(dma_map_t *map1, dma_map_t *map2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/odp_dma.c b/platform/linux-generic/odp_dma.c
new file mode 100644
index 0000000..513e46f
--- /dev/null
+++ b/platform/linux-generic/odp_dma.c
@@ -0,0 +1,78 @@
+/* Copyright (c) 2015, Linaro Limited
+ * Copyright (c) 2015, Nokia Solutions and Networks
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp/dma.h>
+#include <odp_dma_internal.h>
+#include <stdlib.h>
+#include <odp/hints.h>
+
+/* operations on DMA map descriptors: */
+
+/*
+ * allocate a single DMA region descriptor
+ */
+dma_map_t *_odp_dma_map_alloc(void)
+{
+	dma_map_t *dma_map = malloc(sizeof(dma_map_t));
+
+	if (!(dma_map))
+		return NULL;
+	dma_map->next = NULL;
+	return  dma_map;
+}
+
+/*
+ * extend a DMA region descriptor list (link map2 to map1)
+ */
+dma_map_t *_odp_dma_map_link(dma_map_t *map1, dma_map_t *map2)
+{
+	if (odp_unlikely(map2 == NULL))
+		return NULL;
+
+	if (odp_unlikely(map1 == NULL))
+		return  map2; /*first of a chain */
+
+	map1->next = map2;
+
+	return  map2;
+}
+
+void *odp_dma_map_get_addr(odp_dma_map_t map)
+{
+	return  dma_map_handle_to_map(map)->addr;
+}
+
+odp_dma_addr_t odp_dma_map_get_dma_addr(odp_dma_map_t map)
+{
+	return  dma_map_handle_to_map(map)->dma_addr;
+}
+
+int odp_dma_map_get_size(odp_dma_map_t map)
+{
+	return  dma_map_handle_to_map(map)->size;
+}
+
+odp_dma_map_t odp_dma_map_get_next(odp_dma_map_t map)
+{
+	dma_map_t *map_s = dma_map_handle_to_map(map)->next;
+
+	if (map_s)
+		return  (odp_dma_map_t)map_s;
+	else
+		return ODP_DMA_REGION_INVALID;
+}
+
+void odp_dma_map_free(odp_dma_map_t map)
+{
+	dma_map_t *next;
+	dma_map_t *map_s = dma_map_handle_to_map(map);
+
+	do {
+		next = map_s->next;
+		free(map);
+	} while (next != NULL);
+}
