media: rc-core: improve ir_raw_store_edge() handling
authorSean Young <sean@mess.org>
Sun, 6 Aug 2017 19:25:52 +0000 (15:25 -0400)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Sun, 20 Aug 2017 13:55:48 +0000 (09:55 -0400)
The gpio-ir-recv driver does many wakeups (once per edge); the saa7134
driver has special handling to only wakeup 15ms after the first edge.
Make this part of rc-core so gpio-ir-recv also benefits from
this (so a rc-5 keypress now causes 3 wakeups rather than 24).

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/pci/saa7134/saa7134-input.c
drivers/media/rc/rc-core-priv.h
drivers/media/rc/rc-ir-raw.c

index ba1fc77a6f7b25f9fafd9e170be9e6b78a78d8b0..81e27ddcf6dffc171e3ef9a685d4b9d6a1a14bc6 100644 (file)
@@ -452,13 +452,6 @@ static void saa7134_input_timer(unsigned long data)
        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 }
 
-static void ir_raw_decode_timer_end(unsigned long data)
-{
-       struct saa7134_dev *dev = (struct saa7134_dev *)data;
-
-       ir_raw_event_handle(dev->remote->dev);
-}
-
 static int __saa7134_ir_start(void *priv)
 {
        struct saa7134_dev *dev = priv;
@@ -514,10 +507,6 @@ static int __saa7134_ir_start(void *priv)
                            (unsigned long)dev);
                ir->timer.expires = jiffies + HZ;
                add_timer(&ir->timer);
-       } else if (ir->raw_decode) {
-               /* set timer_end for code completion */
-               setup_timer(&ir->timer, ir_raw_decode_timer_end,
-                           (unsigned long)dev);
        }
 
        return 0;
@@ -535,7 +524,7 @@ static void __saa7134_ir_stop(void *priv)
        if (!ir->running)
                return;
 
-       if (ir->polling || ir->raw_decode)
+       if (ir->polling)
                del_timer_sync(&ir->timer);
 
        ir->running = false;
@@ -1057,7 +1046,6 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
 {
        struct saa7134_card_ir *ir = dev->remote;
-       unsigned long timeout;
        int space;
 
        /* Generate initial event */
@@ -1066,17 +1054,5 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev)
        space = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2) & ir->mask_keydown;
        ir_raw_event_store_edge(dev->remote->dev, space ? IR_SPACE : IR_PULSE);
 
-       /*
-        * Wait 15 ms from the start of the first IR event before processing
-        * the event. This time is enough for NEC protocol. May need adjustments
-        * to work with other protocols.
-        */
-       smp_mb();
-
-       if (!timer_pending(&ir->timer)) {
-               timeout = jiffies + msecs_to_jiffies(15);
-               mod_timer(&ir->timer, timeout);
-       }
-
        return 1;
 }
index b3e7cac2c3eee7780711bea7340becb4f4b02c8e..cae13efc1a884a488369baff59f1f41f9b05c3f9 100644 (file)
@@ -43,6 +43,8 @@ struct ir_raw_event_ctrl {
        ktime_t                         last_event;     /* when last event occurred */
        enum raw_event_type             last_type;      /* last event type */
        struct rc_dev                   *dev;           /* pointer to the parent rc_dev */
+       /* edge driver */
+       struct timer_list edge_handle;
 
        /* raw decoder state follows */
        struct ir_raw_event prev_ev;
index b6d256f0384727c95eca781ee302504522bd8245..07a694298119491445d3059be7d8351d5479cda8 100644 (file)
@@ -133,6 +133,11 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type)
 
        dev->raw->last_event = now;
        dev->raw->last_type = type;
+
+       if (!timer_pending(&dev->raw->edge_handle))
+               mod_timer(&dev->raw->edge_handle,
+                         jiffies + msecs_to_jiffies(15));
+
        return rc;
 }
 EXPORT_SYMBOL_GPL(ir_raw_event_store_edge);
@@ -483,6 +488,13 @@ int ir_raw_encode_scancode(enum rc_type protocol, u32 scancode,
 }
 EXPORT_SYMBOL(ir_raw_encode_scancode);
 
+static void edge_handle(unsigned long arg)
+{
+       struct rc_dev *dev = (struct rc_dev *)arg;
+
+       ir_raw_event_handle(dev);
+}
+
 /*
  * Used to (un)register raw event clients
  */
@@ -504,6 +516,8 @@ int ir_raw_event_prepare(struct rc_dev *dev)
 
        dev->raw->dev = dev;
        dev->change_protocol = change_protocol;
+       setup_timer(&dev->raw->edge_handle, edge_handle,
+                   (unsigned long)dev);
        INIT_KFIFO(dev->raw->kfifo);
 
        return 0;
@@ -555,6 +569,7 @@ void ir_raw_event_unregister(struct rc_dev *dev)
                return;
 
        kthread_stop(dev->raw->thread);
+       del_timer_sync(&dev->raw->edge_handle);
 
        mutex_lock(&ir_raw_handler_lock);
        list_del(&dev->raw->list);