diff options
author | Andi Shyti <andi.shyti@samsung.com> | 2016-07-06 12:01:14 +0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-07-13 20:54:58 +0300 |
commit | 70143984dd2c714386ee2d6c0f650bff75873d75 (patch) | |
tree | 39446cf67f9084b122bc5ddd415969c634336fea /drivers/media | |
parent | 6fa99e1af1981d9a57cc73b5c2f05903f18413c1 (diff) | |
download | linux-70143984dd2c714386ee2d6c0f650bff75873d75.tar.xz |
[media] lirc_dev: allow bufferless driver registration
Transmitters don't necessarily need to have a FIFO managed buffer
for their transfers.
When registering the driver, before allocating the buffer, check
whether the device is a transmitter or receiver. Allocate the
buffer only for receivers.
Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/rc/lirc_dev.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 571697811e4d..154e553b3b67 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -205,12 +205,14 @@ err_out: static int lirc_allocate_buffer(struct irctl *ir) { - int err; + int err = 0; int bytes_in_key; unsigned int chunk_size; unsigned int buffer_size; struct lirc_driver *d = &ir->d; + mutex_lock(&lirc_dev_lock); + bytes_in_key = BITS_TO_LONGS(d->code_length) + (d->code_length % 8 ? 1 : 0); buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; @@ -220,21 +222,26 @@ static int lirc_allocate_buffer(struct irctl *ir) ir->buf = d->rbuf; } else { ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); - if (!ir->buf) - return -ENOMEM; + if (!ir->buf) { + err = -ENOMEM; + goto out; + } err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); if (err) { kfree(ir->buf); - return err; + goto out; } } ir->chunk_size = ir->buf->chunk_size; - return 0; +out: + mutex_unlock(&lirc_dev_lock); + + return err; } -int lirc_register_driver(struct lirc_driver *d) +static int lirc_allocate_driver(struct lirc_driver *d) { struct irctl *ir; int minor; @@ -342,10 +349,6 @@ int lirc_register_driver(struct lirc_driver *d) /* some safety check 8-) */ d->name[sizeof(d->name)-1] = '\0'; - err = lirc_allocate_buffer(ir); - if (err) - goto out_lock; - if (d->features == 0) d->features = LIRC_CAN_REC_LIRCCODE; @@ -385,6 +388,23 @@ out_lock: out: return err; } + +int lirc_register_driver(struct lirc_driver *d) +{ + int minor, err = 0; + + minor = lirc_allocate_driver(d); + if (minor < 0) + return minor; + + if (LIRC_CAN_REC(d->features)) { + err = lirc_allocate_buffer(irctls[minor]); + if (err) + lirc_unregister_driver(minor); + } + + return err ? err : minor; +} EXPORT_SYMBOL(lirc_register_driver); int lirc_unregister_driver(int minor) |