|
@@ -97,10 +97,9 @@ static int caam_jr_remove(struct platform_device *pdev)
|
|
|
jrpriv = dev_get_drvdata(jrdev);
|
|
|
|
|
|
/*
|
|
|
- * Make sure ring is empty before release
|
|
|
+ * Return EBUSY if job ring already allocated.
|
|
|
*/
|
|
|
- if (rd_reg32(&jrpriv->rregs->outring_used) ||
|
|
|
- (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) {
|
|
|
+ if (atomic_read(&jrpriv->tfm_count)) {
|
|
|
dev_err(jrdev, "Device is busy\n");
|
|
|
return -EBUSY;
|
|
|
}
|
|
@@ -233,6 +232,59 @@ static void caam_jr_dequeue(unsigned long devarg)
|
|
|
clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
|
|
|
+ *
|
|
|
+ * returns : pointer to the newly allocated physical
|
|
|
+ * JobR dev can be written to if successful.
|
|
|
+ **/
|
|
|
+struct device *caam_jr_alloc(void)
|
|
|
+{
|
|
|
+ struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
|
|
|
+ struct device *dev = NULL;
|
|
|
+ int min_tfm_cnt = INT_MAX;
|
|
|
+ int tfm_cnt;
|
|
|
+
|
|
|
+ spin_lock(&driver_data.jr_alloc_lock);
|
|
|
+
|
|
|
+ if (list_empty(&driver_data.jr_list)) {
|
|
|
+ spin_unlock(&driver_data.jr_alloc_lock);
|
|
|
+ return ERR_PTR(-ENODEV);
|
|
|
+ }
|
|
|
+
|
|
|
+ list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) {
|
|
|
+ tfm_cnt = atomic_read(&jrpriv->tfm_count);
|
|
|
+ if (tfm_cnt < min_tfm_cnt) {
|
|
|
+ min_tfm_cnt = tfm_cnt;
|
|
|
+ min_jrpriv = jrpriv;
|
|
|
+ }
|
|
|
+ if (!min_tfm_cnt)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (min_jrpriv) {
|
|
|
+ atomic_inc(&min_jrpriv->tfm_count);
|
|
|
+ dev = min_jrpriv->dev;
|
|
|
+ }
|
|
|
+ spin_unlock(&driver_data.jr_alloc_lock);
|
|
|
+
|
|
|
+ return dev;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(caam_jr_alloc);
|
|
|
+
|
|
|
+/**
|
|
|
+ * caam_jr_free() - Free the Job Ring
|
|
|
+ * @rdev - points to the dev that identifies the Job ring to
|
|
|
+ * be released.
|
|
|
+ **/
|
|
|
+void caam_jr_free(struct device *rdev)
|
|
|
+{
|
|
|
+ struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
|
|
|
+
|
|
|
+ atomic_dec(&jrpriv->tfm_count);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(caam_jr_free);
|
|
|
+
|
|
|
/**
|
|
|
* caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
|
|
|
* -EBUSY if the queue is full, -EIO if it cannot map the caller's
|
|
@@ -442,6 +494,8 @@ static int caam_jr_probe(struct platform_device *pdev)
|
|
|
list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
|
|
|
spin_unlock(&driver_data.jr_alloc_lock);
|
|
|
|
|
|
+ atomic_set(&jrpriv->tfm_count, 0);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|