aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/caam/Kconfig25
-rw-r--r--drivers/crypto/caam/Makefile4
-rw-r--r--drivers/crypto/caam/caamalg.c4
-rw-r--r--drivers/crypto/caam/caamhash.c4
-rw-r--r--drivers/crypto/caam/caamrng.c7
-rw-r--r--drivers/crypto/caam/ctrl.c30
-rw-r--r--drivers/crypto/caam/intern.h6
-rw-r--r--drivers/crypto/caam/jr.c285
-rw-r--r--drivers/crypto/caam/jr.h3
9 files changed, 232 insertions, 136 deletions
diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig
index ca89f6b84b06..e7555ff4cafd 100644
--- a/drivers/crypto/caam/Kconfig
+++ b/drivers/crypto/caam/Kconfig
@@ -4,16 +4,29 @@ config CRYPTO_DEV_FSL_CAAM
4 help 4 help
5 Enables the driver module for Freescale's Cryptographic Accelerator 5 Enables the driver module for Freescale's Cryptographic Accelerator
6 and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). 6 and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
7 This module adds a job ring operation interface, and configures h/w 7 This module creates job ring devices, and configures h/w
8 to operate as a DPAA component automatically, depending 8 to operate as a DPAA component automatically, depending
9 on h/w feature availability. 9 on h/w feature availability.
10 10
11 To compile this driver as a module, choose M here: the module 11 To compile this driver as a module, choose M here: the module
12 will be called caam. 12 will be called caam.
13 13
14config CRYPTO_DEV_FSL_CAAM_JR
15 tristate "Freescale CAAM Job Ring driver backend"
16 depends on CRYPTO_DEV_FSL_CAAM
17 default y
18 help
19 Enables the driver module for Job Rings which are part of
20 Freescale's Cryptographic Accelerator
21 and Assurance Module (CAAM). This module adds a job ring operation
22 interface.
23
24 To compile this driver as a module, choose M here: the module
25 will be called caam_jr.
26
14config CRYPTO_DEV_FSL_CAAM_RINGSIZE 27config CRYPTO_DEV_FSL_CAAM_RINGSIZE
15 int "Job Ring size" 28 int "Job Ring size"
16 depends on CRYPTO_DEV_FSL_CAAM 29 depends on CRYPTO_DEV_FSL_CAAM_JR
17 range 2 9 30 range 2 9
18 default "9" 31 default "9"
19 help 32 help
@@ -31,7 +44,7 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
31 44
32config CRYPTO_DEV_FSL_CAAM_INTC 45config CRYPTO_DEV_FSL_CAAM_INTC
33 bool "Job Ring interrupt coalescing" 46 bool "Job Ring interrupt coalescing"
34 depends on CRYPTO_DEV_FSL_CAAM 47 depends on CRYPTO_DEV_FSL_CAAM_JR
35 default n 48 default n
36 help 49 help
37 Enable the Job Ring's interrupt coalescing feature. 50 Enable the Job Ring's interrupt coalescing feature.
@@ -62,7 +75,7 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD
62 75
63config CRYPTO_DEV_FSL_CAAM_CRYPTO_API 76config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
64 tristate "Register algorithm implementations with the Crypto API" 77 tristate "Register algorithm implementations with the Crypto API"
65 depends on CRYPTO_DEV_FSL_CAAM 78 depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
66 default y 79 default y
67 select CRYPTO_ALGAPI 80 select CRYPTO_ALGAPI
68 select CRYPTO_AUTHENC 81 select CRYPTO_AUTHENC
@@ -76,7 +89,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
76 89
77config CRYPTO_DEV_FSL_CAAM_AHASH_API 90config CRYPTO_DEV_FSL_CAAM_AHASH_API
78 tristate "Register hash algorithm implementations with Crypto API" 91 tristate "Register hash algorithm implementations with Crypto API"
79 depends on CRYPTO_DEV_FSL_CAAM 92 depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
80 default y 93 default y
81 select CRYPTO_HASH 94 select CRYPTO_HASH
82 help 95 help
@@ -88,7 +101,7 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API
88 101
89config CRYPTO_DEV_FSL_CAAM_RNG_API 102config CRYPTO_DEV_FSL_CAAM_RNG_API
90 tristate "Register caam device for hwrng API" 103 tristate "Register caam device for hwrng API"
91 depends on CRYPTO_DEV_FSL_CAAM 104 depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
92 default y 105 default y
93 select CRYPTO_RNG 106 select CRYPTO_RNG
94 select HW_RANDOM 107 select HW_RANDOM
diff --git a/drivers/crypto/caam/Makefile b/drivers/crypto/caam/Makefile
index d56bd0ec65d8..550758a333e7 100644
--- a/drivers/crypto/caam/Makefile
+++ b/drivers/crypto/caam/Makefile
@@ -6,8 +6,10 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG), y)
6endif 6endif
7 7
8obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o 8obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
9obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
9obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o 10obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
10obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o 11obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
11obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o 12obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
12 13
13caam-objs := ctrl.o jr.o error.o key_gen.o 14caam-objs := ctrl.o
15caam_jr-objs := jr.o key_gen.o error.o
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 86a0d415b9a7..ad9781e646c0 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -2071,13 +2071,15 @@ static int caam_cra_init(struct crypto_tfm *tfm)
2071 container_of(alg, struct caam_crypto_alg, crypto_alg); 2071 container_of(alg, struct caam_crypto_alg, crypto_alg);
2072 struct caam_ctx *ctx = crypto_tfm_ctx(tfm); 2072 struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
2073 struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev); 2073 struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev);
2074 struct platform_device *pdev;
2074 int tgt_jr = atomic_inc_return(&priv->tfm_count); 2075 int tgt_jr = atomic_inc_return(&priv->tfm_count);
2075 2076
2076 /* 2077 /*
2077 * distribute tfms across job rings to ensure in-order 2078 * distribute tfms across job rings to ensure in-order
2078 * crypto request processing per tfm 2079 * crypto request processing per tfm
2079 */ 2080 */
2080 ctx->jrdev = priv->jrdev[(tgt_jr / 2) % priv->total_jobrs]; 2081 pdev = priv->jrpdev[(tgt_jr / 2) % priv->total_jobrs];
2082 ctx->jrdev = &pdev->dev;
2081 2083
2082 /* copy descriptor header template value */ 2084 /* copy descriptor header template value */
2083 ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type; 2085 ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index ca6218eee460..91a93541ed7f 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -1680,12 +1680,14 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm)
1680 HASH_MSG_LEN + SHA512_DIGEST_SIZE }; 1680 HASH_MSG_LEN + SHA512_DIGEST_SIZE };
1681 int tgt_jr = atomic_inc_return(&priv->tfm_count); 1681 int tgt_jr = atomic_inc_return(&priv->tfm_count);
1682 int ret = 0; 1682 int ret = 0;
1683 struct platform_device *pdev;
1683 1684
1684 /* 1685 /*
1685 * distribute tfms across job rings to ensure in-order 1686 * distribute tfms across job rings to ensure in-order
1686 * crypto request processing per tfm 1687 * crypto request processing per tfm
1687 */ 1688 */
1688 ctx->jrdev = priv->jrdev[tgt_jr % priv->total_jobrs]; 1689 pdev = priv->jrpdev[tgt_jr % priv->total_jobrs];
1690 ctx->jrdev = &pdev->dev;
1689 1691
1690 /* copy descriptor header template value */ 1692 /* copy descriptor header template value */
1691 ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type; 1693 ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index 588ad2288f82..4e4ed155c5be 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -279,7 +279,7 @@ static void __exit caam_rng_exit(void)
279static int __init caam_rng_init(void) 279static int __init caam_rng_init(void)
280{ 280{
281 struct device_node *dev_node; 281 struct device_node *dev_node;
282 struct platform_device *pdev; 282 struct platform_device *pdev, *jrpdev;
283 struct device *ctrldev; 283 struct device *ctrldev;
284 struct caam_drv_private *priv; 284 struct caam_drv_private *priv;
285 285
@@ -305,9 +305,10 @@ static int __init caam_rng_init(void)
305 if (!priv) 305 if (!priv)
306 return -ENODEV; 306 return -ENODEV;
307 307
308 caam_init_rng(&rng_ctx, priv->jrdev[0]); 308 jrpdev = priv->jrpdev[0];
309 caam_init_rng(&rng_ctx, &jrpdev->dev);
309 310
310 dev_info(priv->jrdev[0], "registering rng-caam\n"); 311 dev_info(&jrpdev->dev, "registering rng-caam\n");
311 return hwrng_register(&caam_rng); 312 return hwrng_register(&caam_rng);
312} 313}
313 314
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 26438cd12685..52cd6c1b71fc 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -268,7 +268,6 @@ static int caam_remove(struct platform_device *pdev)
268{ 268{
269 struct device *ctrldev; 269 struct device *ctrldev;
270 struct caam_drv_private *ctrlpriv; 270 struct caam_drv_private *ctrlpriv;
271 struct caam_drv_private_jr *jrpriv;
272 struct caam_full __iomem *topregs; 271 struct caam_full __iomem *topregs;
273 int ring, ret = 0; 272 int ring, ret = 0;
274 273
@@ -276,11 +275,10 @@ static int caam_remove(struct platform_device *pdev)
276 ctrlpriv = dev_get_drvdata(ctrldev); 275 ctrlpriv = dev_get_drvdata(ctrldev);
277 topregs = (struct caam_full __iomem *)ctrlpriv->ctrl; 276 topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
278 277
279 /* shut down JobRs */ 278 /* Remove platform devices for JobRs */
280 for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) { 279 for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
281 ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]); 280 if (ctrlpriv->jrpdev[ring])
282 jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]); 281 of_device_unregister(ctrlpriv->jrpdev[ring]);
283 irq_dispose_mapping(jrpriv->irq);
284 } 282 }
285 283
286 /* De-initialize RNG state handles initialized by this driver. */ 284 /* De-initialize RNG state handles initialized by this driver. */
@@ -295,7 +293,7 @@ static int caam_remove(struct platform_device *pdev)
295 /* Unmap controller region */ 293 /* Unmap controller region */
296 iounmap(&topregs->ctrl); 294 iounmap(&topregs->ctrl);
297 295
298 kfree(ctrlpriv->jrdev); 296 kfree(ctrlpriv->jrpdev);
299 kfree(ctrlpriv); 297 kfree(ctrlpriv);
300 298
301 return ret; 299 return ret;
@@ -450,8 +448,9 @@ static int caam_probe(struct platform_device *pdev)
450 rspec++; 448 rspec++;
451 } 449 }
452 450
453 ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL); 451 ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
454 if (ctrlpriv->jrdev == NULL) { 452 GFP_KERNEL);
453 if (ctrlpriv->jrpdev == NULL) {
455 iounmap(&topregs->ctrl); 454 iounmap(&topregs->ctrl);
456 return -ENOMEM; 455 return -ENOMEM;
457 } 456 }
@@ -459,13 +458,24 @@ static int caam_probe(struct platform_device *pdev)
459 ring = 0; 458 ring = 0;
460 ctrlpriv->total_jobrs = 0; 459 ctrlpriv->total_jobrs = 0;
461 for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") { 460 for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
462 caam_jr_probe(pdev, np, ring); 461 ctrlpriv->jrpdev[ring] =
462 of_platform_device_create(np, NULL, dev);
463 if (!ctrlpriv->jrpdev[ring]) {
464 pr_warn("JR%d Platform device creation error\n", ring);
465 continue;
466 }
463 ctrlpriv->total_jobrs++; 467 ctrlpriv->total_jobrs++;
464 ring++; 468 ring++;
465 } 469 }
466 if (!ring) { 470 if (!ring) {
467 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") { 471 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
468 caam_jr_probe(pdev, np, ring); 472 ctrlpriv->jrpdev[ring] =
473 of_platform_device_create(np, NULL, dev);
474 if (!ctrlpriv->jrpdev[ring]) {
475 pr_warn("JR%d Platform device creation error\n",
476 ring);
477 continue;
478 }
469 ctrlpriv->total_jobrs++; 479 ctrlpriv->total_jobrs++;
470 ring++; 480 ring++;
471 } 481 }
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index bbc1ac9ec720..bff4acd3882d 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -37,8 +37,8 @@ struct caam_jrentry_info {
37 37
38/* Private sub-storage for a single JobR */ 38/* Private sub-storage for a single JobR */
39struct caam_drv_private_jr { 39struct caam_drv_private_jr {
40 struct device *parentdev; /* points back to controller dev */ 40 struct list_head list_node; /* Job Ring device list */
41 struct platform_device *jr_pdev;/* points to platform device for JR */ 41 struct device *dev;
42 int ridx; 42 int ridx;
43 struct caam_job_ring __iomem *rregs; /* JobR's register space */ 43 struct caam_job_ring __iomem *rregs; /* JobR's register space */
44 struct tasklet_struct irqtask; 44 struct tasklet_struct irqtask;
@@ -63,7 +63,7 @@ struct caam_drv_private_jr {
63struct caam_drv_private { 63struct caam_drv_private {
64 64
65 struct device *dev; 65 struct device *dev;
66 struct device **jrdev; /* Alloc'ed array per sub-device */ 66 struct platform_device **jrpdev; /* Alloc'ed array per sub-device */
67 struct platform_device *pdev; 67 struct platform_device *pdev;
68 68
69 /* Physical-presence section */ 69 /* Physical-presence section */
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 105ba4da6180..cdeaf2519b48 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -11,6 +11,114 @@
11#include "desc.h" 11#include "desc.h"
12#include "intern.h" 12#include "intern.h"
13 13
14struct jr_driver_data {
15 /* List of Physical JobR's with the Driver */
16 struct list_head jr_list;
17 spinlock_t jr_alloc_lock; /* jr_list lock */
18} ____cacheline_aligned;
19
20static struct jr_driver_data driver_data;
21
22static int caam_reset_hw_jr(struct device *dev)
23{
24 struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
25 unsigned int timeout = 100000;
26
27 /*
28 * mask interrupts since we are going to poll
29 * for reset completion status
30 */
31 setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
32
33 /* initiate flush (required prior to reset) */
34 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
35 while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
36 JRINT_ERR_HALT_INPROGRESS) && --timeout)
37 cpu_relax();
38
39 if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
40 JRINT_ERR_HALT_COMPLETE || timeout == 0) {
41 dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
42 return -EIO;
43 }
44
45 /* initiate reset */
46 timeout = 100000;
47 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
48 while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
49 cpu_relax();
50
51 if (timeout == 0) {
52 dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
53 return -EIO;
54 }
55
56 /* unmask interrupts */
57 clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
58
59 return 0;
60}
61
62/*
63 * Shutdown JobR independent of platform property code
64 */
65int caam_jr_shutdown(struct device *dev)
66{
67 struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
68 dma_addr_t inpbusaddr, outbusaddr;
69 int ret;
70
71 ret = caam_reset_hw_jr(dev);
72
73 tasklet_kill(&jrp->irqtask);
74
75 /* Release interrupt */
76 free_irq(jrp->irq, dev);
77
78 /* Free rings */
79 inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
80 outbusaddr = rd_reg64(&jrp->rregs->outring_base);
81 dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
82 jrp->inpring, inpbusaddr);
83 dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
84 jrp->outring, outbusaddr);
85 kfree(jrp->entinfo);
86
87 return ret;
88}
89
90static int caam_jr_remove(struct platform_device *pdev)
91{
92 int ret;
93 struct device *jrdev;
94 struct caam_drv_private_jr *jrpriv;
95
96 jrdev = &pdev->dev;
97 jrpriv = dev_get_drvdata(jrdev);
98
99 /*
100 * Make sure ring is empty before release
101 */
102 if (rd_reg32(&jrpriv->rregs->outring_used) ||
103 (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) {
104 dev_err(jrdev, "Device is busy\n");
105 return -EBUSY;
106 }
107
108 /* Remove the node from Physical JobR list maintained by driver */
109 spin_lock(&driver_data.jr_alloc_lock);
110 list_del(&jrpriv->list_node);
111 spin_unlock(&driver_data.jr_alloc_lock);
112
113 /* Release ring */
114 ret = caam_jr_shutdown(jrdev);
115 if (ret)
116 dev_err(jrdev, "Failed to shut down job ring\n");
117 irq_dispose_mapping(jrpriv->irq);
118
119 return ret;
120}
121
14/* Main per-ring interrupt handler */ 122/* Main per-ring interrupt handler */
15static irqreturn_t caam_jr_interrupt(int irq, void *st_dev) 123static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
16{ 124{
@@ -205,46 +313,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
205} 313}
206EXPORT_SYMBOL(caam_jr_enqueue); 314EXPORT_SYMBOL(caam_jr_enqueue);
207 315
208static int caam_reset_hw_jr(struct device *dev)
209{
210 struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
211 unsigned int timeout = 100000;
212
213 /*
214 * mask interrupts since we are going to poll
215 * for reset completion status
216 */
217 setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
218
219 /* initiate flush (required prior to reset) */
220 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
221 while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
222 JRINT_ERR_HALT_INPROGRESS) && --timeout)
223 cpu_relax();
224
225 if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
226 JRINT_ERR_HALT_COMPLETE || timeout == 0) {
227 dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
228 return -EIO;
229 }
230
231 /* initiate reset */
232 timeout = 100000;
233 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
234 while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
235 cpu_relax();
236
237 if (timeout == 0) {
238 dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
239 return -EIO;
240 }
241
242 /* unmask interrupts */
243 clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
244
245 return 0;
246}
247
248/* 316/*
249 * Init JobR independent of platform property detection 317 * Init JobR independent of platform property detection
250 */ 318 */
@@ -260,7 +328,7 @@ static int caam_jr_init(struct device *dev)
260 328
261 /* Connect job ring interrupt handler. */ 329 /* Connect job ring interrupt handler. */
262 error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED, 330 error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
263 "caam-jobr", dev); 331 dev_name(dev), dev);
264 if (error) { 332 if (error) {
265 dev_err(dev, "can't connect JobR %d interrupt (%d)\n", 333 dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
266 jrp->ridx, jrp->irq); 334 jrp->ridx, jrp->irq);
@@ -316,86 +384,43 @@ static int caam_jr_init(struct device *dev)
316 return 0; 384 return 0;
317} 385}
318 386
319/*
320 * Shutdown JobR independent of platform property code
321 */
322int caam_jr_shutdown(struct device *dev)
323{
324 struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
325 dma_addr_t inpbusaddr, outbusaddr;
326 int ret;
327
328 ret = caam_reset_hw_jr(dev);
329
330 tasklet_kill(&jrp->irqtask);
331
332 /* Release interrupt */
333 free_irq(jrp->irq, dev);
334
335 /* Free rings */
336 inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
337 outbusaddr = rd_reg64(&jrp->rregs->outring_base);
338 dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
339 jrp->inpring, inpbusaddr);
340 dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
341 jrp->outring, outbusaddr);
342 kfree(jrp->entinfo);
343 of_device_unregister(jrp->jr_pdev);
344
345 return ret;
346}
347 387
348/* 388/*
349 * Probe routine for each detected JobR subsystem. It assumes that 389 * Probe routine for each detected JobR subsystem.
350 * property detection was picked up externally.
351 */ 390 */
352int caam_jr_probe(struct platform_device *pdev, struct device_node *np, 391static int caam_jr_probe(struct platform_device *pdev)
353 int ring)
354{ 392{
355 struct device *ctrldev, *jrdev; 393 struct device *jrdev;
356 struct platform_device *jr_pdev; 394 struct device_node *nprop;
357 struct caam_drv_private *ctrlpriv; 395 struct caam_job_ring __iomem *ctrl;
358 struct caam_drv_private_jr *jrpriv; 396 struct caam_drv_private_jr *jrpriv;
359 u32 *jroffset; 397 static int total_jobrs;
360 int error; 398 int error;
361 399
362 ctrldev = &pdev->dev; 400 jrdev = &pdev->dev;
363 ctrlpriv = dev_get_drvdata(ctrldev);
364
365 jrpriv = kmalloc(sizeof(struct caam_drv_private_jr), 401 jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
366 GFP_KERNEL); 402 GFP_KERNEL);
367 if (jrpriv == NULL) { 403 if (!jrpriv)
368 dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
369 ring);
370 return -ENOMEM; 404 return -ENOMEM;
371 }
372 jrpriv->parentdev = ctrldev; /* point back to parent */
373 jrpriv->ridx = ring; /* save ring identity relative to detection */
374 405
375 /* 406 dev_set_drvdata(jrdev, jrpriv);
376 * Derive a pointer to the detected JobRs regs
377 * Driver has already iomapped the entire space, we just
378 * need to add in the offset to this JobR. Don't know if I
379 * like this long-term, but it'll run
380 */
381 jroffset = (u32 *)of_get_property(np, "reg", NULL);
382 jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
383 + *jroffset);
384 407
385 /* Build a local dev for each detected queue */ 408 /* save ring identity relative to detection */
386 jr_pdev = of_platform_device_create(np, NULL, ctrldev); 409 jrpriv->ridx = total_jobrs++;
387 if (jr_pdev == NULL) { 410
388 kfree(jrpriv); 411 nprop = pdev->dev.of_node;
389 return -EINVAL; 412 /* Get configuration properties from device tree */
413 /* First, get register page */
414 ctrl = of_iomap(nprop, 0);
415 if (!ctrl) {
416 dev_err(jrdev, "of_iomap() failed\n");
417 return -ENOMEM;
390 } 418 }
391 419
392 jrpriv->jr_pdev = jr_pdev; 420 jrpriv->rregs = (struct caam_job_ring __force *)ctrl;
393 jrdev = &jr_pdev->dev;
394 dev_set_drvdata(jrdev, jrpriv);
395 ctrlpriv->jrdev[ring] = jrdev;
396 421
397 if (sizeof(dma_addr_t) == sizeof(u64)) 422 if (sizeof(dma_addr_t) == sizeof(u64))
398 if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring")) 423 if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
399 dma_set_mask(jrdev, DMA_BIT_MASK(40)); 424 dma_set_mask(jrdev, DMA_BIT_MASK(40));
400 else 425 else
401 dma_set_mask(jrdev, DMA_BIT_MASK(36)); 426 dma_set_mask(jrdev, DMA_BIT_MASK(36));
@@ -403,15 +428,59 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
403 dma_set_mask(jrdev, DMA_BIT_MASK(32)); 428 dma_set_mask(jrdev, DMA_BIT_MASK(32));
404 429
405 /* Identify the interrupt */ 430 /* Identify the interrupt */
406 jrpriv->irq = of_irq_to_resource(np, 0, NULL); 431 jrpriv->irq = of_irq_to_resource(nprop, 0, NULL);
407 432
408 /* Now do the platform independent part */ 433 /* Now do the platform independent part */
409 error = caam_jr_init(jrdev); /* now turn on hardware */ 434 error = caam_jr_init(jrdev); /* now turn on hardware */
410 if (error) { 435 if (error) {
411 of_device_unregister(jr_pdev);
412 kfree(jrpriv); 436 kfree(jrpriv);
413 return error; 437 return error;
414 } 438 }
415 439
416 return error; 440 jrpriv->dev = jrdev;
441 spin_lock(&driver_data.jr_alloc_lock);
442 list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
443 spin_unlock(&driver_data.jr_alloc_lock);
444
445 return 0;
446}
447
448static struct of_device_id caam_jr_match[] = {
449 {
450 .compatible = "fsl,sec-v4.0-job-ring",
451 },
452 {
453 .compatible = "fsl,sec4.0-job-ring",
454 },
455 {},
456};
457MODULE_DEVICE_TABLE(of, caam_jr_match);
458
459static struct platform_driver caam_jr_driver = {
460 .driver = {
461 .name = "caam_jr",
462 .owner = THIS_MODULE,
463 .of_match_table = caam_jr_match,
464 },
465 .probe = caam_jr_probe,
466 .remove = caam_jr_remove,
467};
468
469static int __init jr_driver_init(void)
470{
471 spin_lock_init(&driver_data.jr_alloc_lock);
472 INIT_LIST_HEAD(&driver_data.jr_list);
473 return platform_driver_register(&caam_jr_driver);
417} 474}
475
476static void __exit jr_driver_exit(void)
477{
478 platform_driver_unregister(&caam_jr_driver);
479}
480
481module_init(jr_driver_init);
482module_exit(jr_driver_exit);
483
484MODULE_LICENSE("GPL");
485MODULE_DESCRIPTION("FSL CAAM JR request backend");
486MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
diff --git a/drivers/crypto/caam/jr.h b/drivers/crypto/caam/jr.h
index 9d8741a59037..02f69bbbab08 100644
--- a/drivers/crypto/caam/jr.h
+++ b/drivers/crypto/caam/jr.h
@@ -13,7 +13,4 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
13 void *areq), 13 void *areq),
14 void *areq); 14 void *areq);
15 15
16extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
17 int ring);
18extern int caam_jr_shutdown(struct device *dev);
19#endif /* JR_H */ 16#endif /* JR_H */