summaryrefslogtreecommitdiff
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorHeiner Kallweit <hkallweit1@gmail.com>2016-02-01 23:49:32 +0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-02-02 19:28:37 +0300
commit842096fc40519e85bd4c0751e65a07cc3e23bd66 (patch)
tree903a848861fe73c9a548e977b965c236cc22be75 /drivers/media/rc
parent6b3f99989eb73e5250bba9dfeaa852939acfbf70 (diff)
downloadlinux-842096fc40519e85bd4c0751e65a07cc3e23bd66.tar.xz
[media] rc/nuvoton_cir: fix locking issue with nvt_enable_cir
nvt_enable_cir calls nvt_enable_logical_dev (that may sleep) while holding a spinlock. This patch fixes this and moves the content of nvt_enable_cir to nvt_open as this is the only caller. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/nuvoton-cir.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index d428b4e6e26f..46a9ece66f75 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -942,23 +942,6 @@ static irqreturn_t nvt_cir_wake_isr(int irq, void *data)
return IRQ_HANDLED;
}
-static void nvt_enable_cir(struct nvt_dev *nvt)
-{
- /* set function enable flags */
- nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN |
- CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL,
- CIR_IRCON);
-
- /* enable the CIR logical device */
- nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR);
-
- /* clear all pending interrupts */
- nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
-
- /* enable interrupts */
- nvt_set_cir_iren(nvt);
-}
-
static void nvt_disable_cir(struct nvt_dev *nvt)
{
/* disable CIR interrupts */
@@ -984,9 +967,23 @@ static int nvt_open(struct rc_dev *dev)
unsigned long flags;
spin_lock_irqsave(&nvt->nvt_lock, flags);
- nvt_enable_cir(nvt);
+
+ /* set function enable flags */
+ nvt_cir_reg_write(nvt, CIR_IRCON_TXEN | CIR_IRCON_RXEN |
+ CIR_IRCON_RXINV | CIR_IRCON_SAMPLE_PERIOD_SEL,
+ CIR_IRCON);
+
+ /* clear all pending interrupts */
+ nvt_cir_reg_write(nvt, 0xff, CIR_IRSTS);
+
+ /* enable interrupts */
+ nvt_set_cir_iren(nvt);
+
spin_unlock_irqrestore(&nvt->nvt_lock, flags);
+ /* enable the CIR logical device */
+ nvt_enable_logical_dev(nvt, LOGICAL_DEV_CIR);
+
return 0;
}