diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 9057087b5..540bb1110 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -919,6 +919,25 @@ static int spi_self_checking(struct intel_max10_device *dev)
 	return 0;
 }
 
+static void init_spi_share_data(struct ifpga_fme_hw *fme,
+				struct altera_spi_device *spi)
+{
+	struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
+	opae_share_data *sd = NULL;
+
+	if (hw && hw->adapter && hw->adapter->shm.ptr) {
+		dev_info(NULL, "transfer share data to spi\n");
+		sd = (opae_share_data *)hw->adapter->shm.ptr;
+		spi->mutex = &sd->spi_mutex;
+		spi->dtb_sz_ptr = &sd->dtb_size;
+		spi->dtb = sd->dtb;
+	} else {
+		spi->mutex = NULL;
+		spi->dtb_sz_ptr = NULL;
+		spi->dtb = NULL;
+	}
+}
+
 static int fme_spi_init(struct ifpga_feature *feature)
 {
 	struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
@@ -935,6 +954,7 @@ static int fme_spi_init(struct ifpga_feature *feature)
 	spi_master = altera_spi_alloc(feature->addr, TYPE_SPI);
 	if (!spi_master)
 		return -ENODEV;
+	init_spi_share_data(fme, spi_master);
 
 	altera_spi_init(spi_master);
 
@@ -945,7 +965,6 @@ static int fme_spi_init(struct ifpga_feature *feature)
 		goto spi_fail;
 	}
 
-
 	fme->max10_dev = max10;
 
 	/* SPI self test */
@@ -1084,11 +1103,15 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
 	spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI);
 	if (!spi_master)
 		return -ENODEV;
+	init_spi_share_data(fme, spi_master);
 
 	/**
 	 * 1. wait A10 NIOS initial finished and
 	 * release the SPI master to Host
 	 */
+	if (spi_master->mutex)
+		pthread_mutex_lock(spi_master->mutex);
+
 	ret = nios_spi_wait_init_done(spi_master);
 	if (ret != 0) {
 		dev_err(fme, "FME NIOS_SPI init fail\n");
@@ -1101,6 +1124,9 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
 	if (nios_spi_check_error(spi_master))
 		dev_info(fme, "NIOS_SPI INIT done, but found some error\n");
 
+	if (spi_master->mutex)
+		pthread_mutex_unlock(spi_master->mutex);
+
 	/* 3. init the spi master*/
 	altera_spi_init(spi_master);
 
@@ -1112,11 +1138,12 @@ static int fme_nios_spi_init(struct ifpga_feature *feature)
 		goto release_dev;
 	}
 
+	fme->max10_dev = max10;
+
 	max10->bus = hw->pci_data->bus;
 
 	fme_get_board_interface(fme);
 
-	fme->max10_dev = max10;
 	mgr->sensor_list = &max10->opae_sensor_list;
 
 	/* SPI self test */
@@ -1178,6 +1205,25 @@ static int i2c_mac_rom_test(struct altera_i2c_dev *dev)
 	return 0;
 }
 
+static void init_i2c_mutex(struct ifpga_fme_hw *fme)
+{
+	struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
+	struct altera_i2c_dev *i2c_dev;
+	opae_share_data *sd = NULL;
+
+	if (fme->i2c_master) {
+		i2c_dev = (struct altera_i2c_dev *)fme->i2c_master;
+		if (hw && hw->adapter && hw->adapter->shm.ptr) {
+			dev_info(NULL, "use multi-process mutex in i2c\n");
+			sd = (opae_share_data *)hw->adapter->shm.ptr;
+			i2c_dev->mutex = &sd->i2c_mutex;
+		} else {
+			dev_info(NULL, "use multi-thread mutex in i2c\n");
+			i2c_dev->mutex = &i2c_dev->lock;
+		}
+	}
+}
+
 static int fme_i2c_init(struct ifpga_feature *feature)
 {
 	struct feature_fme_i2c *i2c;
@@ -1191,6 +1237,8 @@ static int fme_i2c_init(struct ifpga_feature *feature)
 	if (!fme->i2c_master)
 		return -ENODEV;
 
+	init_i2c_mutex(fme);
+
 	/* MAC ROM self test */
 	i2c_mac_rom_test(fme->i2c_master);
 
diff --git a/drivers/raw/ifpga/base/meson.build b/drivers/raw/ifpga/base/meson.build
index b13e13e89..da2d6e33c 100644
--- a/drivers/raw/ifpga/base/meson.build
+++ b/drivers/raw/ifpga/base/meson.build
@@ -23,6 +23,18 @@ sources = [
 	'opae_eth_group.c',
 ]
 
+rtdep = dependency('librt', required: false)
+if not rtdep.found()
+	rtdep = cc.find_library('librt', required: false)
+endif
+if not rtdep.found()
+	build = false
+	reason = 'missing dependency, "librt"'
+	subdir_done()
+endif
+
+ext_deps += rtdep
+
 base_lib = static_library('ifpga_rawdev_base', sources,
 	dependencies: static_rte_eal,
 	c_args: cflags)
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index c969dfed3..600afdea1 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -2,6 +2,10 @@
  * Copyright(c) 2010-2018 Intel Corporation
  */
 
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "opae_hw_api.h"
 #include "opae_debug.h"
 #include "ifpga_api.h"
@@ -305,6 +309,244 @@ static struct opae_adapter_ops *match_ops(struct opae_adapter *adapter)
 	return NULL;
 }
 
+static void opae_mutex_init(pthread_mutex_t *mutex)
+{
+	pthread_mutexattr_t mattr;
+
+	pthread_mutexattr_init(&mattr);
+	pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
+	pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
+	pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST);
+	pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT);
+	pthread_mutex_init(mutex, &mattr);
+	pthread_mutexattr_destroy(&mattr);
+}
+
+static int opae_shm_open(char *shm_name, u32 size, int *new_shm)
+{
+	int shm_id;
+	int ret;
+
+	shm_id = shm_open(shm_name, O_CREAT | O_EXCL | O_RDWR, 0666);
+	if (shm_id == -1) {
+		if (errno == EEXIST) {
+			dev_info(NULL, "shared memory %s already exist\n",
+					shm_name);
+			shm_id = shm_open(shm_name, O_RDWR, 0666);
+		} else {
+			dev_err(NULL, "failed to create shared memory %s\n",
+					shm_name);
+			return -1;
+		}
+	} else {
+		*new_shm = 1;
+		ret = ftruncate(shm_id, size);
+		if (ret == -1) {
+			dev_err(NULL,
+					"failed to set shared memory size to %u\n",
+					size);
+			ret = shm_unlink(shm_name);
+			if (ret == -1) {
+				dev_err(NULL,
+						"failed to unlink shared memory %s\n",
+						shm_name);
+			}
+			return -1;
+		}
+	}
+
+	return shm_id;
+}
+
+static pthread_mutex_t *opae_adapter_mutex_open(struct opae_adapter *adapter)
+{
+	char shm_name[32];
+	void *ptr;
+	int shm_id;
+	int new_shm = 0;
+
+	if (!adapter->data)
+		return NULL;
+	adapter->lock = NULL;
+
+	snprintf(shm_name, sizeof(shm_name), "/mutex.IFPGA:%s", adapter->name);
+	shm_id = opae_shm_open(shm_name, sizeof(pthread_mutex_t), &new_shm);
+	if (shm_id == -1) {
+		dev_err(NULL, "failed to open shared memory %s\n", shm_name);
+	} else {
+		dev_info(NULL, "shared memory %s id is %d\n",
+				shm_name, shm_id);
+		ptr = mmap(NULL, sizeof(pthread_mutex_t),
+				PROT_READ | PROT_WRITE, MAP_SHARED,
+				shm_id, 0);
+		adapter->lock = (pthread_mutex_t *)ptr;
+		if (ptr) {
+			dev_info(NULL,
+					"shared memory %s address is %p\n",
+					shm_name, ptr);
+			if (new_shm)
+				opae_mutex_init(adapter->lock);
+		} else {
+			dev_err(NULL, "failed to map shared memory %s\n",
+					shm_name);
+		}
+	}
+
+	return adapter->lock;
+}
+
+static void opae_adapter_mutex_close(struct opae_adapter *adapter)
+{
+	char shm_name[32];
+	int ret;
+
+	if (!adapter->lock)
+		return;
+
+	snprintf(shm_name, sizeof(shm_name), "/mutex.IFPGA:%s", adapter->name);
+
+	ret = munmap(adapter->lock, sizeof(pthread_mutex_t));
+	if (ret == -1)
+		dev_err(NULL, "failed to unmap shared memory %s\n", shm_name);
+	else
+		adapter->lock = NULL;
+}
+
+/**
+ * opae_adapter_lock - lock this adapter
+ * @adapter: adapter to lock.
+ * @timeout: maximum time to wait for lock done
+ *           -1  wait until the lock is available
+ *           0   do not wait and return immediately
+ *           t   positive time in second to wait
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_adapter_lock(struct opae_adapter *adapter, int timeout)
+{
+	struct timespec t;
+	int ret = -EINVAL;
+
+	if (adapter && adapter->lock) {
+		if (timeout < 0) {
+			ret = pthread_mutex_lock(adapter->lock);
+		} else if (timeout == 0) {
+			ret = pthread_mutex_trylock(adapter->lock);
+		} else {
+			clock_gettime(CLOCK_REALTIME, &t);
+			t.tv_sec += timeout;
+			ret = pthread_mutex_timedlock(adapter->lock, &t);
+		}
+	}
+	return ret;
+}
+
+/**
+ * opae_adapter_unlock - unlock this adapter
+ * @adapter: adapter to unlock.
+ *
+ * Return: 0 on success, otherwise error code.
+ */
+int opae_adapter_unlock(struct opae_adapter *adapter)
+{
+	int ret = -EINVAL;
+
+	if (adapter && adapter->lock)
+		ret = pthread_mutex_unlock(adapter->lock);
+
+	return ret;
+}
+
+static void opae_adapter_shm_init(struct opae_adapter *adapter)
+{
+	opae_share_data *sd;
+
+	if (!adapter->shm.ptr)
+		return;
+
+	sd = (opae_share_data *)adapter->shm.ptr;
+	dev_info(NULL, "initialize shared memory\n");
+	opae_mutex_init(&sd->spi_mutex);
+	opae_mutex_init(&sd->i2c_mutex);
+	sd->ref_cnt = 0;
+	sd->dtb_size = SHM_BLK_SIZE;
+}
+
+static void *opae_adapter_shm_alloc(struct opae_adapter *adapter)
+{
+	char shm_name[32];
+	opae_share_data *sd;
+	u32 size = sizeof(opae_share_data);
+	int shm_id;
+	int new_shm = 0;
+
+	if (!adapter->data)
+		return NULL;
+
+	snprintf(shm_name, sizeof(shm_name), "/IFPGA:%s", adapter->name);
+	adapter->shm.ptr = NULL;
+
+	opae_adapter_lock(adapter, -1);
+	shm_id = opae_shm_open(shm_name, size, &new_shm);
+	if (shm_id == -1) {
+		dev_err(NULL, "failed to open shared memory %s\n", shm_name);
+	} else {
+		dev_info(NULL, "shared memory %s id is %d\n",
+				shm_name, shm_id);
+		adapter->shm.id = shm_id;
+		adapter->shm.size = size;
+		adapter->shm.ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+							MAP_SHARED, shm_id, 0);
+		if (adapter->shm.ptr) {
+			dev_info(NULL,
+					"shared memory %s address is %p\n",
+					shm_name, adapter->shm.ptr);
+			if (new_shm)
+				opae_adapter_shm_init(adapter);
+			sd = (opae_share_data *)adapter->shm.ptr;
+			sd->ref_cnt++;
+		} else {
+			dev_err(NULL, "failed to map shared memory %s\n",
+					shm_name);
+		}
+	}
+	opae_adapter_unlock(adapter);
+
+	return adapter->shm.ptr;
+}
+
+static void opae_adapter_shm_free(struct opae_adapter *adapter)
+{
+	char shm_name[32];
+	opae_share_data *sd;
+	u32 ref_cnt;
+	int ret;
+
+	if (!adapter->shm.ptr)
+		return;
+
+	sd = (opae_share_data *)adapter->shm.ptr;
+	snprintf(shm_name, sizeof(shm_name), "/IFPGA:%s", adapter->name);
+
+	opae_adapter_lock(adapter, -1);
+	ref_cnt = --sd->ref_cnt;
+	ret = munmap(adapter->shm.ptr, adapter->shm.size);
+	if (ret == -1)
+		dev_err(NULL, "failed to unmap shared memory %s\n", shm_name);
+	else
+		adapter->shm.ptr = NULL;
+
+	if (ref_cnt == 0) {
+		dev_info(NULL, "unlink shared memory %s\n", shm_name);
+		ret = shm_unlink(shm_name);
+		if (ret == -1) {
+			dev_err(NULL, "failed to unlink shared memory %s\n",
+					shm_name);
+		}
+	}
+	opae_adapter_unlock(adapter);
+}
+
 /**
  * opae_adapter_init - init opae_adapter data structure
  * @adapter: pointer of opae_adapter data structure
@@ -324,6 +566,12 @@ int opae_adapter_init(struct opae_adapter *adapter,
 	adapter->name = name;
 	adapter->ops = match_ops(adapter);
 
+	if (!opae_adapter_mutex_open(adapter))
+		return -ENOMEM;
+
+	if (!opae_adapter_shm_alloc(adapter))
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -359,6 +607,8 @@ void opae_adapter_destroy(struct opae_adapter *adapter)
 {
 	if (adapter && adapter->ops && adapter->ops->destroy)
 		adapter->ops->destroy(adapter);
+	opae_adapter_shm_free(adapter);
+	opae_adapter_mutex_close(adapter);
 }
 
 /**
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index cf8ff93a6..e99ee4564 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -265,12 +265,36 @@ TAILQ_HEAD(opae_accelerator_list, opae_accelerator);
 #define opae_adapter_for_each_acc(adatper, acc) \
 	TAILQ_FOREACH(acc, &adapter->acc_list, node)
 
+#define SHM_PREFIX     "/IFPGA:"
+#define SHM_BLK_SIZE   0x2000
+
+typedef struct {
+	union {
+		u8 byte[SHM_BLK_SIZE];
+		struct {
+			pthread_mutex_t spi_mutex;
+			pthread_mutex_t i2c_mutex;
+			u32 ref_cnt;    /* reference count of shared memory */
+			u32 dtb_size;   /* actual length of DTB data in byte */
+		};
+	};
+	u8 dtb[SHM_BLK_SIZE];   /* DTB data */
+} opae_share_data;
+
+typedef struct  {
+	int id;       /* shared memory id returned by shm_open */
+	u32 size;     /* size of shared memory in byte */
+	void *ptr;    /* start address of shared memory */
+} opae_share_memory;
+
 struct opae_adapter {
 	const char *name;
 	struct opae_manager *mgr;
 	struct opae_accelerator_list acc_list;
 	struct opae_adapter_ops *ops;
 	void *data;
+	pthread_mutex_t *lock;   /* multi-process mutex for IFPGA */
+	opae_share_memory shm;
 };
 
 /* OPAE Adapter APIs */
@@ -280,7 +304,8 @@ void *opae_adapter_data_alloc(enum opae_adapter_type type);
 int opae_adapter_init(struct opae_adapter *adapter,
 		const char *name, void *data);
 #define opae_adapter_free(adapter) opae_free(adapter)
-
+int opae_adapter_lock(struct opae_adapter *adapter, int timeout);
+int opae_adapter_unlock(struct opae_adapter *adapter);
 int opae_adapter_enumerate(struct opae_adapter *adapter);
 void opae_adapter_destroy(struct opae_adapter *adapter);
 static inline struct opae_manager *
diff --git a/drivers/raw/ifpga/base/opae_i2c.c b/drivers/raw/ifpga/base/opae_i2c.c
index 846d751f5..598eab574 100644
--- a/drivers/raw/ifpga/base/opae_i2c.c
+++ b/drivers/raw/ifpga/base/opae_i2c.c
@@ -30,7 +30,7 @@ int i2c_read(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
 	int i = 0;
 	int ret;
 
-	pthread_mutex_lock(&dev->lock);
+	pthread_mutex_lock(dev->mutex);
 
 	if (flags & I2C_FLAG_ADDR16)
 		msgbuf[i++] = offset >> 8;
@@ -60,7 +60,7 @@ int i2c_read(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
 	ret = i2c_transfer(dev, msg, 2);
 
 exit:
-	pthread_mutex_unlock(&dev->lock);
+	pthread_mutex_unlock(dev->mutex);
 	return ret;
 }
 
@@ -72,7 +72,7 @@ int i2c_write(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
 	int ret;
 	int i = 0;
 
-	pthread_mutex_lock(&dev->lock);
+	pthread_mutex_lock(dev->mutex);
 
 	if (!dev->xfer) {
 		ret = -ENODEV;
@@ -100,7 +100,7 @@ int i2c_write(struct altera_i2c_dev *dev, int flags, unsigned int slave_addr,
 
 	opae_free(buf);
 exit:
-	pthread_mutex_unlock(&dev->lock);
+	pthread_mutex_unlock(dev->mutex);
 	return ret;
 }
 
@@ -496,6 +496,7 @@ struct altera_i2c_dev *altera_i2c_probe(void *base)
 
 	if (pthread_mutex_init(&dev->lock, NULL))
 		return NULL;
+	dev->mutex = &dev->lock;
 
 	altera_i2c_hardware_init(dev);
 
diff --git a/drivers/raw/ifpga/base/opae_i2c.h b/drivers/raw/ifpga/base/opae_i2c.h
index 266e127b7..4f6b0b28b 100644
--- a/drivers/raw/ifpga/base/opae_i2c.h
+++ b/drivers/raw/ifpga/base/opae_i2c.h
@@ -94,6 +94,7 @@ struct altera_i2c_dev {
 	u8 *buf;
 	int (*xfer)(struct altera_i2c_dev *dev, struct i2c_msg *msg, int num);
 	pthread_mutex_t lock;
+	pthread_mutex_t *mutex;  /* multi-process mutex from adapter */
 };
 
 /**
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 8e23ca18a..1a526ea54 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -138,84 +138,116 @@ static int enable_nor_flash(struct intel_max10_device *dev, bool on)
 
 static int init_max10_device_table(struct intel_max10_device *max10)
 {
+	struct altera_spi_device *spi = NULL;
 	struct max10_compatible_id *id;
 	struct fdt_header hdr;
 	char *fdt_root = NULL;
-
+	u32 dtb_magic = 0;
 	u32 dt_size, dt_addr, val;
-	int ret;
-
-	ret = max10_sys_read(max10, DT_AVAIL_REG, &val);
-	if (ret) {
-		dev_err(max10 "cannot read DT_AVAIL_REG\n");
-		return ret;
-	}
+	int ret = 0;
 
-	if (!(val & DT_AVAIL)) {
-		dev_err(max10 "DT not available\n");
+	spi = (struct altera_spi_device *)max10->spi_master;
+	if (!spi) {
+		dev_err(max10, "spi master is not set\n");
 		return -EINVAL;
 	}
+	if (spi->dtb)
+		dtb_magic = *(u32 *)spi->dtb;
+
+	if (dtb_magic != 0xEDFE0DD0) {
+		dev_info(max10, "read DTB from NOR flash\n");
+		ret = max10_sys_read(max10, DT_AVAIL_REG, &val);
+		if (ret) {
+			dev_err(max10 "cannot read DT_AVAIL_REG\n");
+			return ret;
+		}
 
-	ret = max10_sys_read(max10, DT_BASE_ADDR_REG, &dt_addr);
-	if (ret) {
-		dev_info(max10 "cannot get base addr of device table\n");
-		return ret;
-	}
-
-	ret = enable_nor_flash(max10, true);
-	if (ret) {
-		dev_err(max10 "fail to enable flash\n");
-		return ret;
-	}
+		if (!(val & DT_AVAIL)) {
+			dev_err(max10 "DT not available\n");
+			return -EINVAL;
+		}
 
-	ret = altera_nor_flash_read(max10, dt_addr, &hdr, sizeof(hdr));
-	if (ret) {
-		dev_err(max10 "read fdt header fail\n");
-		goto done;
-	}
+		ret = max10_sys_read(max10, DT_BASE_ADDR_REG, &dt_addr);
+		if (ret) {
+			dev_info(max10 "cannot get base addr of device table\n");
+			return ret;
+		}
 
-	ret = fdt_check_header(&hdr);
-	if (ret) {
-		dev_err(max10 "check fdt header fail\n");
-		goto done;
-	}
+		ret = enable_nor_flash(max10, true);
+		if (ret) {
+			dev_err(max10 "fail to enable flash\n");
+			return ret;
+		}
 
-	dt_size = fdt_totalsize(&hdr);
-	if (dt_size > DFT_MAX_SIZE) {
-		dev_err(max10 "invalid device table size\n");
-		ret = -EINVAL;
-		goto done;
-	}
+		ret = altera_nor_flash_read(max10, dt_addr, &hdr, sizeof(hdr));
+		if (ret) {
+			dev_err(max10 "read fdt header fail\n");
+			goto disable_nor_flash;
+		}
 
-	fdt_root = opae_malloc(dt_size);
-	if (!fdt_root) {
-		ret = -ENOMEM;
-		goto done;
-	}
+		ret = fdt_check_header(&hdr);
+		if (ret) {
+			dev_err(max10 "check fdt header fail\n");
+			goto disable_nor_flash;
+		}
 
-	ret = altera_nor_flash_read(max10, dt_addr, fdt_root, dt_size);
-	if (ret) {
-		dev_err(max10 "cannot read device table\n");
-		goto done;
-	}
+		dt_size = fdt_totalsize(&hdr);
+		if (dt_size > DFT_MAX_SIZE) {
+			dev_err(max10 "invalid device table size\n");
+			ret = -EINVAL;
+			goto disable_nor_flash;
+		}
 
-	id = max10_match_compatible(fdt_root);
-	if (!id) {
-		dev_err(max10 "max10 compatible not found\n");
-		ret = -ENODEV;
-		goto done;
-	}
+		fdt_root = opae_malloc(dt_size);
+		if (!fdt_root) {
+			ret = -ENOMEM;
+			goto disable_nor_flash;
+		}
 
-	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+		ret = altera_nor_flash_read(max10, dt_addr, fdt_root, dt_size);
+		if (ret) {
+			opae_free(fdt_root);
+			fdt_root = NULL;
+			dev_err(max10 "cannot read device table\n");
+			goto disable_nor_flash;
+		}
 
-	max10->id = id;
-	max10->fdt_root = fdt_root;
+		if (spi->dtb) {
+			if (*spi->dtb_sz_ptr < dt_size) {
+				dev_warn(max10,
+						 "share memory for dtb is smaller than required %u\n",
+						 dt_size);
+			} else {
+				*spi->dtb_sz_ptr = dt_size;
+			}
+			/* store dtb data into share memory  */
+			memcpy(spi->dtb, fdt_root, *spi->dtb_sz_ptr);
+		}
 
-done:
-	ret = enable_nor_flash(max10, false);
+disable_nor_flash:
+		enable_nor_flash(max10, false);
+	} else {
+		if (*spi->dtb_sz_ptr > 0) {
+			dev_info(max10, "read DTB from shared memory\n");
+			fdt_root = opae_malloc(*spi->dtb_sz_ptr);
+			if (fdt_root)
+				memcpy(fdt_root, spi->dtb, *spi->dtb_sz_ptr);
+			else
+				ret = -ENOMEM;
+		}
+	}
 
-	if (ret && fdt_root)
-		opae_free(fdt_root);
+	if (fdt_root) {
+		id = max10_match_compatible(fdt_root);
+		if (!id) {
+			dev_err(max10 "max10 compatible not found\n");
+			ret = -ENODEV;
+		} else {
+			max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+			max10->id = id;
+			max10->fdt_root = fdt_root;
+		}
+	}
 
 	return ret;
 }
diff --git a/drivers/raw/ifpga/base/opae_spi.c b/drivers/raw/ifpga/base/opae_spi.c
index bfdc83e6c..9efeecb79 100644
--- a/drivers/raw/ifpga/base/opae_spi.c
+++ b/drivers/raw/ifpga/base/opae_spi.c
@@ -285,11 +285,15 @@ void altera_spi_init(struct altera_spi_device *spi_dev)
 			spi_dev->num_chipselect,
 			spi_dev->spi_param.clock_phase);
 
+	if (spi_dev->mutex)
+		pthread_mutex_lock(spi_dev->mutex);
 	/* clear */
 	spi_reg_write(spi_dev, ALTERA_SPI_CONTROL, 0);
 	spi_reg_write(spi_dev, ALTERA_SPI_STATUS, 0);
 	/* flush rxdata */
 	spi_flush_rx(spi_dev);
+	if (spi_dev->mutex)
+		pthread_mutex_unlock(spi_dev->mutex);
 }
 
 void altera_spi_release(struct altera_spi_device *dev)
diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h
index 73a227673..af11656e4 100644
--- a/drivers/raw/ifpga/base/opae_spi.h
+++ b/drivers/raw/ifpga/base/opae_spi.h
@@ -77,6 +77,10 @@ struct altera_spi_device {
 	int (*reg_read)(struct altera_spi_device *dev, u32 reg, u32 *val);
 	int (*reg_write)(struct altera_spi_device *dev, u32 reg,
 			u32 value);
+	/* below are data to be shared in multiple process */
+	pthread_mutex_t *mutex;     /* to be passed to spi_transaction_dev */
+	unsigned int *dtb_sz_ptr;   /* to be used in init_max10_device_table */
+	unsigned char *dtb;         /* to be used in init_max10_device_table */
 };
 
 #define HEADER_LEN 8
@@ -103,6 +107,7 @@ struct spi_transaction_dev {
 	int chipselect;
 	struct spi_tran_buffer *buffer;
 	pthread_mutex_t lock;
+	pthread_mutex_t *mutex;  /* multi-process mutex from adapter */
 };
 
 struct spi_tran_header {
diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c
index d13d2fbc8..006cdb4c1 100644
--- a/drivers/raw/ifpga/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga/base/opae_spi_transaction.c
@@ -434,11 +434,11 @@ int spi_transaction_read(struct spi_transaction_dev *dev, unsigned int addr,
 {
 	int ret;
 
-	pthread_mutex_lock(&dev->lock);
+	pthread_mutex_lock(dev->mutex);
 	ret = do_transaction(dev, addr, size, data,
 			(size > SPI_REG_BYTES) ?
 			SPI_TRAN_SEQ_READ : SPI_TRAN_NON_SEQ_READ);
-	pthread_mutex_unlock(&dev->lock);
+	pthread_mutex_unlock(dev->mutex);
 
 	return ret;
 }
@@ -448,11 +448,11 @@ int spi_transaction_write(struct spi_transaction_dev *dev, unsigned int addr,
 {
 	int ret;
 
-	pthread_mutex_lock(&dev->lock);
+	pthread_mutex_lock(dev->mutex);
 	ret = do_transaction(dev, addr, size, data,
 			(size > SPI_REG_BYTES) ?
 			SPI_TRAN_SEQ_WRITE : SPI_TRAN_NON_SEQ_WRITE);
-	pthread_mutex_unlock(&dev->lock);
+	pthread_mutex_unlock(dev->mutex);
 
 	return ret;
 }
@@ -479,6 +479,13 @@ struct spi_transaction_dev *spi_transaction_init(struct altera_spi_device *dev,
 		dev_err(spi_tran_dev, "fail to init mutex lock\n");
 		goto err;
 	}
+	if (dev->mutex) {
+		dev_info(NULL, "use multi-process mutex in spi\n");
+		spi_tran_dev->mutex = dev->mutex;
+	} else {
+		dev_info(NULL, "use multi-thread mutex in spi\n");
+		spi_tran_dev->mutex = &spi_tran_dev->lock;
+	}
 
 	return spi_tran_dev;
 
