aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch337
1 files changed, 337 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch
new file mode 100644
index 0000000000..469fb2e362
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch
@@ -0,0 +1,337 @@
+From 8b60a441202cb5c6b5264dbee633fcb24414bab4 Mon Sep 17 00:00:00 2001
+From: Sandeep Malik <Sandeep.Malik@nxp.com>
+Date: Wed, 15 Nov 2017 17:16:13 +0530
+Subject: [PATCH] crypto: caam - add CAAM job ring UIO support
+
+This patch add the support for job ring UIO so
+that userspace drivers can have access to the
+caam job rings
+
+Signed-off-by: Sandeep Malik <Sandeep.Malik@nxp.com>
+Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
+---
+ drivers/crypto/caam/Kconfig | 11 ++
+ drivers/crypto/caam/Makefile | 1 +
+ drivers/crypto/caam/fsl_jr_uio.c | 256 +++++++++++++++++++++++++++++++++++++++
+ drivers/crypto/caam/fsl_jr_uio.h | 25 ++++
+ 4 files changed, 293 insertions(+)
+ create mode 100644 drivers/crypto/caam/fsl_jr_uio.c
+ create mode 100644 drivers/crypto/caam/fsl_jr_uio.h
+
+--- a/drivers/crypto/caam/Kconfig
++++ b/drivers/crypto/caam/Kconfig
+@@ -202,6 +202,17 @@ config CRYPTO_DEV_FSL_CAAM_SECVIO
+ handler functions which can be specified to act on the consequences
+ of a security violation.
+
++config CRYPTO_DEV_FSL_CAAM_JR_UIO
++ tristate "Freescale Job Ring UIO support"
++ depends on UIO
++ default y
++ help
++ Selecting this will allow job ring UIO support for
++ Userspace drivers
++
++ To compile this as a module, choose M here: the module
++ will be called fsl_jr_uio.
++
+ endif # CRYPTO_DEV_FSL_CAAM_JR
+
+ endif # CRYPTO_DEV_FSL_CAAM
+--- a/drivers/crypto/caam/Makefile
++++ b/drivers/crypto/caam/Makefile
+@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caa
+ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
+ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
+ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
++obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR_UIO) += fsl_jr_uio.o
+
+ caam-y := ctrl.o
+ caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
+--- /dev/null
++++ b/drivers/crypto/caam/fsl_jr_uio.c
+@@ -0,0 +1,256 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright 2013 Freescale Semiconductor, Inc.
++ * Copyright 2018 NXP
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/of_address.h>
++#include <linux/of_irq.h>
++#include <linux/of_platform.h>
++#include <linux/io.h>
++#include <linux/uio_driver.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include "regs.h"
++#include "fsl_jr_uio.h"
++
++static const char jr_uio_version[] = "fsl JR UIO driver v1.0";
++
++#define NAME_LENGTH 30
++#define JR_INDEX_OFFSET 12
++
++static const char uio_device_name[] = "fsl-jr";
++static LIST_HEAD(jr_list);
++
++struct jr_uio_info {
++ atomic_t ref; /* exclusive, only one open() at a time */
++ struct uio_info uio;
++ char name[NAME_LENGTH];
++};
++
++struct jr_dev {
++ u32 revision;
++ u32 index;
++ u32 irq;
++ struct caam_job_ring __iomem *global_regs;
++ struct device *dev;
++ struct resource *res;
++ struct jr_uio_info info;
++ struct list_head node;
++ struct list_head jr_list;
++};
++
++static int jr_uio_open(struct uio_info *info, struct inode *inode)
++{
++ struct jr_uio_info *uio_info = container_of(info,
++ struct jr_uio_info, uio);
++
++ if (!atomic_dec_and_test(&uio_info->ref)) {
++ pr_err("%s: failing non-exclusive open()\n", uio_info->name);
++ atomic_inc(&uio_info->ref);
++ return -EBUSY;
++ }
++
++ return 0;
++}
++
++static int jr_uio_release(struct uio_info *info, struct inode *inode)
++{
++ struct jr_uio_info *uio_info = container_of(info,
++ struct jr_uio_info, uio);
++ atomic_inc(&uio_info->ref);
++
++ return 0;
++}
++
++static irqreturn_t jr_uio_irq_handler(int irq, struct uio_info *dev_info)
++{
++ struct jr_dev *jrdev = dev_info->priv;
++ u32 irqstate;
++
++ irqstate = rd_reg32(&jrdev->global_regs->jrintstatus);
++
++ if (!irqstate)
++ return IRQ_NONE;
++
++ if (irqstate & JRINT_JR_ERROR)
++ dev_info(jrdev->dev, "uio job ring error - irqstate: %08x\n",
++ irqstate);
++
++ /*mask valid interrupts */
++ clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK);
++
++ /* Have valid interrupt at this point, just ACK and trigger */
++ wr_reg32(&jrdev->global_regs->jrintstatus, irqstate);
++
++ return IRQ_HANDLED;
++}
++
++static int jr_uio_irqcontrol(struct uio_info *dev_info, int irqon)
++{
++ struct jr_dev *jrdev = dev_info->priv;
++
++ switch (irqon) {
++ case SEC_UIO_SIMULATE_IRQ_CMD:
++ uio_event_notify(dev_info);
++ break;
++ case SEC_UIO_ENABLE_IRQ_CMD:
++ /* Enable Job Ring interrupt */
++ clrsetbits_32(&jrdev->global_regs->rconfig_lo, JRCFG_IMSK, 0);
++ break;
++ case SEC_UIO_DISABLE_IRQ_CMD:
++ /* Disable Job Ring interrupt */
++ clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK);
++ break;
++ default:
++ break;
++ }
++ return 0;
++}
++
++static int __init jr_uio_init(struct jr_dev *uio_dev)
++{
++ int ret;
++ struct jr_uio_info *info;
++
++ info = &uio_dev->info;
++ atomic_set(&info->ref, 1);
++ info->uio.version = jr_uio_version;
++ info->uio.name = uio_dev->info.name;
++ info->uio.mem[0].name = "JR config space";
++ info->uio.mem[0].addr = uio_dev->res->start;
++ info->uio.mem[0].size = uio_dev->res->end - uio_dev->res->start + 1;
++ info->uio.mem[0].internal_addr = uio_dev->global_regs;
++ info->uio.mem[0].memtype = UIO_MEM_PHYS;
++ info->uio.irq = uio_dev->irq;
++ info->uio.irq_flags = IRQF_SHARED;
++ info->uio.handler = jr_uio_irq_handler;
++ info->uio.irqcontrol = jr_uio_irqcontrol;
++ info->uio.open = jr_uio_open;
++ info->uio.release = jr_uio_release;
++ info->uio.priv = uio_dev;
++
++ ret = uio_register_device(uio_dev->dev, &info->uio);
++ if (ret) {
++ dev_err(uio_dev->dev, "jr_uio: UIO registration failed\n");
++ return ret;
++ }
++
++ return 0;
++}
++
++static const struct of_device_id jr_ids[] = {
++ { .compatible = "fsl,sec-v4.0-job-ring", },
++ { .compatible = "fsl,sec-v4.4-job-ring", },
++ { .compatible = "fsl,sec-v5.0-job-ring", },
++ { .compatible = "fsl,sec-v6.0-job-ring", },
++ {},
++};
++
++static int fsl_jr_probe(struct platform_device *dev)
++{
++ struct resource regs;
++ struct jr_dev *jr_dev;
++ struct device_node *jr_node;
++ int ret, count = 0;
++ struct list_head *p;
++
++ jr_node = dev->dev.of_node;
++ if (!jr_node) {
++ dev_err(&dev->dev, "Device OF-Node is NULL\n");
++ return -EFAULT;
++ }
++
++ jr_dev = devm_kzalloc(&dev->dev, sizeof(*jr_dev), GFP_KERNEL);
++ if (!jr_dev)
++ return -ENOMEM;
++
++ /* Creat name and index */
++ list_for_each(p, &jr_list) {
++ count++;
++ }
++ jr_dev->index = count;
++
++ snprintf(jr_dev->info.name, sizeof(jr_dev->info.name) - 1,
++ "%s%d", uio_device_name, jr_dev->index);
++
++ jr_dev->dev = &dev->dev;
++ platform_set_drvdata(dev, jr_dev);
++
++ /* Get the resource from dtb node */
++ ret = of_address_to_resource(jr_node, 0, &regs);
++ if (unlikely(ret < 0)) {
++ dev_err(&dev->dev, "OF-Address-to-resource Failed\n");
++ ret = -EFAULT;
++ goto abort;
++ }
++
++ jr_dev->res = devm_request_mem_region(&dev->dev, regs.start,
++ regs.end - regs.start + 1,
++ jr_dev->info.name);
++ if (unlikely(!jr_dev->res)) {
++ dev_err(jr_dev->dev, "devm_request_mem_region failed\n");
++ ret = -ENOMEM;
++ goto abort;
++ }
++
++ jr_dev->global_regs =
++ devm_ioremap(&dev->dev, jr_dev->res->start,
++ jr_dev->res->end - jr_dev->res->start + 1);
++ if (unlikely(jr_dev->global_regs == 0)) {
++ dev_err(jr_dev->dev, "devm_ioremap failed\n");
++ ret = -EIO;
++ goto abort;
++ }
++ jr_dev->irq = irq_of_parse_and_map(jr_node, 0);
++ dev_dbg(jr_dev->dev, "errirq: %d\n", jr_dev->irq);
++
++ /* Register UIO */
++ ret = jr_uio_init(jr_dev);
++ if (ret) {
++ dev_err(&dev->dev, "UIO init Failed\n");
++ goto abort;
++ }
++
++ list_add_tail(&jr_dev->node, &jr_list);
++
++ dev_info(jr_dev->dev, "UIO device full name %s initialized\n",
++ jr_dev->info.name);
++
++ return 0;
++
++abort:
++ return ret;
++}
++
++static int fsl_jr_remove(struct platform_device *dev)
++{
++ struct jr_dev *jr_dev = platform_get_drvdata(dev);
++
++ if (!jr_dev)
++ return 0;
++
++ list_del(&jr_dev->node);
++ uio_unregister_device(&jr_dev->info.uio);
++
++ return 0;
++}
++
++MODULE_DEVICE_TABLE(of, jr_ids);
++
++static struct platform_driver fsl_jr_driver = {
++ .driver = {
++ .name = "fsl-jr-uio",
++ .of_match_table = jr_ids,
++ },
++ .probe = fsl_jr_probe,
++ .remove = fsl_jr_remove,
++};
++
++module_platform_driver(fsl_jr_driver);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("NXP");
++MODULE_DESCRIPTION("FSL SEC UIO Driver");
+--- /dev/null
++++ b/drivers/crypto/caam/fsl_jr_uio.h
+@@ -0,0 +1,25 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * CAAM Job RING UIO support header file
++ *
++ * Copyright 2013 Freescale Semiconductor, Inc
++ * Copyright 2018 NXP
++ */
++
++#ifndef FSL_JR_UIO_H
++#define FSL_JR_UIO_H
++
++/** UIO command used by user-space driver to request
++ * disabling IRQs on a certain job ring
++ */
++#define SEC_UIO_DISABLE_IRQ_CMD 0
++/** UIO command used by user-space driver to request
++ * enabling IRQs on a certain job ring
++ */
++#define SEC_UIO_ENABLE_IRQ_CMD 1
++/** UIO command used by user-space driver to request SEC kernel driver
++ * to simulate that an IRQ is generated on a certain job ring
++ */
++#define SEC_UIO_SIMULATE_IRQ_CMD 2
++
++#endif