aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam/jr.c
diff options
context:
space:
mode:
authorRuchika Gupta <ruchika.gupta@freescale.com>2013-10-25 02:31:02 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-10-30 00:02:57 -0400
commit07defbfb0fd662272dff5207001a0a5e09aeaeec (patch)
tree8a62247e570d9cdad5fec0a31d494c76e532a4b3 /drivers/crypto/caam/jr.c
parent313ea293e9c4d1eabcaddd2c0800f083b03c2a2e (diff)
crypto: caam - Add API's to allocate/free Job Rings
With each of the Job Ring available as a platform device, the Job Ring driver needs to take care of allocation/deallocation of the Job Rings to the above interface layers. Added APIs in Job Ring Driver to allocate/free Job rings 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/jr.c')
-rw-r--r--drivers/crypto/caam/jr.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index cdeaf2519b48..636bb53125ab 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -97,10 +97,9 @@ static int caam_jr_remove(struct platform_device *pdev)
97 jrpriv = dev_get_drvdata(jrdev); 97 jrpriv = dev_get_drvdata(jrdev);
98 98
99 /* 99 /*
100 * Make sure ring is empty before release 100 * Return EBUSY if job ring already allocated.
101 */ 101 */
102 if (rd_reg32(&jrpriv->rregs->outring_used) || 102 if (atomic_read(&jrpriv->tfm_count)) {
103 (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) {
104 dev_err(jrdev, "Device is busy\n"); 103 dev_err(jrdev, "Device is busy\n");
105 return -EBUSY; 104 return -EBUSY;
106 } 105 }
@@ -234,6 +233,59 @@ static void caam_jr_dequeue(unsigned long devarg)
234} 233}
235 234
236/** 235/**
236 * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
237 *
238 * returns : pointer to the newly allocated physical
239 * JobR dev can be written to if successful.
240 **/
241struct device *caam_jr_alloc(void)
242{
243 struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
244 struct device *dev = NULL;
245 int min_tfm_cnt = INT_MAX;
246 int tfm_cnt;
247
248 spin_lock(&driver_data.jr_alloc_lock);
249
250 if (list_empty(&driver_data.jr_list)) {
251 spin_unlock(&driver_data.jr_alloc_lock);
252 return ERR_PTR(-ENODEV);
253 }
254
255 list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
256 tfm_cnt = atomic_read(&jrpriv->tfm_count);
257 if (tfm_cnt < min_tfm_cnt) {
258 min_tfm_cnt = tfm_cnt;
259 min_jrpriv = jrpriv;
260 }
261 if (!min_tfm_cnt)
262 break;
263 }
264
265 if (min_jrpriv) {
266 atomic_inc(&min_jrpriv->tfm_count);
267 dev = min_jrpriv->dev;
268 }
269 spin_unlock(&driver_data.jr_alloc_lock);
270
271 return dev;
272}
273EXPORT_SYMBOL(caam_jr_alloc);
274
275/**
276 * caam_jr_free() - Free the Job Ring
277 * @rdev - points to the dev that identifies the Job ring to
278 * be released.
279 **/
280void caam_jr_free(struct device *rdev)
281{
282 struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
283
284 atomic_dec(&jrpriv->tfm_count);
285}
286EXPORT_SYMBOL(caam_jr_free);
287
288/**
237 * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK, 289 * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
238 * -EBUSY if the queue is full, -EIO if it cannot map the caller's 290 * -EBUSY if the queue is full, -EIO if it cannot map the caller's
239 * descriptor. 291 * descriptor.
@@ -442,6 +494,8 @@ static int caam_jr_probe(struct platform_device *pdev)
442 list_add_tail(&jrpriv->list_node, &driver_data.jr_list); 494 list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
443 spin_unlock(&driver_data.jr_alloc_lock); 495 spin_unlock(&driver_data.jr_alloc_lock);
444 496
497 atomic_set(&jrpriv->tfm_count, 0);
498
445 return 0; 499 return 0;
446} 500}
447 501