aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHoria Geantă <horia.geanta@nxp.com>2017-04-03 11:12:04 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2017-04-05 09:20:15 -0400
commitec360607a25fae97c81eef2f02268ae8ed3649b4 (patch)
tree6fc53fd820ad07ee4b0e2e5d9ac2fe0a8823c0ee /drivers
parent9df0eb180c2074451f25556eb566d89c7057c2ac (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.c63
-rw-r--r--drivers/crypto/caam/intern.h1
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");
418DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n"); 416DEFINE_SIMPLE_ATTRIBUTE(caam_fops_u64_ro, caam_debugfs_u64_get, NULL, "%llu\n");
419#endif 417#endif
420 418
419static const struct of_device_id caam_match[] = {
420 {
421 .compatible = "fsl,sec-v4.0",
422 },
423 {
424 .compatible = "fsl,sec4.0",
425 },
426 {},
427};
428MODULE_DEVICE_TABLE(of, caam_match);
429
421/* Probe routine for CAAM top (controller) level */ 430/* Probe routine for CAAM top (controller) level */
422static int caam_probe(struct platform_device *pdev) 431static 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
850static struct of_device_id caam_match[] = {
851 {
852 .compatible = "fsl,sec-v4.0",
853 },
854 {
855 .compatible = "fsl,sec4.0",
856 },
857 {},
858};
859MODULE_DEVICE_TABLE(of, caam_match);
860
861static struct platform_driver caam_driver = { 836static 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 {
66struct caam_drv_private { 66struct 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 */