diff options
author | Horia Geantă <horia.geanta@nxp.com> | 2017-04-03 11:12:04 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-04-05 09:20:15 -0400 |
commit | ec360607a25fae97c81eef2f02268ae8ed3649b4 (patch) | |
tree | 6fc53fd820ad07ee4b0e2e5d9ac2fe0a8823c0ee /drivers | |
parent | 9df0eb180c2074451f25556eb566d89c7057c2ac (diff) |
crypto: caam - fix JR platform device subsequent (re)creations
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: <stable@vger.kernel.org>
Fixes: 313ea293e9c4d ("crypto: caam - Add Platform driver for Job Ring")
Reported-by: Russell King <rmk+kernel@armlinux.org.uk>
Suggested-by: Rob Herring <robh+dt@kernel.org>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/crypto/caam/ctrl.c | 63 | ||||
-rw-r--r-- | drivers/crypto/caam/intern.h | 1 |
2 files changed, 19 insertions, 45 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index fef39f9f41ee..220f94bd1635 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c | |||
@@ -301,15 +301,13 @@ static int caam_remove(struct platform_device *pdev) | |||
301 | struct device *ctrldev; | 301 | struct device *ctrldev; |
302 | struct caam_drv_private *ctrlpriv; | 302 | struct caam_drv_private *ctrlpriv; |
303 | struct caam_ctrl __iomem *ctrl; | 303 | struct caam_ctrl __iomem *ctrl; |
304 | int ring; | ||
305 | 304 | ||
306 | ctrldev = &pdev->dev; | 305 | ctrldev = &pdev->dev; |
307 | ctrlpriv = dev_get_drvdata(ctrldev); | 306 | ctrlpriv = dev_get_drvdata(ctrldev); |
308 | ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl; | 307 | ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl; |
309 | 308 | ||
310 | /* Remove platform devices for JobRs */ | 309 | /* Remove platform devices under the crypto node */ |
311 | for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) | 310 | of_platform_depopulate(ctrldev); |
312 | of_device_unregister(ctrlpriv->jrpdev[ring]); | ||
313 | 311 | ||
314 | /* De-initialize RNG state handles initialized by this driver. */ | 312 | /* De-initialize RNG state handles initialized by this driver. */ |
315 | if (ctrlpriv->rng4_sh_init) | 313 | if (ctrlpriv->rng4_sh_init) |
@@ -418,10 +416,21 @@ DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u32_ro, caam_debugfs_u32_get, NULL, "%llu\n"); | |||
418 | DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n"); | 416 | DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n"); |
419 | #endif | 417 | #endif |
420 | 418 | ||
419 | static const struct of_device_id caam_match[] = { | ||
420 | { | ||
421 | .compatible = "fsl,sec-v4.0", | ||
422 | }, | ||
423 | { | ||
424 | .compatible = "fsl,sec4.0", | ||
425 | }, | ||
426 | {}, | ||
427 | }; | ||
428 | MODULE_DEVICE_TABLE(of, caam_match); | ||
429 | |||
421 | /* Probe routine for CAAM top (controller) level */ | 430 | /* Probe routine for CAAM top (controller) level */ |
422 | static int caam_probe(struct platform_device *pdev) | 431 | static int caam_probe(struct platform_device *pdev) |
423 | { | 432 | { |
424 | int ret, ring, ridx, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; | 433 | int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; |
425 | u64 caam_id; | 434 | u64 caam_id; |
426 | struct device *dev; | 435 | struct device *dev; |
427 | struct device_node *nprop, *np; | 436 | struct device_node *nprop, *np; |
@@ -597,47 +606,24 @@ static int caam_probe(struct platform_device *pdev) | |||
597 | goto iounmap_ctrl; | 606 | goto iounmap_ctrl; |
598 | } | 607 | } |
599 | 608 | ||
600 | /* | 609 | ret = of_platform_populate(nprop, caam_match, NULL, dev); |
601 | * Detect and enable JobRs | 610 | if (ret) { |
602 | * First, find out how many ring spec'ed, allocate references | 611 | dev_err(dev, "JR platform devices creation error\n"); |
603 | * for all, then go probe each one. | ||
604 | */ | ||
605 | rspec = 0; | ||
606 | for_each_available_child_of_node(nprop, np) | ||
607 | if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || | ||
608 | of_device_is_compatible(np, "fsl,sec4.0-job-ring")) | ||
609 | rspec++; | ||
610 | |||
611 | ctrlpriv->jrpdev = devm_kcalloc(&pdev->dev, rspec, | ||
612 | sizeof(*ctrlpriv->jrpdev), GFP_KERNEL); | ||
613 | if (ctrlpriv->jrpdev == NULL) { | ||
614 | ret = -ENOMEM; | ||
615 | goto iounmap_ctrl; | 612 | goto iounmap_ctrl; |
616 | } | 613 | } |
617 | 614 | ||
618 | ring = 0; | 615 | ring = 0; |
619 | ridx = 0; | ||
620 | ctrlpriv->total_jobrs = 0; | ||
621 | for_each_available_child_of_node(nprop, np) | 616 | for_each_available_child_of_node(nprop, np) |
622 | if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || | 617 | if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || |
623 | of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { | 618 | of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { |
624 | ctrlpriv->jrpdev[ring] = | ||
625 | of_platform_device_create(np, NULL, dev); | ||
626 | if (!ctrlpriv->jrpdev[ring]) { | ||
627 | pr_warn("JR physical index %d: Platform device creation error\n", | ||
628 | ridx); | ||
629 | ridx++; | ||
630 | continue; | ||
631 | } | ||
632 | ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) | 619 | ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) |
633 | ((__force uint8_t *)ctrl + | 620 | ((__force uint8_t *)ctrl + |
634 | (ridx + JR_BLOCK_NUMBER) * | 621 | (ring + JR_BLOCK_NUMBER) * |
635 | BLOCK_OFFSET | 622 | BLOCK_OFFSET |
636 | ); | 623 | ); |
637 | ctrlpriv->total_jobrs++; | 624 | ctrlpriv->total_jobrs++; |
638 | ring++; | 625 | ring++; |
639 | ridx++; | 626 | } |
640 | } | ||
641 | 627 | ||
642 | /* Check to see if QI present. If so, enable */ | 628 | /* Check to see if QI present. If so, enable */ |
643 | ctrlpriv->qi_present = | 629 | ctrlpriv->qi_present = |
@@ -847,17 +833,6 @@ disable_caam_ipg: | |||
847 | return ret; | 833 | return ret; |
848 | } | 834 | } |
849 | 835 | ||
850 | static struct of_device_id caam_match[] = { | ||
851 | { | ||
852 | .compatible = "fsl,sec-v4.0", | ||
853 | }, | ||
854 | { | ||
855 | .compatible = "fsl,sec4.0", | ||
856 | }, | ||
857 | {}, | ||
858 | }; | ||
859 | MODULE_DEVICE_TABLE(of, caam_match); | ||
860 | |||
861 | static struct platform_driver caam_driver = { | 836 | static struct platform_driver caam_driver = { |
862 | .driver = { | 837 | .driver = { |
863 | .name = "caam", | 838 | .name = "caam", |
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h index e2bcacc1a921..dbed8baeebe5 100644 --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h | |||
@@ -66,7 +66,6 @@ struct caam_drv_private_jr { | |||
66 | struct caam_drv_private { | 66 | struct caam_drv_private { |
67 | 67 | ||
68 | struct device *dev; | 68 | struct device *dev; |
69 | struct platform_device **jrpdev; /* Alloc'ed array per sub-device */ | ||
70 | struct platform_device *pdev; | 69 | struct platform_device *pdev; |
71 | 70 | ||
72 | /* Physical-presence section */ | 71 | /* Physical-presence section */ |