diff --git a/drivers/crypto/caam_jr/Makefile b/drivers/crypto/caam_jr/Makefile
index e22943749..cfd093a5f 100644
--- a/drivers/crypto/caam_jr/Makefile
+++ b/drivers/crypto/caam_jr/Makefile
@@ -32,6 +32,7 @@ LIBABIVER := 1
 # library source files
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr_hw.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_CAAM_JR) += caam_jr_uio.c
 # library dependencies
 
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/crypto/caam_jr/caam_jr_hw.c b/drivers/crypto/caam_jr/caam_jr_hw.c
index 73cc61a27..4a2b08995 100644
--- a/drivers/crypto/caam_jr/caam_jr_hw.c
+++ b/drivers/crypto/caam_jr/caam_jr_hw.c
@@ -91,18 +91,6 @@ hw_handle_jr_err(union hw_error_code hw_error_code __rte_unused)
 	CAAM_JR_DEBUG(" Not implemented");
 }
 
-uint32_t
-caam_jr_enable_irqs(uint32_t uio_fd __rte_unused)
-{
-	return 0;
-}
-
-uint32_t
-caam_jr_disable_irqs(uint32_t uio_fd __rte_unused)
-{
-	return 0;
-}
-
 int
 hw_reset_job_ring(struct sec_job_ring_t *job_ring)
 {
diff --git a/drivers/crypto/caam_jr/caam_jr_uio.c b/drivers/crypto/caam_jr/caam_jr_uio.c
new file mode 100644
index 000000000..c07d9db01
--- /dev/null
+++ b/drivers/crypto/caam_jr/caam_jr_uio.c
@@ -0,0 +1,501 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017-2018 NXP
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_crypto.h>
+#include <rte_security.h>
+
+#include <caam_jr_config.h>
+#include <caam_jr_hw_specific.h>
+#include <caam_jr_pvt.h>
+#include <caam_jr_log.h>
+
+/* RTA header files */
+#include <hw/desc/common.h>
+#include <hw/desc/algo.h>
+#include <hw/desc/ipsec.h>
+
+/* Prefix path to sysfs directory where UIO device attributes are exported.
+ * Path for UIO device X is /sys/class/uio/uioX
+ */
+#define SEC_UIO_DEVICE_SYS_ATTR_PATH    "/sys/class/uio"
+
+/* Subfolder in sysfs where mapping attributes are exported
+ * for each UIO device. Path for mapping Y for device X is:
+ *      /sys/class/uio/uioX/maps/mapY
+ */
+#define SEC_UIO_DEVICE_SYS_MAP_ATTR     "maps/map"
+
+/* Name of UIO device file prefix. Each UIO device will have a device file
+ * /dev/uioX, where X is the minor device number.
+ */
+#define SEC_UIO_DEVICE_FILE_NAME    "/dev/uio"
+
+/*
+ * Name of UIO device. Each user space SEC job ring will have a corresponding
+ * UIO device with the name sec-channelX, where X is the job ring id.
+ * Maximum length is #SEC_UIO_MAX_DEVICE_NAME_LENGTH.
+ *
+ * @note  Must be kept in synch with SEC kernel driver
+ * define #SEC_UIO_DEVICE_NAME !
+ */
+#define SEC_UIO_DEVICE_NAME     "fsl-jr"
+
+/* Maximum length for the name of an UIO device file.
+ * Device file name format is: /dev/uioX.
+ */
+#define SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH 30
+
+/* Maximum length for the name of an attribute file for an UIO device.
+ * Attribute files are exported in sysfs and have the name formatted as:
+ *      /sys/class/uio/uioX/<attribute_file_name>
+ */
+#define SEC_UIO_MAX_ATTR_FILE_NAME  100
+
+/* Command that is used by SEC user space driver and SEC kernel driver
+ *  to signal a request from the former to the later to disable job DONE
+ *  and error IRQs on a certain job ring.
+ *  The configuration is done at SEC Controller's level.
+ *  @note   Need to be kept in synch with #SEC_UIO_DISABLE_IRQ_CMD from
+ *          linux/drivers/crypto/talitos.c !
+ */
+#define SEC_UIO_DISABLE_IRQ_CMD     0
+
+/* Command that is used by SEC user space driver and SEC kernel driver
+ *  to signal a request from the former to the later to enable job DONE
+ *  and error IRQs on a certain job ring.
+ *  The configuration is done at SEC Controller's level.
+ *  @note   Need to be kept in synch with #SEC_UIO_ENABLE_IRQ_CMD from
+ *          linux/drivers/crypto/talitos.c !
+ */
+#define SEC_UIO_ENABLE_IRQ_CMD      1
+
+/** Command that is used by SEC user space driver and SEC kernel driver
+ *  to signal a request from the former to the later to do a SEC engine reset.
+ *  @note   Need to be kept in synch with #SEC_UIO_RESET_SEC_ENGINE_CMD from
+ *          linux/drivers/crypto/talitos.c !
+ */
+#define SEC_UIO_RESET_SEC_ENGINE_CMD    3
+
+/* The id for the mapping used to export SEC's registers to
+ * user space through UIO devices.
+ */
+#define SEC_UIO_MAP_ID              0
+
+static struct uio_job_ring g_uio_job_ring[MAX_SEC_JOB_RINGS];
+static int g_uio_jr_num;
+
+/** @brief Checks if a file name contains a certain substring.
+ * If so, it extracts the number following the substring.
+ * This function assumes a filename format of: [text][number].
+ * @param [in]  filename    File name
+ * @param [in]  match       String to match in file name
+ * @param [out] number      The number extracted from filename
+ *
+ * @retval true if file name matches the criteria
+ * @retval false if file name does not match the criteria
+ */
+static bool
+file_name_match_extract(const char filename[], const char match[], int *number)
+{
+	char *substr = NULL;
+
+	substr = strstr(filename, match);
+	if (substr == NULL)
+		return false;
+
+	/* substring <match> was found in <filename>
+	 * read number following <match> substring in <filename>
+	 */
+	if (sscanf(filename + strlen(match), "%d", number) <= 0)
+		return false;
+
+	return true;
+}
+
+/** @brief Reads first line from a file.
+ * Composes file name as: root/subdir/filename
+ *
+ * @param [in]  root     Root path
+ * @param [in]  subdir   Subdirectory name
+ * @param [in]  filename File name
+ * @param [out] line     The first line read from file.
+ *
+ * @retval 0 for succes
+ * @retval other value for error
+ */
+static int
+file_read_first_line(const char root[], const char subdir[],
+		     const char filename[], char *line)
+{
+	char absolute_file_name[SEC_UIO_MAX_ATTR_FILE_NAME];
+	int fd = 0, ret = 0;
+
+	/*compose the file name: root/subdir/filename */
+	memset(absolute_file_name, 0, sizeof(absolute_file_name));
+	snprintf(absolute_file_name, SEC_UIO_MAX_ATTR_FILE_NAME,
+		 "%s/%s/%s", root, subdir, filename);
+
+	fd = open(absolute_file_name, O_RDONLY);
+	SEC_ASSERT(fd > 0, fd, "Error opening file %s",
+			absolute_file_name);
+
+	/* read UIO device name from first line in file */
+	ret = read(fd, line, SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH);
+	close(fd);
+
+	/* NULL-ify string */
+	line[SEC_UIO_MAX_DEVICE_FILE_NAME_LENGTH - 1] = '\0';
+
+	if (ret <= 0) {
+		CAAM_JR_ERR("Error reading from file %s", absolute_file_name);
+		return ret;
+	}
+
+	return 0;
+}
+
+/** @brief Uses UIO control to send commands to SEC kernel driver.
+ * The mechanism is to write a command word into the file descriptor
+ * that the user-space driver obtained for each user-space SEC job ring.
+ * Both user-space driver and kernel driver must have the same understanding
+ * about the command codes.
+ *
+ * @param [in]  UIO FD		    The UIO file descriptor
+ * @param [in]  uio_command         Command word
+ *
+ * @retval Result of write operation on the job ring's UIO file descriptor.
+ *         Should be sizeof(int) for success operations.
+ *         Other values can be returned and used, if desired to add special
+ *         meaning to return values, but this has to be programmed in SEC
+ *         kernel driver as well. No special return values are used.
+ */
+static int
+sec_uio_send_command(uint32_t uio_fd, int32_t uio_command)
+{
+	int ret;
+
+	/* Use UIO file descriptor we have for this job ring.
+	 * Writing a command code to this file descriptor will make the
+	 * SEC kernel driver execute the desired command.
+	 */
+	ret = write(uio_fd, &uio_command, sizeof(int));
+	return ret;
+}
+
+/** @brief Request to SEC kernel driver to enable interrupts for
+ *         descriptor finished processing
+ *  Use UIO to communicate with SEC kernel driver: write command
+ *  value that indicates an IRQ enable action into UIO file descriptor
+ *  of this job ring.
+ *
+ * @param [in]  uio_fd     Job Ring UIO File descriptor
+ * @retval 0 for success
+ * @retval -1 value for error
+ */
+uint32_t
+caam_jr_enable_irqs(uint32_t uio_fd)
+{
+	int ret;
+
+	/* Use UIO file descriptor we have for this job ring.
+	 * Writing a command code to this file descriptor will make the
+	 * SEC kernel driver enable DONE and Error IRQs for this job ring,
+	 * at Controller level.
+	 */
+	ret = sec_uio_send_command(uio_fd, SEC_UIO_ENABLE_IRQ_CMD);
+	SEC_ASSERT(ret == sizeof(int), -1,
+		"Failed to request SEC engine to enable job done and "
+		"error IRQs through UIO control. UIO FD %d. Reset SEC driver!",
+		uio_fd);
+	CAAM_JR_DEBUG("Enabled IRQs on jr with uio_fd %d", uio_fd);
+	return 0;
+}
+
+
+/** @brief Request to SEC kernel driver to disable interrupts for descriptor
+ *  finished processing
+ *  Use UIO to communicate with SEC kernel driver: write command
+ *  value that indicates an IRQ disable action into UIO file descriptor
+ *  of this job ring.
+ *
+ * @param [in]  uio_fd    UIO File descripto
+ * @retval 0 for success
+ * @retval -1 value for error
+ *
+ */
+uint32_t
+caam_jr_disable_irqs(uint32_t uio_fd)
+{
+	int ret;
+
+	/* Use UIO file descriptor we have for this job ring.
+	 * Writing a command code to this file descriptor will make the
+	 * SEC kernel driver disable IRQs for this job ring,
+	 * at Controller level.
+	 */
+
+	ret = sec_uio_send_command(uio_fd, SEC_UIO_DISABLE_IRQ_CMD);
+	SEC_ASSERT(ret == sizeof(int), -1,
+		"Failed to request SEC engine to disable job done and "
+		"IRQs through UIO control. UIO_FD %d Reset SEC driver!",
+		uio_fd);
+	CAAM_JR_DEBUG("Disabled IRQs on jr with uio_fd %d", uio_fd);
+	return 0;
+}
+
+/** @brief Maps register range assigned for a job ring.
+ *
+ * @param [in] uio_device_fd    UIO device file descriptor
+ * @param [in] uio_device_id    UIO device id
+ * @param [in] uio_map_id       UIO allows maximum 5 different mapping for
+				each device. Maps start with id 0.
+ * @param [out] map_size        Map size.
+ * @retval  NULL if failed to map registers
+ * @retval  Virtual address for mapped register address range
+ */
+static void *
+uio_map_registers(int uio_device_fd, int uio_device_id,
+		  int uio_map_id, int *map_size)
+{
+	void *mapped_address = NULL;
+	unsigned int uio_map_size = 0;
+	char uio_sys_root[SEC_UIO_MAX_ATTR_FILE_NAME];
+	char uio_sys_map_subdir[SEC_UIO_MAX_ATTR_FILE_NAME];
+	char uio_map_size_str[32];
+	int ret = 0;
+
+	/* compose the file name: root/subdir/filename */
+	memset(uio_sys_root, 0, sizeof(uio_sys_root));
+	memset(uio_sys_map_subdir, 0, sizeof(uio_sys_map_subdir));
+	memset(uio_map_size_str, 0, sizeof(uio_map_size_str));
+
+	/* Compose string: /sys/class/uio/uioX */
+	sprintf(uio_sys_root, "%s/%s%d", SEC_UIO_DEVICE_SYS_ATTR_PATH,
+		"uio", uio_device_id);
+	/* Compose string: maps/mapY */
+	sprintf(uio_sys_map_subdir, "%s%d", SEC_UIO_DEVICE_SYS_MAP_ATTR,
+		uio_map_id);
+
+	/* Read first (and only) line from file
+	 * /sys/class/uio/uioX/maps/mapY/size
+	 */
+	ret = file_read_first_line(uio_sys_root, uio_sys_map_subdir,
+				 "size", uio_map_size_str);
+	SEC_ASSERT(ret == 0, NULL, "file_read_first_line() failed");
+
+	/* Read mapping size, expressed in hexa(base 16) */
+	uio_map_size = strtol(uio_map_size_str, NULL, 16);
+
+	/* Map the region in user space */
+	mapped_address = mmap(0, /*dynamically choose virtual address */
+		uio_map_size, PROT_READ | PROT_WRITE,
+		MAP_SHARED, uio_device_fd, 0);
+	/* offset = 0 because UIO device has only one mapping
+	 * for the entire SEC register memory
+	 */
+	if (mapped_address == MAP_FAILED) {
+		CAAM_JR_ERR(
+			"Failed to map registers! errno = %d job ring fd  = %d,"
+			"uio device id = %d, uio map id = %d", errno,
+			uio_device_fd, uio_device_id, uio_map_id);
+		return NULL;
+	}
+
+	/*
+	 * Save the map size to use it later on for munmap-ing.
+	 */
+	*map_size = uio_map_size;
+
+	CAAM_JR_INFO("UIO dev[%d] mapped region [id =%d] size 0x%x at %p",
+		uio_device_id, uio_map_id, uio_map_size, mapped_address);
+
+	return mapped_address;
+}
+
+void
+free_job_ring(uint32_t uio_fd)
+{
+	struct uio_job_ring *job_ring = NULL;
+	int i;
+
+	if (!job_ring->uio_fd)
+		return;
+
+	for (i = 0; i < MAX_SEC_JOB_RINGS; i++) {
+		if (g_uio_job_ring[i].uio_fd == uio_fd) {
+			job_ring = &g_uio_job_ring[i];
+			break;
+		}
+	}
+
+	if (job_ring == NULL) {
+		CAAM_JR_ERR("JR not available for fd = %x\n", uio_fd);
+		return;
+	}
+
+	/* Open device file */
+	CAAM_JR_INFO("Closed device file for job ring %d , fd = %d",
+			job_ring->jr_id, job_ring->uio_fd);
+	close(job_ring->uio_fd);
+	g_uio_jr_num--;
+	job_ring->uio_fd = 0;
+	if (job_ring->register_base_addr == NULL)
+		return;
+
+	/* Unmap the PCI memory resource of device */
+	if (munmap(job_ring->register_base_addr, job_ring->map_size)) {
+		CAAM_JR_INFO("cannot munmap(%p, 0x%lx): %s",
+			job_ring->register_base_addr,
+			(unsigned long)job_ring->map_size, strerror(errno));
+	} else
+		CAAM_JR_DEBUG("  JR UIO memory unmapped at %p",
+				job_ring->register_base_addr);
+	job_ring->register_base_addr = NULL;
+}
+
+struct
+uio_job_ring *config_job_ring(void)
+{
+	char uio_device_file_name[32];
+	struct uio_job_ring *job_ring = NULL;
+	int i;
+
+	for (i = 0; i < MAX_SEC_JOB_RINGS; i++) {
+		if (g_uio_job_ring[i].uio_fd == 0) {
+			job_ring = &g_uio_job_ring[i];
+			g_uio_jr_num++;
+			break;
+		}
+	}
+
+	if (job_ring == NULL) {
+		CAAM_JR_ERR("No free job ring\n");
+		return NULL;
+	}
+
+	/* Find UIO device created by SEC kernel driver for this job ring. */
+	memset(uio_device_file_name, 0, sizeof(uio_device_file_name));
+
+	sprintf(uio_device_file_name, "%s%d", SEC_UIO_DEVICE_FILE_NAME,
+		job_ring->uio_minor_number);
+
+	/* Open device file */
+	job_ring->uio_fd = open(uio_device_file_name, O_RDWR);
+	SEC_ASSERT(job_ring->uio_fd > 0, NULL,
+		"Failed to open UIO device file for job ring %d",
+		job_ring->jr_id);
+
+	CAAM_JR_INFO("Open device(%s) file for job ring=%d , uio_fd = %d",
+		uio_device_file_name, job_ring->jr_id, job_ring->uio_fd);
+
+	ASSERT(job_ring->register_base_addr == NULL);
+	job_ring->register_base_addr = uio_map_registers(
+			job_ring->uio_fd, job_ring->uio_minor_number,
+			SEC_UIO_MAP_ID, &job_ring->map_size);
+
+	SEC_ASSERT(job_ring->register_base_addr != NULL, NULL,
+		"Failed to map SEC registers");
+	return job_ring;
+}
+
+int
+sec_configure(void)
+{
+	char uio_name[32];
+	int config_jr_no = 0, jr_id = -1;
+	int uio_minor_number = -1;
+	int ret;
+	DIR *d = NULL;
+	struct dirent *dir;
+
+	d = opendir(SEC_UIO_DEVICE_SYS_ATTR_PATH);
+	if (d == NULL) {
+		printf("\nError opening directory '%s': %s\n",
+			SEC_UIO_DEVICE_SYS_ATTR_PATH, strerror(errno));
+		return -1;
+	}
+
+	/* Iterate through all subdirs */
+	while ((dir = readdir(d)) != NULL) {
+		if (!strncmp(dir->d_name, ".", 1) ||
+				!strncmp(dir->d_name, "..", 2))
+			continue;
+
+		if (file_name_match_extract
+			(dir->d_name, "uio", &uio_minor_number)) {
+		/*
+		 * Open file uioX/name and read first line which contains
+		 * the name for the device. Based on the name check if this
+		 * UIO device is UIO device for job ring with id jr_id.
+		 */
+			memset(uio_name, 0, sizeof(uio_name));
+			ret = file_read_first_line(SEC_UIO_DEVICE_SYS_ATTR_PATH,
+					dir->d_name, "name", uio_name);
+			CAAM_JR_INFO("sec device uio name: %s", uio_name);
+			SEC_ASSERT(ret == 0, -1, "file_read_first_line failed");
+
+			if (file_name_match_extract(uio_name,
+						SEC_UIO_DEVICE_NAME,
+						&jr_id)) {
+				g_uio_job_ring[config_jr_no].jr_id = jr_id;
+				g_uio_job_ring[config_jr_no].uio_minor_number =
+							uio_minor_number;
+				CAAM_JR_INFO("Detected logical JRID:%d", jr_id);
+				config_jr_no++;
+
+				/* todo  find the actual ring id
+				 * OF_FULLNAME=/soc/crypto@1700000/jr@20000
+				 */
+			}
+		}
+	}
+	closedir(d);
+
+	if (config_jr_no == 0) {
+		CAAM_JR_ERR("! No SEC Job Rings assigned for userspace usage!");
+		return 0;
+	}
+	CAAM_JR_INFO("Total JR detected =%d", config_jr_no);
+	return config_jr_no;
+}
+
+int
+sec_cleanup(void)
+{
+	int i;
+	struct uio_job_ring *job_ring;
+
+	for (i = 0; i < g_uio_jr_num; i++) {
+		job_ring = &g_uio_job_ring[i];
+		/* munmap SEC's register memory */
+		if (job_ring->register_base_addr) {
+			munmap(job_ring->register_base_addr,
+				job_ring->map_size);
+			job_ring->register_base_addr = NULL;
+		}
+		/* I need to close the fd after shutdown UIO commands need to be
+		 * sent using the fd
+		 */
+		if (job_ring->uio_fd != 0) {
+			CAAM_JR_INFO(
+			"Closed device file for job ring %d , fd = %d",
+			job_ring->jr_id, job_ring->uio_fd);
+			close(job_ring->uio_fd);
+		}
+	}
+	return 0;
+}
diff --git a/drivers/crypto/caam_jr/meson.build b/drivers/crypto/caam_jr/meson.build
index c282eb4dc..7b024e886 100644
--- a/drivers/crypto/caam_jr/meson.build
+++ b/drivers/crypto/caam_jr/meson.build
@@ -6,7 +6,7 @@ if host_machine.system() != 'linux'
 endif
 
 deps += ['bus_vdev', 'bus_dpaa', 'security']
-sources = files('caam_jr_hw.c', 'caam_jr.c')
+sources = files('caam_jr_hw.c', 'caam_jr_uio.c', 'caam_jr.c')
 
 allow_experimental_apis = true
 
