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>
This commit is contained in:
parent
0d28978824
commit
313ea293e9
|
@ -4,16 +4,29 @@ config CRYPTO_DEV_FSL_CAAM
|
|||
help
|
||||
Enables the driver module for Freescale's Cryptographic Accelerator
|
||||
and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
|
||||
This module adds a job ring operation interface, and configures h/w
|
||||
This module creates job ring devices, and configures h/w
|
||||
to operate as a DPAA component automatically, depending
|
||||
on h/w feature availability.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called caam.
|
||||
|
||||
config CRYPTO_DEV_FSL_CAAM_JR
|
||||
tristate "Freescale CAAM Job Ring driver backend"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
default y
|
||||
help
|
||||
Enables the driver module for Job Rings which are part of
|
||||
Freescale's Cryptographic Accelerator
|
||||
and Assurance Module (CAAM). This module adds a job ring operation
|
||||
interface.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called caam_jr.
|
||||
|
||||
config CRYPTO_DEV_FSL_CAAM_RINGSIZE
|
||||
int "Job Ring size"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM_JR
|
||||
range 2 9
|
||||
default "9"
|
||||
help
|
||||
|
@ -31,7 +44,7 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE
|
|||
|
||||
config CRYPTO_DEV_FSL_CAAM_INTC
|
||||
bool "Job Ring interrupt coalescing"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM_JR
|
||||
default n
|
||||
help
|
||||
Enable the Job Ring's interrupt coalescing feature.
|
||||
|
@ -62,7 +75,7 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD
|
|||
|
||||
config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
|
||||
tristate "Register algorithm implementations with the Crypto API"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
|
||||
default y
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_AUTHENC
|
||||
|
@ -76,7 +89,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
|
|||
|
||||
config CRYPTO_DEV_FSL_CAAM_AHASH_API
|
||||
tristate "Register hash algorithm implementations with Crypto API"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
|
||||
default y
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
|
@ -88,7 +101,7 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API
|
|||
|
||||
config CRYPTO_DEV_FSL_CAAM_RNG_API
|
||||
tristate "Register caam device for hwrng API"
|
||||
depends on CRYPTO_DEV_FSL_CAAM
|
||||
depends on CRYPTO_DEV_FSL_CAAM && CRYPTO_DEV_FSL_CAAM_JR
|
||||
default y
|
||||
select CRYPTO_RNG
|
||||
select HW_RANDOM
|
||||
|
|
|
@ -6,8 +6,10 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG), y)
|
|||
endif
|
||||
|
||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o
|
||||
|
||||
caam-objs := ctrl.o jr.o error.o key_gen.o
|
||||
caam-objs := ctrl.o
|
||||
caam_jr-objs := jr.o key_gen.o error.o
|
||||
|
|
|
@ -2071,13 +2071,15 @@ static int caam_cra_init(struct crypto_tfm *tfm)
|
|||
container_of(alg, struct caam_crypto_alg, crypto_alg);
|
||||
struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev);
|
||||
struct platform_device *pdev;
|
||||
int tgt_jr = atomic_inc_return(&priv->tfm_count);
|
||||
|
||||
/*
|
||||
* distribute tfms across job rings to ensure in-order
|
||||
* crypto request processing per tfm
|
||||
*/
|
||||
ctx->jrdev = priv->jrdev[(tgt_jr / 2) % priv->total_jobrs];
|
||||
pdev = priv->jrpdev[(tgt_jr / 2) % priv->total_jobrs];
|
||||
ctx->jrdev = &pdev->dev;
|
||||
|
||||
/* copy descriptor header template value */
|
||||
ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
|
||||
|
|
|
@ -1680,12 +1680,14 @@ static int caam_hash_cra_init(struct crypto_tfm *tfm)
|
|||
HASH_MSG_LEN + SHA512_DIGEST_SIZE };
|
||||
int tgt_jr = atomic_inc_return(&priv->tfm_count);
|
||||
int ret = 0;
|
||||
struct platform_device *pdev;
|
||||
|
||||
/*
|
||||
* distribute tfms across job rings to ensure in-order
|
||||
* crypto request processing per tfm
|
||||
*/
|
||||
ctx->jrdev = priv->jrdev[tgt_jr % priv->total_jobrs];
|
||||
pdev = priv->jrpdev[tgt_jr % priv->total_jobrs];
|
||||
ctx->jrdev = &pdev->dev;
|
||||
|
||||
/* copy descriptor header template value */
|
||||
ctx->alg_type = OP_TYPE_CLASS2_ALG | caam_hash->alg_type;
|
||||
|
|
|
@ -279,7 +279,7 @@ static void __exit caam_rng_exit(void)
|
|||
static int __init caam_rng_init(void)
|
||||
{
|
||||
struct device_node *dev_node;
|
||||
struct platform_device *pdev;
|
||||
struct platform_device *pdev, *jrpdev;
|
||||
struct device *ctrldev;
|
||||
struct caam_drv_private *priv;
|
||||
|
||||
|
@ -305,9 +305,10 @@ static int __init caam_rng_init(void)
|
|||
if (!priv)
|
||||
return -ENODEV;
|
||||
|
||||
caam_init_rng(&rng_ctx, priv->jrdev[0]);
|
||||
jrpdev = priv->jrpdev[0];
|
||||
caam_init_rng(&rng_ctx, &jrpdev->dev);
|
||||
|
||||
dev_info(priv->jrdev[0], "registering rng-caam\n");
|
||||
dev_info(&jrpdev->dev, "registering rng-caam\n");
|
||||
return hwrng_register(&caam_rng);
|
||||
}
|
||||
|
||||
|
|
|
@ -268,7 +268,6 @@ static int caam_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct device *ctrldev;
|
||||
struct caam_drv_private *ctrlpriv;
|
||||
struct caam_drv_private_jr *jrpriv;
|
||||
struct caam_full __iomem *topregs;
|
||||
int ring, ret = 0;
|
||||
|
||||
|
@ -276,11 +275,10 @@ static int caam_remove(struct platform_device *pdev)
|
|||
ctrlpriv = dev_get_drvdata(ctrldev);
|
||||
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
|
||||
|
||||
/* shut down JobRs */
|
||||
/* Remove platform devices for JobRs */
|
||||
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
|
||||
ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
|
||||
jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
|
||||
irq_dispose_mapping(jrpriv->irq);
|
||||
if (ctrlpriv->jrpdev[ring])
|
||||
of_device_unregister(ctrlpriv->jrpdev[ring]);
|
||||
}
|
||||
|
||||
/* De-initialize RNG state handles initialized by this driver. */
|
||||
|
@ -295,7 +293,7 @@ static int caam_remove(struct platform_device *pdev)
|
|||
/* Unmap controller region */
|
||||
iounmap(&topregs->ctrl);
|
||||
|
||||
kfree(ctrlpriv->jrdev);
|
||||
kfree(ctrlpriv->jrpdev);
|
||||
kfree(ctrlpriv);
|
||||
|
||||
return ret;
|
||||
|
@ -450,8 +448,9 @@ static int caam_probe(struct platform_device *pdev)
|
|||
rspec++;
|
||||
}
|
||||
|
||||
ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
|
||||
if (ctrlpriv->jrdev == NULL) {
|
||||
ctrlpriv->jrpdev = kzalloc(sizeof(struct platform_device *) * rspec,
|
||||
GFP_KERNEL);
|
||||
if (ctrlpriv->jrpdev == NULL) {
|
||||
iounmap(&topregs->ctrl);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -459,13 +458,24 @@ static int caam_probe(struct platform_device *pdev)
|
|||
ring = 0;
|
||||
ctrlpriv->total_jobrs = 0;
|
||||
for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
|
||||
caam_jr_probe(pdev, np, ring);
|
||||
ctrlpriv->jrpdev[ring] =
|
||||
of_platform_device_create(np, NULL, dev);
|
||||
if (!ctrlpriv->jrpdev[ring]) {
|
||||
pr_warn("JR%d Platform device creation error\n", ring);
|
||||
continue;
|
||||
}
|
||||
ctrlpriv->total_jobrs++;
|
||||
ring++;
|
||||
}
|
||||
if (!ring) {
|
||||
for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
|
||||
caam_jr_probe(pdev, np, ring);
|
||||
ctrlpriv->jrpdev[ring] =
|
||||
of_platform_device_create(np, NULL, dev);
|
||||
if (!ctrlpriv->jrpdev[ring]) {
|
||||
pr_warn("JR%d Platform device creation error\n",
|
||||
ring);
|
||||
continue;
|
||||
}
|
||||
ctrlpriv->total_jobrs++;
|
||||
ring++;
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ struct caam_jrentry_info {
|
|||
|
||||
/* Private sub-storage for a single JobR */
|
||||
struct caam_drv_private_jr {
|
||||
struct device *parentdev; /* points back to controller dev */
|
||||
struct platform_device *jr_pdev;/* points to platform device for JR */
|
||||
struct list_head list_node; /* Job Ring device list */
|
||||
struct device *dev;
|
||||
int ridx;
|
||||
struct caam_job_ring __iomem *rregs; /* JobR's register space */
|
||||
struct tasklet_struct irqtask;
|
||||
|
@ -63,7 +63,7 @@ struct caam_drv_private_jr {
|
|||
struct caam_drv_private {
|
||||
|
||||
struct device *dev;
|
||||
struct device **jrdev; /* Alloc'ed array per sub-device */
|
||||
struct platform_device **jrpdev; /* Alloc'ed array per sub-device */
|
||||
struct platform_device *pdev;
|
||||
|
||||
/* Physical-presence section */
|
||||
|
|
|
@ -11,6 +11,114 @@
|
|||
#include "desc.h"
|
||||
#include "intern.h"
|
||||
|
||||
struct jr_driver_data {
|
||||
/* List of Physical JobR's with the Driver */
|
||||
struct list_head jr_list;
|
||||
spinlock_t jr_alloc_lock; /* jr_list lock */
|
||||
} ____cacheline_aligned;
|
||||
|
||||
static struct jr_driver_data driver_data;
|
||||
|
||||
static int caam_reset_hw_jr(struct device *dev)
|
||||
{
|
||||
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||
unsigned int timeout = 100000;
|
||||
|
||||
/*
|
||||
* mask interrupts since we are going to poll
|
||||
* for reset completion status
|
||||
*/
|
||||
setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
|
||||
|
||||
/* initiate flush (required prior to reset) */
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
|
||||
JRINT_ERR_HALT_INPROGRESS) && --timeout)
|
||||
cpu_relax();
|
||||
|
||||
if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
|
||||
JRINT_ERR_HALT_COMPLETE || timeout == 0) {
|
||||
dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* initiate reset */
|
||||
timeout = 100000;
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
|
||||
cpu_relax();
|
||||
|
||||
if (timeout == 0) {
|
||||
dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* unmask interrupts */
|
||||
clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown JobR independent of platform property code
|
||||
*/
|
||||
int caam_jr_shutdown(struct device *dev)
|
||||
{
|
||||
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||
dma_addr_t inpbusaddr, outbusaddr;
|
||||
int ret;
|
||||
|
||||
ret = caam_reset_hw_jr(dev);
|
||||
|
||||
tasklet_kill(&jrp->irqtask);
|
||||
|
||||
/* Release interrupt */
|
||||
free_irq(jrp->irq, dev);
|
||||
|
||||
/* Free rings */
|
||||
inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
|
||||
outbusaddr = rd_reg64(&jrp->rregs->outring_base);
|
||||
dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
|
||||
jrp->inpring, inpbusaddr);
|
||||
dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
|
||||
jrp->outring, outbusaddr);
|
||||
kfree(jrp->entinfo);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int caam_jr_remove(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct device *jrdev;
|
||||
struct caam_drv_private_jr *jrpriv;
|
||||
|
||||
jrdev = &pdev->dev;
|
||||
jrpriv = dev_get_drvdata(jrdev);
|
||||
|
||||
/*
|
||||
* Make sure ring is empty before release
|
||||
*/
|
||||
if (rd_reg32(&jrpriv->rregs->outring_used) ||
|
||||
(rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH)) {
|
||||
dev_err(jrdev, "Device is busy\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Remove the node from Physical JobR list maintained by driver */
|
||||
spin_lock(&driver_data.jr_alloc_lock);
|
||||
list_del(&jrpriv->list_node);
|
||||
spin_unlock(&driver_data.jr_alloc_lock);
|
||||
|
||||
/* Release ring */
|
||||
ret = caam_jr_shutdown(jrdev);
|
||||
if (ret)
|
||||
dev_err(jrdev, "Failed to shut down job ring\n");
|
||||
irq_dispose_mapping(jrpriv->irq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Main per-ring interrupt handler */
|
||||
static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
|
||||
{
|
||||
|
@ -205,46 +313,6 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
|
|||
}
|
||||
EXPORT_SYMBOL(caam_jr_enqueue);
|
||||
|
||||
static int caam_reset_hw_jr(struct device *dev)
|
||||
{
|
||||
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||
unsigned int timeout = 100000;
|
||||
|
||||
/*
|
||||
* mask interrupts since we are going to poll
|
||||
* for reset completion status
|
||||
*/
|
||||
setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
|
||||
|
||||
/* initiate flush (required prior to reset) */
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
|
||||
JRINT_ERR_HALT_INPROGRESS) && --timeout)
|
||||
cpu_relax();
|
||||
|
||||
if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
|
||||
JRINT_ERR_HALT_COMPLETE || timeout == 0) {
|
||||
dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* initiate reset */
|
||||
timeout = 100000;
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
|
||||
cpu_relax();
|
||||
|
||||
if (timeout == 0) {
|
||||
dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* unmask interrupts */
|
||||
clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init JobR independent of platform property detection
|
||||
*/
|
||||
|
@ -260,7 +328,7 @@ static int caam_jr_init(struct device *dev)
|
|||
|
||||
/* Connect job ring interrupt handler. */
|
||||
error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
|
||||
"caam-jobr", dev);
|
||||
dev_name(dev), dev);
|
||||
if (error) {
|
||||
dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
|
||||
jrp->ridx, jrp->irq);
|
||||
|
@ -316,86 +384,43 @@ static int caam_jr_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown JobR independent of platform property code
|
||||
*/
|
||||
int caam_jr_shutdown(struct device *dev)
|
||||
{
|
||||
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||
dma_addr_t inpbusaddr, outbusaddr;
|
||||
int ret;
|
||||
|
||||
ret = caam_reset_hw_jr(dev);
|
||||
|
||||
tasklet_kill(&jrp->irqtask);
|
||||
|
||||
/* Release interrupt */
|
||||
free_irq(jrp->irq, dev);
|
||||
|
||||
/* Free rings */
|
||||
inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
|
||||
outbusaddr = rd_reg64(&jrp->rregs->outring_base);
|
||||
dma_free_coherent(dev, sizeof(dma_addr_t) * JOBR_DEPTH,
|
||||
jrp->inpring, inpbusaddr);
|
||||
dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
|
||||
jrp->outring, outbusaddr);
|
||||
kfree(jrp->entinfo);
|
||||
of_device_unregister(jrp->jr_pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Probe routine for each detected JobR subsystem. It assumes that
|
||||
* property detection was picked up externally.
|
||||
* Probe routine for each detected JobR subsystem.
|
||||
*/
|
||||
int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
|
||||
int ring)
|
||||
static int caam_jr_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *ctrldev, *jrdev;
|
||||
struct platform_device *jr_pdev;
|
||||
struct caam_drv_private *ctrlpriv;
|
||||
struct device *jrdev;
|
||||
struct device_node *nprop;
|
||||
struct caam_job_ring __iomem *ctrl;
|
||||
struct caam_drv_private_jr *jrpriv;
|
||||
u32 *jroffset;
|
||||
static int total_jobrs;
|
||||
int error;
|
||||
|
||||
ctrldev = &pdev->dev;
|
||||
ctrlpriv = dev_get_drvdata(ctrldev);
|
||||
|
||||
jrdev = &pdev->dev;
|
||||
jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
|
||||
GFP_KERNEL);
|
||||
if (jrpriv == NULL) {
|
||||
dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
|
||||
ring);
|
||||
if (!jrpriv)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(jrdev, jrpriv);
|
||||
|
||||
/* save ring identity relative to detection */
|
||||
jrpriv->ridx = total_jobrs++;
|
||||
|
||||
nprop = pdev->dev.of_node;
|
||||
/* Get configuration properties from device tree */
|
||||
/* First, get register page */
|
||||
ctrl = of_iomap(nprop, 0);
|
||||
if (!ctrl) {
|
||||
dev_err(jrdev, "of_iomap() failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
jrpriv->parentdev = ctrldev; /* point back to parent */
|
||||
jrpriv->ridx = ring; /* save ring identity relative to detection */
|
||||
|
||||
/*
|
||||
* Derive a pointer to the detected JobRs regs
|
||||
* Driver has already iomapped the entire space, we just
|
||||
* need to add in the offset to this JobR. Don't know if I
|
||||
* like this long-term, but it'll run
|
||||
*/
|
||||
jroffset = (u32 *)of_get_property(np, "reg", NULL);
|
||||
jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
|
||||
+ *jroffset);
|
||||
|
||||
/* Build a local dev for each detected queue */
|
||||
jr_pdev = of_platform_device_create(np, NULL, ctrldev);
|
||||
if (jr_pdev == NULL) {
|
||||
kfree(jrpriv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
jrpriv->jr_pdev = jr_pdev;
|
||||
jrdev = &jr_pdev->dev;
|
||||
dev_set_drvdata(jrdev, jrpriv);
|
||||
ctrlpriv->jrdev[ring] = jrdev;
|
||||
jrpriv->rregs = (struct caam_job_ring __force *)ctrl;
|
||||
|
||||
if (sizeof(dma_addr_t) == sizeof(u64))
|
||||
if (of_device_is_compatible(np, "fsl,sec-v5.0-job-ring"))
|
||||
if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
|
||||
dma_set_mask(jrdev, DMA_BIT_MASK(40));
|
||||
else
|
||||
dma_set_mask(jrdev, DMA_BIT_MASK(36));
|
||||
|
@ -403,15 +428,59 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
|
|||
dma_set_mask(jrdev, DMA_BIT_MASK(32));
|
||||
|
||||
/* Identify the interrupt */
|
||||
jrpriv->irq = of_irq_to_resource(np, 0, NULL);
|
||||
jrpriv->irq = of_irq_to_resource(nprop, 0, NULL);
|
||||
|
||||
/* Now do the platform independent part */
|
||||
error = caam_jr_init(jrdev); /* now turn on hardware */
|
||||
if (error) {
|
||||
of_device_unregister(jr_pdev);
|
||||
kfree(jrpriv);
|
||||
return error;
|
||||
}
|
||||
|
||||
return error;
|
||||
jrpriv->dev = jrdev;
|
||||
spin_lock(&driver_data.jr_alloc_lock);
|
||||
list_add_tail(&jrpriv->list_node, &driver_data.jr_list);
|
||||
spin_unlock(&driver_data.jr_alloc_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id caam_jr_match[] = {
|
||||
{
|
||||
.compatible = "fsl,sec-v4.0-job-ring",
|
||||
},
|
||||
{
|
||||
.compatible = "fsl,sec4.0-job-ring",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, caam_jr_match);
|
||||
|
||||
static struct platform_driver caam_jr_driver = {
|
||||
.driver = {
|
||||
.name = "caam_jr",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = caam_jr_match,
|
||||
},
|
||||
.probe = caam_jr_probe,
|
||||
.remove = caam_jr_remove,
|
||||
};
|
||||
|
||||
static int __init jr_driver_init(void)
|
||||
{
|
||||
spin_lock_init(&driver_data.jr_alloc_lock);
|
||||
INIT_LIST_HEAD(&driver_data.jr_list);
|
||||
return platform_driver_register(&caam_jr_driver);
|
||||
}
|
||||
|
||||
static void __exit jr_driver_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&caam_jr_driver);
|
||||
}
|
||||
|
||||
module_init(jr_driver_init);
|
||||
module_exit(jr_driver_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("FSL CAAM JR request backend");
|
||||
MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
|
||||
|
|
|
@ -13,7 +13,4 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
|
|||
void *areq),
|
||||
void *areq);
|
||||
|
||||
extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
|
||||
int ring);
|
||||
extern int caam_jr_shutdown(struct device *dev);
|
||||
#endif /* JR_H */
|
||||
|
|
Loading…
Reference in New Issue
Block a user