diff options
author | Matthijs Kooijman <matthijs@stdin.nl> | 2012-11-02 09:13:56 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-12-21 18:26:11 -0200 |
commit | 9fa35204dd19eb0e96ee870b7128a8f5da51dbfa (patch) | |
tree | 5496a8441112847b57a97324c39e907d77cff5c4 /drivers/media/rc/nuvoton-cir.c | |
parent | d62b6818477704683d00c680335eff5833bd3906 (diff) | |
download | blackbird-op-linux-9fa35204dd19eb0e96ee870b7128a8f5da51dbfa.tar.gz blackbird-op-linux-9fa35204dd19eb0e96ee870b7128a8f5da51dbfa.zip |
[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.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index c6441e690dd4..6cf43cc237eb 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); |