aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam
diff options
context:
space:
mode:
authorRuchika Gupta <ruchika.gupta@freescale.com>2013-10-25 02:31:01 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-10-30 00:02:57 -0400
commit313ea293e9c4d1eabcaddd2c0800f083b03c2a2e (patch)
treecd6e48a5aa2a1ea84895cbe1278c1318eece5cdb /drivers/crypto/caam
parent0d289788247a4751b2dfa0a23960ac4de9450a94 (diff)
crypto: caam - Add Platform driver for Job Ring
The SEC Job Rings are now available as individual devices. This would enable sharing of job rings between kernel and user space. Job Rings can now be dynamically bound/unbound from kernel. Changes are made in the following layers of CAAM Driver 1. Controller driver - Does basic initialization of CAAM Block. - Creates platform devices for Job Rings. (Earlier the initialization of Job ring was done by the controller driver) 2. JobRing Platform driver - Manages the platform Job Ring devices created by the controller driver Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com> Reviewed-by: Garg Vakul-B16394 <vakul@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/caam')
-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 */