diff options
author | David Härdeman <david@hardeman.nu> | 2011-04-28 16:14:03 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 00:59:41 +0200 |
commit | f8e00d5fa86fbc4462647da162152d4e74db784c (patch) | |
tree | 142c42d64707914aea0b6194322c3cd6db47c9c3 /drivers/media/rc/ir-lirc-codec.c | |
parent | [media] lmedm04: fix data usage past the end of the buffer (diff) | |
download | linux-f8e00d5fa86fbc4462647da162152d4e74db784c.tar.xz linux-f8e00d5fa86fbc4462647da162152d4e74db784c.zip |
[media] rc-core: move timeout and checks to lirc
The lirc TX functionality expects the process which writes (TX) data to
the lirc dev to sleep until the actual data has been transmitted by the
hardware.
Since the same timeout calculation is duplicated in more than one driver
(and would have to be duplicated in even more drivers as they gain TX
support), it makes sense to move this timeout calculation to the lirc
layer instead.
At the same time, centralize some of the sanity checks.
Signed-off-by: David Härdeman <david@hardeman.nu>
Cc: Jarod Wilson <jwilson@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/rc/ir-lirc-codec.c')
-rw-r--r-- | drivers/media/rc/ir-lirc-codec.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index d2fd064474aa..6ad4a0770613 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -107,6 +107,12 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, unsigned int *txbuf; /* buffer with values to transmit */ ssize_t ret = -EINVAL; size_t count; + ktime_t start; + s64 towait; + unsigned int duration = 0; /* signal duration in us */ + int i; + + start = ktime_get(); lirc = lirc_get_pdata(file); if (!lirc) @@ -129,11 +135,30 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, goto out; } - if (dev->tx_ir) - ret = dev->tx_ir(dev, txbuf, count); + if (!dev->tx_ir) { + ret = -ENOSYS; + goto out; + } + + ret = dev->tx_ir(dev, txbuf, (u32)n); + if (ret < 0) + goto out; + + for (i = 0; i < ret; i++) + duration += txbuf[i]; - if (ret > 0) - ret *= sizeof(unsigned); + ret *= sizeof(unsigned int); + + /* + * The lircd gap calculation expects the write function to + * wait for the actual IR signal to be transmitted before + * returning. + */ + towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); + if (towait > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(towait)); + } out: kfree(txbuf); |