kernel-5.4: bump to 5.4.102 and refresh patches
[openwrt/openwrt.git] / target / linux / layerscape / patches-5.4 / 804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch
1 From 8b60a441202cb5c6b5264dbee633fcb24414bab4 Mon Sep 17 00:00:00 2001
2 From: Sandeep Malik <Sandeep.Malik@nxp.com>
3 Date: Wed, 15 Nov 2017 17:16:13 +0530
4 Subject: [PATCH] crypto: caam - add CAAM job ring UIO support
5
6 This patch add the support for job ring UIO so
7 that userspace drivers can have access to the
8 caam job rings
9
10 Signed-off-by: Sandeep Malik <Sandeep.Malik@nxp.com>
11 Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
12 ---
13 drivers/crypto/caam/Kconfig | 11 ++
14 drivers/crypto/caam/Makefile | 1 +
15 drivers/crypto/caam/fsl_jr_uio.c | 256 +++++++++++++++++++++++++++++++++++++++
16 drivers/crypto/caam/fsl_jr_uio.h | 25 ++++
17 4 files changed, 293 insertions(+)
18 create mode 100644 drivers/crypto/caam/fsl_jr_uio.c
19 create mode 100644 drivers/crypto/caam/fsl_jr_uio.h
20
21 --- a/drivers/crypto/caam/Kconfig
22 +++ b/drivers/crypto/caam/Kconfig
23 @@ -203,6 +203,17 @@ config CRYPTO_DEV_FSL_CAAM_SECVIO
24 handler functions which can be specified to act on the consequences
25 of a security violation.
26
27 +config CRYPTO_DEV_FSL_CAAM_JR_UIO
28 + tristate "Freescale Job Ring UIO support"
29 + depends on UIO
30 + default y
31 + help
32 + Selecting this will allow job ring UIO support for
33 + Userspace drivers
34 +
35 + To compile this as a module, choose M here: the module
36 + will be called fsl_jr_uio.
37 +
38 endif # CRYPTO_DEV_FSL_CAAM_JR
39
40 endif # CRYPTO_DEV_FSL_CAAM
41 --- a/drivers/crypto/caam/Makefile
42 +++ b/drivers/crypto/caam/Makefile
43 @@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caa
44 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
45 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o
46 obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o
47 +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR_UIO) += fsl_jr_uio.o
48
49 caam-y := ctrl.o
50 caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o
51 --- /dev/null
52 +++ b/drivers/crypto/caam/fsl_jr_uio.c
53 @@ -0,0 +1,256 @@
54 +// SPDX-License-Identifier: GPL-2.0
55 +/*
56 + * Copyright 2013 Freescale Semiconductor, Inc.
57 + * Copyright 2018 NXP
58 + */
59 +
60 +#include <linux/kernel.h>
61 +#include <linux/module.h>
62 +#include <linux/of_address.h>
63 +#include <linux/of_irq.h>
64 +#include <linux/of_platform.h>
65 +#include <linux/io.h>
66 +#include <linux/uio_driver.h>
67 +#include <linux/slab.h>
68 +#include <linux/list.h>
69 +#include "regs.h"
70 +#include "fsl_jr_uio.h"
71 +
72 +static const char jr_uio_version[] = "fsl JR UIO driver v1.0";
73 +
74 +#define NAME_LENGTH 30
75 +#define JR_INDEX_OFFSET 12
76 +
77 +static const char uio_device_name[] = "fsl-jr";
78 +static LIST_HEAD(jr_list);
79 +
80 +struct jr_uio_info {
81 + atomic_t ref; /* exclusive, only one open() at a time */
82 + struct uio_info uio;
83 + char name[NAME_LENGTH];
84 +};
85 +
86 +struct jr_dev {
87 + u32 revision;
88 + u32 index;
89 + u32 irq;
90 + struct caam_job_ring __iomem *global_regs;
91 + struct device *dev;
92 + struct resource *res;
93 + struct jr_uio_info info;
94 + struct list_head node;
95 + struct list_head jr_list;
96 +};
97 +
98 +static int jr_uio_open(struct uio_info *info, struct inode *inode)
99 +{
100 + struct jr_uio_info *uio_info = container_of(info,
101 + struct jr_uio_info, uio);
102 +
103 + if (!atomic_dec_and_test(&uio_info->ref)) {
104 + pr_err("%s: failing non-exclusive open()\n", uio_info->name);
105 + atomic_inc(&uio_info->ref);
106 + return -EBUSY;
107 + }
108 +
109 + return 0;
110 +}
111 +
112 +static int jr_uio_release(struct uio_info *info, struct inode *inode)
113 +{
114 + struct jr_uio_info *uio_info = container_of(info,
115 + struct jr_uio_info, uio);
116 + atomic_inc(&uio_info->ref);
117 +
118 + return 0;
119 +}
120 +
121 +static irqreturn_t jr_uio_irq_handler(int irq, struct uio_info *dev_info)
122 +{
123 + struct jr_dev *jrdev = dev_info->priv;
124 + u32 irqstate;
125 +
126 + irqstate = rd_reg32(&jrdev->global_regs->jrintstatus);
127 +
128 + if (!irqstate)
129 + return IRQ_NONE;
130 +
131 + if (irqstate & JRINT_JR_ERROR)
132 + dev_info(jrdev->dev, "uio job ring error - irqstate: %08x\n",
133 + irqstate);
134 +
135 + /*mask valid interrupts */
136 + clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK);
137 +
138 + /* Have valid interrupt at this point, just ACK and trigger */
139 + wr_reg32(&jrdev->global_regs->jrintstatus, irqstate);
140 +
141 + return IRQ_HANDLED;
142 +}
143 +
144 +static int jr_uio_irqcontrol(struct uio_info *dev_info, int irqon)
145 +{
146 + struct jr_dev *jrdev = dev_info->priv;
147 +
148 + switch (irqon) {
149 + case SEC_UIO_SIMULATE_IRQ_CMD:
150 + uio_event_notify(dev_info);
151 + break;
152 + case SEC_UIO_ENABLE_IRQ_CMD:
153 + /* Enable Job Ring interrupt */
154 + clrsetbits_32(&jrdev->global_regs->rconfig_lo, JRCFG_IMSK, 0);
155 + break;
156 + case SEC_UIO_DISABLE_IRQ_CMD:
157 + /* Disable Job Ring interrupt */
158 + clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK);
159 + break;
160 + default:
161 + break;
162 + }
163 + return 0;
164 +}
165 +
166 +static int __init jr_uio_init(struct jr_dev *uio_dev)
167 +{
168 + int ret;
169 + struct jr_uio_info *info;
170 +
171 + info = &uio_dev->info;
172 + atomic_set(&info->ref, 1);
173 + info->uio.version = jr_uio_version;
174 + info->uio.name = uio_dev->info.name;
175 + info->uio.mem[0].name = "JR config space";
176 + info->uio.mem[0].addr = uio_dev->res->start;
177 + info->uio.mem[0].size = uio_dev->res->end - uio_dev->res->start + 1;
178 + info->uio.mem[0].internal_addr = uio_dev->global_regs;
179 + info->uio.mem[0].memtype = UIO_MEM_PHYS;
180 + info->uio.irq = uio_dev->irq;
181 + info->uio.irq_flags = IRQF_SHARED;
182 + info->uio.handler = jr_uio_irq_handler;
183 + info->uio.irqcontrol = jr_uio_irqcontrol;
184 + info->uio.open = jr_uio_open;
185 + info->uio.release = jr_uio_release;
186 + info->uio.priv = uio_dev;
187 +
188 + ret = uio_register_device(uio_dev->dev, &info->uio);
189 + if (ret) {
190 + dev_err(uio_dev->dev, "jr_uio: UIO registration failed\n");
191 + return ret;
192 + }
193 +
194 + return 0;
195 +}
196 +
197 +static const struct of_device_id jr_ids[] = {
198 + { .compatible = "fsl,sec-v4.0-job-ring", },
199 + { .compatible = "fsl,sec-v4.4-job-ring", },
200 + { .compatible = "fsl,sec-v5.0-job-ring", },
201 + { .compatible = "fsl,sec-v6.0-job-ring", },
202 + {},
203 +};
204 +
205 +static int fsl_jr_probe(struct platform_device *dev)
206 +{
207 + struct resource regs;
208 + struct jr_dev *jr_dev;
209 + struct device_node *jr_node;
210 + int ret, count = 0;
211 + struct list_head *p;
212 +
213 + jr_node = dev->dev.of_node;
214 + if (!jr_node) {
215 + dev_err(&dev->dev, "Device OF-Node is NULL\n");
216 + return -EFAULT;
217 + }
218 +
219 + jr_dev = devm_kzalloc(&dev->dev, sizeof(*jr_dev), GFP_KERNEL);
220 + if (!jr_dev)
221 + return -ENOMEM;
222 +
223 + /* Creat name and index */
224 + list_for_each(p, &jr_list) {
225 + count++;
226 + }
227 + jr_dev->index = count;
228 +
229 + snprintf(jr_dev->info.name, sizeof(jr_dev->info.name) - 1,
230 + "%s%d", uio_device_name, jr_dev->index);
231 +
232 + jr_dev->dev = &dev->dev;
233 + platform_set_drvdata(dev, jr_dev);
234 +
235 + /* Get the resource from dtb node */
236 + ret = of_address_to_resource(jr_node, 0, &regs);
237 + if (unlikely(ret < 0)) {
238 + dev_err(&dev->dev, "OF-Address-to-resource Failed\n");
239 + ret = -EFAULT;
240 + goto abort;
241 + }
242 +
243 + jr_dev->res = devm_request_mem_region(&dev->dev, regs.start,
244 + regs.end - regs.start + 1,
245 + jr_dev->info.name);
246 + if (unlikely(!jr_dev->res)) {
247 + dev_err(jr_dev->dev, "devm_request_mem_region failed\n");
248 + ret = -ENOMEM;
249 + goto abort;
250 + }
251 +
252 + jr_dev->global_regs =
253 + devm_ioremap(&dev->dev, jr_dev->res->start,
254 + jr_dev->res->end - jr_dev->res->start + 1);
255 + if (unlikely(jr_dev->global_regs == 0)) {
256 + dev_err(jr_dev->dev, "devm_ioremap failed\n");
257 + ret = -EIO;
258 + goto abort;
259 + }
260 + jr_dev->irq = irq_of_parse_and_map(jr_node, 0);
261 + dev_dbg(jr_dev->dev, "errirq: %d\n", jr_dev->irq);
262 +
263 + /* Register UIO */
264 + ret = jr_uio_init(jr_dev);
265 + if (ret) {
266 + dev_err(&dev->dev, "UIO init Failed\n");
267 + goto abort;
268 + }
269 +
270 + list_add_tail(&jr_dev->node, &jr_list);
271 +
272 + dev_info(jr_dev->dev, "UIO device full name %s initialized\n",
273 + jr_dev->info.name);
274 +
275 + return 0;
276 +
277 +abort:
278 + return ret;
279 +}
280 +
281 +static int fsl_jr_remove(struct platform_device *dev)
282 +{
283 + struct jr_dev *jr_dev = platform_get_drvdata(dev);
284 +
285 + if (!jr_dev)
286 + return 0;
287 +
288 + list_del(&jr_dev->node);
289 + uio_unregister_device(&jr_dev->info.uio);
290 +
291 + return 0;
292 +}
293 +
294 +MODULE_DEVICE_TABLE(of, jr_ids);
295 +
296 +static struct platform_driver fsl_jr_driver = {
297 + .driver = {
298 + .name = "fsl-jr-uio",
299 + .of_match_table = jr_ids,
300 + },
301 + .probe = fsl_jr_probe,
302 + .remove = fsl_jr_remove,
303 +};
304 +
305 +module_platform_driver(fsl_jr_driver);
306 +
307 +MODULE_LICENSE("GPL");
308 +MODULE_AUTHOR("NXP");
309 +MODULE_DESCRIPTION("FSL SEC UIO Driver");
310 --- /dev/null
311 +++ b/drivers/crypto/caam/fsl_jr_uio.h
312 @@ -0,0 +1,25 @@
313 +/* SPDX-License-Identifier: GPL-2.0 */
314 +/*
315 + * CAAM Job RING UIO support header file
316 + *
317 + * Copyright 2013 Freescale Semiconductor, Inc
318 + * Copyright 2018 NXP
319 + */
320 +
321 +#ifndef FSL_JR_UIO_H
322 +#define FSL_JR_UIO_H
323 +
324 +/** UIO command used by user-space driver to request
325 + * disabling IRQs on a certain job ring
326 + */
327 +#define SEC_UIO_DISABLE_IRQ_CMD 0
328 +/** UIO command used by user-space driver to request
329 + * enabling IRQs on a certain job ring
330 + */
331 +#define SEC_UIO_ENABLE_IRQ_CMD 1
332 +/** UIO command used by user-space driver to request SEC kernel driver
333 + * to simulate that an IRQ is generated on a certain job ring
334 + */
335 +#define SEC_UIO_SIMULATE_IRQ_CMD 2
336 +
337 +#endif