aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam
diff options
context:
space:
mode:
authorVakul Garg <vakul@freescale.com>2013-04-15 00:25:51 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-04-25 09:09:07 -0400
commit3862de1f6c442d53bd828d39f86d07d933a70605 (patch)
treec2899b4cae0a427eecca8c57891baaae5976765b /drivers/crypto/caam
parentf3f935a76aa0eee68da2b273a08d84ba8ffc7a73 (diff)
crypto: caam - fix job ring cleanup code
The job ring init function creates a platform device for each job ring. While the job ring is shutdown, e.g. while caam module removal, its platform device was not being removed. This leads to failure while reinsertion and then removal of caam module second time. The following kernel crash dump appears when caam module is reinserted and then removed again. This patch fixes it. root@p4080ds:~# rmmod caam.ko Unable to handle kernel paging request for data at address 0x00000008 Faulting instruction address: 0xf94aca18 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=8 P4080 DS Modules linked in: caam(-) qoriq_dbg(O) [last unloaded: caam] NIP: f94aca18 LR: f94aca18 CTR: c029f950 REGS: eac47d60 TRAP: 0300 Tainted: G O (3.8.4-rt2) MSR: 00029002 <CE,EE,ME> CR: 22022484 XER: 20000000 DEAR: 00000008, ESR: 00000000 TASK = e49dfaf0[2110] 'rmmod' THREAD: eac46000 CPU: 1 GPR00: f94ad3f4 eac47e10 e49dfaf0 00000000 00000005 ea2ac210 ffffffff 00000000 GPR08: c286de68 e4977ce0 c029b1c0 00000001 c029f950 10029738 00000000 100e0000 GPR16: 00000000 10023d00 1000cbdc 1000cb8c 1000cbb8 00000000 c07dfecc 00000000 GPR24: c07e0000 00000000 1000cbd8 f94e0000 ffffffff 00000000 ea53cd40 00000000 NIP [f94aca18] caam_reset_hw_jr+0x18/0x1c0 [caam] LR [f94aca18] caam_reset_hw_jr+0x18/0x1c0 [caam] Call Trace: [eac47e10] [eac47e30] 0xeac47e30 (unreliable) [eac47e20] [f94ad3f4] caam_jr_shutdown+0x34/0x220 [caam] [eac47e60] [f94ac0e4] caam_remove+0x54/0xb0 [caam] [eac47e80] [c029fb38] __device_release_driver+0x68/0x120 [eac47e90] [c02a05c8] driver_detach+0xd8/0xe0 [eac47eb0] [c029f8e0] bus_remove_driver+0xa0/0x110 [eac47ed0] [c00768e4] sys_delete_module+0x144/0x270 [eac47f40] [c000e2f0] ret_from_syscall+0x0/0x3c Signed-off-by: Vakul Garg <vakul@freescale.com> Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com> Reviewed-by: Horia Geanta <horia.geanta@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r--drivers/crypto/caam/intern.h1
-rw-r--r--drivers/crypto/caam/jr.c4
2 files changed, 5 insertions, 0 deletions
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 5cd4c1b268a1..e4a16b741371 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -41,6 +41,7 @@ struct caam_jrentry_info {
41/* Private sub-storage for a single JobR */ 41/* Private sub-storage for a single JobR */
42struct caam_drv_private_jr { 42struct caam_drv_private_jr {
43 struct device *parentdev; /* points back to controller dev */ 43 struct device *parentdev; /* points back to controller dev */
44 struct platform_device *jr_pdev;/* points to platform device for JR */
44 int ridx; 45 int ridx;
45 struct caam_job_ring __iomem *rregs; /* JobR's register space */ 46 struct caam_job_ring __iomem *rregs; /* JobR's register space */
46 struct tasklet_struct irqtask; 47 struct tasklet_struct irqtask;
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 93d14070141a..b4aa773ecbc8 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -407,6 +407,7 @@ int caam_jr_shutdown(struct device *dev)
407 dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, 407 dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
408 jrp->outring, outbusaddr); 408 jrp->outring, outbusaddr);
409 kfree(jrp->entinfo); 409 kfree(jrp->entinfo);
410 of_device_unregister(jrp->jr_pdev);
410 411
411 return ret; 412 return ret;
412} 413}
@@ -454,6 +455,8 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
454 kfree(jrpriv); 455 kfree(jrpriv);
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
458
459 jrpriv->jr_pdev = jr_pdev;
457 jrdev = &jr_pdev->dev; 460 jrdev = &jr_pdev->dev;
458 dev_set_drvdata(jrdev, jrpriv); 461 dev_set_drvdata(jrdev, jrpriv);
459 ctrlpriv->jrdev[ring] = jrdev; 462 ctrlpriv->jrdev[ring] = jrdev;
@@ -472,6 +475,7 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
472 /* Now do the platform independent part */ 475 /* Now do the platform independent part */
473 error = caam_jr_init(jrdev); /* now turn on hardware */ 476 error = caam_jr_init(jrdev); /* now turn on hardware */
474 if (error) { 477 if (error) {
478 of_device_unregister(jr_pdev);
475 kfree(jrpriv); 479 kfree(jrpriv);
476 return error; 480 return error;
477 } 481 }