summaryrefslogtreecommitdiff
path: root/drivers/media/rc/nuvoton-cir.c
diff options
context:
space:
mode:
authorMatthijs Kooijman <matthijs@stdin.nl>2012-11-02 12:13:56 (GMT)
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-12-21 20:26:11 (GMT)
commit9fa35204dd19eb0e96ee870b7128a8f5da51dbfa (patch)
tree5496a8441112847b57a97324c39e907d77cff5c4 /drivers/media/rc/nuvoton-cir.c
parentd62b6818477704683d00c680335eff5833bd3906 (diff)
downloadlinux-fsl-qoriq-9fa35204dd19eb0e96ee870b7128a8f5da51dbfa.tar.xz
[media] rc: Call rc_register_device before irq setup
This should fix a potential race condition, when the irq handler triggers while rc_register_device is still setting up the rdev->raw device. This crash has not been observed in practice, but there should be a very small window where it could occur. Since ir_raw_event_store_with_filter checks if rdev->raw is not NULL before using it, this bug is not triggered if the request_irq triggers a pending irq directly (since rdev->raw will still be NULL then). This commit was tested on nuvoton-cir only. Cc: Jarod Wilson <jarod@redhat.com> Cc: Maxim Levitsky <maximlevitsky@gmail.com> Cc: David Härdeman <david@hardeman.nu> Signed-off-by: Matthijs Kooijman <matthijs@stdin.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc/nuvoton-cir.c')
-rw-r--r--drivers/media/rc/nuvoton-cir.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index c6441e6..6cf43cc 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1067,11 +1067,15 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
#endif
nvt->rdev = rdev;
+ ret = rc_register_device(rdev);
+ if (ret)
+ goto exit_free_dev_rdev;
+
ret = -EBUSY;
/* now claim resources */
if (!request_region(nvt->cir_addr,
CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
- goto exit_free_dev_rdev;
+ goto exit_unregister_device;
if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
NVT_DRIVER_NAME, (void *)nvt))
@@ -1085,10 +1089,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
NVT_DRIVER_NAME, (void *)nvt))
goto exit_release_cir_wake_addr;
- ret = rc_register_device(rdev);
- if (ret)
- goto exit_free_wake_irq;
-
device_init_wakeup(&pdev->dev, true);
nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
@@ -1099,14 +1099,14 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
return 0;
-exit_free_wake_irq:
- free_irq(nvt->cir_wake_irq, nvt);
exit_release_cir_wake_addr:
release_region(nvt->cir_wake_addr, CIR_IOREG_LENGTH);
exit_free_irq:
free_irq(nvt->cir_irq, nvt);
exit_release_cir_addr:
release_region(nvt->cir_addr, CIR_IOREG_LENGTH);
+exit_unregister_device:
+ rc_unregister_device(rdev);
exit_free_dev_rdev:
rc_free_device(rdev);
kfree(nvt);