Commit 3862de1f authored by Vakul Garg's avatar Vakul Garg Committed by Herbert Xu

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: default avatarVakul Garg <vakul@freescale.com>
Signed-off-by: default avatarBharat Bhushan <bharat.bhushan@freescale.com>
Reviewed-by: default avatarHoria Geanta <horia.geanta@freescale.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent f3f935a7
...@@ -41,6 +41,7 @@ struct caam_jrentry_info { ...@@ -41,6 +41,7 @@ struct caam_jrentry_info {
/* Private sub-storage for a single JobR */ /* Private sub-storage for a single JobR */
struct caam_drv_private_jr { struct caam_drv_private_jr {
struct device *parentdev; /* points back to controller dev */ struct device *parentdev; /* points back to controller dev */
struct platform_device *jr_pdev;/* points to platform device for JR */
int ridx; int ridx;
struct caam_job_ring __iomem *rregs; /* JobR's register space */ struct caam_job_ring __iomem *rregs; /* JobR's register space */
struct tasklet_struct irqtask; struct tasklet_struct irqtask;
......
...@@ -407,6 +407,7 @@ int caam_jr_shutdown(struct device *dev) ...@@ -407,6 +407,7 @@ int caam_jr_shutdown(struct device *dev)
dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH, dma_free_coherent(dev, sizeof(struct jr_outentry) * JOBR_DEPTH,
jrp->outring, outbusaddr); jrp->outring, outbusaddr);
kfree(jrp->entinfo); kfree(jrp->entinfo);
of_device_unregister(jrp->jr_pdev);
return ret; return ret;
} }
...@@ -454,6 +455,8 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np, ...@@ -454,6 +455,8 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
kfree(jrpriv); kfree(jrpriv);
return -EINVAL; return -EINVAL;
} }
jrpriv->jr_pdev = jr_pdev;
jrdev = &jr_pdev->dev; jrdev = &jr_pdev->dev;
dev_set_drvdata(jrdev, jrpriv); dev_set_drvdata(jrdev, jrpriv);
ctrlpriv->jrdev[ring] = jrdev; ctrlpriv->jrdev[ring] = jrdev;
...@@ -472,6 +475,7 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np, ...@@ -472,6 +475,7 @@ int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
/* Now do the platform independent part */ /* Now do the platform independent part */
error = caam_jr_init(jrdev); /* now turn on hardware */ error = caam_jr_init(jrdev); /* now turn on hardware */
if (error) { if (error) {
of_device_unregister(jr_pdev);
kfree(jrpriv); kfree(jrpriv);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment