summaryrefslogtreecommitdiffstats
path: root/drivers/media/rc
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2018-03-08 15:42:44 +0100
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2018-03-21 18:54:51 +0100
commit8d7a77ce56cdb5f50b83ca0c59a31362e1a5eeb4 (patch)
tree704d04613b6aedc97be22b042cac5ddc91aa058e /drivers/media/rc
parentmedia: cpia2_usb: drop bogus interface-release call (diff)
downloadlinux-8d7a77ce56cdb5f50b83ca0c59a31362e1a5eeb4.tar.xz
linux-8d7a77ce56cdb5f50b83ca0c59a31362e1a5eeb4.zip
media: rc: meson-ir: add timeout on idle
Meson doesn't seem to be able to generate timeout events in hardware. So install a software timer to generate the timeout events required by the decoders to prevent "ghost keypresses". Reported-by: Matthias Reichl <hias@horus.com> Tested-by: Matthias Reichl <hias@horus.com> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/rc')
-rw-r--r--drivers/media/rc/meson-ir.c3
-rw-r--r--drivers/media/rc/rc-ir-raw.c30
2 files changed, 28 insertions, 5 deletions
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index f2204eb77e2a..64b0aa4f4db7 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -97,8 +97,7 @@ static irqreturn_t meson_ir_irq(int irqno, void *dev_id)
status = readl_relaxed(ir->reg + IR_DEC_STATUS);
rawir.pulse = !!(status & STATUS_IR_DEC_IN);
- ir_raw_event_store(ir->rc, &rawir);
- ir_raw_event_handle(ir->rc);
+ ir_raw_event_store_with_timeout(ir->rc, &rawir);
spin_unlock(&ir->lock);
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 984bb82851f9..374f83105a23 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -92,7 +92,6 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
{
ktime_t now;
DEFINE_IR_RAW_EVENT(ev);
- int rc = 0;
if (!dev->raw)
return -EINVAL;
@@ -101,8 +100,33 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
ev.duration = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
ev.pulse = !pulse;
+ return ir_raw_event_store_with_timeout(dev, &ev);
+}
+EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
+
+/*
+ * ir_raw_event_store_with_timeout() - pass a pulse/space duration to the raw
+ * ir decoders, schedule decoding and
+ * timeout
+ * @dev: the struct rc_dev device descriptor
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This routine (which may be called from an interrupt context) stores a
+ * pulse/space duration for the raw ir decoding state machines, schedules
+ * decoding and generates a timeout.
+ */
+int ir_raw_event_store_with_timeout(struct rc_dev *dev, struct ir_raw_event *ev)
+{
+ ktime_t now;
+ int rc = 0;
+
+ if (!dev->raw)
+ return -EINVAL;
+
+ now = ktime_get();
+
spin_lock(&dev->raw->edge_spinlock);
- rc = ir_raw_event_store(dev, &ev);
+ rc = ir_raw_event_store(dev, ev);
dev->raw->last_event = now;
@@ -117,7 +141,7 @@ int ir_raw_event_store_edge(struct rc_dev *dev, bool pulse)
return rc;
}
-EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
+EXPORT_SYMBOL_GPL(ir_raw_event_store_with_timeout);
/**
* ir_raw_event_store_with_filter() - pass next pulse/space to decoders with some processing