Skip to content

Commit

Permalink
crypto: caam - fix JR platform device subsequent (re)creations
Browse files Browse the repository at this point in the history
The way Job Ring platform devices are created and released does not
allow for multiple create-release cycles.

JR0 Platform device creation error
JR0 Platform device creation error
caam 2100000.caam: no queues configured, terminating
caam: probe of 2100000.caam failed with error -12

The reason is that platform devices are created for each job ring:

        for_each_available_child_of_node(nprop, np)
                if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
                    of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
                        ctrlpriv->jrpdev[ring] =
                                of_platform_device_create(np, NULL, dev);

which sets OF_POPULATED on the device node, but then it cleans these up:

        /* Remove platform devices for JobRs */
        for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
                if (ctrlpriv->jrpdev[ring])
                        of_device_unregister(ctrlpriv->jrpdev[ring]);
        }

which leaves OF_POPULATED set.

Use of_platform_populate / of_platform_depopulate instead.
This allows for a bit of driver clean-up, jrpdev is no longer needed.

Logic changes a bit too:
-exit in case of_platform_populate fails, since currently even QI backend
depends on JR; true, we no longer support the case when "some" of the JR
DT nodes are incorrect
-when cleaning up, caam_remove() would also depopulate RTIC in case
it would have been populated somewhere else - not the case for now

Cc: <[email protected]>
Fixes: 313ea29 ("crypto: caam - Add Platform driver for Job Ring")
Reported-by: Russell King <[email protected]>
Suggested-by: Rob Herring <[email protected]>
Signed-off-by: Horia Geantă <[email protected]>
Acked-by: Rob Herring <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
horiag authored and herbertx committed Apr 5, 2017
1 parent 9df0eb1 commit ec36060
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 45 deletions.
63 changes: 19 additions & 44 deletions drivers/crypto/caam/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,13 @@ static int caam_remove(struct platform_device *pdev)
struct device *ctrldev;
struct caam_drv_private *ctrlpriv;
struct caam_ctrl __iomem *ctrl;
int ring;

ctrldev = &pdev->dev;
ctrlpriv = dev_get_drvdata(ctrldev);
ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;

/* Remove platform devices for JobRs */
for (ring = 0; ring < ctrlpriv->total_jobrs; ring++)
of_device_unregister(ctrlpriv->jrpdev[ring]);
/* Remove platform devices under the crypto node */
of_platform_depopulate(ctrldev);

/* De-initialize RNG state handles initialized by this driver. */
if (ctrlpriv->rng4_sh_init)
Expand Down Expand Up @@ -418,10 +416,21 @@ DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u32_ro, caam_debugfs_u32_get, NULL, "%llu\n");
DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n");
#endif

static const struct of_device_id caam_match[] = {
{
.compatible = "fsl,sec-v4.0",
},
{
.compatible = "fsl,sec4.0",
},
{},
};
MODULE_DEVICE_TABLE(of, caam_match);

/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
int ret, ring, ridx, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
u64 caam_id;
struct device *dev;
struct device_node *nprop, *np;
Expand Down Expand Up @@ -597,47 +606,24 @@ static int caam_probe(struct platform_device *pdev)
goto iounmap_ctrl;
}

/*
* Detect and enable JobRs
* First, find out how many ring spec'ed, allocate references
* for all, then go probe each one.
*/
rspec = 0;
for_each_available_child_of_node(nprop, np)
if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
of_device_is_compatible(np, "fsl,sec4.0-job-ring"))
rspec++;

ctrlpriv->jrpdev = devm_kcalloc(&pdev->dev, rspec,
sizeof(*ctrlpriv->jrpdev), GFP_KERNEL);
if (ctrlpriv->jrpdev == NULL) {
ret = -ENOMEM;
ret = of_platform_populate(nprop, caam_match, NULL, dev);
if (ret) {
dev_err(dev, "JR platform devices creation error\n");
goto iounmap_ctrl;
}

ring = 0;
ridx = 0;
ctrlpriv->total_jobrs = 0;
for_each_available_child_of_node(nprop, np)
if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") ||
of_device_is_compatible(np, "fsl,sec4.0-job-ring")) {
ctrlpriv->jrpdev[ring] =
of_platform_device_create(np, NULL, dev);
if (!ctrlpriv->jrpdev[ring]) {
pr_warn("JR physical index %d: Platform device creation error\n",
ridx);
ridx++;
continue;
}
ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *)
((__force uint8_t *)ctrl +
(ridx + JR_BLOCK_NUMBER) *
(ring + JR_BLOCK_NUMBER) *
BLOCK_OFFSET
);
ctrlpriv->total_jobrs++;
ring++;
ridx++;
}
}

/* Check to see if QI present. If so, enable */
ctrlpriv->qi_present =
Expand Down Expand Up @@ -847,17 +833,6 @@ static int caam_probe(struct platform_device *pdev)
return ret;
}

static struct of_device_id caam_match[] = {
{
.compatible = "fsl,sec-v4.0",
},
{
.compatible = "fsl,sec4.0",
},
{},
};
MODULE_DEVICE_TABLE(of, caam_match);

static struct platform_driver caam_driver = {
.driver = {
.name = "caam",
Expand Down
1 change: 0 additions & 1 deletion drivers/crypto/caam/intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ struct caam_drv_private_jr {
struct caam_drv_private {

struct device *dev;
struct platform_device **jrpdev; /* Alloc'ed array per sub-device */
struct platform_device *pdev;

/* Physical-presence section */
Expand Down

0 comments on commit ec36060

Please sign in to comment.